def test_esky_patch(): '''need to have our esky fixes developed in freeze future moved to f_py2exe or f_cxfrexe etc for patchingo work''' tdir=os.getcwd() uzdir = os.path.join(tdir,"unzip") try: really_rmtree(uzdir) except Exception: pass setup, options, new_script = esky_setup('Simple Working', WORKING_SCRIPT) setup(**options) new_script2 = make_new_script_name('testing_patching.py') insert_code(new_script2,'import sys') options2 = copy.deepcopy(options) options2['scripts'] = [new_script2] options2['script_args'] = ['bdist_esky_patch'] options2['version'] = '2.0' options2['freezer'] = '2.0' setup(**options2) platform = get_platform() deep_extract_zipfile(os.path.join(tdir,"dist","Simple Working-1.0.%s.zip"%(platform,)),uzdir) with open(os.path.join(tdir,"dist","Simple Working-2.0.%s.from-1.0.patch"%(platform,)),"rb") as f: esky.patch.apply_patch(uzdir,f) filewithext = os.path.basename(new_script2) file = os.path.splitext(filewithext)[0] path_file = os.path.join(uzdir, file) cmd = [path_file] proc = subprocess.Popen(cmd, stderr=subprocess.PIPE) errs = proc.communicate() if not proc.returncode: exit_code = True else: exit_code = False assert exit_code really_rmtree(uzdir)
def _run_eskytester(self, options): """Build and run the eskytester app using the given distutils options. The "eskytester" application can be found next to this file, and the sequence of tests performed range across "script1.py" to "script3.py". """ olddir = os.path.abspath(os.curdir) # tdir = os.path.join(os.path.dirname(__file__),"DIST") # if os.path.exists(tdir): # really_rmtree(tdir) # os.mkdir(tdir) tdir = tempfile.mkdtemp() server = None script2 = None try: options.setdefault("build", {})["build_base"] = os.path.join(tdir, "build") options.setdefault("bdist", {})["dist_dir"] = os.path.join(tdir, "dist") # Set some callbacks to test that they work correctly options.setdefault("bdist_esky", {}).setdefault( "pre_freeze_callback", "esky.tests.test_esky.assert_freezedir_exists" ) options.setdefault("bdist_esky", {}).setdefault("pre_zip_callback", assert_freezedir_exists) platform = get_platform() deploydir = "deploy.%s" % (platform,) esky_root = dirname(dirname(dirname(__file__))) os.chdir(tdir) shutil.copytree(os.path.join(esky_root, "esky", "tests", "eskytester"), "eskytester") dir_util._path_created.clear() # Build three increasing versions of the test package. # Version 0.2 will include a bundled MSVCRT on win32. # Version 0.3 will be distributed as a patch. metadata = dict( name="eskytester", packages=["eskytester"], author="rfk", description="the esky test package", data_files=[("data", ["eskytester/datafile.txt"])], package_data={"eskytester": ["pkgdata.txt"]}, ) options2 = options.copy() options2["bdist_esky"] = options["bdist_esky"].copy() options2["bdist_esky"]["bundle_msvcrt"] = True script1 = "eskytester/script1.py" script2 = Executable([None, open("eskytester/script2.py")], name="script2") script3 = "eskytester/script3.py" dist_setup(version="0.1", scripts=[script1], options=options, script_args=["bdist_esky"], **metadata) dist_setup( version="0.2", scripts=[script1, script2], options=options2, script_args=["bdist_esky"], **metadata ) dist_setup( version="0.3", scripts=[script2, script3], options=options, script_args=["bdist_esky_patch"], **metadata ) os.unlink(os.path.join(tdir, "dist", "eskytester-0.3.%s.zip" % (platform,))) # Check that the patches apply cleanly uzdir = os.path.join(tdir, "unzip") deep_extract_zipfile(os.path.join(tdir, "dist", "eskytester-0.1.%s.zip" % (platform,)), uzdir) with open(os.path.join(tdir, "dist", "eskytester-0.3.%s.from-0.1.patch" % (platform,)), "rb") as f: esky.patch.apply_patch(uzdir, f) shutil.rmtree(uzdir) deep_extract_zipfile(os.path.join(tdir, "dist", "eskytester-0.2.%s.zip" % (platform,)), uzdir) with open(os.path.join(tdir, "dist", "eskytester-0.3.%s.from-0.2.patch" % (platform,)), "rb") as f: esky.patch.apply_patch(uzdir, f) shutil.rmtree(uzdir) # Serve the updates at http://localhost:8000/dist/ print "running local update server" server = HTTPServer(("localhost", 8000), SimpleHTTPRequestHandler) server_thread = threading.Thread(target=server.serve_forever) server_thread.daemon = True server_thread.start() # Set up the deployed esky environment for the initial version zfname = os.path.join(tdir, "dist", "eskytester-0.1.%s.zip" % (platform,)) os.mkdir(deploydir) extract_zipfile(zfname, deploydir) # Run the scripts in order. if options["bdist_esky"]["freezer_module"] == "py2app": appdir = os.path.join(deploydir, os.listdir(deploydir)[0]) cmd1 = os.path.join(appdir, "Contents", "MacOS", "script1") cmd2 = os.path.join(appdir, "Contents", "MacOS", "script2") cmd3 = os.path.join(appdir, "Contents", "MacOS", "script3") else: appdir = deploydir if sys.platform == "win32": cmd1 = os.path.join(deploydir, "script1.exe") cmd2 = os.path.join(deploydir, "script2.exe") cmd3 = os.path.join(deploydir, "script3.exe") else: cmd1 = os.path.join(deploydir, "script1") cmd2 = os.path.join(deploydir, "script2") cmd3 = os.path.join(deploydir, "script3") print "spawning eskytester script1", options["bdist_esky"]["freezer_module"] os.unlink(os.path.join(tdir, "dist", "eskytester-0.1.%s.zip" % (platform,))) p = subprocess.Popen(cmd1) assert p.wait() == 0 os.unlink(os.path.join(appdir, "tests-completed")) print "spawning eskytester script2" os.unlink(os.path.join(tdir, "dist", "eskytester-0.2.%s.zip" % (platform,))) p = subprocess.Popen(cmd2) assert p.wait() == 0 os.unlink(os.path.join(appdir, "tests-completed")) print "spawning eskytester script3" p = subprocess.Popen(cmd3) assert p.wait() == 0 os.unlink(os.path.join(appdir, "tests-completed")) finally: if script2: script2.script[1].close() os.chdir(olddir) if sys.platform == "win32": # wait for the cleanup-at-exit pocess to finish time.sleep(4) really_rmtree(tdir) if server: server.shutdown()
else: if path[0][0].endswith(".patch"): # We're direcly applying a series of patches. # Copy the current version across and go from there. try: self._copy_best_version(app,uppath) except EnvironmentError, e: self.version_graph.remove_all_links(path[0][1]) err = "couldn't copy current version: %s" % (e,) raise PatchError(err) patches = path else: # We're starting from a zipfile. Extract the first dir # containing more than a single item and go from there. try: deep_extract_zipfile(path[0][0],uppath) except (zipfile.BadZipfile,zipfile.LargeZipFile): self.version_graph.remove_all_links(path[0][1]) try: os.unlink(path[0][0]) except EnvironmentError: pass raise patches = path[1:] # TODO: remove compatability hooks for ESKY_APPDATA_DIR="". # If a patch fails to apply because we've put an appdata dir # where it doesn't expect one, try again with old layout. for _ in xrange(2): # Apply any patches in turn. for (patchfile,patchurl) in patches: try:
def _run_eskytester(self, options): """Build and run the eskytester app using the given distutils options. The "eskytester" application can be found next to this file, and the sequence of tests performed range across "script1.py" to "script3.py". """ olddir = os.path.abspath(os.curdir) # tdir = os.path.join(os.path.dirname(__file__),"DIST") # if os.path.exists(tdir): # really_rmtree(tdir) # os.mkdir(tdir) tdir = tempfile.mkdtemp() server = None script2 = None try: options.setdefault("build", {})["build_base"] = os.path.join(tdir, "build") options.setdefault("bdist", {})["dist_dir"] = os.path.join(tdir, "dist") # Set some callbacks to test that they work correctly options.setdefault("bdist_esky", {}).setdefault( "pre_freeze_callback", "esky.tests.test_esky.assert_freezedir_exists") options.setdefault("bdist_esky", {}).setdefault("pre_zip_callback", assert_freezedir_exists) options["bdist_esky"].setdefault("excludes", []).extend(["Tkinter", "tkinter"]) platform = get_platform() deploydir = "deploy.%s" % (platform, ) esky_root = dirname(dirname(dirname(__file__))) os.chdir(tdir) shutil.copytree( os.path.join(esky_root, "esky", "tests", "eskytester"), "eskytester") dir_util._path_created.clear() # Build three increasing versions of the test package. # Version 0.2 will include a bundled MSVCRT on win32. # Version 0.3 will be distributed as a patch. metadata = dict( name="eskytester", packages=["eskytester"], author="rfk", description="the esky test package", data_files=[("data", ["eskytester/datafile.txt"])], package_data={"eskytester": ["pkgdata.txt"]}, ) options2 = options.copy() options2["bdist_esky"] = options["bdist_esky"].copy() options2["bdist_esky"]["bundle_msvcrt"] = True script1 = "eskytester/script1.py" script2 = Executable([None, open("eskytester/script2.py")], name="script2") script3 = "eskytester/script3.py" dist_setup(version="0.1", scripts=[script1], options=options, script_args=["bdist_esky"], **metadata) dist_setup(version="0.2", scripts=[script1, script2], options=options2, script_args=["bdist_esky"], **metadata) dist_setup(version="0.3", scripts=[script2, script3], options=options, script_args=["bdist_esky_patch"], **metadata) os.unlink( os.path.join(tdir, "dist", "eskytester-0.3.%s.zip" % (platform, ))) # Check that the patches apply cleanly uzdir = os.path.join(tdir, "unzip") deep_extract_zipfile( os.path.join(tdir, "dist", "eskytester-0.1.%s.zip" % (platform, )), uzdir) with open( os.path.join( tdir, "dist", "eskytester-0.3.%s.from-0.1.patch" % (platform, )), "rb") as f: esky.patch.apply_patch(uzdir, f) really_rmtree(uzdir) deep_extract_zipfile( os.path.join(tdir, "dist", "eskytester-0.2.%s.zip" % (platform, )), uzdir) with open( os.path.join( tdir, "dist", "eskytester-0.3.%s.from-0.2.patch" % (platform, )), "rb") as f: esky.patch.apply_patch(uzdir, f) really_rmtree(uzdir) # Serve the updates at LOCAL_HTTP_PORT set in esky.util print "running local update server" try: server = HTTPServer(("localhost", LOCAL_HTTP_PORT), SimpleHTTPRequestHandler) except Exception: # in travis ci we start our own server pass else: server_thread = threading.Thread(target=server.serve_forever) server_thread.daemon = True server_thread.start() # Set up the deployed esky environment for the initial version zfname = os.path.join(tdir, "dist", "eskytester-0.1.%s.zip" % (platform, )) os.mkdir(deploydir) extract_zipfile(zfname, deploydir) # Run the scripts in order. if options["bdist_esky"]["freezer_module"] == "py2app": appdir = os.path.join(deploydir, os.listdir(deploydir)[0]) cmd1 = os.path.join(appdir, "Contents", "MacOS", "script1") cmd2 = os.path.join(appdir, "Contents", "MacOS", "script2") cmd3 = os.path.join(appdir, "Contents", "MacOS", "script3") else: appdir = deploydir if sys.platform == "win32": cmd1 = os.path.join(deploydir, "script1.exe") cmd2 = os.path.join(deploydir, "script2.exe") cmd3 = os.path.join(deploydir, "script3.exe") else: cmd1 = os.path.join(deploydir, "script1") cmd2 = os.path.join(deploydir, "script2") cmd3 = os.path.join(deploydir, "script3") print "spawning eskytester script1", options["bdist_esky"][ "freezer_module"] os.unlink( os.path.join(tdir, "dist", "eskytester-0.1.%s.zip" % (platform, ))) p = subprocess.Popen(cmd1) assert p.wait() == 0 os.unlink(os.path.join(appdir, "tests-completed")) print "spawning eskytester script2" os.unlink( os.path.join(tdir, "dist", "eskytester-0.2.%s.zip" % (platform, ))) p = subprocess.Popen(cmd2) assert p.wait() == 0 os.unlink(os.path.join(appdir, "tests-completed")) print "spawning eskytester script3" p = subprocess.Popen(cmd3) assert p.wait() == 0 os.unlink(os.path.join(appdir, "tests-completed")) finally: if script2: script2.script[1].close() os.chdir(olddir) if sys.platform == "win32": # wait for the cleanup-at-exit pocess to finish time.sleep(4) really_rmtree(tdir) if server: server.shutdown()
def main(args): """Command-line diffing and patching for esky.""" parser = optparse.OptionParser() parser.add_option("-z","--zipped",action="store_true",dest="zipped", help="work with zipped source/target dirs") parser.add_option("-Z","--deep-zipped",action="store_true", dest="deep_zipped", help="work with deep zipped source/target dirs") parser.add_option("","--diff-window",dest="diff_window",metavar="N", help="set the window size for diffing files") parser.add_option("","--dry-run",dest="dry_run",action="store_true", help="print commands instead of executing them") (opts,args) = parser.parse_args(args) if opts.deep_zipped: opts.zipped = True if opts.zipped: workdir = tempfile.mkdtemp() if opts.diff_window: scale = 1 if opts.diff_window[-1].lower() == "k": scale = 1024 opts.diff_window = opts.diff_window[:-1] elif opts.diff_window[-1].lower() == "m": scale = 1024 * 1024 opts.diff_window = opts.diff_window[:-1] elif opts.diff_window[-1].lower() == "g": scale = 1024 * 1024 * 1024 opts.diff_window = opts.diff_window[:-1] opts.diff_window = int(float(opts.diff_window)*scale) stream = None try: cmd = args[0] if cmd == "diff": # Generate a diff between two files/directories. # If --zipped is specified, the source and/or target is unzipped # to a temporary directory before processing. source = args[1] target = args[2] if len(args) > 3: stream = open(args[3],"wb") else: stream = sys.stdout if opts.zipped: if os.path.isfile(source): source_zip = source source = os.path.join(workdir,"source") if opts.deep_zipped: deep_extract_zipfile(source_zip,source) else: extract_zipfile(source_zip,source) if os.path.isfile(target): target_zip = target target = os.path.join(workdir,"target") if opts.deep_zipped: deep_extract_zipfile(target_zip,target) else: extract_zipfile(target_zip,target) write_patch(source,target,stream,diff_window_size=opts.diff_window) elif cmd == "patch": # Patch a file or directory. # If --zipped is specified, the target is unzipped to a temporary # directory before processing, then overwritten with a zipfile # containing the new directory contents. target = args[1] if len(args) > 2: stream = open(args[2],"rb") else: stream = sys.stdin target_zip = None if opts.zipped: if os.path.isfile(target): target_zip = target target = os.path.join(workdir,"target") if opts.deep_zipped: deep_extract_zipfile(target_zip,target) else: extract_zipfile(target_zip,target) apply_patch(target,stream,dry_run=opts.dry_run) if opts.zipped and target_zip is not None: target_dir = os.path.dirname(target_zip) (fd,target_temp) = tempfile.mkstemp(dir=target_dir) os.close(fd) if opts.deep_zipped: prefix = zipfile_common_prefix_dir(target_zip) def name_filter(nm): return prefix + nm create_zipfile(target,target_temp,name_filter) else: create_zipfile(target,target_temp) if sys.platform == "win32": os.unlink(target_zip) time.sleep(0.01) really_rename(target_temp,target_zip) else: raise ValueError("invalid command: " + cmd) finally: if stream is not None: if stream not in (sys.stdin,sys.stdout,): stream.close() if opts.zipped: really_rmtree(workdir)