archive: use a templater to build the metadata file
authorMatt Harbison <matt_harbison@yahoo.com>
Sun, 16 Jul 2017 17:40:36 -0400
changeset 33544 4c4e95cae33a
parent 33543 3ef3bf704e47
child 33545 8074e2d006c0
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.)
mercurial/archival.py
--- a/mercurial/archival.py	Sun Jul 16 11:17:00 2017 -0700
+++ b/mercurial/archival.py	Sun Jul 16 17:40:36 2017 -0400
@@ -18,9 +18,8 @@
 from .i18n import _
 
 from . import (
-    cmdutil,
-    encoding,
     error,
+    formatter,
     match as matchmod,
     util,
     vfs as vfsmod,
@@ -80,30 +79,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,