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/MergeActor.py

    r16 r17  
    77
    88import os
    9 import sys
    10 import trac.env
     9import shutil
    1110
    12 import SvnOps
    13 from WorkQueue import MergeBotActor, VersionToDir
    14 from TrackerTools import GetWorkDir, GetRepositoryLocalUrl, Task, GetLogFile
     11from mergebot import SvnOps
     12from mergebot.Actor import Actor
    1513
    16 def merge_action(trac_env, ticketnum, component, version, requestor):
    17     "Merge a branch to its trunk"
    18     task_obj = Task(trac_env, ticketnum)
    19     logfile = GetLogFile(trac_env, ticketnum)
     14class MergeActor(Actor):
     15    """Merges a branch to the line of development on which it is based.
     16    """
     17    def execute(self):
     18        "Merge a branch to its trunk"
     19        results = {}
     20        logfile = self.logfilename()
     21        checkoutdir = self.work_dir
     22        # Delete the working directory so we get a completely clean working
     23        # copy.
     24        if os.path.exists(checkoutdir):
     25            shutil.rmtree(checkoutdir)
    2026
    21     checkoutdir = GetWorkDir(trac_env, ticketnum, __name__)
    22     # FIXME: Should we just bail out instead?
    23     if os.path.exists(checkoutdir):
    24         os.system("rm -rf \"%s\" >>%s 2>&1" % (checkoutdir, logfile))
     27        # Make sure the various urls we require do exist
     28        if not SvnOps.get_branch_info(self.local_url(), logfile):
     29            comment = 'Component %s does not exist in the repository.' \
     30                % self.component
     31            return results, comment, False
     32        if not SvnOps.get_branch_info(self.local_url() + '/branches', logfile):
     33            comment = 'No directory in which to create branches for component %s in the repository.' % self.component
     34            return results, comment, False
     35        if not SvnOps.get_branch_info(self.baseline_local_url(), logfile):
     36            comment = 'Version %s for component %s does not exist in the repository.' % (self.version, self.component)
     37            return results, comment, False
    2538
    26     sourceurl = os.path.join(GetRepositoryLocalUrl(trac_env), component,
    27         VersionToDir(version))
    28     ticketurl = os.path.join(GetRepositoryLocalUrl(trac_env), component, "branches",
    29         "ticket-%s" % ticketnum)
     39        rev_info = SvnOps.get_branch_info(self.branch_local_url(), logfile)
     40        if not rev_info:
     41            comment = 'Branch for ticket %s does not exist in the repository.' % (self.ticket)
     42            return results, comment, False
     43        startrev, endrev = rev_info
    3044
    31     # FIXME: needs error checking
    32     startrev, endrev = SvnOps.get_branch_info(ticketurl, logfile)
     45        SvnOps.checkout(self.baseline_local_url(), checkoutdir, logfile)
     46        # FIXME: check return code
     47        merge_results = SvnOps.merge(self.branch_local_url(), checkoutdir,
     48                               (startrev, endrev), logfile)
     49        conflicts = SvnOps.conflicts_from_merge_results(merge_results)
     50        if conflicts:
     51            comment = "\n".join([
     52                "Found %s conflicts in attempt to merge %s:%s to %s for %s." % \
     53                    (len(conflicts), startrev, endrev, self.version,
     54                     self.requestor),
     55                "Files in conflict:",
     56                "{{{",
     57                "\n".join(conflicts),
     58                "}}}",
     59                "A rebranch will be needed before this can be merged.",
     60            ])
     61            results['mergebotstate'] = 'conflicts'
     62            success = False
     63        else:
     64            # The merge worked, so commit the changes.
     65            commitmessage = "\n".join([
     66                "Ticket #%s: %s" % (self.ticket, self.summary),
     67                "    Merge of %s:%s to %s for %s." % (startrev, endrev,
     68                    self.version, self.requestor),
     69            ])
     70            committedrev = SvnOps.commit(checkoutdir, commitmessage, logfile)
     71            # Sed message and endstatus
     72            if committedrev == None:
     73                # Apparently nothing to commit.
     74                comment = "\n".join([
     75                    "Merged %s:%s to %s for %s." % (startrev, endrev,
     76                        self.version, self.requestor),
     77                    "No changes to commit.",
     78                ])
     79                results['mergebotstate'] = 'merged'
     80                success = True
     81            elif committedrev >= 0:
     82                # The commit succeeded.
     83                comment = "\n".join([
     84                    "Merged %s:%s to %s for %s." % (startrev, endrev,
     85                        self.version, self.requestor),
     86                    "Changeset [%s]. [source:%s/%s@%s]" % (committedrev,
     87                        self.component, self.version_subdir(), committedrev),
     88                ])
     89                results['mergebotstate'] = 'merged'
     90                success = True
     91            else:
     92                # The commit for the merge failed.
     93                comment = \
     94                    "Commit failed in attempt to merge %s:%s to %s for %s." \
     95                    % (startrev, endrev, self.version, self.requestor)
     96                #results['mergebotstate'] = 'mergefailed'
     97                success = False
    3398
    34     SvnOps.checkout(sourceurl, checkoutdir, logfile)
    35     # FIXME: check return code
    36     results = SvnOps.merge(ticketurl, checkoutdir, (startrev, endrev), logfile)
    37     conflicts = SvnOps.conflicts_from_merge_results(results)
    38     if conflicts:
    39         message = "\n".join([
    40             "Found %s conflicts in attempt to merge %s:%s to %s for %s." % \
    41                 (len(conflicts), startrev, endrev, version, requestor),
    42             "Files in conflict:",
    43             "{{{",
    44             "\n".join(conflicts),
    45             "}}}",
    46             "A rebranch will be needed before this can be merged.",
    47         ])
    48         endstatus = "conflicts"
    49     else:
    50         # The merge worked, so commit the changes.
    51         summary = task_obj.GetSummary()
    52         commitmessage = "\n".join([
    53             "Ticket #%s: %s" % (ticketnum, summary),
    54             "    Merge of %s:%s to %s for %s." % (startrev, endrev, version,
    55                 requestor),
    56         ])
    57         committedrev = SvnOps.commit(checkoutdir, commitmessage, logfile)
    58         # Sed message and endstatus
    59         if committedrev == None:
    60             # Apparently nothing to commit.
    61             message = "\n".join([
    62                 "Merged %s:%s to %s for %s." % (startrev, endrev, version,
    63                     requestor),
    64                 "No changes to commit.",
    65             ])
    66             endstatus = "merged"
    67         elif committedrev >= 0:
    68             # The commit succeeded.
    69             message = "\n".join([
    70                 "Merged %s:%s to %s for %s." % (startrev, endrev, version,
    71                     requestor),
    72                 "Changeset [%s]. [source:%s/%s@%s]" % (committedrev,
    73                     component, VersionToDir(version), committedrev),
    74             ])
    75             endstatus = "merged"
    76         else:
    77             # The commit for the merge failed.
    78             message = "Commit failed in attempt to merge %s:%s to %s for %s." \
    79                 % (startrev, endrev, version, requestor)
    80             endstatus = "mergefailed"
     99        # Clean up the work area
     100        if os.path.exists(checkoutdir):
     101            shutil.rmtree(checkoutdir)
    81102
    82     # Clean up the work area
    83     os.system("rm -rf \"%s\" >>%s 2>&1" % (checkoutdir, logfile))
    84 
    85     task_obj.AddComment(message)
    86     return endstatus, task_obj
    87 
    88 class MergeActor(MergeBotActor):
    89     "Actor wrapper for merge_action"
    90     def __init__(self, trac_env):
    91         MergeBotActor.__init__(self, trac_env, "merge", merge_action)
    92 
    93 def main():
    94     tracdir = sys.argv[1]
    95     trac_env = trac.env.open_environment(tracdir)
    96     mergingActor = MergeActor(trac_env)
    97     mergingActor.AddTask(sys.argv[2:])
    98     mergingActor.Run()
    99 
    100 if __name__ == "__main__":
    101     main()
     103        return results, comment, success
    102104
    103105# vim:foldcolumn=4 foldmethod=indent
Note: See TracChangeset for help on using the changeset viewer.