Changeset 45160 in webkit


Ignore:
Timestamp:
Jun 25, 2009 1:09:28 AM (15 years ago)
Author:
eric@webkit.org
Message:

2009-06-24 Eric Seidel <eric@webkit.org>

Reviewed by Dave Levin.

Support local commits during apply-patches
and let land-patches take multiple bug ids.
https://bugs.webkit.org/show_bug.cgi?id=26703

I also restructured parts of land-patches into
class methods and static methods in preparation
for future code sharing with other commands.

  • Scripts/bugzilla-tool:
  • Scripts/modules/bugzilla.py:
  • Scripts/modules/scm.py:
Location:
trunk/WebKitTools
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebKitTools/ChangeLog

    r45153 r45160  
     12009-06-24  Eric Seidel  <eric@webkit.org>
     2
     3        Reviewed by Dave Levin.
     4
     5        Support local commits during apply-patches
     6        and let land-patches take multiple bug ids.
     7        https://bugs.webkit.org/show_bug.cgi?id=26703
     8
     9        I also restructured parts of land-patches into
     10        class methods and static methods in preparation
     11        for future code sharing with other commands.
     12
     13        * Scripts/bugzilla-tool:
     14        * Scripts/modules/bugzilla.py:
     15        * Scripts/modules/scm.py:
     16
    1172009-06-25  Eric Seidel  <eric@webkit.org>
    218
  • trunk/WebKitTools/Scripts/bugzilla-tool

    r45062 r45160  
    4848    exit(1)
    4949
     50def plural(noun):
     51    # This is a dumb plural() implementation which was just enough for our uses.
     52    if re.search('h$', noun):
     53        return noun + 'es'
     54    else:
     55        return noun + 's'
     56
     57def pluralize(noun, count):
     58    if count != 1:
     59        noun = plural(noun)
     60    return "%d %s" % (count, noun)
     61
    5062# These could be put in some sort of changelogs.py.
    5163def latest_changelog_entry(changelog_path):
     
    159171            make_option("--force-clean", action="store_true", dest="force_clean", default=False, help="Clean working directory before applying patches (removes local changes and commits)"),
    160172            make_option("--no-clean", action="store_false", dest="clean", default=True, help="Don't check if the working directory is clean before applying patches"),
     173            make_option("--local-commit", action="store_true", dest="local_commit", default=False, help="Make a local commit for each applied patch"),
    161174        ]
    162175        Command.__init__(self, 'Applies all patches on a bug to the local working directory without committing.', 'BUGID', options=options)
     176
     177    @staticmethod
     178    def apply_patches(patches, scm, commit_each):
     179        for patch in patches:
     180            scm.apply_patch(patch)
     181            if commit_each:
     182                commit_message = commit_message_for_this_commit(scm)
     183                scm.commit_locally_with_message(commit_message or patch['name'])
    163184
    164185    def execute(self, options, args, tool):
     
    171192            tool.scm().update_webkit()
    172193       
    173         for patch in patches:
    174             # FIXME: Should have an option to local-commit each patch after application.
    175             tool.scm().apply_patch(patch)
    176 
     194        if options.local_commit and not tool.scm().supports_local_commits():
     195            error("--local-commit passed, but %s does not support local commits" % tool.scm().display_name())
     196       
     197        self.apply_patches(patches, tool.scm(), options.local_commit)
    177198
    178199def bug_comment_from_commit_text(commit_text):
     
    202223
    203224
    204 class LandPatchesFromBug(Command):
     225class LandPatchesFromBugs(Command):
    205226    def __init__(self):
    206227        options = [
     
    218239        return_code = build_webkit_process.wait()
    219240        if return_code:
    220             raise ScriptError(script_name + " failed with code " + return_code)
    221 
    222     def build_webkit(self):
    223         self.run_and_throw_if_fail("build-webkit")
    224 
    225     def run_webkit_tests(self):
    226         self.run_and_throw_if_fail("run-webkit-tests")
    227 
    228     def execute(self, options, args, tool):
    229         bug_id = args[0]
    230 
     241            raise ScriptError("%s failed with exit code %d" % (script_name, return_code))
     242
     243    @classmethod
     244    def build_webkit(cls):
     245        cls.run_and_throw_if_fail("build-webkit")
     246
     247    @classmethod
     248    def run_webkit_tests(cls):
     249        cls.run_and_throw_if_fail("run-webkit-tests")
     250
     251    @staticmethod
     252    def setup_for_landing(scm, options):
     253        os.chdir(scm.checkout_root)
     254        scm.ensure_no_local_commits(options.force_clean)
     255        if options.clean:
     256            scm.ensure_clean_working_directory(options.force_clean)
     257        if options.update:
     258            scm.update_webkit()
     259
     260    @classmethod
     261    def build_and_commit(cls, scm, options):
     262        if options.build:
     263            cls.build_webkit()
     264            if options.test:
     265                cls.run_webkit_tests()
     266        commit_message = commit_message_for_this_commit(scm)
     267        commit_log = scm.commit_with_message(commit_message)
     268        return bug_comment_from_commit_text(commit_log)
     269
     270    @classmethod
     271    def land_patches(cls, bug_id, patches, options, tool):
    231272        try:
    232             patches = tool.bugs.fetch_reviewed_patches_from_bug(bug_id)
    233273            comment_text = ""
    234 
    235             os.chdir(tool.scm().checkout_root)
    236             tool.scm().ensure_no_local_commits(options.force_clean)
    237             if options.clean:
    238                 tool.scm().ensure_clean_working_directory(options.force_clean)
    239             if options.update:
    240                 tool.scm().update_webkit()
    241            
    242274            for patch in patches:
    243275                tool.scm().apply_patch(patch)
    244                 if options.build:
    245                     self.build_webkit()
    246                     if options.test:
    247                         self.run_webkit_tests()
    248                 commit_message = commit_message_for_this_commit(tool.scm())
    249                 commit_log = tool.scm().commit_with_message(commit_message)
    250                 comment_text = bug_comment_from_commit_text(commit_log)
     276                comment_text = cls.build_and_commit(tool.scm(), options)
     277
    251278                # If we're commiting more than one patch, update the bug as we go.
    252279                if len(patches) > 1:
     
    257284
    258285            tool.bugs.close_bug_as_fixed(bug_id, comment_text)
    259         except ScriptError, error:
    260             log(error)
    261             # We could add a comment to the bug about the failure.
    262 
     286        except ScriptError, e:
     287            # We should add a comment to the bug, and r- the patch on failure
     288            error(e)
     289
     290    def execute(self, options, args, tool):
     291        if not len(args):
     292            error("bug-id(s) required")
     293
     294        bugs_to_patches = {}
     295        patch_count = 0
     296        for bug_id in args:
     297            patches = tool.bugs.fetch_reviewed_patches_from_bug(bug_id)
     298            if not len(patches):
     299                exit("No reviewed patches found on %s" % bug_id)
     300            patch_count += len(patches)
     301            bugs_to_patches[bug_id] = patches
     302
     303        log("Landing %s from %s." % (pluralize("patch", patch_count), pluralize("bug", len(args))))
     304       
     305        self.setup_for_landing(tool.scm(), options)
     306
     307        for bug_id in args:
     308            self.land_patches(bug_id, bugs_to_patches[bug_id], options, tool)
    263309
    264310class CommitMessageForCurrentDiff(Command):
     
    318364       
    319365        if len(commit_ids) > 10:
    320             log("Are you sure you want to attach %d patches to bug %s?" % (len(commit_ids), bug_id))
     366            log("Are you sure you want to attach %s to bug %s?" % (pluralize('patch', len(commit_ids)), bug_id))
    321367            # Could add a --patches-limit option.
    322368            exit(1)
    323369       
    324         log("Attaching %d commits as patches to bug %s" % (len(commit_ids), bug_id))
     370        log("Attaching %s as patches to bug %s" % (pluralize('commit', len(commit_ids)), bug_id))
    325371        for commit_id in commit_ids:
    326372            commit_message = tool.scm().commit_message_for_commit(commit_id)
     
    358404            { 'name' : 'apply-patches', 'object' : ApplyPatchesFromBug() },
    359405            { 'name' : 'land-and-update', 'object' : LandAndUpdateBug() },
    360             { 'name' : 'land-patches', 'object' : LandPatchesFromBug() },
     406            { 'name' : 'land-patches', 'object' : LandPatchesFromBugs() },
    361407            { 'name' : 'commit-message', 'object' : CommitMessageForCurrentDiff() },
    362408            { 'name' : 'obsolete-attachments', 'object' : ObsoleteAttachmentsOnBug() },
  • trunk/WebKitTools/Scripts/modules/bugzilla.py

    r45152 r45160  
    147147            attachment['url'] = self.bug_server + attachment_link['href'] # urls are relative
    148148            attachment['id'] = attachment['url'].split('=')[1] # e.g. https://bugs.webkit.org/attachment.cgi?id=31223
    149             attachment['name'] = attachment_link.string
     149            attachment['name'] = str(attachment_link.string) # w/o str it returns some sort of non-string object
    150150            # attachment['type'] = cells[1]
    151151            # attachment['date'] = cells[2]
  • trunk/WebKitTools/Scripts/modules/scm.py

    r45152 r45160  
    6666        exit_code = process.wait()
    6767        if raise_on_failure and exit_code:
    68             raise ScriptError("Failed to run " + command)
     68            raise ScriptError('Failed to run "%s"  exit_code: %d  cwd: %s' % (command, exit_code, cwd))
    6969        if return_exit_code:
    7070            return exit_code
     
    7373    def ensure_clean_working_directory(self, force):
    7474        if not force and not self.working_directory_is_clean():
    75             print self.run_command(self.status_command())
     75            print self.run_command(self.status_command(), raise_on_failure=False)
    7676            error("Working directory has modifications, pass --force-clean or --no-clean to continue.")
    7777       
     
    147147        raise NotImplementedError, "subclasses must implement"
    148148
     149    def commit_locally_with_message(self, message):
     150        pass
     151
    149152    def discard_local_commits(self):
    150153        pass
Note: See TracChangeset for help on using the changeset viewer.