Ignore:
Timestamp:
Jun 8, 2009 3:07:47 AM (15 years ago)
Author:
retracile
Message:

Mergebot: redesigned implementation. Still has rough edges.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • mergebot/trunk/mergebot/CheckMergeActor.py

    r16 r17  
    11#!/usr/bin/env python
    22"""
    3 Syntax: MergeActor.py ticketnum component version requestor
    4 
    53Verify that a branch can be merged to its trunk without conflicts, but don't
    64commit the merge.
     
    86
    97import os
    10 import sys
    11 import trac.env
     8import shutil
    129
    13 import SvnOps
    14 from WorkQueue import MergeBotActor, VersionToDir
    15 from TrackerTools import GetWorkDir, GetRepositoryLocalUrl, Task, GetLogFile
     10from mergebot import SvnOps
     11from mergebot.Actor import Actor
    1612
    17 def check_merge_action(trac_env, ticketnum, component, version, requestor):
     13class CheckMergeActor(Actor):
     14    """Checks that this ticket can be merged to its baseline, but don't modify
     15    the repository.
    1816    """
    19     Verify that a branch can be merged to its trunk without conflicts, but
    20     don't commit the merge.
    21     """
    22     task_obj = Task(trac_env, ticketnum)
    23     endstatus = "???????"
    24     workdir = GetWorkDir(trac_env, ticketnum, __name__)
    25     logfile = GetLogFile(trac_env, ticketnum)
    26     # FIXME: Should we just bail out instead?
    27     if os.path.exists(workdir):
    28         os.system("rm -rf \"%s\"" % (workdir))
     17    def execute(self):
     18        """
     19        Verify that a branch can be merged to its trunk without conflicts, but
     20        don't commit the merge.
     21        """
     22        results = {}
     23        workdir = self.work_dir
     24        logfile = self.logfilename()
    2925
    30     sourceurl = os.path.join(GetRepositoryLocalUrl(trac_env), component,
    31         VersionToDir(version))
    32     ticketurl = os.path.join(GetRepositoryLocalUrl(trac_env), component, "branches",
    33         "ticket-%s" % ticketnum)
     26        if os.path.exists(workdir):
     27            shutil.rmtree(workdir)
    3428
    35     branch_info = SvnOps.get_branch_info(ticketurl, GetLogFile(trac_env, ticketnum))
    36     # FIXME: if not branch_info: # Error case
    37     startrev, endrev = branch_info
     29        # Make sure the various urls we require do exist
     30        if not SvnOps.get_branch_info(self.local_url(), logfile):
     31            comment = 'Component %s does not exist in the repository.' \
     32                % self.component
     33            return results, comment, False
     34        if not SvnOps.get_branch_info(self.local_url() + '/branches', logfile):
     35            comment = 'No directory in which to create branches for ' \
     36                'component %s in the repository.' % self.component
     37            return results, comment, False
     38        if not SvnOps.get_branch_info(self.baseline_local_url(), logfile):
     39            comment = 'Version %s for component %s does not exist in the ' \
     40                'repository.' % (self.version, self.component)
     41            return results, comment, False
    3842
    39     SvnOps.checkout(sourceurl, workdir, logfile)
    40     # TODO: check return code of the above
    41     results = SvnOps.merge(ticketurl, workdir, (startrev, endrev), logfile)
    42     conflicts = SvnOps.conflicts_from_merge_results(results)
    43     if conflicts:
    44         message = "\n".join([
    45             "Found %s conflicts while checking merge of %s:%s to %s for %s." % \
    46                 (len(conflicts), startrev, endrev, version, requestor),
    47             "Files in conflict:",
    48             "{{{",
    49             "\n".join(conflicts),
    50             "}}}",
    51             "A rebranch will be needed before this can be merged.",
    52         ])
    53         endstatus = "conflicts"
    54     else:
    55         message = \
    56             "Found no conflicts while checking merge of %s:%s to %s for %s." \
    57             % (startrev, endrev, version, requestor)
    58         endstatus = "branched"
     43        branch_info = SvnOps.get_branch_info(self.branch_local_url(), logfile)
     44        if not branch_info:
     45            comment = 'Branch for ticket %s does not exist in the repository.' \
     46                % (self.ticket)
     47            return results, comment, False
     48        startrev, endrev = branch_info
    5949
    60     # Clean up the work area
    61     os.system("rm -rf \"%s\"" % (workdir, ))
     50        SvnOps.checkout(self.baseline_local_url(), workdir, logfile)
     51        # TODO: check return code of the above
     52        merge_results = SvnOps.merge(self.branch_local_url(), workdir,
     53                                     (startrev, endrev), logfile)
     54        conflicts = SvnOps.conflicts_from_merge_results(merge_results)
     55        if conflicts:
     56            message = '\n'.join([
     57                'Found %s conflicts while checking merge of %s:%s to %s for ' \
     58                    '%s.' % (len(conflicts), startrev, endrev, self.version,
     59                    self.requestor),
     60                'Files in conflict:',
     61                '{{{',
     62                '\n'.join(conflicts),
     63                '}}}',
     64                'A rebranch will be needed before this can be merged.',
     65            ])
     66            success = False
     67        else:
     68            message = 'Found no conflicts while checking merge of %s:%s to ' \
     69                '%s for %s.' % (startrev, endrev, self.version, self.requestor)
     70            success = True
    6271
    63     task_obj.AddComment(message)
    64     return endstatus, task_obj
     72        # Clean up the work area
     73        if os.path.exists(workdir):
     74            shutil.rmtree(workdir)
    6575
    66 class CheckMergeActor(MergeBotActor):
    67     "Actor wrapper for the check_merge_action"
    68     def __init__(self, trac_env):
    69         MergeBotActor.__init__(self, trac_env, "checkmerge", check_merge_action)
    70 
    71 def main():
    72     tracdir = sys.argv[1]
    73     trac_env = trac.env.open_environment(tracdir)
    74     mergingActor = CheckMergeActor(trac_env)
    75     mergingActor.AddTask(sys.argv[1:])
    76     mergingActor.Run()
    77 
    78 if __name__ == "__main__":
    79     main()
     76        return results, message, success
    8077
    8178# vim:foldcolumn=4 foldmethod=indent
Note: See TracChangeset for help on using the changeset viewer.