Skip to content

Commit 21c39c9

Browse files
committed
Fixed scm.outgoing() to detect outgoing commits in the current branch, not master.
This is important for the publishing process (`mbed publish`). Unified handling of branches and remotes for both Git and Mercurial Error reporting for subprocesses (hg, mercurial..) so the command, working dir and error code are displayed Verbose mode `-v` now shows the command for subprocess queries, e.g. process output that is piped/not shown
1 parent 350d1d3 commit 21c39c9

File tree

1 file changed

+68
-26
lines changed

1 file changed

+68
-26
lines changed

mbed/mbed.py

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/usr/bin/env python
2-
# pylint: disable=too-many-arguments, too-many-locals, too-many-branches, too-many-lines, line-too-long, too-many-nested-blocks
2+
# pylint: disable=too-many-arguments, too-many-locals, too-many-branches, too-many-lines, line-too-long, too-many-nested-blocks, too-many-public-methods
33
# pylint: disable=invalid-name, missing-docstring
44

55
import argparse
@@ -132,7 +132,7 @@ class ProcessException(Exception):
132132

133133
def popen(command, stdin=None, **kwargs):
134134
# print for debugging
135-
log('"'+' '.join(command)+'"')
135+
log('Exec "'+' '.join(command)+'"" in '+os.getcwd())
136136
try:
137137
proc = subprocess.Popen(command, **kwargs)
138138
except OSError as e:
@@ -141,13 +141,13 @@ def popen(command, stdin=None, **kwargs):
141141
"Could not execute \"%s\".\n"
142142
"Please verify that it's installed and accessible from your current path by executing \"%s\".\n" % (command[0], command[0]), e[0])
143143
else:
144-
raise
144+
raise e
145145

146146
if proc.wait() != 0:
147-
raise ProcessException(proc.returncode)
147+
raise ProcessException(proc.returncode, command[0], ' '.join(command), os.getcwd())
148148

149149
def pquery(command, stdin=None, **kwargs):
150-
#log("Query "+' '.join(command)+" in "+os.getcwd())
150+
log('Query "'+' '.join(command)+'" in '+os.getcwd())
151151
try:
152152
proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
153153
except OSError as e:
@@ -156,11 +156,12 @@ def pquery(command, stdin=None, **kwargs):
156156
"Could not execute \"%s\".\n"
157157
"Please verify that it's installed and accessible from your current path by executing \"%s\".\n" % (command[0], command[0]), e[0])
158158
else:
159-
raise
159+
raise e
160+
160161
stdout, _ = proc.communicate(stdin)
161162

162163
if proc.returncode != 0:
163-
raise ProcessException(proc.returncode)
164+
raise ProcessException(proc.returncode, command[0], ' '.join(command), os.getcwd())
164165

165166
return stdout
166167

@@ -274,11 +275,11 @@ def untracked():
274275
def outgoing():
275276
try:
276277
pquery([hg_cmd, 'outgoing'])
277-
return True
278+
return 1
278279
except ProcessException as e:
279280
if e[0] != 1:
280-
raise
281-
return False
281+
raise e
282+
return 0
282283

283284
def isdetached():
284285
return False
@@ -310,6 +311,9 @@ def gethash(repo):
310311
else:
311312
return ""
312313

314+
def getbranch():
315+
return pquery([hg_cmd, 'branch']).strip() or ""
316+
313317
def ignores(repo):
314318
hook = 'ignore.local = .hg/hgignore'
315319
hgrc = os.path.join(repo.path, '.hg', 'hgrc')
@@ -463,31 +467,66 @@ def untracked():
463467
return pquery([git_cmd, 'ls-files', '--others', '--exclude-standard']).splitlines()
464468

