mirror of
https://github.com/vaadin/framework.git
synced 2024-08-05 20:16:03 +02:00
705 lines
21 KiB
Python
705 lines
21 KiB
Python
#!/usr/bin/python
|
|
|
|
import sys,re,os,string,urllib,httplib
|
|
|
|
################################################################################
|
|
# Configuration
|
|
################################################################################
|
|
|
|
# Determine repository root
|
|
pin = os.popen("svn info|grep 'Repository Root'|sed -e 's/^.\+: //'", "r")
|
|
REPOSITORY = pin.read().rstrip()+"/"
|
|
pin.close()
|
|
|
|
print "Repository: %s" % (REPOSITORY)
|
|
|
|
################################################################################
|
|
# Parse command-line arguments
|
|
################################################################################
|
|
def help(exitvalue = 0):
|
|
print "Usage: batchmerge [options] <command>\n"
|
|
print "Options:"
|
|
print "\t-m\tOnly merge. (For 'single' command.)"
|
|
print "\t-c\tOnly commit. (For 'single' command.)"
|
|
print "\t-html\tHTML output. (For 'log' command.)"
|
|
print "\t-author\tHTML output. (Include author in HTML log.)"
|
|
print "\t-milestone <ms>\tList tickets in milestone (For 'log' command.)"
|
|
print "\nCommands:"
|
|
print "massmerge <cfg> <src> [<from>] "
|
|
print " - Merges changesets listed in the configuration"
|
|
print " file. The file is in svn log (text) format."
|
|
print " You can comment out unwanted changesets."
|
|
print " Merge is stopped on conflict."
|
|
print " If you give the optional <from> parameter,"
|
|
print " merge is started from the changeset number. "
|
|
print "single <chg#> <target> - Merges a single changeset. If -m is given,"
|
|
print " only merge is done. If -c is given, only commit is done."
|
|
print "revert - Reverts all changes made to repository except"
|
|
print " changes in this program and the merge files."
|
|
print "log <cfg> <src> <trg> - Prints a ChangeLog as it will appear in the"
|
|
print " commit log. If -html option is given,"
|
|
print " the log is printed in a HTML format"
|
|
print " suitable for the Release Notes."
|
|
print "commit <cfg> <src> <trg> - Commits all changes, except changes to this"
|
|
print " program and merge files. The commit log"
|
|
print " comment includes list of all changesets"
|
|
print " listed in the configuration. The <target>"
|
|
print " is the branch name, e.g., \"5.2\".\n"
|
|
print "Common parameters:"
|
|
print " <cfg> - Configuration file (svn text log format)."
|
|
print " <src> - Source branch relative to repository URI."
|
|
print " <trg> - Target branch relative to repository URI."
|
|
print "You must run the command in the root directory of the branch."
|
|
print "The program file contains some basic configuration parameters."
|
|
sys.exit(exitvalue)
|
|
|
|
################################################################################
|
|
# Globals
|
|
################################################################################
|
|
tickets = {}
|
|
|
|
################################################################################
|
|
# Utility Functions
|
|
################################################################################
|
|
def command(cmd, dryrun=0):
|
|
print cmd
|
|
if not dryrun:
|
|
if os.system(cmd):
|
|
print "Command failed, exiting."
|
|
sys.exit(1)
|
|
else:
|
|
print "Dry run - not executing."
|
|
|
|
def listChangedFiles():
|
|
# Get Svn status
|
|
pin = os.popen("svn st", "r")
|
|
lines = pin.readlines()
|
|
pin.close()
|
|
|
|
changed = []
|
|
for line in lines:
|
|
# Remove trailing newline
|
|
line = line[:-1]
|
|
|
|
# Extract the file state and name
|
|
(filestate, filename) = re.split(r'[ \+]+', line.lstrip())
|
|
|
|
# Ignore files in build directory
|
|
if (filename.startswith("build/merge/") \
|
|
or filename.startswith("build/bin/mergetool.py") \
|
|
or filename.startswith("build/testing")) \
|
|
and filestate == "M":
|
|
continue
|
|
|
|
# File is changed if it is not local
|
|
if filestate != "?":
|
|
changed.append(filename)
|
|
|
|
return changed
|
|
|
|
# Retrieves ticket summary string with HTTP
|
|
# Returns: (summary, milestone)
|
|
def fetchSummary(ticketno):
|
|
params = urllib.urlencode({'format': 'tab'})
|
|
conn = httplib.HTTPConnection("dev.itmill.com")
|
|
conn.request("GET", "/ticket/%d?%s" % (ticketno, params) )
|
|
response = conn.getresponse()
|
|
data = response.read()
|
|
conn.close()
|
|
|
|
lines = data.split("\n")
|
|
data = reduce(lambda x,y: x+"\n"+y, lines[1:])
|
|
#cols = lines[1].split("\t")
|
|
|
|
cols = data.split("\t")
|
|
|
|
return (cols[1],cols[8])
|
|
|
|
# Adds summary to ticket number, unless the context already has it
|
|
# Returns: (summary, milestone)
|
|
def addSummary(m):
|
|
ticketnum = int(m.group(1))
|
|
context = m.group(2)
|
|
if re.match(" *\(", context):
|
|
# The context already has ticket summary
|
|
return "#%d%s" % (ticketnum, context)
|
|
|
|
(summary,milestone) = fetchSummary(ticketnum)
|
|
|
|
# Remove possible " quotation from the summary
|
|
if summary.startswith('"'):
|
|
summary = summary.strip('"')
|
|
summary = summary.replace('""', '"')
|
|
|
|
# Add summaries to further ticket numbers recursively
|
|
context = re.sub(r'#([0-9]+)(.*)', addSummary, context)
|
|
|
|
return "#%s (<i>%s</i>) %s" % (ticketnum, summary, context)
|
|
|
|
################################################################################
|
|
# Change
|
|
################################################################################
|
|
class Ticket:
|
|
def __init__(self, id, summary=None, milestone=None):
|
|
self.id = id
|
|
self.summary = summary
|
|
self.milestone = milestone
|
|
|
|
def fetchData(self):
|
|
(summary, milestone) = fetchSummary(self.id)
|
|
self.summary = summary
|
|
self.milestone = milestone
|
|
|
|
################################################################################
|
|
# Change
|
|
################################################################################
|
|
class Change:
|
|
def __init__(self, id, undo=0, author=""):
|
|
self.id = id
|
|
self.author = author
|
|
self.comment = ""
|
|
self.undo = undo
|
|
self.tickets = []
|
|
|
|
def addCommentLine(self, line):
|
|
self.comment += line
|
|
|
|
def merge(self, trunkURI, dryrun=0):
|
|
drycmd = ""
|
|
if dryrun:
|
|
drycmd = "--dry-run"
|
|
|
|
# Handle negative merge
|
|
mergesign = ""
|
|
if self.undo:
|
|
mergesign = "-"
|
|
|
|
# Build the merge command
|
|
cmd = "svn merge --non-interactive %s -c %s%d %s" % (drycmd, mergesign, self.id, trunkURI)
|
|
print cmd
|
|
|
|
# Run the merge command
|
|
pin = os.popen(cmd, "r")
|
|
lines = pin.readlines()
|
|
pin.close()
|
|
|
|
# Parse the lines for conflicts
|
|
conflicts = 0
|
|
for line in lines:
|
|
print line[:-1]
|
|
|
|
# Check for conflict
|
|
if line.startswith("C"):
|
|
conflicts += 1
|
|
|
|
# Check for skipped file
|
|
elif line.startswith("Skipped"):
|
|
conflicts += 1
|
|
|
|
filename = line[8:-1]
|
|
|
|
# Simply exit if there was any problem
|
|
if conflicts > 0:
|
|
print "Problems detected. Exiting."
|
|
sys.exit(1)
|
|
|
|
def fetchComment(self, trunkURI):
|
|
cmd = "svn log -r %d %s" % (self.id, trunkURI)
|
|
|
|
# Run the log command
|
|
pin = os.popen(cmd, "r")
|
|
lines = pin.readlines()
|
|
pin.close()
|
|
|
|
STATE_START = 0
|
|
STATE_COMMENT = 1
|
|
comment = None
|
|
state = STATE_START
|
|
for line in lines:
|
|
if state == STATE_START:
|
|
if line == "\n":
|
|
state = STATE_COMMENT
|
|
elif state == STATE_COMMENT:
|
|
if line.startswith("-----------------"):
|
|
self.comment = comment
|
|
return comment
|
|
elif comment:
|
|
comment += "\n" + line.rstrip("\n")
|
|
else:
|
|
comment = line.rstrip("\n")
|
|
|
|
self.comment = comment
|
|
return comment
|
|
|
|
def commit(self):
|
|
# Write the log comment to a temporary file
|
|
logtmpname = "/tmp/merge-single-%d.log" % (os.getpid())
|
|
fout = open(logtmpname, "w")
|
|
fout.write(self.comment)
|
|
fout.close()
|
|
|
|
# Get listo
|
|
files = listChangedFiles()
|
|
if len(files) == 0:
|
|
print "Error: Will not do empty commit."
|
|
sys.exit(1)
|
|
|
|
# Write the list of files to be committed to a temporary file
|
|
changedfiles = ("\n".join(files)) + "\n"
|
|
targettmpname = "/tmp/merge-targets-%d.txt" % (os.getpid())
|
|
fout = open(targettmpname, "w")
|
|
fout.write(changedfiles)
|
|
fout.close()
|
|
print changedfiles,
|
|
|
|
command("svn commit --file %s --targets %s" % (logtmpname, targettmpname))
|
|
|
|
command("rm %s %s" % (logtmpname, targettmpname))
|
|
|
|
|
|
def getNumber(self):
|
|
return self.id
|
|
|
|
def getComment(self):
|
|
return self.comment
|
|
|
|
def getUndo(self):
|
|
return self.undo
|
|
|
|
def getAuthor(self):
|
|
return self.author
|
|
|
|
def isForMilestone(self, milestone):
|
|
return self.author
|
|
|
|
def addSummary(self, m, target_milestone=None):
|
|
ticketnum = int(m.group(1))
|
|
context = m.group(2)
|
|
if re.match(" *\(", context):
|
|
# The context already has ticket summary
|
|
return "#%d%s" % (ticketnum, context)
|
|
|
|
# Check for cached ticket
|
|
if tickets.has_key(ticketnum):
|
|
summary = tickets[ticketnum].summary
|
|
ticket_milestone = tickets[ticketnum].milestone
|
|
else:
|
|
# Fetch ticket from server and add to cache
|
|
(summary,ticket_milestone) = fetchSummary(ticketnum)
|
|
tickets[ticketnum] = Ticket(ticketnum,summary,ticket_milestone)
|
|
|
|
self.tickets.append(ticketnum);
|
|
|
|
# Remove possible " quotation from the summary
|
|
if summary.startswith('"'):
|
|
summary = summary.strip('"')
|
|
summary = summary.replace('""', '"')
|
|
|
|
ticketnum = "#%s" % (ticketnum)
|
|
|
|
# Emphasize tickets matching the target milestone
|
|
if target_milestone:
|
|
if ticket_milestone.find(target_milestone) != -1:
|
|
ticketnum = "<b>%s</b>" % (ticketnum)
|
|
|
|
# Add summaries to further ticket numbers recursively
|
|
context = re.sub(r'#([0-9]+)(.*)', lambda m: self.addSummary(m, target_milestone=target_milestone), context)
|
|
|
|
return "%s (<i>%s</i>) %s" % (ticketnum, summary, context)
|
|
|
|
def registerTicket(self, m, ticketNumbers):
|
|
ticketNumbers[int(m.group(1))] = 1
|
|
return ""
|
|
|
|
# Returns a list of ticket numbers referenced by this change
|
|
def listTickets(self):
|
|
ticketNumbers = {}
|
|
re.sub(r'#([0-9]+)', lambda m: self.registerTicket(m,ticketNumbers=ticketNumbers), self.comment)
|
|
return ticketNumbers.keys()
|
|
|
|
################################################################################
|
|
# Read configuration file
|
|
################################################################################
|
|
class Configuration:
|
|
def __init__(self, cfgfilename, startfrom=0):
|
|
self.changes = []
|
|
self.readConfig(cfgfilename, startfrom)
|
|
|
|
def readConfig(self, cfgfilename, startfrom=0):
|
|
fin = open(cfgfilename, "r")
|
|
content = fin.readlines()
|
|
fin.close()
|
|
|
|
# Parse configuration
|
|
currentChange = None
|
|
skipChange = 0
|
|
for line in content:
|
|
m_changestart = re.match(r'(-?)r([0-9]+)', line)
|
|
m_endofchange = re.match(r'------+', line)
|
|
m_emptyline = re.match(r'^$', line)
|
|
if m_changestart:
|
|
# Parse negative merge
|
|
undo = 0
|
|
if m_changestart.group(1) == "-":
|
|
undo = 1
|
|
|
|
# Get changeset number
|
|
id = int(m_changestart.group(2))
|
|
|
|
# Skip the target if its number is too small
|
|
if startfrom != 0 and id < startfrom:
|
|
skipChange = 1
|
|
|
|
# Get the author
|
|
author = re.sub(r'\@.+', '', line.split("|")[1].strip())
|
|
|
|
currentChange = Change(id, undo=undo, author=author)
|
|
|
|
elif m_endofchange:
|
|
# Register changeset, unless it is marked
|
|
# for skipping.
|
|
if currentChange:
|
|
if skipChange:
|
|
skipChange = 0
|
|
else:
|
|
self.changes.append(currentChange)
|
|
currentChange = None
|
|
elif m_emptyline:
|
|
pass
|
|
else:
|
|
if currentChange:
|
|
currentChange.addCommentLine(line)
|
|
|
|
def massMerge(self, trunkURI, dryrun=0, allatonce=0):
|
|
if not allatonce:
|
|
# Merge one changeset at a time
|
|
for change in self.changes:
|
|
change.merge(trunkURI, dryrun=dryrun)
|
|
else:
|
|
# What is the first changeset in the merge?
|
|
smallest = 99999999
|
|
for change in self.changes:
|
|
if change.getNumber() < smallest:
|
|
smallest = change.getNumber()
|
|
|
|
drycmd = ""
|
|
if dryrun:
|
|
drycmd = "--dry-run"
|
|
|
|
# Merge from the first changeset to HEAD
|
|
cmd = "svn merge --non-interactive %s -r %d:HEAD %s" % (drycmd, smallest, trunkURI)
|
|
print cmd
|
|
command(cmd)
|
|
|
|
def createLogComment(self):
|
|
# Create a log comment that lists all merged changesets with
|
|
# comments
|
|
logcomment = "Merge from %s to %s:\n" % (sourcebranch, targetbranch)
|
|
for change in self.changes:
|
|
changeno = change.getNumber()
|
|
changecomment = change.getComment().rstrip("\n")
|
|
if change.getUndo():
|
|
logcomment += "Reverted [%d] merge: %s\n" % (changeno, changecomment)
|
|
else:
|
|
logcomment += "Merged [%d]: %s\n" % (changeno, changecomment)
|
|
return logcomment
|
|
|
|
def logHtml(self, author=0, milestone=None):
|
|
# In author inclusion mode, include some styles to make a printout look better
|
|
if author:
|
|
print "<head>\n<style type=\"text/css\">\n"+ \
|
|
"tr {\n vertical-align: top;\n}\ntd {\n font-size: 8pt;\n}\n</style>\n</head>\n"
|
|
|
|
# Print header
|
|
print "<table id=\"changelog-table\">"
|
|
authorcolumnheader = ""
|
|
if author:
|
|
authorcolumnheader = "<td>Author</td>"
|
|
print " <tr><td>#</td><td>Changeset Comment</td>%s</tr>" % (authorcolumnheader)
|
|
|
|
# Print body: the changes
|
|
for change in self.changes:
|
|
changeno = change.getNumber()
|
|
changecomment = change.getComment().rstrip("\n")
|
|
|
|
changeref = "[%d]" % (changeno)
|
|
|
|
# Handle merge undo markup
|
|
if change.getUndo():
|
|
changeref = "<font class=\"changeset-merge-undone\">%s</font>" % (changeref)
|
|
changecomment = "<font class=\"changeset-merge-undone\">%s</font>" % (changecomment)
|
|
changecomment = "Reverted a change: "+changecomment
|
|
|
|
authorcolumn = ""
|
|
if author:
|
|
authorcolumn = "<td>%s</td>" % (change.getAuthor())
|
|
|
|
# Add ticket summary after ticket number, if missing
|
|
# TODO: this handles only one
|
|
changecomment = re.sub(r'#([0-9]+)(.*)', lambda m: change.addSummary(m, target_milestone=milestone), changecomment, 100)
|
|
# item = re.sub(r'#([0-9]+)(.*)', '#\\1 (SUMMARY) \\2', item)
|
|
|
|
# Change ticket numbers to references to tickets
|
|
changecomment = re.sub(r'#([0-9]+)', '#<a href="http://dev.itmill.com/ticket/\\1">\\1</a>', changecomment)
|
|
|
|
# Change changeset numbers to references to changesets
|
|
changecomment = re.sub(r'\[([0-9]+)\]', '[<a href="http://dev.itmill.com/changeset/\\1">\\1</a>]', changecomment)
|
|
changeref = re.sub(r'\[([0-9]+)\]', '[<a href="http://dev.itmill.com/changeset/\\1">\\1</a>]', changeref)
|
|
|
|
# See if any of the tickets have milestone under work.
|
|
if milestone:
|
|
for ticketnum in change.tickets:
|
|
ticket = tickets[ticketnum]
|
|
if ticket.milestone.find(milestone) != -1:
|
|
changeref = "<b>%s</b>" % (changeref)
|
|
|
|
# Make basic HTML formatting
|
|
item = " <tr><td>%s:</td><td>%s</td>%s</tr>" % (changeref, changecomment, authorcolumn)
|
|
|
|
print item
|
|
sys.stdout.flush()
|
|
print "</table>"
|
|
|
|
# Prints a commit log to standard output
|
|
def log(self, sourcebranch, targetbranch, html=0, author=0, milestone=None):
|
|
if html:
|
|
self.logHtml(author=author,milestone=milestone)
|
|
return
|
|
sys.stdout.write(self.createLogComment())
|
|
|
|
def commit(self, sourcebranch, targetbranch, dryrun=0):
|
|
logcomment = self.createLogComment()
|
|
|
|
# Write the log comment to a temporary file
|
|
logtmpname = "/tmp/massmerge-pid-%d.log" % (os.getpid())
|
|
fout = open(logtmpname, "w")
|
|
fout.write(logcomment)
|
|
fout.close()
|
|
|
|
# Write the list of files to be committed to a temporary file
|
|
changedfiles = "\n".join(listChangedFiles())
|
|
targettmpname = "/tmp/massmerge-targets-%d.txt" % (os.getpid())
|
|
fout = open(targettmpname, "w")
|
|
fout.write(changedfiles)
|
|
fout.close()
|
|
|
|
if dryrun:
|
|
print "Log:"
|
|
os.system("cat %s" % (logtmpname))
|
|
print "\nChanged Files:"
|
|
os.system("cat %s" % (targettmpname))
|
|
print "\n"
|
|
|
|
command("svn commit --file %s --targets %s" % (logtmpname, targettmpname), dryrun=dryrun)
|
|
|
|
command("rm %s %s" % (logtmpname, targettmpname))
|
|
|
|
def listTickets(self):
|
|
fixed = {}
|
|
|
|
for change in self.changes:
|
|
changeno = change.getNumber()
|
|
changeTickets = change.listTickets()
|
|
if len(changeTickets)>0 and change.comment.lower().find("fix") != -1:
|
|
for ticket in changeTickets:
|
|
fixed[ticket] = 1
|
|
|
|
fixedlist = fixed.keys()
|
|
fixedlist.sort()
|
|
# print "Fixed:", fixedlist
|
|
|
|
print "<ul>"
|
|
|
|
for ticketNum in fixedlist:
|
|
if not tickets.has_key(ticketNum):
|
|
ticket = Ticket(ticketNum)
|
|
ticket.fetchData()
|
|
tickets[ticketNum] = ticket
|
|
|
|
ticket = tickets[ticketNum]
|
|
# print "%d: %s" % (ticket.id, ticket.summary)
|
|
print " <li><a href=\"http://dev.itmill.com/ticket/%d\">#%d</a>: %s</li>" % (ticket.id, ticket.id, ticket.summary)
|
|
sys.stdout.flush()
|
|
|
|
print "</ul>"
|
|
|
|
################################################################################
|
|
# Commands
|
|
################################################################################
|
|
|
|
# Command: revert
|
|
def commandRevert():
|
|
# Get Svn status
|
|
pin = os.popen("svn st", "r")
|
|
lines = pin.readlines()
|
|
pin.close()
|
|
|
|
reverted = []
|
|
removed = []
|
|
for line in lines:
|
|
# Remove trailing newline
|
|
line = line[:-1]
|
|
|
|
# Extract the file state and name
|
|
(filestate, filename) = re.split(r'[ \+]+', line)
|
|
|
|
# Ignore files in build directory
|
|
if (filename.startswith("build/merge/") \
|
|
or filename.startswith("build/bin/")) \
|
|
and filestate == "M":
|
|
continue
|
|
|
|
# Added files are simply deleted
|
|
if filestate != "?":
|
|
reverted.append(filename)
|
|
|
|
# Added files have to be removed in addition to reverting
|
|
if filestate == "A":
|
|
removed.append(filename)
|
|
|
|
# Remove conflict choises
|
|
elif filestate == "?" and \
|
|
(filename.find(".merge-left.r") != -1 or \
|
|
filename.find(".merge-right.r") != -1):
|
|
removed.append(filename)
|
|
|
|
# Revert files marked for reverting
|
|
donework = 0
|
|
if len(reverted) > 0:
|
|
files = " ".join(reverted)
|
|
command("svn revert -R %s" % (files))
|
|
donework = 1
|
|
|
|
# Remove files marked for deletion
|
|
if len(removed) > 0:
|
|
files = " ".join(removed)
|
|
command("rm %s" % (files))
|
|
donework = 1
|
|
|
|
if not donework:
|
|
print "Nothing to do."
|
|
|
|
# Command: massmerge
|
|
def commandMassmerge(cfgfilename, sourceuri, startfrom, dryrun=0, allatonce=0):
|
|
cfg = Configuration(cfgfilename, startfrom=startfrom)
|
|
cfg.massMerge(sourceuri, dryrun=dryrun, allatonce=allatonce)
|
|
|
|
# Command: single
|
|
def commandSingle(trunkuri, changeset, sourcebranch, targetbranch, onlymerge=0, onlycommit=0):
|
|
change = Change(changeset)
|
|
print "Found changeset with log comment:\n "+change.fetchComment(trunkuri) + "\n"
|
|
|
|
change.merge(trunkuri, dryrun=onlycommit)
|
|
if onlycommit:
|
|
print "Got file list."
|
|
else:
|
|
print "Merge successful."
|
|
|
|
# Change the comment
|
|
change.comment = "Merged [%d] from %s to %s branch: %s" % (change.id, sourcebranch, branchname, change.comment)
|
|
print "\nLog comment: \"%s\"" % (change.comment)
|
|
|
|
if not onlymerge:
|
|
print "Committing."
|
|
change.commit()
|
|
|
|
# Command: commit
|
|
def commandCommit(cfgfilename, sourcebranch, targetbranch, dryrun=0):
|
|
cfg = Configuration(cfgfilename)
|
|
cfg.commit(sourcebranch, targetbranch, dryrun=dryrun)
|
|
|
|
# Command: log
|
|
def commandLog(cfgfilename, sourcebranch, targetbranch, html=0, author=0, milestone=None):
|
|
cfg = Configuration(cfgfilename)
|
|
cfg.log(sourcebranch, targetbranch, html=html, author=author, milestone=milestone)
|
|
|
|
# Command: tickets
|
|
def commandTickets(cfgfilename):
|
|
cfg = Configuration(cfgfilename)
|
|
cfg.listTickets()
|
|
|
|
################################################################################
|
|
# Main Program
|
|
################################################################################
|
|
|
|
# Handle switches
|
|
dryrun = 0
|
|
html = 0
|
|
html_author = 0
|
|
html_milestone = None
|
|
onlymerge = 0
|
|
onlycommit = 0
|
|
all = 0
|
|
while len(sys.argv)>1 and sys.argv[1][0] == '-':
|
|
if sys.argv[1] == "-d":
|
|
dryrun = 1
|
|
del sys.argv[1:2]
|
|
|
|
elif sys.argv[1] == "-html":
|
|
html = 1
|
|
del sys.argv[1:2]
|
|
|
|
elif sys.argv[1] == "-author":
|
|
html_author = 1
|
|
del sys.argv[1:2]
|
|
|
|
elif sys.argv[1] == "-milestone":
|
|
html_milestone = sys.argv[2]
|
|
del sys.argv[1:3]
|
|
|
|
elif sys.argv[1] == "-m":
|
|
onlymerge = 1
|
|
del sys.argv[1:2]
|
|
|
|
elif sys.argv[1] == "-c":
|
|
onlycommit = 1
|
|
del sys.argv[1:2]
|
|
|
|
elif sys.argv[1] == "-all":
|
|
all = 1
|
|
del sys.argv[1:2]
|
|
|
|
else:
|
|
print "Invalid option '%s'." % (sys.argv[1])
|
|
sys.exit(1)
|
|
|
|
if len(sys.argv) < 2:
|
|
help(1)
|
|
|
|
# Handle commands
|
|
if sys.argv[1] == "revert":
|
|
commandRevert()
|
|
|
|
elif (len(sys.argv) == 4 or len(sys.argv)==5) and sys.argv[1] == "massmerge":
|
|
cfgfilename = sys.argv[2]
|
|
sourcebranch = sys.argv[3]
|
|
startfrom = None
|
|
if len(sys.argv)>4:
|
|
startfrom = int(sys.argv[4])
|
|
commandMassmerge(cfgfilename, sourceuri=REPOSITORY+sourcebranch, startfrom=startfrom, dryrun=dryrun, allatonce=all)
|
|
|
|
elif len(sys.argv) == 5 and sys.argv[1] == "single":
|
|
changeset = int(sys.argv[2])
|
|
sourcebranch = sys.argv[3]
|
|
targetbranch = sys.argv[4]
|
|
commandSingle(REPOSITORY+sourcebranch, changeset, targetbranch, onlymerge=onlymerge, onlycommit=onlycommit)
|
|
|
|
elif len(sys.argv) == 5 and sys.argv[1] == "commit":
|
|
cfgfilename = sys.argv[2]
|
|
sourcebranch = sys.argv[3]
|
|
targetbranch = sys.argv[4]
|
|
commandCommit(cfgfilename, sourcebranch, targetbranch, dryrun=dryrun)
|
|
|
|
elif len(sys.argv) == 5 and sys.argv[1] == "log":
|
|
cfgfilename = sys.argv[2]
|
|
sourcebranch = sys.argv[3]
|
|
targetbranch = sys.argv[4]
|
|
commandLog(cfgfilename, sourcebranch, targetbranch, html=html, author=html_author, milestone=html_milestone)
|
|
|
|
elif len(sys.argv) == 3 and sys.argv[1] == "tickets":
|
|
cfgfilename = sys.argv[2]
|
|
commandTickets(cfgfilename)
|
|
|
|
else:
|
|
help(1)
|