# the editor
editor = config.get('stgit.editor')
- if editor:
- pass
- elif 'EDITOR' in os.environ:
- editor = os.environ['EDITOR']
- else:
- editor = 'vi'
+ if not editor:
+ editor = os.environ.get('EDITOR', 'vi')
editor += ' %s' % filename
out.start('Invoking the editor: "%s"' % editor)
raise EditorException, 'editor failed, exit code: %d' % err
out.done()
+def edit_string(s, filename):
+ f = file(filename, 'w')
+ f.write(s)
+ f.close()
+ call_editor(filename)
+ f = file(filename)
+ s = f.read()
+ f.close()
+ os.remove(filename)
+ return s
+
def patch_name_from_msg(msg):
"""Return a string to be used as a patch name. This is generated
from the top line of the string passed as argument."""
if not any(s in desc for s in ['\nSigned-off-by:', '\nAcked-by:']):
desc = desc + '\n'
return '%s\n%s\n' % (desc, sign_str)
+
+def make_message_options():
+ def no_dup(parser):
+ if parser.values.message != None:
+ raise optparse.OptionValueError(
+ 'Cannot give more than one --message or --file')
+ def no_combine(parser):
+ if (parser.values.message != None
+ and parser.values.save_template != None):
+ raise optparse.OptionValueError(
+ 'Cannot give both --message/--file and --save-template')
+ def msg_callback(option, opt_str, value, parser):
+ no_dup(parser)
+ parser.values.message = value
+ no_combine(parser)
+ def file_callback(option, opt_str, value, parser):
+ no_dup(parser)
+ if value == '-':
+ parser.values.message = sys.stdin.read()
+ else:
+ f = file(value)
+ parser.values.message = f.read()
+ f.close()
+ no_combine(parser)
+ def templ_callback(option, opt_str, value, parser):
+ if value == '-':
+ def w(s):
+ sys.stdout.write(s)
+ else:
+ def w(s):
+ f = file(value, 'w+')
+ f.write(s)
+ f.close()
+ parser.values.save_template = w
+ no_combine(parser)
+ m = optparse.make_option
+ return [m('-m', '--message', action = 'callback', callback = msg_callback,
+ dest = 'message', type = 'string',
+ help = 'use MESSAGE instead of invoking the editor'),
+ m('-f', '--file', action = 'callback', callback = file_callback,
+ dest = 'message', type = 'string', metavar = 'FILE',
+ help = 'use FILE instead of invoking the editor'),
+ m('--save-template', action = 'callback', callback = templ_callback,
+ metavar = 'FILE', dest = 'save_template', type = 'string',
+ help = 'save the message template to FILE and exit')]
+
+def make_diff_opts_option():
+ def diff_opts_callback(option, opt_str, value, parser):
+ if value:
+ parser.values.diff_flags.extend(value.split())
+ else:
+ parser.values.diff_flags = []
+ return [optparse.make_option(
+ '-O', '--diff-opts', dest = 'diff_flags',
+ default = (config.get('stgit.diff-opts') or '').split(),
+ action = 'callback', callback = diff_opts_callback,
+ type = 'string', metavar = 'OPTIONS',
+ help = 'extra options to pass to "git diff"')]
+
+def parse_name_email(address):
+ """Return a tuple consisting of the name and email parsed from a
+ standard 'name <email>' or 'email (name)' string."""
+ address = re.sub(r'[\\"]', r'\\\g<0>', address)
+ str_list = re.findall(r'^(.*)\s*<(.*)>\s*$', address)
+ if not str_list:
+ str_list = re.findall(r'^(.*)\s*\((.*)\)\s*$', address)
+ if not str_list:
+ return None
+ return (str_list[0][1], str_list[0][0])
+ return str_list[0]
+
+def parse_name_email_date(address):
+ """Return a tuple consisting of the name, email and date parsed
+ from a 'name <email> date' string."""
+ address = re.sub(r'[\\"]', r'\\\g<0>', address)
+ str_list = re.findall('^(.*)\s*<(.*)>\s*(.*)\s*$', address)
+ if not str_list:
+ return None
+ return str_list[0]
+
+def make_person_options(person, short):
+ """Sets options.<person> to a function that modifies a Person
+ according to the commandline options."""
+ def short_callback(option, opt_str, value, parser, field):
+ f = getattr(parser.values, person)
+ setattr(parser.values, person,
+ lambda p: getattr(f(p), 'set_' + field)(value))
+ def full_callback(option, opt_str, value, parser):
+ ne = parse_name_email(value)
+ if not ne:
+ raise optparse.OptionValueError(
+ 'Bad %s specification: %r' % (opt_str, value))
+ name, email = ne
+ short_callback(option, opt_str, name, parser, 'name')
+ short_callback(option, opt_str, email, parser, 'email')
+ return ([optparse.make_option(
+ '--%s' % person, metavar = '"NAME <EMAIL>"', type = 'string',
+ action = 'callback', callback = full_callback, dest = person,
+ default = lambda p: p, help = 'set the %s details' % person)]
+ + [optparse.make_option(
+ '--%s%s' % (short, f), metavar = f.upper(), type = 'string',
+ action = 'callback', callback = short_callback, dest = person,
+ callback_args = (f,), help = 'set the %s %s' % (person, f))
+ for f in ['name', 'email', 'date']])
+
+def make_author_committer_options():
+ return (make_person_options('author', 'auth')
+ + make_person_options('committer', 'comm'))
+
+# Exit codes.
+STGIT_SUCCESS = 0 # everything's OK
+STGIT_GENERAL_ERROR = 1 # seems to be non-command-specific error
+STGIT_COMMAND_ERROR = 2 # seems to be a command that failed
+STGIT_CONFLICT = 3 # merge conflict, otherwise OK
+STGIT_BUG_ERROR = 4 # a bug in StGit
+
+def strip_leading(prefix, s):
+ """Strip leading prefix from a string. Blow up if the prefix isn't
+ there."""
+ assert s.startswith(prefix)
+ return s[len(prefix):]
+
+def add_dict(d1, d2):
+ """Return a new dict with the contents of both d1 and d2. In case of
+ conflicting mappings, d2 takes precedence."""
+ d = dict(d1)
+ d.update(d2)
+ return d