[PATCH 1 of 2] archive: use a templater to build the metadata file

Matt Harbison mharbison72 at gmail.com
Mon Jul 17 04:57:38 UTC 2017


# HG changeset patch
# User Matt Harbison <matt_harbison at yahoo.com>
# Date 1500241236 14400
#      Sun Jul 16 17:40:36 2017 -0400
# Node ID 4d37def90ad5e0196dadb9bc2c9e62effad63691
# Parent  d09de637cbc88ed2db989298115d0c0cb6cc6f27
archive: use a templater to build the metadata file

There are no visible changes here.

I'm starting to wonder if adding the '+' to the 'node' line instead of a
separate key line in 3047167733dc was the right thing to do.  The '{node}'
keyword never includes '+' elsewhere, and the way setup.py works, it would
truncate it anyway.  Additionally, the file is missing '{p2node}' when 'wdir()'
merges are archived.  I thought about adding an 'identify' line that would
correspond to `hg id -n`.  But the other nodes are the full 40 characters, and
the output most useful for versioning is the short form.  All of this cries out
for customization via templating.  (Although maybe having the short identify
line by default is still a good idea.)

diff --git a/mercurial/archival.py b/mercurial/archival.py
--- a/mercurial/archival.py
+++ b/mercurial/archival.py
@@ -21,6 +21,7 @@
     cmdutil,
     encoding,
     error,
+    formatter,
     match as matchmod,
     util,
     vfs as vfsmod,
@@ -80,30 +81,42 @@
 def buildmetadata(ctx):
     '''build content of .hg_archival.txt'''
     repo = ctx.repo()
-    hex = ctx.hex()
-    if ctx.rev() is None:
-        hex = ctx.p1().hex()
-        if ctx.dirty(missing=True):
-            hex += '+'
+
+    default = (
+        r'repo: {root}\n'
+        r'node: {ifcontains(rev, revset("wdir()"),'
+                            r'"{p1node}{dirty}", "{node}")}\n'
+        r'branch: {branch|utf8}\n'
 
-    base = 'repo: %s\nnode: %s\nbranch: %s\n' % (
-        _rootctx(repo).hex(), hex, encoding.fromlocal(ctx.branch()))
+        # {tags} on ctx includes local tags and 'tip', with no current way to
+        # limit that to global tags.  Therefore, use {latesttag} as a substitute
+        # when the distance is 0, since that will be the list of global tags on
+        # ctx.
+        r'{ifeq(latesttagdistance, 0, latesttag % "tag: {tag}\n",'
+                       r'"{latesttag % "latesttag: {tag}\n"}'
+                       r'latesttagdistance: {latesttagdistance}\n'
+                       r'changessincelatesttag: {changessincelatesttag}\n")}'
+    )
 
-    tags = ''.join('tag: %s\n' % t for t in ctx.tags()
-                   if repo.tagtype(t) == 'global')
-    if not tags:
-        repo.ui.pushbuffer()
-        opts = {'template': '{latesttag}\n{latesttagdistance}\n'
-                            '{changessincelatesttag}',
-                'style': '', 'patch': None, 'git': None}
-        cmdutil.show_changeset(repo.ui, repo, opts).show(ctx)
-        ltags, dist, changessince = repo.ui.popbuffer().split('\n')
-        ltags = ltags.split(':')
-        tags = ''.join('latesttag: %s\n' % t for t in ltags)
-        tags += 'latesttagdistance: %s\n' % dist
-        tags += 'changessincelatesttag: %s\n' % changessince
+    opts = {
+        'template': default
+    }
+
+    out = util.stringio()
 
-    return base + tags
+    fm = formatter.formatter(repo.ui, out, 'archive', opts)
+    fm.startitem()
+    fm.context(ctx=ctx)
+    fm.data(root=_rootctx(repo).hex())
+
+    if ctx.rev() is None:
+        dirty = ''
+        if ctx.dirty(missing=True):
+            dirty = '+'
+        fm.data(dirty=dirty)
+    fm.end()
+
+    return out.getvalue()
 
 class tarit(object):
     '''write archive to tar file or stream.  can write uncompressed,


More information about the Mercurial-devel mailing list