示例#1
0
文件: patch.py 项目: alarmz/esky
 def _diff_dotzip_file(self,source,target):
     s_zf = self._open_and_check_zipfile(source)
     if s_zf is None:
         self._diff_binary_file(source,target)
     else:
         t_zf = self._open_and_check_zipfile(target)
         if t_zf is None:
             s_zf.close()
             self._diff_binary_file(source,target)
         else:
             try:
                 self._write_command(PF_REC_ZIP)
                 with _tempdir() as workdir:
                     #  Write commands to transform source metadata file
                     #  into target metadata file.
                     s_meta = os.path.join(workdir,"s_meta")
                     with open(s_meta,"wb") as f:
                         _write_zipfile_metadata(f,s_zf)
                     t_meta = os.path.join(workdir,"t_meta")
                     with open(t_meta,"wb") as f:
                         _write_zipfile_metadata(f,t_zf)
                     self._diff_binary_file(s_meta,t_meta)
                     self._write_command(END)
                     #  Write commands to transform source contents
                     #  directory into target contents directory.
                     s_workdir = os.path.join(workdir,"source")
                     t_workdir = os.path.join(workdir,"target")
                     extract_zipfile(source,s_workdir)
                     extract_zipfile(target,t_workdir)
                     self._diff(s_workdir,t_workdir)
                     self._write_command(END)
             finally:
                 t_zf.close() 
                 s_zf.close() 
示例#2
0
 def _diff_dotzip_file(self,source,target):
     s_zf = self._open_and_check_zipfile(source)
     if s_zf is None:
         self._diff_binary_file(source,target)
     else:
         t_zf = self._open_and_check_zipfile(target)
         if t_zf is None:
             s_zf.close()
             self._diff_binary_file(source,target)
         else:
             try:
                 self._write_command(PF_REC_ZIP)
                 with _tempdir() as workdir:
                     #  Write commands to transform source metadata file
                     #  into target metadata file.
                     s_meta = os.path.join(workdir,"s_meta")
                     with open(s_meta,"wb") as f:
                         _write_zipfile_metadata(f,s_zf)
                     t_meta = os.path.join(workdir,"t_meta")
                     with open(t_meta,"wb") as f:
                         _write_zipfile_metadata(f,t_zf)
                     self._diff_binary_file(s_meta,t_meta)
                     self._write_command(END)
                     #  Write commands to transform source contents
                     #  directory into target contents directory.
                     s_workdir = os.path.join(workdir,"source")
                     t_workdir = os.path.join(workdir,"target")
                     extract_zipfile(source,s_workdir)
                     extract_zipfile(target,t_workdir)
                     self._diff(s_workdir,t_workdir)
                     self._write_command(END)
             finally:
                 t_zf.close()
                 s_zf.close()
示例#3
0
文件: patch.py 项目: alarmz/esky
    def _do_PF_REC_ZIP(self):
        """Execute the PF_REC_ZIP command.

        This patches the current target by treating it as a zipfile and
        recursing into it.  It extracts the source file to a temp directory,
        then reads commands and applies them to that directory.

        This command expects two END-terminated blocks of sub-commands.  The
        first block patches the zipfile metadata, and the second patches the
        actual contents of the zipfile.
        """
        self._check_begin_patch()
        if not self.dry_run:
            workdir = os.path.join(self._workdir,str(len(self._context_stack)))
            os.mkdir(workdir)
            t_temp = os.path.join(workdir,"contents")
            m_temp = os.path.join(workdir,"meta")
            z_temp = os.path.join(workdir,"result.zip")
        cur_state = self._blank_state()
        zfmeta = [None]  # stupid lack of mutable closure variables...
        #  First we process a set of commands to generate the zipfile metadata.
        def end_metadata():
            if not self.dry_run:
                zfmeta[0] = _read_zipfile_metadata(m_temp)
                self.target = t_temp
        #  Then we process a set of commands to patch the actual contents.
        def end_contents():
            self._restore_state(cur_state)
            if not self.dry_run:
                create_zipfile(t_temp,z_temp,members=zfmeta[0].infolist())
                with open(z_temp,"rb") as f:
                    data = f.read(1024*16)
                    while data:
                        self.outfile.write(data)
                        data = f.read(1024*16)
                zfmeta[0].close()
                really_rmtree(workdir)
        self._context_stack.append(end_contents)
        self._context_stack.append(end_metadata)
        if not self.dry_run:
            #  Begin by writing the current zipfile metadata to a temp file.
            #  This will be patched, then end_metadata() will be called.
            with open(m_temp,"wb") as f:
                zf = zipfile.ZipFile(self.target)
                try:
                    _write_zipfile_metadata(f,zf)
                finally:
                    zf.close()
            extract_zipfile(self.target,t_temp)
            self.root_dir = workdir
            self.target = m_temp
示例#4
0
    def _do_PF_REC_ZIP(self):
        """Execute the PF_REC_ZIP command.

        This patches the current target by treating it as a zipfile and
        recursing into it.  It extracts the source file to a temp directory,
        then reads commands and applies them to that directory.

        This command expects two END-terminated blocks of sub-commands.  The
        first block patches the zipfile metadata, and the second patches the
        actual contents of the zipfile.
        """
        self._check_begin_patch()
        if not self.dry_run:
            workdir = os.path.join(self._workdir,str(len(self._context_stack)))
            os.mkdir(workdir)
            t_temp = os.path.join(workdir,"contents")
            m_temp = os.path.join(workdir,"meta")
            z_temp = os.path.join(workdir,"result.zip")
        cur_state = self._blank_state()
        zfmeta = [None]  # stupid lack of mutable closure variables...
        #  First we process a set of commands to generate the zipfile metadata.
        def end_metadata():
            if not self.dry_run:
                zfmeta[0] = _read_zipfile_metadata(m_temp)
                self.target = t_temp
        #  Then we process a set of commands to patch the actual contents.
        def end_contents():
            self._restore_state(cur_state)
            if not self.dry_run:
                create_zipfile(t_temp,z_temp,members=zfmeta[0].infolist())
                with open(z_temp,"rb") as f:
                    data = f.read(1024*16)
                    while data:
                        self.outfile.write(data)
                        data = f.read(1024*16)
                zfmeta[0].close()
                really_rmtree(workdir)
        self._context_stack.append(end_contents)
        self._context_stack.append(end_metadata)
        if not self.dry_run:
            #  Begin by writing the current zipfile metadata to a temp file.
            #  This will be patched, then end_metadata() will be called.
            with open(m_temp,"wb") as f:
                zf = zipfile.ZipFile(self.target)
                try:
                    _write_zipfile_metadata(f,zf)
                finally:
                    zf.close()
            extract_zipfile(self.target,t_temp)
            self.root_dir = workdir
            self.target = m_temp
示例#5
0
文件: test_esky.py 项目: orng/esky
    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()
示例#6
0
    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()
示例#7
0
文件: patch.py 项目: alarmz/esky
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)
示例#8
0
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)