def verify(self, data, sig): """ returns of the good and bad signatures""" sigfile = datafile = None try: # create temporary files fd, sigfile = tempfile.mkstemp(prefix="hg-gpg-", suffix=".sig") fp = util.fdopen(fd, "wb") fp.write(sig) fp.close() fd, datafile = tempfile.mkstemp(prefix="hg-gpg-", suffix=".txt") fp = util.fdopen(fd, "wb") fp.write(data) fp.close() gpgcmd = "%s --logger-fd 1 --status-fd 1 --verify " '"%s" "%s"' % ( self.path, sigfile, datafile, ) ret = util.filter("", gpgcmd) finally: for f in (sigfile, datafile): try: if f: os.unlink(f) except OSError: pass keys = [] key, fingerprint = None, None for l in ret.splitlines(): # see DETAILS in the gnupg documentation # filter the logger output if not l.startswith("[GNUPG:]"): continue l = l[9:] if l.startswith("VALIDSIG"): # fingerprint of the primary key fingerprint = l.split()[10] elif l.startswith("ERRSIG"): key = l.split(" ", 3)[:2] key.append("") fingerprint = None elif ( l.startswith("GOODSIG") or l.startswith("EXPSIG") or l.startswith("EXPKEYSIG") or l.startswith("BADSIG") ): if key is not None: keys.append(key + [fingerprint]) key = l.split(" ", 2) fingerprint = None if key is not None: keys.append(key + [fingerprint]) return keys
def winpopen4(orig, cmd, env=None, newlines=False, bufsize=-1): """Same as util.popen4, but manually creates an input pipe with a larger than default buffer""" import msvcrt if sys.version_info[0] < 3: import _subprocess handles = _subprocess.CreatePipe(None, pipei_bufsize) rfd, wfd = [msvcrt.open_osfhandle(h, 0) for h in handles] else: import _winapi handles = _winapi.CreatePipe(None, pipei_bufsize) rfd, wfd = [msvcrt.open_osfhandle(h, 0) for h in handles] handles = [subprocess.Handle(h) for h in handles] handles[0].Detach() handles[1].Detach() p = subprocess.Popen( cmd, shell=True, bufsize=bufsize, close_fds=False, stdin=rfd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=newlines, env=env, ) p.stdin = util.fdopen(wfd, "wb", bufsize) return p.stdin, p.stdout, p.stderr, p
def bundle2scratchbranch(op, part): """unbundle a bundle2 part containing a changegroup to store""" bundler = bundle2.bundle20(op.repo.ui) cgversion = part.params.get("cgversion", "01") cgpart = bundle2.bundlepart("changegroup", data=part.read()) cgpart.addparam("version", cgversion) bundler.addpart(cgpart) buf = util.chunkbuffer(bundler.getchunks()) fd, bundlefile = tempfile.mkstemp() try: try: fp = util.fdopen(fd, "wb") fp.write(buf.read()) finally: fp.close() server.storebundle(op, part.params, bundlefile) finally: try: os.unlink(bundlefile) except OSError as e: if e.errno != errno.ENOENT: raise return 1
def winpopen4(orig, cmd, env=None, newlines=False, bufsize=-1): """Same as util.popen4, but manually creates an input pipe with a larger than default buffer""" import msvcrt # pyre-fixme[21]: Could not find module `_subprocess`. import _subprocess handles = _subprocess.CreatePipe(None, pipei_bufsize) rfd, wfd = [msvcrt.open_osfhandle(h, 0) for h in handles] handles[0].Detach() handles[1].Detach() p = subprocess.Popen( cmd, shell=True, bufsize=bufsize, close_fds=False, stdin=rfd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=newlines, env=env, ) p.stdin = util.fdopen(wfd, "wb", bufsize) return p.stdin, p.stdout, p.stderr, p
def rage(ui, repo, *pats, **opts): """collect troubleshooting diagnostics The rage command collects useful diagnostic information. By default, the information will be uploaded to Phabricator and instructions about how to ask for help will be printed. After submitting to Phabricator, it prints configerable advice:: [rage] advice = Please see our FAQ guide: https://... """ with progress.spinner(ui, "collecting information"): msg = _makerage(ui, repo, **opts) if opts.get("preview"): ui.pager("rage") ui.write("%s\n" % msg) return with progress.spinner(ui, "saving paste"): try: p = subprocess.Popen( ["pastry", "--lang", "hgrage", "--title", "hgrage"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, shell=pycompat.iswindows, ) out, err = p.communicate(input=msg + "\n") ret = p.returncode except OSError: ui.write(_("Failed calling pastry. (is it in your PATH?)\n")) ret = 1 if ret: fd, tmpname = tempfile.mkstemp(prefix="hg-rage-") with util.fdopen(fd, r"w") as tmpfp: tmpfp.write(msg) ui.write( _( "Failed to post the diagnostic paste to Phabricator, " "but its contents have been written to:\n\n" ) ) ui.write(_(" %s\n") % tmpname, label="rage.link") ui.write( _("\nPlease include this file in the %s.\n") % ui.config("ui", "supportcontact") ) else: ui.write( _("Please post in %s with the following link:\n\n") % (ui.config("ui", "supportcontact")) ) ui.write(" " + out + "\n", label="rage.link") ui.write(ui.config("rage", "advice", "") + "\n")
def downloadbundle(repo, unknownbinhead): index = repo.bundlestore.index store = repo.bundlestore.store bundleid = index.getbundle(nodemod.hex(unknownbinhead)) if bundleid is None: raise error.Abort("%s head is not known" % nodemod.hex(unknownbinhead)) data = store.read(bundleid) fp = None fd, bundlefile = tempfile.mkstemp() try: # guards bundlefile try: # guards fp fp = util.fdopen(fd, "wb") fp.write(data) finally: fp.close() except Exception: try: os.unlink(bundlefile) except Exception: # we would rather see the original exception pass raise return bundlefile
def processparts(orig, repo, op, unbundler): if unbundler.params.get("infinitepush") != "True": return orig(repo, op, unbundler) handleallparts = repo.ui.configbool("infinitepush", "storeallparts") partforwardingwhitelist = [constants.scratchmutationparttype] try: treemfmod = extensions.find("treemanifest") partforwardingwhitelist.append(treemfmod.TREEGROUP_PARTTYPE2) except KeyError: pass try: snapshot = extensions.find("snapshot") partforwardingwhitelist.append(snapshot.bundleparts.snapshotmetadataparttype) except KeyError: pass bundler = bundle2.bundle20(repo.ui) compress = repo.ui.config("infinitepush", "bundlecompression", "UN") bundler.setcompression(compress) cgparams = None scratchbookpart = None with bundle2.partiterator(repo, op, unbundler) as parts: for part in parts: bundlepart = None if part.type == "replycaps": # This configures the current operation to allow reply parts. bundle2._processpart(op, part) elif part.type == constants.scratchbranchparttype: # Scratch branch parts need to be converted to normal # changegroup parts, and the extra parameters stored for later # when we upload to the store. Eventually those parameters will # be put on the actual bundle instead of this part, then we can # send a vanilla changegroup instead of the scratchbranch part. cgversion = part.params.get("cgversion", "01") bundlepart = bundle2.bundlepart("changegroup", data=part.read()) bundlepart.addparam("version", cgversion) cgparams = part.params # If we're not dumping all parts into the new bundle, we need to # alert the future pushkey and phase-heads handler to skip # the part. if not handleallparts: op.records.add( constants.scratchbranchparttype + "_skippushkey", True ) op.records.add( constants.scratchbranchparttype + "_skipphaseheads", True ) elif part.type == constants.scratchbookmarksparttype: # Save this for later processing. Details below. # # Upstream https://phab.mercurial-scm.org/D1389 and its # follow-ups stop part.seek support to reduce memory usage # (https://bz.mercurial-scm.org/5691). So we need to copy # the part so it can be consumed later. scratchbookpart = copiedpart(part) else: if handleallparts or part.type in partforwardingwhitelist: # Ideally we would not process any parts, and instead just # forward them to the bundle for storage, but since this # differs from previous behavior, we need to put it behind a # config flag for incremental rollout. bundlepart = bundle2.bundlepart(part.type, data=part.read()) for key, value in pycompat.iteritems(part.params): bundlepart.addparam(key, value) # Certain parts require a response if part.type == "pushkey": if op.reply is not None: rpart = op.reply.newpart("reply:pushkey") rpart.addparam("in-reply-to", str(part.id), mandatory=False) rpart.addparam("return", "1", mandatory=False) else: bundle2._processpart(op, part) if handleallparts: op.records.add(part.type, {"return": 1}) if bundlepart: bundler.addpart(bundlepart) # If commits were sent, store them if cgparams: buf = util.chunkbuffer(bundler.getchunks()) fd, bundlefile = tempfile.mkstemp() try: try: fp = util.fdopen(fd, "wb") fp.write(buf.read()) finally: fp.close() storebundle(op, cgparams, bundlefile) finally: try: os.unlink(bundlefile) except Exception: # we would rather see the original exception pass # The scratch bookmark part is sent as part of a push backup. It needs to be # processed after the main bundle has been stored, so that any commits it # references are available in the store. if scratchbookpart: bundle2._processpart(op, scratchbookpart)
def putcommit(self, files, copies, parents, commit, source, revmap, full, cleanp2): for parent in parents: try: return self.revid(self.childmap[parent]) except KeyError: pass # Apply changes to working copy for f, v in files: data, mode = source.getfile(f, v) if data is None: self.delete.append(f) else: self.putfile(f, mode, data) if f in copies: self.copies.append([copies[f], f]) if full: self.delete.extend(sorted(self.manifest.difference(files))) files = [f[0] for f in files] entries = set(self.delete) files = frozenset(files) entries.update(self.add_dirs(files.difference(entries))) if self.copies: for s, d in self.copies: self._copyfile(s, d) self.copies = [] if self.delete: self.xargs(self.delete, "delete") for f in self.delete: self.manifest.remove(f) self.delete = [] entries.update(self.add_files(files.difference(entries))) if self.delexec: self.xargs(self.delexec, "propdel", "svn:executable") self.delexec = [] if self.setexec: self.xargs(self.setexec, "propset", "svn:executable", "*") self.setexec = [] fd, messagefile = tempfile.mkstemp(prefix="hg-convert-") fp = util.fdopen(fd, "w") fp.write(commit.desc) fp.close() try: output = self.run0( "commit", username=util.shortuser(commit.author), file=messagefile, encoding="utf-8", ) try: rev = self.commit_re.search(output).group(1) except AttributeError: if parents and not files: return parents[0] self.ui.warn(_("unexpected svn output:\n")) self.ui.warn(output) raise error.Abort(_("unable to cope with svn output")) if commit.rev: self.run( "propset", "hg:convert-rev", commit.rev, revprop=True, revision=rev ) if commit.branch and commit.branch != "default": self.run( "propset", "hg:convert-branch", commit.branch, revprop=True, revision=rev, ) for parent in parents: self.addchild(parent, rev) return self.revid(rev) finally: os.unlink(messagefile)