Mercurial > public > mercurial-scm > hg-stable
diff hgext/patchbomb.py @ 43076:2372284d9457
formatting: blacken the codebase
This is using my patch to black
(https://github.com/psf/black/pull/826) so we don't un-wrap collection
literals.
Done with:
hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S
# skip-blame mass-reformatting only
# no-check-commit reformats foo_bar functions
Differential Revision: https://phab.mercurial-scm.org/D6971
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:45:02 -0400 |
parents | 943248e47864 |
children | 687b865b95ad |
line wrap: on
line diff
--- a/hgext/patchbomb.py Sat Oct 05 10:29:34 2019 -0400 +++ b/hgext/patchbomb.py Sun Oct 06 09:45:02 2019 -0400 @@ -100,6 +100,7 @@ util, ) from mercurial.utils import dateutil + stringio = util.stringio cmdtable = {} @@ -108,35 +109,35 @@ configtable = {} configitem = registrar.configitem(configtable) -configitem('patchbomb', 'bundletype', - default=None, +configitem( + 'patchbomb', 'bundletype', default=None, ) -configitem('patchbomb', 'bcc', - default=None, +configitem( + 'patchbomb', 'bcc', default=None, ) -configitem('patchbomb', 'cc', - default=None, +configitem( + 'patchbomb', 'cc', default=None, ) -configitem('patchbomb', 'confirm', - default=False, +configitem( + 'patchbomb', 'confirm', default=False, ) -configitem('patchbomb', 'flagtemplate', - default=None, +configitem( + 'patchbomb', 'flagtemplate', default=None, ) -configitem('patchbomb', 'from', - default=None, +configitem( + 'patchbomb', 'from', default=None, ) -configitem('patchbomb', 'intro', - default='auto', +configitem( + 'patchbomb', 'intro', default='auto', ) -configitem('patchbomb', 'publicurl', - default=None, +configitem( + 'patchbomb', 'publicurl', default=None, ) -configitem('patchbomb', 'reply-to', - default=None, +configitem( + 'patchbomb', 'reply-to', default=None, ) -configitem('patchbomb', 'to', - default=None, +configitem( + 'patchbomb', 'to', default=None, ) if pycompat.ispy3: @@ -150,6 +151,7 @@ # leave the attribute unspecified. testedwith = 'ships-with-hg-core' + def _addpullheader(seq, ctx): """Add a header pointing to a public URL where the changeset is available """ @@ -159,24 +161,31 @@ # destination before patchbombing anything. publicurl = repo.ui.config('patchbomb', 'publicurl') if publicurl: - return ('Available At %s\n' - '# hg pull %s -r %s' % (publicurl, publicurl, ctx)) + return 'Available At %s\n' '# hg pull %s -r %s' % ( + publicurl, + publicurl, + ctx, + ) return None + def uisetup(ui): cmdutil.extraexport.append('pullurl') cmdutil.extraexportmap['pullurl'] = _addpullheader + def reposetup(ui, repo): if not repo.local(): return repo._wlockfreeprefix.add('last-email.txt') + def prompt(ui, prompt, default=None, rest=':'): if default: prompt += ' [%s]' % default return ui.prompt(prompt + rest, default) + def introwanted(ui, opts, number): '''is an introductory message apparently wanted?''' introconfig = ui.config('patchbomb', 'intro') @@ -189,12 +198,14 @@ elif introconfig == 'auto': intro = number > 1 else: - ui.write_err(_('warning: invalid patchbomb.intro value "%s"\n') - % introconfig) + ui.write_err( + _('warning: invalid patchbomb.intro value "%s"\n') % introconfig + ) ui.write_err(_('(should be one of always, never, auto)\n')) intro = number > 1 return intro + def _formatflags(ui, repo, rev, flags): """build flag string optionally by template""" tmpl = ui.config('patchbomb', 'flagtemplate') @@ -208,6 +219,7 @@ fm.write('flags', '%s', fm.formatlist(flags, name='flag')) return out.getvalue() + def _formatprefix(ui, repo, rev, flags, idx, total, numbered): """build prefix to patch subject""" flag = _formatflags(ui, repo, rev, flags) @@ -220,8 +232,19 @@ tlen = len("%d" % total) return '[PATCH %0*d of %d%s]' % (tlen, idx, total, flag) -def makepatch(ui, repo, rev, patchlines, opts, _charsets, idx, total, numbered, - patchname=None): + +def makepatch( + ui, + repo, + rev, + patchlines, + opts, + _charsets, + idx, + total, + numbered, + patchname=None, +): desc = [] node = None @@ -240,8 +263,9 @@ raise ValueError if opts.get('attach') and not opts.get('body'): - body = ('\n'.join(desc[1:]).strip() or - 'Patch subject is complete summary.') + body = ( + '\n'.join(desc[1:]).strip() or 'Patch subject is complete summary.' + ) body += '\n\n\n' if opts.get('plain'): @@ -264,31 +288,38 @@ msg = emimemultipart.MIMEMultipart() if body: msg.attach(mail.mimeencode(ui, body, _charsets, opts.get('test'))) - p = mail.mimetextpatch('\n'.join(patchlines), 'x-patch', - opts.get('test')) + p = mail.mimetextpatch( + '\n'.join(patchlines), 'x-patch', opts.get('test') + ) binnode = nodemod.bin(node) # if node is mq patch, it will have the patch file's name as a tag if not patchname: - patchtags = [t for t in repo.nodetags(binnode) - if t.endswith('.patch') or t.endswith('.diff')] + patchtags = [ + t + for t in repo.nodetags(binnode) + if t.endswith('.patch') or t.endswith('.diff') + ] if patchtags: patchname = patchtags[0] elif total > 1: - patchname = cmdutil.makefilename(repo[node], '%b-%n.patch', - seqno=idx, total=total) + patchname = cmdutil.makefilename( + repo[node], '%b-%n.patch', seqno=idx, total=total + ) else: patchname = cmdutil.makefilename(repo[node], '%b.patch') disposition = r'inline' if opts.get('attach'): disposition = r'attachment' p[r'Content-Disposition'] = ( - disposition + r'; filename=' + encoding.strfromlocal(patchname)) + disposition + r'; filename=' + encoding.strfromlocal(patchname) + ) msg.attach(p) else: msg = mail.mimetextpatch(body, display=opts.get('test')) - prefix = _formatprefix(ui, repo, rev, opts.get('flag'), idx, total, - numbered) + prefix = _formatprefix( + ui, repo, rev, opts.get('flag'), idx, total, numbered + ) subj = desc[0].strip().rstrip('. ') if not numbered: subj = ' '.join([prefix, opts.get('subject') or subj]) @@ -300,6 +331,7 @@ msg['X-Mercurial-Series-Total'] = '%i' % total return msg, subj, ds + def _getpatches(repo, revs, **opts): """return a list of patches for a list of revisions @@ -309,12 +341,16 @@ prev = repo['.'].rev() for r in revs: if r == prev and (repo[None].files() or repo[None].deleted()): - ui.warn(_('warning: working directory has ' - 'uncommitted changes\n')) + ui.warn( + _('warning: working directory has ' 'uncommitted changes\n') + ) output = stringio() - cmdutil.exportfile(repo, [r], output, - opts=patch.difffeatureopts(ui, opts, git=True)) + cmdutil.exportfile( + repo, [r], output, opts=patch.difffeatureopts(ui, opts, git=True) + ) yield output.getvalue().split('\n') + + def _getbundle(repo, dest, **opts): """return a bundle containing changesets missing in "dest" @@ -339,6 +375,7 @@ pass os.rmdir(tmpdir) + def _getdescription(repo, defaultbody, sender, **opts): """obtain the body of the introduction message and return it @@ -351,16 +388,19 @@ if opts.get(r'desc'): body = open(opts.get(r'desc')).read() else: - ui.write(_('\nWrite the introductory message for the ' - 'patch series.\n\n')) - body = ui.edit(defaultbody, sender, repopath=repo.path, - action='patchbombbody') + ui.write( + _('\nWrite the introductory message for the ' 'patch series.\n\n') + ) + body = ui.edit( + defaultbody, sender, repopath=repo.path, action='patchbombbody' + ) # Save series description in case sendmail fails msgfile = repo.vfs('last-email.txt', 'wb') msgfile.write(body) msgfile.close() return body + def _getbundlemsgs(repo, sender, bundle, **opts): """Get the full email for sending a given bundle @@ -369,8 +409,9 @@ """ ui = repo.ui _charsets = mail._charsets(ui) - subj = (opts.get(r'subject') - or prompt(ui, 'Subject:', 'A bundle for your repository')) + subj = opts.get(r'subject') or prompt( + ui, 'Subject:', 'A bundle for your repository' + ) body = _getdescription(repo, '', sender, **opts) msg = emimemultipart.MIMEMultipart() @@ -379,13 +420,17 @@ datapart = emimebase.MIMEBase(r'application', r'x-mercurial-bundle') datapart.set_payload(bundle) bundlename = '%s.hg' % opts.get(r'bundlename', 'bundle') - datapart.add_header(r'Content-Disposition', r'attachment', - filename=encoding.strfromlocal(bundlename)) + datapart.add_header( + r'Content-Disposition', + r'attachment', + filename=encoding.strfromlocal(bundlename), + ) emailencoders.encode_base64(datapart) msg.attach(datapart) msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get(r'test')) return [(msg, subj, None)] + def _makeintro(repo, sender, revs, patches, **opts): """make an introduction email, asking the user for content if needed @@ -394,12 +439,14 @@ _charsets = mail._charsets(ui) # use the last revision which is likely to be a bookmarked head - prefix = _formatprefix(ui, repo, revs.last(), opts.get(r'flag'), - 0, len(patches), numbered=True) - subj = (opts.get(r'subject') or - prompt(ui, '(optional) Subject: ', rest=prefix, default='')) + prefix = _formatprefix( + ui, repo, revs.last(), opts.get(r'flag'), 0, len(patches), numbered=True + ) + subj = opts.get(r'subject') or prompt( + ui, '(optional) Subject: ', rest=prefix, default='' + ) if not subj: - return None # skip intro if the user doesn't bother + return None # skip intro if the user doesn't bother subj = prefix + ' ' + subj @@ -413,10 +460,10 @@ body = _getdescription(repo, body, sender, **opts) msg = mail.mimeencode(ui, body, _charsets, opts.get(r'test')) - msg['Subject'] = mail.headencode(ui, subj, _charsets, - opts.get(r'test')) + msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get(r'test')) return (msg, subj, diffstat) + def _getpatchmsgs(repo, sender, revs, patchnames=None, **opts): """return a list of emails from a list of patches @@ -430,8 +477,7 @@ patches = list(_getpatches(repo, revs, **opts)) msgs = [] - ui.write(_('this patch series consists of %d patches.\n\n') - % len(patches)) + ui.write(_('this patch series consists of %d patches.\n\n') % len(patches)) # build the intro message, or skip it if the user declines if introwanted(ui, bytesopts, len(patches)): @@ -448,12 +494,23 @@ for i, (r, p) in enumerate(zip(revs, patches)): if patchnames: name = patchnames[i] - msg = makepatch(ui, repo, r, p, bytesopts, _charsets, - i + 1, len(patches), numbered, name) + msg = makepatch( + ui, + repo, + r, + p, + bytesopts, + _charsets, + i + 1, + len(patches), + numbered, + name, + ) msgs.append(msg) return msgs + def _getoutgoing(repo, dest, revs): '''Return the revisions present locally but not in dest''' ui = repo.ui @@ -469,54 +526,122 @@ ui.status(_("no changes found\n")) return revs + def _msgid(node, timestamp): hostname = encoding.strtolocal(socket.getfqdn()) hostname = encoding.environ.get('HGHOSTNAME', hostname) return '<%s.%d@%s>' % (node, timestamp, hostname) + emailopts = [ ('', 'body', None, _('send patches as inline message text (default)')), ('a', 'attach', None, _('send patches as attachments')), ('i', 'inline', None, _('send patches as inline attachments')), - ('', 'bcc', [], - _('email addresses of blind carbon copy recipients'), _('EMAIL')), + ( + '', + 'bcc', + [], + _('email addresses of blind carbon copy recipients'), + _('EMAIL'), + ), ('c', 'cc', [], _('email addresses of copy recipients'), _('EMAIL')), ('', 'confirm', None, _('ask for confirmation before sending')), ('d', 'diffstat', None, _('add diffstat output to messages')), ('', 'date', '', _('use the given date as the sending date'), _('DATE')), - ('', 'desc', '', - _('use the given file as the series description'), _('FILE')), + ( + '', + 'desc', + '', + _('use the given file as the series description'), + _('FILE'), + ), ('f', 'from', '', _('email address of sender'), _('EMAIL')), ('n', 'test', None, _('print messages that would be sent')), - ('m', 'mbox', '', - _('write messages to mbox file instead of sending them'), _('FILE')), - ('', 'reply-to', [], - _('email addresses replies should be sent to'), _('EMAIL')), - ('s', 'subject', '', - _('subject of first message (intro or single patch)'), _('TEXT')), + ( + 'm', + 'mbox', + '', + _('write messages to mbox file instead of sending them'), + _('FILE'), + ), + ( + '', + 'reply-to', + [], + _('email addresses replies should be sent to'), + _('EMAIL'), + ), + ( + 's', + 'subject', + '', + _('subject of first message (intro or single patch)'), + _('TEXT'), + ), ('', 'in-reply-to', '', _('message identifier to reply to'), _('MSGID')), ('', 'flag', [], _('flags to add in subject prefixes'), _('FLAG')), - ('t', 'to', [], _('email addresses of recipients'), _('EMAIL'))] + ('t', 'to', [], _('email addresses of recipients'), _('EMAIL')), +] + -@command('email', - [('g', 'git', None, _('use git extended diff format')), - ('', 'plain', None, _('omit hg patch header')), - ('o', 'outgoing', None, - _('send changes not found in the target repository')), - ('b', 'bundle', None, _('send changes not in target as a binary bundle')), - ('B', 'bookmark', '', - _('send changes only reachable by given bookmark'), _('BOOKMARK')), - ('', 'bundlename', 'bundle', - _('name of the bundle attachment file'), _('NAME')), - ('r', 'rev', [], _('a revision to send'), _('REV')), - ('', 'force', None, _('run even when remote repository is unrelated ' - '(with -b/--bundle)')), - ('', 'base', [], _('a base changeset to specify instead of a destination ' - '(with -b/--bundle)'), _('REV')), - ('', 'intro', None, _('send an introduction email for a single patch')), - ] + emailopts + cmdutil.remoteopts, +@command( + 'email', + [ + ('g', 'git', None, _('use git extended diff format')), + ('', 'plain', None, _('omit hg patch header')), + ( + 'o', + 'outgoing', + None, + _('send changes not found in the target repository'), + ), + ( + 'b', + 'bundle', + None, + _('send changes not in target as a binary bundle'), + ), + ( + 'B', + 'bookmark', + '', + _('send changes only reachable by given bookmark'), + _('BOOKMARK'), + ), + ( + '', + 'bundlename', + 'bundle', + _('name of the bundle attachment file'), + _('NAME'), + ), + ('r', 'rev', [], _('a revision to send'), _('REV')), + ( + '', + 'force', + None, + _( + 'run even when remote repository is unrelated ' + '(with -b/--bundle)' + ), + ), + ( + '', + 'base', + [], + _( + 'a base changeset to specify instead of a destination ' + '(with -b/--bundle)' + ), + _('REV'), + ), + ('', 'intro', None, _('send an introduction email for a single patch')), + ] + + emailopts + + cmdutil.remoteopts, _('hg email [OPTION]... [DEST]...'), - helpcategory=command.CATEGORY_IMPORT_EXPORT) + helpcategory=command.CATEGORY_IMPORT_EXPORT, +) def email(ui, repo, *revs, **opts): '''send changesets by email @@ -621,8 +746,12 @@ raise error.Abort(_('specify at least one changeset with -B, -r or -o')) if outgoing and bundle: - raise error.Abort(_("--outgoing mode always on with --bundle;" - " do not re-specify --outgoing")) + raise error.Abort( + _( + "--outgoing mode always on with --bundle;" + " do not re-specify --outgoing" + ) + ) if rev and bookmark: raise error.Abort(_("-r and -B are mutually exclusive")) @@ -657,8 +786,9 @@ try: publicpeer = hg.peer(repo, {}, publicurl) except error.RepoError: - repo.ui.write_err(_('unable to access public repo: %s\n') - % publicurl) + repo.ui.write_err( + _('unable to access public repo: %s\n') % publicurl + ) raise if not publicpeer.capable('known'): repo.ui.debug('skipping existence checks: public repo too old\n') @@ -677,8 +807,9 @@ msg = _('public url %s is missing %s') msg %= (publicurl, missing[0]) missingrevs = [ctx.rev() for ctx in missing] - revhint = ' '.join('-r %s' % h - for h in repo.set('heads(%ld)', missingrevs)) + revhint = ' '.join( + '-r %s' % h for h in repo.set('heads(%ld)', missingrevs) + ) hint = _("use 'hg push %s %s'") % (publicurl, revhint) raise error.Abort(msg, hint=hint) @@ -692,9 +823,12 @@ return _msgid(id[:20], int(start_time[0])) # deprecated config: patchbomb.from - sender = (opts.get('from') or ui.config('email', 'from') or - ui.config('patchbomb', 'from') or - prompt(ui, 'From', ui.username())) + sender = ( + opts.get('from') + or ui.config('email', 'from') + or ui.config('patchbomb', 'from') + or prompt(ui, 'From', ui.username()) + ) if bundle: stropts = pycompat.strkwargs(opts) @@ -716,11 +850,13 @@ return mail.addrlistencode(ui, addrs, _charsets, opts.get('test')) # not on the command line: fallback to config and then maybe ask - addr = (ui.config('email', configkey) or - ui.config('patchbomb', configkey)) + addr = ui.config('email', configkey) or ui.config( + 'patchbomb', configkey + ) if not addr: - specified = (ui.hasconfig('email', configkey) or - ui.hasconfig('patchbomb', configkey)) + specified = ui.hasconfig('email', configkey) or ui.hasconfig( + 'patchbomb', configkey + ) if not specified and ask: addr = prompt(ui, header, default=default) if addr: @@ -728,7 +864,8 @@ return mail.addrlistencode(ui, [addr], _charsets, opts.get('test')) elif default: return mail.addrlistencode( - ui, [default], _charsets, opts.get('test')) + ui, [default], _charsets, opts.get('test') + ) return [] to = getaddrs('To', ask=True) @@ -752,8 +889,9 @@ if ds: ui.write(ds, label='patchbomb.diffstats') ui.write('\n') - if ui.promptchoice(_('are you sure you want to send (yn)?' - '$$ &Yes $$ &No')): + if ui.promptchoice( + _('are you sure you want to send (yn)?' '$$ &Yes $$ &No') + ): raise error.Abort(_('patchbomb canceled')) ui.write('\n') @@ -792,7 +930,7 @@ m['From'] = sender m['To'] = ', '.join(to) if cc: - m['Cc'] = ', '.join(cc) + m['Cc'] = ', '.join(cc) if bcc: m['Bcc'] = ', '.join(bcc) if replyto: