applied = crt_series.get_applied()
if options.count:
- print len(applied)
+ out.stdout(len(applied))
else:
for p in applied:
- print p
+ out.stdout(p)
"""
def nothing_to_do():
- print 'No commits to assimilate'
+ out.info('No commits to assimilate')
top_patch = crt_series.get_current_patch()
if not top_patch:
victims.reverse()
for victim in victims:
- print ('Creating patch "%s" from commit %s'
- % (patch2name[victim], victim))
+ out.info('Creating patch "%s" from commit %s'
+ % (patch2name[victim], victim))
aname, amail, adate = name_email_date(victim.get_author())
cname, cmail, cdate = name_email_date(victim.get_committer())
crt_series.new_patch(
current = '>'
if branch.get_protected():
protected = 'p'
- print current + ' ' + initialized + protected + '\t' + \
- branch_name.ljust(length) + ' | ' + branch.get_description()
+ out.stdout(current + ' ' + initialized + protected + '\t'
+ + branch_name.ljust(length) + ' | ' + branch.get_description())
def __delete_branch(doomed_name, force = False):
doomed = stack.Series(doomed_name)
if doomed.get_protected():
raise CmdException, 'This branch is protected. Delete is not permitted'
- print 'Deleting branch "%s"...' % doomed_name,
- sys.stdout.flush()
+ out.start('Deleting branch "%s"' % doomed_name)
if __is_current_branch(doomed_name):
check_local_changes()
if doomed_name != 'master':
git.delete_branch(doomed_name)
- print 'done'
+ out.done()
def func(parser, options, args):
if git.rev_parse(args[1]) == git.rev_parse('refs/heads/' + args[1]):
# we are for sure referring to a branch
parentbranch = 'refs/heads/' + args[1]
- print 'Recording "%s" as parent branch.' % parentbranch
+ out.info('Recording "%s" as parent branch' % parentbranch)
elif git.rev_parse(args[1]) and re.search('/', args[1]):
# FIXME: should the test be more strict ?
parentbranch = args[1]
else:
# Note: this includes refs to StGIT patches
- print 'Don\'t know how to determine parent branch from "%s".' % args[1]
+ out.info('Don\'t know how to determine parent branch'
+ ' from "%s"' % args[1])
parentbranch = None
except git.GitException:
- # should use a more specific exception to catch only non-git refs ?
- print 'Don\'t know how to determine parent branch from "%s".' % args[1]
+ # should use a more specific exception to catch only
+ # non-git refs ?
+ out.info('Don\'t know how to determine parent branch'
+ ' from "%s"' % args[1])
parentbranch = None
tree_id = git_id(args[1])
if parentbranch:
parentremote = git.identify_remote(parentbranch)
if parentremote:
- print 'Using "%s" remote to pull parent from.' % parentremote
+ out.info('Using remote "%s" to pull parent from'
+ % parentremote)
else:
- print 'Recording as a local branch.'
+ out.info('Recording as a local branch')
else:
# no known parent branch, can't guess the remote
parentremote = None
parent_remote = parentremote,
parent_branch = parentbranch)
- print 'Branch "%s" created.' % args[0]
+ out.info('Branch "%s" created' % args[0])
return
elif options.clone:
check_conflicts()
check_head_top_equal()
- print 'Cloning current branch to "%s"...' % clone,
- sys.stdout.flush()
+ out.start('Cloning current branch to "%s"' % clone)
crt_series.clone(clone)
- print 'done'
+ out.done()
return
branches.sort()
if branches:
- print 'Available branches:'
+ out.info('Available branches:')
max_len = max([len(i) for i in branches])
for i in branches:
__print_branch(i, max_len)
else:
- print 'No branches'
+ out.info('No branches')
return
elif options.protect:
raise CmdException, 'Branch "%s" is not controlled by StGIT' \
% branch_name
- print 'Protecting branch "%s"...' % branch_name,
- sys.stdout.flush()
+ out.start('Protecting branch "%s"' % branch_name)
branch.protect()
- print 'done'
+ out.done()
return
stack.Series(args[0]).rename(args[1])
- print 'Renamed branch "%s" as "%s".' % (args[0], args[1])
+ out.info('Renamed branch "%s" to "%s"' % (args[0], args[1]))
return
raise CmdException, 'Branch "%s" is not controlled by StGIT' \
% branch_name
- print 'Unprotecting branch "%s"...' % branch_name,
- sys.stdout.flush()
+ out.info('Unprotecting branch "%s"' % branch_name)
branch.unprotect()
- print 'done'
+ out.done()
return
check_conflicts()
check_head_top_equal()
- print 'Switching to branch "%s"...' % args[0],
- sys.stdout.flush()
-
+ out.start('Switching to branch "%s"' % args[0])
git.switch_branch(args[0])
-
- print 'done'
+ out.done()
return
# default action: print the current branch
"""
for p in patches:
if crt_series.empty_patch(p):
- print 'Deleting patch "%s"...' % p,
- sys.stdout.flush()
-
+ out.start('Deleting patch "%s"' % p)
if applied and crt_series.patch_applied(p):
crt_series.pop_patch(p)
crt_series.delete_patch(p)
-
- print 'done'
+ out.done()
elif applied and crt_series.patch_unapplied(p):
crt_series.push_patch(p)
crt_head = git.get_head()
- print 'Committing %d patches...' % len(applied),
- sys.stdout.flush()
+ out.start('Committing %d patches' % len(applied))
crt_series.pop_patch(applied[0])
git.switch(crt_head)
for patch in applied:
crt_series.delete_patch(patch)
- print 'done'
+ out.done()
patch = stack.Series(branch).get_current()
if patch:
- print 'Now at patch "%s"' % patch
+ out.info('Now at patch "%s"' % patch)
else:
- print 'No patches applied'
+ out.info('No patches applied')
def resolved(filename, reset = None):
if reset:
"""
forwarded = crt_series.forward_patches(patches)
if forwarded > 1:
- print 'Fast-forwarded patches "%s" - "%s"' % (patches[0],
- patches[forwarded - 1])
+ out.info('Fast-forwarded patches "%s" - "%s"'
+ % (patches[0], patches[forwarded - 1]))
elif forwarded == 1:
- print 'Fast-forwarded patch "%s"' % patches[0]
+ out.info('Fast-forwarded patch "%s"' % patches[0])
names = patches[forwarded:]
# check for patches merged upstream
if names and check_merged:
- print 'Checking for patches merged upstream...',
- sys.stdout.flush()
+ out.start('Checking for patches merged upstream')
merged = crt_series.merged_patches(names)
- print 'done (%d found)' % len(merged)
+ out.done('%d found' % len(merged))
else:
merged = []
for p in names:
- print 'Pushing patch "%s"...' % p,
- sys.stdout.flush()
+ out.start('Pushing patch "%s"' % p)
if p in merged:
crt_series.push_patch(p, empty = True)
- print 'done (merged upstream)'
+ out.done('merged upstream')
else:
modified = crt_series.push_patch(p)
if crt_series.empty_patch(p):
- print 'done (empty patch)'
+ out.done('empty patch')
elif modified:
- print 'done (modified)'
+ out.done('modified')
else:
- print 'done'
+ out.done()
def pop_patches(patches, keep = False):
"""Pop the patches in the list from the stack. It is assumed that
the patches are listed in the stack reverse order.
"""
if len(patches) == 0:
- print 'nothing to push/pop'
+ out.info('Nothing to push/pop')
else:
p = patches[-1]
if len(patches) == 1:
- print 'Popping patch "%s"...' % p,
+ out.start('Popping patch "%s"' % p)
else:
- print 'Popping "%s" - "%s" patches...' % (patches[0], p),
- sys.stdout.flush()
-
+ out.start('Popping patches "%s" - "%s"' % (patches[0], p))
crt_series.pop_patch(p, keep)
-
- print 'done'
+ out.done()
def parse_patches(patch_args, patch_list, boundary = 0, ordered = False):
"""Parse patch_args list for patch names in patch_list and return
# pop all patches
applied = crt_series.get_applied()
if len(applied) > 0:
- print 'Popping all applied patches...',
- sys.stdout.flush()
+ out.start('Popping all applied patches')
crt_series.pop_patch(applied[0])
- print 'done'
+ out.done()
return applied
def rebase(target):
if target == git.get_head():
- print 'Already at "%s", no need for rebasing.' % target
+ out.info('Already at "%s", no need for rebasing.' % target)
return
-
- print 'Rebasing to "%s"...' % target
+ out.start('Rebasing to "%s"' % target)
git.reset(tree_id = git_id(target))
+ out.done()
def post_rebase(applied, nopush, merged):
# memorize that we rebased to here
# delete the patches
for patch in applied + patches:
crt_series.delete_patch(patch)
- print 'Patch "%s" successfully deleted' % patch
+ out.info('Patch "%s" successfully deleted' % patch)
if not options.branch:
print_crt_patch()
rev2 = None
if options.stat:
- print git.diffstat(args, git_id(rev1), git_id(rev2))
+ out.stdout_raw(git.diffstat(args, git_id(rev1), git_id(rev2)) + '\n')
else:
diff_str = git.diff(args, git_id(rev1), git_id(rev2),
binary = options.binary)
dirname = 'patches-%s' % crt_series.get_branch()
if not options.branch and git.local_changes():
- print 'Warning: local changes in the tree. ' \
- 'You might want to commit them first'
+ out.warn('Local changes in the tree;'
+ ' you might want to commit them first')
if not options.stdout:
if not os.path.isdir(dirname):
f = open(pfile, 'w+')
if options.stdout and num > 1:
- print '-------------------------------------------------------------------------------'
+ print '-'*79
print patch.get_name()
- print '-------------------------------------------------------------------------------'
+ print '-'*79
# write description
f.write(descr)
rev2 = git_id('%s//top' % patch)
if options.stat:
- print git.diffstat(rev1 = rev1, rev2 = rev2)
+ out.stdout_raw(git.diffstat(rev1 = rev1, rev2 = rev2) + '\n')
elif options.bare:
- print git.barefiles(rev1, rev2)
+ out.stdout_raw(git.barefiles(rev1, rev2) + '\n')
else:
- print git.files(rev1, rev2)
+ out.stdout_raw(git.files(rev1, rev2) + '\n')
if filename:
if os.path.exists(filename):
- print 'Folding patch "%s"...' % filename,
+ out.start('Folding patch "%s"' % filename)
else:
raise CmdException, 'No such file: %s' % filename
else:
- print 'Folding patch from stdin...',
- sys.stdout.flush()
+ out.start('Folding patch from stdin')
if options.threeway:
crt_patch = crt_series.get_patch(current)
else:
git.apply_patch(filename = filename)
- print 'done'
+ out.done()
for patch in patches:
crt_series.hide_patch(patch)
- print 'Patch "%s" hidden' % patch
+ out.info('Patch "%s" hidden' % patch)
else:
parser.error('incorrect number of arguments')
- print git_id(id_str)
+ out.stdout(git_id(id_str))
raise CmdException, 'No diff found inside the patch'
if options.ignore and patch in crt_series.get_applied():
- print 'Ignoring already applied patch "%s"' % patch
+ out.info('Ignoring already applied patch "%s"' % patch)
return
if options.replace and patch in crt_series.get_unapplied():
crt_series.delete_patch(patch)
committer_name = committer_name,
committer_email = committer_email)
- print 'Importing patch "%s"...' % patch,
- sys.stdout.flush()
-
+ out.start('Importing patch "%s"' % patch)
if options.base:
git.apply_patch(diff = diff, base = git_id(options.base))
else:
git.apply_patch(diff = diff)
-
crt_series.refresh_patch(edit = options.edit,
show_patch = options.showpatch)
-
- print 'done'
+ out.done()
def __import_file(filename, options, patch = None):
"""Import a patch from a file or standard input
secs, tz = author_date.split()
date = '%s %s' % (time.ctime(int(secs)), tz)
- print descr, date
+ out.stdout('%s %s' % (descr, date))
parent = commit.get_parent()
if parent:
ref_id = msg_id
if options.mbox:
- print msg_string
+ out.stdout_raw(msg_string + '\n')
else:
- print 'Sending the cover message...',
- sys.stdout.flush()
+ out.start('Sending the cover message')
__send_message(smtpserver, from_addr, to_addr_list, msg_string,
sleep, smtpuser, smtppassword)
- print 'done'
+ out.done()
# send the patches
if options.template:
ref_id = msg_id
if options.mbox:
- print msg_string
+ out.stdout_raw(msg_string + '\n')
else:
- print 'Sending patch "%s"...' % p,
- sys.stdout.flush()
+ out.start('Sending patch "%s"' % p)
__send_message(smtpserver, from_addr, to_addr_list, msg_string,
sleep, smtpuser, smtppassword)
- print 'done'
+ out.done()
git.diff(args, patch.get_bottom(),
patch.get_top()))
else:
- print patch.get_name()
+ out.stdout(patch.get_name())
if options.diff:
pager(diff_output)
top = parent
if options.fold:
- print 'Folding commit %s...' % commit_id,
- sys.stdout.flush()
+ out.start('Folding commit %s' % commit_id)
# try a direct git-apply first
if not git.apply_diff(bottom, top):
git.merge(bottom, git.get_head(), top, recursive = True)
- print 'done'
+ out.done()
elif options.update:
rev1 = git_id('//bottom')
rev2 = git_id('//top')
files = git.barefiles(rev1, rev2).split('\n')
- print 'Updating with commit %s...' % commit_id,
- sys.stdout.flush()
+ out.start('Updating with commit %s' % commit_id)
if not git.apply_diff(bottom, top, files = files):
raise CmdException, 'Patch updating failed'
- print 'done'
+ out.done()
else:
message = commit.get_log()
author_name, author_email, author_date = \
name_email_date(commit.get_author())
- print 'Importing commit %s...' % commit_id,
- sys.stdout.flush()
+ out.start('Importing commit %s' % commit_id)
newpatch = crt_series.new_patch(patchname, message = message, can_edit = False,
unapplied = True, bottom = bottom, top = top,
refseries = crt_series
patch = refseries.get_patch(refpatchname)
if patch.get_log():
- print"log was %s" % newpatch.get_log()
- print "setting log to %s\n" % patch.get_log()
+ out.info("Log was %s" % newpatch.get_log())
+ out.info("Setting log to %s\n" % patch.get_log())
newpatch.set_log(patch.get_log())
- print"log is now %s" % newpatch.get_log()
+ out.info("Log is now %s" % newpatch.get_log())
else:
- print "no log for %s\n" % patchname
-
+ out.info("No log for %s\n" % patchname)
+
if not options.unapplied:
modified = crt_series.push_patch(patchname)
else:
modified = False
if crt_series.empty_patch(patchname):
- print 'done (empty patch)'
+ out.done('empty patch')
elif modified:
- print 'done (modified)'
+ out.done('modified')
else:
- print 'done'
-
+ out.done()
+
print_crt_patch()
# pull the remote changes
if policy == 'pull':
- print 'Pulling from "%s"...' % repository
+ out.info('Pulling from "%s"' % repository)
git.pull(repository)
elif policy == 'fetch-rebase':
- print 'Fetching from "%s"...' % repository
+ out.info('Fetching from "%s"' % repository)
git.fetch(repository)
rebase(git.fetch_head())
elif policy == 'rebase':
if not patch:
raise CmdException, 'No patch to undo'
- print 'Undoing the "%s" push...' % patch,
- sys.stdout.flush()
+ out.start('Undoing push of "%s"' % patch)
resolved_all()
if crt_series.undo_push():
- print 'done'
+ out.done()
else:
- print 'done (patch unchanged)'
+ out.done('patch unchanged')
print_crt_patch()
return
check_head_top_equal()
if options.undo:
- print 'Undoing the "%s" refresh...' % patch,
- sys.stdout.flush()
+ out.start('Undoing the refresh of "%s"' % patch)
crt_series.undo_refresh()
- print 'done'
+ out.done()
return
if options.author:
between = applied[:applied.index(patch):-1]
pop_patches(between, keep = True)
- print 'Refreshing patch "%s"...' % patch,
- sys.stdout.flush()
+ out.start('Refreshing patch "%s"' % patch)
if autoresolved == 'yes':
resolved_all()
backup = True, sign_str = sign_str)
if crt_series.empty_patch(patch):
- print 'done (empty patch)'
+ out.done('empty patch')
else:
- print 'done'
+ out.done()
if options.patch:
between.reverse()
push_patches(between)
else:
- print 'Patch "%s" is already up to date' % patch
+ out.info('Patch "%s" is already up to date' % patch)
if len(args) != 2:
parser.error('incorrect number of arguments')
- print 'Renaming patch "%s" -> "%s"...' % (args[0], args[1]),
- sys.stdout.flush()
+ out.start('Renaming patch "%s" to "%s"' % (args[0], args[1]))
crt_series.rename_patch(args[0], args[1])
- print 'done'
+ out.done()
patch_str = patch_str.ljust(length)
if options.description:
- print prefix + patch_str + ' | ' + __get_description(patch)
+ out.stdout(prefix + patch_str + ' | ' + __get_description(patch))
elif options.author:
- print prefix + patch_str + ' | ' + __get_author(patch)
+ out.stdout(prefix + patch_str + ' | ' + __get_author(patch))
else:
- print prefix + patch_str
+ out.stdout(prefix + patch_str)
def func(parser, options, args):
"""Show the patch series
patches = applied + unapplied
if options.count:
- print len(patches)
+ out.stdout(len(patches))
return
if not patches:
'--undo cannot be specified with --branch or --series'
__check_all()
- print 'Undoing the "%s" sync...' % crt_series.get_current(),
- sys.stdout.flush()
-
+ out.start('Undoing the sync of "%s"' % crt_series.get_current())
crt_series.undo_refresh()
git.reset()
-
- print 'done'
+ out.done()
return
if options.branch:
del popped[:idx]
# the actual sync
- print 'Synchronising "%s"...' % p,
- sys.stdout.flush()
+ out.start('Synchronising "%s"' % p)
patch = crt_series.get_patch(p)
bottom = patch.get_bottom()
# backup information was already reset above
crt_series.refresh_patch(cache_update = False, backup = False,
log = 'sync')
- print 'done (updated)'
+ out.done('updated')
else:
- print 'done'
+ out.done()
# push the remaining patches
if popped:
name = crt_series.get_current()
if name:
- print name
+ out.stdout(name)
else:
raise CmdException, 'No patches applied'
unapplied = crt_series.get_unapplied()
if options.count:
- print len(unapplied)
+ out.stdout(len(unapplied))
else:
for p in unapplied:
- print p
+ out.stdout(p)
commits = []
next_commit = crt_series.get_base()
if patch_nr:
- print 'Uncommitting %d patches...' % patch_nr,
+ out.start('Uncommitting %d patches' % patch_nr)
for i in xrange(patch_nr):
commit, commit_id, parent = get_commit(next_commit)
commits.append((commit, commit_id, parent))
next_commit = parent
else:
- print 'Uncommitting to %s...' % to_commit
+ out.start('Uncommitting to %s' % to_commit)
while True:
commit, commit_id, parent = get_commit(next_commit)
commits.append((commit, commit_id, parent))
next_commit = parent
patch_nr = len(commits)
- sys.stdout.flush()
for (commit, commit_id, parent), patchname in \
zip(commits, patchnames or [None for i in xrange(len(commits))]):
author_name, author_email, author_date = \
author_email = author_email,
author_date = author_date)
-
- print 'done'
+ out.done()
for patch in patches:
crt_series.unhide_patch(patch)
- print 'Patch "%s" unhidden' % patch
+ out.info('Patch "%s" unhidden' % patch)
noexclude = True, verbose = False):
"""Returns a list of pairs - [status, filename]
"""
- if verbose and sys.stdout.isatty():
- print 'Checking for changes in the working directory...',
- sys.stdout.flush()
+ if verbose:
+ out.start('Checking for changes in the working directory')
refresh_index()
if fs[1] not in conflicts:
cache_files.append(fs)
- if verbose and sys.stdout.isatty():
- print 'done'
+ if verbose:
+ out.done()
return cache_files
for f in [f.strip() for f in realfiles]:
m = prefix_regexp.match(f)
if not m:
- print '"%s" does not match "%s"' % (f, re_string)
- assert(m)
+ raise Exception, '"%s" does not match "%s"' % (f, re_string)
newname = target+target2+'/'+m.group(1)
if not os.path.exists(os.path.dirname(newname)):
os.makedirs(os.path.dirname(newname))
if files and not fs[1] in files:
continue
if all:
- print '%s %s' % (fs[0], fs[1])
+ out.stdout('%s %s' % (fs[0], fs[1]))
else:
- print '%s' % fs[1]
+ out.stdout('%s' % fs[1])
def diff(files = None, rev1 = 'HEAD', rev2 = None, out_fd = None,
binary = False):
f = file('.stgit-failed.patch', 'w+')
f.write(diff)
f.close()
- print >> sys.stderr, 'Diff written to the .stgit-failed.patch file'
+ out.warn('Diff written to the .stgit-failed.patch file')
raise
import sys, os
from stgit import basedir
from stgit.config import config, file_extensions, ConfigOption
-from stgit.utils import append_string
+from stgit.utils import append_string, out
class GitMergeException(Exception):
mtime = os.path.getmtime(filename)
- print 'Trying the interractive %s merge' % \
- (three_way and 'three-way' or 'two-way')
+ out.info('Trying the interactive %s merge'
+ % (three_way and 'three-way' or 'two-way'))
err = os.system(imerger % files_dict)
if err != 0:
if file1_hash == file2_hash:
if os.system('git-update-index --cacheinfo %s %s %s'
% (file1_mode, file1_hash, path)) != 0:
- print >> sys.stderr, 'Error: git-update-index failed'
+ out.error('git-update-index failed')
__conflict(path)
return 1
if os.system('git-checkout-index -u -f -- %s' % path):
- print >> sys.stderr, 'Error: git-checkout-index failed'
+ out.error('git-checkout-index failed')
__conflict(path)
return 1
if file1_mode != file2_mode:
- print >> sys.stderr, \
- 'Error: File added in both, permissions conflict'
+ out.error('File added in both, permissions conflict')
__conflict(path)
return 1
# 3-way merge
__remove_files(orig_hash, file1_hash, file2_hash)
return 0
else:
- print >> sys.stderr, \
- 'Error: three-way merge tool failed for file "%s"' \
- % path
+ out.error('Three-way merge tool failed for file "%s"'
+ % path)
# reset the cache to the first branch
os.system('git-update-index --cacheinfo %s %s %s'
% (file1_mode, file1_hash, path))
interactive_merge(path)
except GitMergeException, ex:
# interactive merge failed
- print >> sys.stderr, str(ex)
+ out.error(ex)
if str(keeporig) != 'yes':
__remove_files(orig_hash, file1_hash,
file2_hash)
if file1_hash == file2_hash:
if os.system('git-update-index --add --cacheinfo %s %s %s'
% (file1_mode, file1_hash, path)) != 0:
- print >> sys.stderr, 'Error: git-update-index failed'
+ out.error('git-update-index failed')
__conflict(path)
return 1
if os.system('git-checkout-index -u -f -- %s' % path):
- print >> sys.stderr, 'Error: git-checkout-index failed'
+ out.error('git-checkout-index failed')
__conflict(path)
return 1
if file1_mode != file2_mode:
- print >> sys.stderr, \
- 'Error: File "s" added in both, ' \
- 'permissions conflict' % path
+ out.error('File "s" added in both, permissions conflict'
+ % path)
__conflict(path)
return 1
# files added in both but different
else:
- print >> sys.stderr, \
- 'Error: File "%s" added in branches but different' % path
+ out.error('File "%s" added in branches but different' % path)
# reset the cache to the first branch
os.system('git-update-index --cacheinfo %s %s %s'
% (file1_mode, file1_hash, path))
interactive_merge(path)
except GitMergeException, ex:
# interactive merge failed
- print >> sys.stderr, str(ex)
+ out.error(ex)
if str(keeporig) != 'yes':
__remove_files(orig_hash, file1_hash,
file2_hash)
obj = file2_hash
if os.system('git-update-index --add --cacheinfo %s %s %s'
% (mode, obj, path)) != 0:
- print >> sys.stderr, 'Error: git-update-index failed'
+ out.error('git-update-index failed')
__conflict(path)
return 1
__remove_files(orig_hash, file1_hash, file2_hash)
return os.system('git-checkout-index -u -f -- %s' % path)
# Unhandled case
- print >> sys.stderr, 'Error: Unhandled merge conflict: ' \
- '"%s" "%s" "%s" "%s" "%s" "%s" "%s"' \
- % (orig_hash, file1_hash, file2_hash,
- path,
- orig_mode, file1_mode, file2_mode)
+ out.error('Unhandled merge conflict: "%s" "%s" "%s" "%s" "%s" "%s" "%s"'
+ % (orig_hash, file1_hash, file2_hash,
+ path,
+ orig_mode, file1_mode, file2_mode))
__conflict(path)
return 1
from optparse import OptionParser
import stgit.commands
+from stgit.utils import out
#
# The commands map
candidates = [cmd for cmd in self.keys() if cmd.startswith(key)]
if not candidates:
- print >> sys.stderr, 'Unknown command: %s' % key
- print >> sys.stderr, ' Try "%s help" for a list of ' \
- 'supported commands' % prog
+ out.error('Unknown command: %s' % key,
+ 'Try "%s help" for a list of supported commands' % prog)
sys.exit(1)
elif len(candidates) > 1:
- print >> sys.stderr, 'Ambiguous command: %s' % key
- print >> sys.stderr, ' Candidates are: %s' \
- % ', '.join(candidates)
+ out.error('Ambiguous command: %s' % key,
+ 'Candidates are: %s' % ', '.join(candidates))
sys.exit(1)
return candidates[0]
if len(sys.argv) == 3 and not sys.argv[2] in ['-h', '--help']:
cmd = commands.canonical_cmd(sys.argv[2])
if not cmd in commands:
- print >> sys.stderr, '%s help: "%s" command unknown' \
- % (prog, cmd)
+ out.error('%s help: "%s" command unknown' % (prog, cmd))
sys.exit(1)
sys.argv[0] += ' %s' % cmd
except KeyError:
debug_level = 0
except ValueError:
- print >> sys.stderr, 'Invalid STGIT_DEBUG_LEVEL environment variable'
+ out.error('Invalid STGIT_DEBUG_LEVEL environment variable')
sys.exit(1)
try:
# The branch doesn't seem to be initialized at all.
return None
def set_format_version(v):
+ out.info('Upgraded branch %s to format version %d' % (branch, v))
config.set(format_version_key(branch), '%d' % v)
def mkdir(d):
if not os.path.isdir(d):
if value:
return value
elif 'origin' in git.remotes_list():
- print 'Notice: no parent remote declared for stack "%s", ' \
- 'defaulting to "origin". Consider setting "branch.%s.remote" ' \
- 'and "branch.%s.merge" with "git repo-config".' \
- % (self.__name, self.__name, self.__name)
+ out.note(('No parent remote declared for stack "%s",'
+ ' defaulting to "origin".' % self.__name),
+ ('Consider setting "branch.%s.remote" and'
+ ' "branch.%s.merge" with "git repo-config".'
+ % (self.__name, self.__name)))
return 'origin'
else:
raise StackException, 'Cannot find a parent remote for "%s"' % self.__name
if value:
return value
elif git.rev_parse('heads/origin'):
- print 'Notice: no parent branch declared for stack "%s", ' \
- 'defaulting to "heads/origin". Consider setting ' \
- '"branch.%s.stgit.parentbranch" with "git repo-config".' \
- % (self.__name, self.__name)
+ out.note(('No parent branch declared for stack "%s",'
+ ' defaulting to "heads/origin".' % self.__name),
+ ('Consider setting "branch.%s.stgit.parentbranch"'
+ ' with "git repo-config".' % self.__name))
return 'heads/origin'
else:
raise StackException, 'Cannot find a parent branch for "%s"' % self.__name
author_email = patch.get_authemail(),
author_date = patch.get_authdate())
if patch.get_log():
- print "setting log to %s" % patch.get_log()
+ out.info('Setting log to %s' % patch.get_log())
newpatch.set_log(patch.get_log())
else:
- print "no log for %s" % p
+ out.info('No log for %s' % p)
# fast forward the cloned series to self's top
new_series.forward_patches(applied)
if not os.listdir(self.__patch_dir):
os.rmdir(self.__patch_dir)
else:
- print 'Patch directory %s is not empty.' % self.__patch_dir
+ out.warn('Patch directory %s is not empty' % self.__patch_dir)
try:
os.removedirs(self._dir())
except OSError:
- raise StackException, 'Series directory %s is not empty.' % self._dir()
+ raise StackException('Series directory %s is not empty'
+ % self._dir())
try:
os.removedirs(self.__refs_dir)
except OSError:
- print 'Refs directory %s is not empty.' % self.__refs_dir
+ out.warn('Refs directory %s is not empty' % self.__refs_dir)
# Cleanup parent informations
# FIXME: should one day make use of git-config --section-remove,
try:
git.merge(bottom, head, top, recursive = True)
except git.GitException, ex:
- print >> sys.stderr, \
- 'The merge failed during "push". ' \
- 'Use "refresh" after fixing the conflicts or ' \
- 'revert the operation with "push --undo".'
+ out.error('The merge failed during "push".',
+ 'Use "refresh" after fixing the conflicts or'
+ ' revert the operation with "push --undo".')
append_string(self.__applied_file, name)
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
+class MessagePrinter(object):
+ def __init__(self):
+ class Output(object):
+ def __init__(self, write, flush):
+ self.write = write
+ self.flush = flush
+ self.at_start_of_line = True
+ self.level = 0
+ def new_line(self):
+ """Ensure that we're at the beginning of a line."""
+ if not self.at_start_of_line:
+ self.write('\n')
+ self.at_start_of_line = True
+ def single_line(self, msg, print_newline = True,
+ need_newline = True):
+ """Write a single line. Newline before and after are
+ separately configurable."""
+ if need_newline:
+ self.new_line()
+ if self.at_start_of_line:
+ self.write(' '*self.level)
+ self.write(msg)
+ if print_newline:
+ self.write('\n')
+ self.at_start_of_line = True
+ else:
+ self.flush()
+ self.at_start_of_line = False
+ def tagged_lines(self, tag, lines):
+ tag += ': '
+ for line in lines:
+ self.single_line(tag + line)
+ tag = ' '*len(tag)
+ def write_line(self, line):
+ """Write one line of text on a lines of its own, not
+ indented."""
+ self.new_line()
+ self.write('%s\n' % line)
+ self.at_start_of_line = True
+ def write_raw(self, string):
+ """Write an arbitrary string, possibly containing
+ newlines."""
+ self.new_line()
+ self.write(string)
+ self.at_start_of_line = string.endswith('\n')
+ self.__stdout = Output(sys.stdout.write, sys.stdout.flush)
+ if sys.stdout.isatty():
+ self.__out = self.__stdout
+ else:
+ self.__out = Output(lambda msg: None, lambda: None)
+ def stdout(self, line):
+ """Write a line to stdout."""
+ self.__stdout.write_line(line)
+ def stdout_raw(self, string):
+ """Write a string possibly containing newlines to stdout."""
+ self.__stdout.write_raw(string)
+ def info(self, *msgs):
+ for msg in msgs:
+ self.__out.single_line(msg)
+ def note(self, *msgs):
+ self.__out.tagged_lines('Notice', msgs)
+ def warn(self, *msgs):
+ self.__out.tagged_lines('Warning', msgs)
+ def error(self, *msgs):
+ self.__out.tagged_lines('Error', msgs)
+ def start(self, msg):
+ """Start a long-running operation."""
+ self.__out.single_line('%s ... ' % msg, print_newline = False)
+ self.__out.level += 1
+ def done(self, extramsg = None):
+ """Finish long-running operation."""
+ self.__out.level -= 1
+ if extramsg:
+ msg = 'done (%s)' % extramsg
+ else:
+ msg = 'done'
+ self.__out.single_line(msg, need_newline = False)
+
+out = MessagePrinter()
+
def mkdir_file(filename, mode):
"""Opens filename with the given mode, creating the directory it's
in if it doesn't already exist."""
editor = 'vi'
editor += ' %s' % filename
- print 'Invoking the editor: "%s"...' % editor,
- sys.stdout.flush()
+ out.start('Invoking the editor: "%s"' % editor)
err = os.system(editor)
if err:
raise EditorException, 'editor failed, exit code: %d' % err
- print 'done'
+ out.done()
def patch_name_from_msg(msg):
"""Return a string to be used as a patch name. This is generated