465469
def outgoing():
470+
# Find the default remote
471+
remote = None
472+
remotes = Git.getremotes('push')
473+
for r in remotes:
474+
remote = r[0]
475+
# Prefer origin which is the default when you clone locally
476+
if r[0] == "origin":
477+
break
478+
479+
if not remote:
480+
return -1
481+
482+
# Get current branch
483+
branch = Git.getbranch()
484+
if not branch:
485+
# Detached mode is okay as we don't expect the user to publish from detached state without branch
486+
return 0
487+
466488
try:
467-
return True if pquery([git_cmd, 'log', 'origin..']) else False
489+
# Check if remote branch exists
490+
if not pquery([git_cmd, 'rev-parse', '%s/%s' % (remote, branch)]):
491+
return 1
468492
except ProcessException as e:
469-
if e[0] != 1:
470-
raise
471-
return True
493+
return 1
472494

495+
# Check for outgoing commits for the same remote branch
496+
return 1 if pquery([git_cmd, 'log', '%s/%s..%s' % (remote, branch, branch)]) else 0
497+
498+
# Checks whether current working tree is detached
473499
def isdetached():
474-
branch = pquery([git_cmd, 'rev-parse', '--symbolic-full-name', '--abbrev-ref', 'HEAD']).strip()
475-
return branch == "HEAD"
500+
return Git.getbranch() == "HEAD"
476501

477-
def geturl(repo):
478-
url = ""
502+
# Finds all associated remotes for the specified remote type
503+
def getremotes(rtype='fetch'):
504+
result = []
479505
remotes = pquery([git_cmd, 'remote', '-v']).strip().splitlines()
480506
for remote in remotes:
481507
remote = re.split(r'\s', remote)
482-
if "(fetch)" in remote:
483-
url = remote[1]
484-
if remote[0] == "origin": # Prefer origin URL
485-
break
508+
t = re.sub('[()]', '', remote[2])
509+
if not rtype or rtype == t:
510+
result.append([remote[0], remote[1], t])
511+
return result
512+
513+
def geturl(repo):
514+
url = ""
515+
remotes = Git.getremotes()
516+
for remote in remotes:
517+
url = remote[1]
518+
if remote[0] == "origin": # Prefer origin URL
519+
break
486520
return formaturl(url)
487521

488522
def gethash(repo):
489523
return pquery([git_cmd, 'rev-parse', 'HEAD']).strip()
490524

525+
# Finds current branch or returns empty string if detached
526+
def getbranch():
527+
branch = pquery([git_cmd, 'rev-parse', '--symbolic-full-name', '--abbrev-ref', 'HEAD']).strip()
528+
return branch if branch != "HEAD" else ""
529+
491530
def ignores(repo):
492531
with open(os.path.join(repo.path, '.git/info/exclude'), 'w') as f:
493532
f.write('\n'.join(ignores)+'\n')
@@ -1124,17 +1163,18 @@ def publish(all=None, top=True):
11241163
sync(recursive=False)
11251164

11261165
if repo.scm.dirty():
1127-
action('Uncommitted changes in \"%s\" (%s)' % (repo.name, relpath(cwd_root, repo.path)))
1166+
action('Uncommitted changes in \"%s\" (%s)' % (repo.name, relpath(cwd_root, repo.path) or "."))
11281167
raw_input('Press enter to commit and push: ')
11291168
repo.scm.commit()
11301169

11311170
try:
1132-
if repo.scm.outgoing():
1171+
outgoing = repo.scm.outgoing()
1172+
if outgoing > 0:
11331173
action("Pushing local repository \"%s\" to remote \"%s\"" % (repo.name, repo.url))
11341174
repo.scm.push(repo, all)
11351175
except ProcessException as e:
11361176
if e[0] != 1:
1137-
raise
1177+
raise e
11381178

11391179

11401180
# Update command
@@ -1492,7 +1532,9 @@ def toolchain_(name=None):
14921532
log('Working path \"%s\" (%s)' % (os.getcwd(), cwd_type))
14931533
status = args.command(args)
14941534
except ProcessException as e:
1495-
error('Subrocess exit with error code %d' % e[0], e[0])
1535+
error(
1536+
"\"%s\" returned error code %d.\n"
1537+
"Command \"%s\" in \"%s\"" % (e[1], e[0], e[2], e[3]), e[0])
14961538
except OSError as e:
14971539
if e[0] == errno.ENOENT:
14981540
error(

0 commit comments

Comments
 (0)