--- a/autoland/autoland/autoland.py
+++ b/autoland/autoland/autoland.py
@@ -12,17 +12,17 @@ import time
import traceback
sys.path.insert(0, os.path.normpath(os.path.join(os.path.normpath(
os.path.abspath(os.path.dirname(__file__))), '..',
'..',
'pylib',
'mozautomation')))
-import transplant
+from transplant import Transplant
import treestatus
# max attempts to transplant before bailing
MAX_TRANSPLANT_ATTEMPTS = 50
# max updates to post to reviewboard / iteration
MOZREVIEW_COMMENT_LIMIT = 10
@@ -115,19 +115,24 @@ def handle_pending_transplants(dbconn):
# TODO: We should break the transplant call into two steps, one
# to pull down the commits to transplant, and another
# one to rebase it and attempt to push so we don't
# duplicate work unnecessarily if we have to rebase more
# than once.
os.environ['AUTOLAND_REQUEST_USER'] = requester
try:
- result = transplant.transplant(tree, destination, rev,
- trysyntax, push_bookmark,
- commit_descriptions)
+ with Transplant(tree, destination, rev) as tp:
+ if trysyntax:
+ result = tp.push_try(str(trysyntax))
+ elif push_bookmark:
+ result = tp.push_bookmark(commit_descriptions,
+ push_bookmark)
+ else:
+ result = tp.push(commit_descriptions)
landed = True
except Exception as e:
result = str(e)
landed = False
finally:
del os.environ['AUTOLAND_REQUEST_USER']
logger.info('transplant from tree: %s rev: %s attempt: %s: %s' % (
--- a/autoland/autoland/transplant.py
+++ b/autoland/autoland/transplant.py
@@ -16,94 +16,84 @@ class HgCommandError(Exception):
# we want to strip out any sensitive --config options
hg_args = map(lambda x: x if not x.startswith('bugzilla') else 'xxx',
hg_args)
message = 'hg error in cmd: hg %s: %s' % (' '.join(hg_args),
out.getvalue())
super(self.__class__, self).__init__(message)
-def transplant(tree, destination, rev, trysyntax=None,
- push_bookmark=False, commit_descriptions=None):
- """Transplant a specified revision and ancestors to the specified tree.
-
- If ``trysyntax`` is specified, a Try commit will be created using the
- syntax specified.
- """
- # These values can appear in command arguments. Don't let unicode leak
- # into these.
- assert isinstance(tree, str)
- assert isinstance(destination, str)
- assert isinstance(rev, str)
- if push_bookmark:
- assert isinstance(push_bookmark, str)
+class Transplant(object):
+ """Transplant a specified revision and ancestors to the specified tree."""
- path = config.get('repos').get(tree,
- os.path.join(os.path.sep, 'repos', tree))
- configs = ['ui.interactive=False']
- with hglib.open(path, encoding='utf-8', configs=configs) as hg_repo:
- tp = Transplant(hg_repo, tree, destination, rev)
-
- if trysyntax:
- return tp.push_try(trysyntax)
+ def __init__(self, tree, destination, rev):
+ # These values can appear in command arguments. Don't let unicode leak
+ # into these.
+ assert isinstance(tree, str), "tree arg is not str"
+ assert isinstance(destination, str), "destination arg is not str"
+ assert isinstance(rev, str), "rev arg is not str"
- elif push_bookmark:
- return tp.push_bookmark(commit_descriptions, push_bookmark)
-
- else:
- return tp.push(commit_descriptions)
-
-
-class Transplant:
- def __init__(self, hg_repo, tree, destination, rev):
- self.hg_repo = hg_repo
self.tree = tree
self.destination = destination
self.source_rev = rev
+ def __enter__(self):
+ path = config.get('repos').get(
+ self.tree, os.path.join(os.path.sep, 'repos', self.tree))
+ configs = ['ui.interactive=False']
+ self.hg_repo = hglib.open(path, encoding='utf-8', configs=configs)
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.strip_drafts()
+ self.hg_repo.close()
+
def push_try(self, trysyntax):
+ # Don't let unicode leak into command arguments.
+ assert isinstance(trysyntax, str), "trysyntax arg is not str"
+
self.update_repo()
if not trysyntax.startswith("try: "):
trysyntax = "try: %s" % trysyntax
rev = self.run_hg_cmds([
[
'--encoding=utf-8',
'--config', 'ui.allowemptycommit=true',
'commit',
'-m', trysyntax
],
['push', '-r', '.', '-f', 'try'],
['log', '-r', 'tip', '-T', '{node|short}'],
])
- self.strip_drafts()
return rev
def push_bookmark(self, commit_descriptions, bookmark):
+ # Don't let unicode leak into command arguments.
+ assert isinstance(bookmark, str), "bookmark arg is not str"
+
remote_tip = self.update_repo()
rev = self.apply_changes(remote_tip, commit_descriptions)
self.run_hg_cmds([
['bookmark', bookmark],
['push', '-B', bookmark, self.destination],
])
- self.strip_drafts()
return rev
def push(self, commit_descriptions):
remote_tip = self.update_repo()
rev = self.apply_changes(remote_tip, commit_descriptions)
self.run_hg_cmds([
['push', '-r', 'tip', self.destination]
])
- self.strip_drafts()
return rev
def update_repo(self):
# Obtain remote tip. We assume there is only a single head.
remote_tip = self.get_remote_tip()
# Strip any lingering draft changesets.
self.strip_drafts()