def writediffproperties(ctx, diff): """write metadata to diff so patches could be applied losslessly""" params = { b'diff_id': diff[r'id'], b'name': b'hg:meta', b'data': json.dumps({ b'user': ctx.user(), b'date': b'%d %d' % ctx.date(), b'node': ctx.hex(), b'parent': ctx.p1().hex(), }), } callconduit(ctx.repo(), b'differential.setdiffproperty', params) params = { b'diff_id': diff[r'id'], b'name': b'local:commits', b'data': json.dumps({ ctx.hex(): { b'author': stringutil.person(ctx.user()), b'authorEmail': stringutil.email(ctx.user()), b'time': ctx.date()[0], }, }), } callconduit(ctx.repo(), b'differential.setdiffproperty', params)
def update(self, bugid, newstate, ctx): '''update bugzilla bug with reference to changeset.''' def webroot(root): '''strip leading prefix of repo root and turn into url-safe path.''' count = int(self.ui.config('bugzilla', 'strip')) root = util.pconvert(root) while count > 0: c = root.find('/') if c == -1: break root = root[c + 1:] count -= 1 return root mapfile = None tmpl = self.ui.config('bugzilla', 'template') if not tmpl: mapfile = self.ui.config('bugzilla', 'style') if not mapfile and not tmpl: tmpl = _('changeset {node|short} in repo {root} refers ' 'to bug {bug}.\ndetails:\n\t{desc|tabindent}') spec = logcmdutil.templatespec(tmpl, mapfile) t = logcmdutil.changesettemplater(self.ui, self.repo, spec) self.ui.pushbuffer() t.show(ctx, changes=ctx.changeset(), bug=str(bugid), hgweb=self.ui.config('web', 'baseurl'), root=self.repo.root, webroot=webroot(self.repo.root)) data = self.ui.popbuffer() self.bzdriver.updatebug(bugid, newstate, data, stringutil.email(ctx.user()))
def fixmail(self, addr): '''try to clean up email addresses.''' addr = stringutil.email(addr.strip()) if self.domain: a = addr.find('@localhost') if a != -1: addr = addr[:a] if '@' not in addr: return addr + '@' + self.domain return addr
def convert_to_git_user(authormap, user, rev): mapped_user = authormap.get(user, user) user_person = stringutil.person(mapped_user) user_email = stringutil.email(mapped_user) if GIT_EMAIL_PROHIBITED.match(user_email) or GIT_PERSON_PROHIBITED.match( user_person): raise error.Abort( _(b"Unable to parse user into person and email for revision %s") % rev) if user_person: return b'"' + user_person + b'" <' + user_email + b'>' else: return b"<" + user_email + b">"
def hook(ui, repo, hooktype, node=None, **kwargs): '''add comment to bugzilla for each changeset that refers to a bugzilla bug id. only add a comment once per bug, so same change seen multiple times does not fill bug with duplicate data.''' if node is None: raise error.Abort(_('hook type %s does not pass a changeset id') % hooktype) try: bz = bugzilla(ui, repo) ctx = repo[node] bugs = bz.find_bugs(ctx) if bugs: for bug in bugs: bz.update(bug, bugs[bug], ctx) bz.notify(bugs, stringutil.email(ctx.user())) except Exception as e: raise error.Abort(_('Bugzilla error: %s') % e)
def add( self, manifest, files, desc, transaction, p1, p2, user, date=None, extra=None, p1copies=None, p2copies=None, filesadded=None, filesremoved=None, ): parents = [] hp1, hp2 = gitutil.togitnode(p1), gitutil.togitnode(p2) if p1 != nullid: parents.append(hp1) if p2 and p2 != nullid: parents.append(hp2) assert date is not None timestamp, tz = date sig = pygit2.Signature( encoding.unifromlocal(stringutil.person(user)), encoding.unifromlocal(stringutil.email(user)), int(timestamp), -int(tz // 60), ) oid = self.gitrepo.create_commit( None, sig, sig, desc, gitutil.togitnode(manifest), parents ) # Set up an internal reference to force the commit into the # changelog. Hypothetically, we could even use this refs/hg/ # namespace to allow for anonymous heads on git repos, which # would be neat. self.gitrepo.references.create( 'refs/hg/internal/latest-commit', oid, force=True ) # Reindex now to pick up changes. We omit the progress # and log callbacks because this will be very quick. index._index_repo(self.gitrepo, self._db) return oid.raw
def send(self, ctx, count, data): '''send message.''' # Select subscribers by revset subs = set() for sub, spec in self.subs: if spec is None: subs.add(sub) continue revs = self.repo.revs('%r and %d:', spec, ctx.rev()) if len(revs): subs.add(sub) continue if len(subs) == 0: self.ui.debug('notify: no subscribers to selected repo ' 'and revset\n') return p = emailparser.Parser() try: msg = p.parsestr(data) except email.Errors.MessageParseError as inst: raise error.Abort(inst) # store sender and subject sender, subject = msg['From'], msg['Subject'] del msg['From'], msg['Subject'] if not msg.is_multipart(): # create fresh mime message from scratch # (multipart templates must take care of this themselves) headers = msg.items() payload = msg.get_payload() # for notification prefer readability over data precision msg = mail.mimeencode(self.ui, payload, self.charsets, self.test) # reinstate custom headers for k, v in headers: msg[k] = v msg['Date'] = dateutil.datestr(format="%a, %d %b %Y %H:%M:%S %1%2") # try to make subject line exist and be useful if not subject: if count > 1: subject = _('%s: %d new changesets') % (self.root, count) else: s = ctx.description().lstrip().split('\n', 1)[0].rstrip() subject = '%s: %s' % (self.root, s) maxsubject = int(self.ui.config('notify', 'maxsubject')) if maxsubject: subject = stringutil.ellipsis(subject, maxsubject) msg['Subject'] = mail.headencode(self.ui, subject, self.charsets, self.test) # try to make message have proper sender if not sender: sender = self.ui.config('email', 'from') or self.ui.username() if '@' not in sender or '@localhost' in sender: sender = self.fixmail(sender) msg['From'] = mail.addressencode(self.ui, sender, self.charsets, self.test) msg['X-Hg-Notification'] = 'changeset %s' % ctx if not msg['Message-Id']: msg['Message-Id'] = ('<hg.%s.%s.%s@%s>' % (ctx, int( time.time()), hash(self.repo.root), socket.getfqdn())) msg['To'] = ', '.join(sorted(subs)) msgtext = msg.as_string() if self.test: self.ui.write(msgtext) if not msgtext.endswith('\n'): self.ui.write('\n') else: self.ui.status( _('notify: sending %d subscribers %d changes\n') % (len(subs), count)) mail.sendmail(self.ui, stringutil.email(msg['From']), subs, msgtext, mbox=self.mbox)