Index: releaseAutomation.py |
diff --git a/releaseAutomation.py b/releaseAutomation.py |
index 5578abf1d948fe185e046cdb70ccd4734fa876ed..82678385338a138fd7e889a3c4f767549bb9c66b 100644 |
--- a/releaseAutomation.py |
+++ b/releaseAutomation.py |
@@ -9,6 +9,8 @@ import subprocess |
import tarfile |
import json |
Vasily Kuznetsov
2017/08/08 18:10:12
There's no need for this empty line. The imports f
tlucas
2017/08/09 08:12:35
Acknowledged.
tlucas
2017/08/15 14:40:12
Done.
|
+from itertools import groupby |
+ |
from packager import readMetadata, getDefaultFileName |
@@ -45,7 +47,100 @@ def create_sourcearchive(repo, output): |
process.wait() |
+def repo_has_uncommitted(aborts_process=True): |
+ """Checks if the given repository is clean""" |
+ uncommitted = False |
Vasily Kuznetsov
2017/08/08 18:10:12
You're spending quite some effort reformatting the
tlucas
2017/08/09 08:12:35
Acknowledged.
tlucas
2017/08/15 14:40:12
Done.
|
+ status_mapping = { |
+ 'M': 'modified', |
+ 'A': 'added', |
+ 'R': 'removed', |
+ '!': 'missing', |
+ '?': 'untracked', |
+ } |
+ |
+ # Check for any uncommitted changes |
+ buff = subprocess.check_output(['hg', 'status']) |
+ if len(buff): |
+ uncommitted = True |
+ dirty_files = buff.strip().split(os.linesep) |
+ print('Dirty / uncommitted changes in repository!') |
Vasily Kuznetsov
2017/08/08 18:10:11
Using print as a function only seems to work under
tlucas
2017/08/09 08:12:35
Acknowledged.
tlucas
2017/08/15 14:40:12
Done.
|
+ grouped_dirty = groupby(dirty_files, key=lambda x: x.split(' ')[0]) |
+ for dirty_grp in grouped_dirty: |
+ print('{}:'.format(status_mapping[dirty_grp[0]])) |
+ for dirty in dirty_grp[1]: |
+ print(' {}'.format(dirty.split(' ')[1])) |
+ |
+ return uncommitted, aborts_process |
+ |
+ |
+def repo_has_outgoing(aborts_process=False): |
+ """Checks whether there would be outgoing changesets to the given path""" |
+ try: |
+ buff = subprocess.check_output(['hg', 'outgoing']) |
+ print('Detected outgoing changesets:') |
+ print(buff) |
+ return True, aborts_process |
+ except subprocess.CalledProcessError: |
+ return False, aborts_process |
+ |
+ |
+def repo_has_incoming(repo_paths, aborts_process=True): |
+ """Checks whether the local repositories are up-to-date""" |
+ incoming = False |
+ |
+ for repo_path in repo_paths: |
+ try: |
+ buff = subprocess.check_output(['hg', 'incoming', '-R', repo_path]) |
+ print('Detected incoming changesets:') |
Vasily Kuznetsov
2017/08/08 18:10:12
Here we're printing the incoming changesets but ac
tlucas
2017/08/09 08:12:35
Acknowledged.
tlucas
2017/08/15 14:40:12
Done.
|
+ print(buff) |
+ incoming = True |
+ except subprocess.CalledProcessError: |
+ pass |
+ |
+ return incoming, aborts_process |
+ |
+ |
+def ask_to_continue(): |
+ """Asks the user if he wants to continue despite facing warnings""" |
+ try: |
+ input = raw_input |
Vasily Kuznetsov
2017/08/08 18:10:11
AFAIK, this compatibility trick doesn't work (unde
tlucas
2017/08/09 08:12:34
I tested a snippet of this, but not in function-sc
Vasily Kuznetsov
2017/08/09 17:09:09
Yes, I think it would be the best to ignore Python
tlucas
2017/08/15 14:40:12
Done.
|
+ except NameError: |
+ pass |
+ |
+ print('The above error/s has/have been detected within the repositories.') |
Vasily Kuznetsov
2017/08/08 18:10:11
I know that you took this from the ticket, but I'm
tlucas
2017/08/09 08:12:35
I like it (and it was actually me, who added this
tlucas
2017/08/15 14:40:12
Done.
|
+ print('You might want to check whether this is ok or not.') |
+ print('Are you sure about continuing the release-process?') |
+ while True: |
Vasily Kuznetsov
2017/08/08 18:10:11
What do you think about rewriting this loop, and t
tlucas
2017/08/09 08:12:35
Acknowledged.
tlucas
2017/08/15 14:40:12
Done.
|
+ choice = input('Please choose (yes / no): ') |
+ if choice.lower() not in ('yes', 'no'): |
Vasily Kuznetsov
2017/08/08 18:10:11
('yes', 'no') should be a set (this is error A102
tlucas
2017/08/09 08:12:35
This is removed while following your proposed appr
tlucas
2017/08/15 14:40:12
Done. Kept the reminder on what to specifically en
|
+ print('Please answer "yes" or "no"!') |
+ else: |
+ break |
+ |
+ return choice.lower() == 'yes' |
+ |
+ |
def run(baseDir, type, version, keyFile, downloadsRepo): |
+ # run repository-checks and bail out early, in case the user does not |
+ # explicitly want to continue OR if the check would cause the process to |
+ # abort anyway |
+ repo_checks = ( |
Vasily Kuznetsov
2017/08/08 18:10:11
I think the new code in this function is unnecessa
tlucas
2017/08/09 08:12:35
Acknowledged. I'll also rename the function accord
tlucas
2017/08/15 14:40:12
Done.
|
+ (repo_has_uncommitted, ()), |
+ (repo_has_outgoing, ()), |
+ (repo_has_incoming, ((baseDir, downloadsRepo),)), |
+ ) |
+ |
+ check_results = [func(*args) for func, args in repo_checks] |
+ |
+ if ( |
+ any(check and aborts for check, aborts in check_results) |
+ or ( |
+ any(check and not aborts for check, aborts in check_results) |
+ and not ask_to_continue() |
+ )): |
+ print('Aborting release.') |
+ return 1 |
+ |
if type == 'gecko': |
import buildtools.packagerGecko as packager |
elif type == 'safari': |