def do_apply()

in tools/client-side/svn-vendor.py [0:0]


    def do_apply(self, arg):
        '''
        apply : Perform copies/renames; then copy imported sources into
                the working copy. Modifies working copy. Exits after
                completion.
        '''
        self.info(1, "Copying imported sources into working copy...")
        # Perform the recorded copies/moves/removals
        self.info(2, "  Preparatory operations (copies/renames/removals)")
        to_be_diffed = []
        for o in self.prepare_ops:
            op = o[0]
            if op == "mv":
                self.run_svn(["mv", "--parents", o[1], o[2]])
                to_be_diffed.append(o[2])
            elif op == "cp":
                self.run_svn(["cp", "--parents", o[1], o[2]])
                to_be_diffed.append(o[2])
            elif op == "rm":
                # --force, as the removed path is likely created as a result
                # of previous copy/rename
                self.run_svn(["rm", "--force", o[1]])
        dirs_added = []
        dirs_removed = []
        files_added = []
        files_removed = []
        files_set_exec = []
        files_clear_exec = []

        self.info(2, "  Creating dirs and copying files...")
        def copyfile_helper(i, nk_wc):
            '''Helper: copy a file and optionally, transfer permissions.'''
            f = os.path.join(self.importdir, i)
            t = os.path.join(self.wcdir, i)
            shutil.copyfile(f, t)
            # If exec-permission is 'clear', we don't need to do anything:
            # shutil.copyfile will create the file as non-executable.
            if self.config.get('exec-permission') == 'preserve':
                # If the file is new, just copying the mode is enough:
                # svn will set the svn:executable upon adding it.
                if nk_wc == "F":
                    # Existing file, check what the setting shall be
                    if os.access(f, os.X_OK) and not os.access(t, os.X_OK):
                        files_set_exec.append(i)
                    elif not os.access(f, os.X_OK) and os.access(t, os.X_OK):
                        files_clear_exec.append(i)
                shutil.copymode(f, t)

        for i in sorted(self.items.keys()):
            e = self.items[i]
            nk_wc = e.state[S_WC]
            nk_im = e.state[S_IM]
            flg = None
            if nk_wc == "-":
                # Absent in working copy
                if nk_im == "D":
                    # Directory added
                    os.mkdir(os.path.join(self.wcdir, i))
                    dirs_added.append(i)
                    flg = "(added dir)"
                elif nk_im == "F":
                    # New file added
                    copyfile_helper(i, nk_wc);
                    files_added.append(i)
                    flg = "(added file)"
                elif nk_im == "L":
                    tim = os.readlink(os.path.join(self.importdir, i))
                    os.symlink(tim, os.path.join(self.wcdir, i))
                    files_added.append(i)
                    flg = "(added symlink)"
                else:
                    # Not in imported sources, not in WC (moved
                    # away/removed) - nothing to do
                    pass
            elif nk_wc == "L":
                # Symbolic link in a working copy
                if nk_im == "L":
                    # Symbolic link in both. If the same target, do nothing. Otherwise,
                    # replace.
                    twc = os.readlink(os.path.join(self.wcdir, i))
                    tim = os.readlink(os.path.join(self.importdir, i))
                    if tim != twc:
                        self.run_svn(["rm", "--force", i])
                        os.symlink(tim, os.path.join(self.wcdir, i))
                        files_added.append(i)
                        flg = "(replaced symlink)"
                elif nk_im == "D":
                    # Was a symlink, now a directory. Replace.
                    self.run_svn(["rm", "--force", i])
                    os.mkdir(os.path.join(self.wcdir, i))
                    dirs_added.append(i)
                    flg = "(replaced symlink with dir)"
                elif nk_im == "F":
                    # Symlink replaced with file.
                    self.run_svn(["rm", "--force", i])
                    copyfile_helper(i, nk_wc);
                    files_added.append(i)
                    flg = "(replaced symlink with file)"
                else:
                    # Was a symlink, removed
                    files_removed.append(i)
                    flg = "(removed symlink)"
            elif nk_wc == "F":
                # File in a working copy
                if nk_im == "D":
                    # File replaced with a directory. See comment above.
                    self.run_svn(["rm", "--force", i])
                    os.mkdir(os.path.join(self.wcdir, i))
                    dirs_added.append(i)
                    flg = "(replaced file with dir)"
                elif nk_im == "F":
                    # Was a file, is a file - just copy contents
                    copyfile_helper(i, nk_wc);
                    flg = "(copied)"
                elif nk_im == "L":
                    # Was a file, now a symlink. Replace.
                    self.run_svn(["rm", "--force", i])
                    tim = os.readlink(os.path.join(self.importdir, i))
                    os.symlink(tim, os.path.join(self.wcdir, i))
                    files_added.append(i)
                    flg = "(replaced file with symlink)"
                else:
                    # Was a file, removed
                    files_removed.append(i)
                    flg = "(removed file)"
            elif nk_wc == "D":
                # Directory in a working copy
                if nk_im == "D":
                    # Was a directory, is a directory - nothing to do
                    pass
                elif nk_im == "F":
                    # Directory replaced with file. Need to remove dir
                    # immediately, as bulk removals/additions assume new files
                    # and dirs already in place. Also, removing a directory
                    # removes all its descendants - mark them as removed.
                    self.run_svn(["rm", "--force", i])
                    self.items.wc_remove(i)
                    copyfile_helper(i, nk_wc);
                    files_added.append(i)
                    flg = "(replaced dir with file)"
                elif nk_im == "L":
                    # Was a directory, now a symlink. Replace.
                    self.run_svn(["rm", "--force", i])
                    self.items.wc_remove(i)
                    tim = os.readlink(os.path.join(self.importdir, i))
                    os.symlink(tim, os.path.join(self.wcdir, i))
                    files_added.append(i)
                    flg = "(replaced dir with symlink)"
                else:
                    # Directory removed
                    dirs_removed.append(i)
                    flg = "(removed dir)"
            if flg is not None:
                self.info(4, "    %s %s %s" % (e.status(), i, flg))
        # Filter files/directories removed as a part of parent directory
        files_removed = list(filter(lambda x: os.path.dirname(x) not in
                dirs_removed, files_removed))
        dirs_removed = list(filter(lambda x: os.path.dirname(x) not in
            dirs_removed, dirs_removed))
        files_added = list(filter(lambda x: os.path.dirname(x) not in
            dirs_added, files_added))
        dirs_added = list(filter(lambda x: os.path.dirname(x) not in
            dirs_added, dirs_added))
        self.info(2, "  Running SVN add/rm/propset/propdel commands");
        if len(dirs_added):
            self.run_svn(["add"], dirs_added)
        if len(files_added):
            self.run_svn(["add"], files_added)
        if len(dirs_removed):
            self.run_svn(["rm"], dirs_removed)
        if len(files_removed):
            self.run_svn(["rm"], files_removed)
        if len(files_set_exec):
            self.run_svn(["propset", "svn:executable", "*"], files_set_exec)
        if len(files_clear_exec):
            self.run_svn(["propdel", "svn:executable"], files_clear_exec)
        # Save the diff for the copied/moved items
        diff_save = self.config.get('save-diff-copied')
        if diff_save is not None:
            self.info(2, "  Saving 'svn diff' on copied files/dirs to `%s'" %
                    diff_save)
            to_be_diffed = list(filter(lambda x: os.path.dirname(x) not in
                to_be_diffed, to_be_diffed))
            if len(to_be_diffed):
                try:
                    rv, out = self.run_svn(["diff"], to_be_diffed)
                except UnicodeDecodeError:
                    # Some binary files not marked with appropriate MIME type,
                    # or broken text files
                    rv, out = (True, "WARNING: diff contained binary files\n")
            else:
                rv, out = (True, "")
            if rv:
                f = open(diff_save, "w")
                f.write(out)
                f.close()
        # Exiting, as the resulting working copy can no longer be used
        # for move analysis
        self.info(1, "Done. Exiting; please examine the working copy " +
                "and commit.")
        return True