Repository: pypa/setuptools_scm

Issue:
cant parse version None
With a repo on an oddly-tagged commit,

```
$ git describe --all
23.46.2post210+gbe48adfpost3+g0cc25f2
```

I get an odd error message for `setuptools_scm.get_version()`:

```
$ rwt -q setuptools_scm==1.15.0 -- -c "import setuptools_scm; setuptools_scm.get_version()"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/rwt-d1ylkuc8/setuptools_scm/__init__.py", line 117, in get_version
    parsed_version = _do_parse(root, parse)
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/rwt-d1ylkuc8/setuptools_scm/__init__.py", line 82, in _do_parse
    version = version_from_scm(root)
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/rwt-d1ylkuc8/setuptools_scm/__init__.py", line 31, in version_from_scm
    return _version_from_entrypoint(root, 'setuptools_scm.parse_scm')
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/rwt-d1ylkuc8/setuptools_scm/__init__.py", line 37, in _version_from_entrypoint
    return ep.load()(root)
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/rwt-d1ylkuc8/setuptools_scm/git.py", line 103, in parse
    return meta(tag, node=node, dirty=dirty)
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/rwt-d1ylkuc8/setuptools_scm/version.py", line 86, in meta
    assert tag is not None, 'cant parse version %s' % tag
AssertionError: cant parse version None
```

I would expect the tag it couldn't parse to be `23.46.2post210+gbe48adfpost3+g0cc25f2` and not `None`.

Discussion:

Patch:
diff --git a/.hgtags b/.hgtags
new file mode 100644
index 0000000..1af47c2
--- /dev/null
+++ b/.hgtags
@@ -0,0 +1,1 @@
+1092123ef78598eade56aa9c57e484f3670c8da8 v1.9.0
diff --git a/.travis.yml b/.travis.yml
index 205f2ea..b731edf 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,7 +6,7 @@ python:
 - '3.3'
 - '3.4'
 - '3.5'
-- '3.6'
+- '3.6-dev'
 env:
 - TOXENV=py-test
 
@@ -46,4 +46,4 @@ deploy:
   - <<: *pypi
     on:
       tags: true
-    distributions: "bdist_egg"
+    distributions: "bdist_egg"
\ No newline at end of file
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 6956fae..c71114b 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -2,7 +2,7 @@ v1.15.3
 =======
 
 * bring back correctly getting our version in the own sdist, finalizes #114
-
+* fix issue #150: strip local components of tags
 
 v1.15.2
 =======
@@ -15,9 +15,6 @@ v1.15.1
 
 * fix issue #126: the local part of any tags is discarded
   when guessing new versions
-* minor performance optimization by doing fewer git calls
-  in the usual cases
-
 
 v1.15.0
 =======
diff --git a/README.rst b/README.rst
index 4262fdd..5d83ba2 100644
--- a/README.rst
+++ b/README.rst
@@ -114,18 +114,15 @@ and uses roughly the following logic to render the version:
 :code:`no distance and clean`:
     :code:`{tag}`
 :code:`distance and clean`:
-    :code:`{next_version}.dev{distance}+{scm letter}{revision hash}`
+    :code:`{next_version}.dev{distance}+n{revision hash}`
 :code:`no distance and not clean`:
     :code:`{tag}+dYYYMMMDD`
 :code:`distance and not clean`:
-    :code:`{next_version}.dev{distance}+{scm letter}{revision hash}.dYYYMMMDD`
+    :code:`{next_version}.dev{distance}+n{revision hash}.dYYYMMMDD`
 
 The next version is calculated by adding ``1`` to the last numeric component
 of the tag.
 
-For git projects, the version relies on `git describe <https://git-scm.com/docs/git-describe>`_,
-so you will see an additional ``g`` prepended to the ``{revision hash}``.
-
 Semantic Versioning (SemVer)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/setup.cfg b/setup.cfg
index d0092d4..f5f917c 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,10 +1,6 @@
 [bdist_wheel]
 universal=1
 
-[metadata]
-# ensure that the LICENSE file is included in the built wheels
-license_file = LICENSE
-
 [devpi:upload]
 formats=sdist,bdist_wheel
 
diff --git a/setuptools_scm/git.py b/setuptools_scm/git.py
index b60279c..e330e58 100644
--- a/setuptools_scm/git.py
+++ b/setuptools_scm/git.py
@@ -4,7 +4,7 @@ from os.path import abspath, normcase, realpath, isfile, join
 import warnings
 
 FILES_COMMAND = 'git ls-files'
-DEFAULT_DESCRIBE = 'git describe --dirty --tags --long --match *.*'
+DEFAULT_DESCRIBE = 'git describe --tags --long --match *.*'
 
 
 def _normalized(path):
@@ -83,31 +83,21 @@ def parse(root, describe_command=DEFAULT_DESCRIBE, pre_parse=warn_on_shallow):
         return
     if pre_parse:
         pre_parse(wd)
+    rev_node = wd.node()
+    dirty = wd.is_dirty()
+
+    if rev_node is None:
+        return meta('0.0', distance=0, dirty=dirty)
 
     out, err, ret = do_ex(describe_command, root)
     if ret:
-        # If 'git describe' failed, try to get the information otherwise.
-        rev_node = wd.node()
-        dirty = wd.is_dirty()
-
-        if rev_node is None:
-            return meta('0.0', distance=0, dirty=dirty)
-
         return meta(
             '0.0',
             distance=wd.count_all_nodes(),
-            node='g' + rev_node,
+            node=rev_node,
             dirty=dirty,
         )
 
-    # 'out' looks e.g. like 'v1.5.0-0-g4060507' or
-    # 'v1.15.1rc1-37-g9bd1298-dirty'.
-    if out.endswith('-dirty'):
-        dirty = True
-        out = out[:-6]
-    else:
-        dirty = False
-
     tag, number, node = out.rsplit('-', 2)
     number = int(number)
     if number:
diff --git a/setuptools_scm/hg.py b/setuptools_scm/hg.py
index cda5fc3..9e126a2 100644
--- a/setuptools_scm/hg.py
+++ b/setuptools_scm/hg.py
@@ -7,7 +7,7 @@ FILES_COMMAND = 'hg locate -I .'
 
 def _hg_tagdist_normalize_tagcommit(root, tag, dist, node):
     dirty = node.endswith('+')
-    node = 'h' + node.strip('+')
+    node = node.strip('+')
     revset = ("(branch(.) and tag({tag!r})::. and file('re:^(?!\.hgtags).*$')"
               " - tag({tag!r}))").format(tag=tag)
     if tag != '0.0':
@@ -58,17 +58,14 @@ def parse(root):
 
 def archival_to_version(data):
     trace('data', data)
-    node = data.get('node', '')[:12]
-    if node:
-        node = 'h' + node
     if 'tag' in data:
         return meta(data['tag'])
     elif 'latesttag' in data:
         return meta(data['latesttag'],
                     distance=data['latesttagdistance'],
-                    node=node)
+                    node=data['node'][:12])
     else:
-        return meta('0.0', node=node)
+        return meta('0.0', node=data.get('node', '')[:12])
 
 
 def parse_archival(root):
diff --git a/setuptools_scm/version.py b/setuptools_scm/version.py
index 042644c..d2caf3d 100644
--- a/setuptools_scm/version.py
+++ b/setuptools_scm/version.py
@@ -1,5 +1,6 @@
 from __future__ import print_function
 import datetime
+import warnings
 import re
 from .utils import trace
 
@@ -31,8 +32,12 @@ def callable_or_entrypoint(group, callable_or_name):
 
 def tag_to_version(tag):
     trace('tag', tag)
+    if '+' in tag:
+        warnings.warn("tag %r will be stripped of the local component" % tag)
+        tag = tag.split('+')[0]
     # lstrip the v because of py2/py3 differences in setuptools
     # also required for old versions of setuptools
+
     version = tag.rsplit('-', 1)[-1].lstrip('v')
     if parse_version is None:
         return version
@@ -125,7 +130,7 @@ def get_local_node_and_date(version):
     if version.exact or version.node is None:
         return version.format_choice("", "+d{time:%Y%m%d}")
     else:
-        return version.format_choice("+{node}", "+{node}.d{time:%Y%m%d}")
+        return version.format_choice("+n{node}", "+n{node}.d{time:%Y%m%d}")
 
 
 def get_local_dirty_tag(version):


Test patch:
diff --git a/testing/test_git.py b/testing/test_git.py
index 9e951a9..5e60d42 100644
--- a/testing/test_git.py
+++ b/testing/test_git.py
@@ -19,21 +19,25 @@ def test_version_from_git(wd):
     assert wd.version == '0.1.dev0'
 
     wd.commit_testfile()
-    assert wd.version.startswith('0.1.dev1+g')
+    assert wd.version.startswith('0.1.dev1+')
     assert not wd.version.endswith('1-')
 
     wd('git tag v0.1')
     assert wd.version == '0.1'
 
     wd.write('test.txt', 'test2')
-    assert wd.version.startswith('0.2.dev0+g')
+    assert wd.version.startswith('0.2.dev0+')
 
     wd.commit_testfile()
-    assert wd.version.startswith('0.2.dev1+g')
+    assert wd.version.startswith('0.2.dev1+')
 
     wd('git tag version-0.2')
     assert wd.version.startswith('0.2')
 
+    wd.commit_testfile()
+    wd('git tag version-0.2.post210+gbe48adfpost3+g0cc25f2')
+    assert wd.version.startswith('0.2')
+
 
 @pytest.mark.issue(108)
 @pytest.mark.issue(109)
@@ -101,4 +105,4 @@ def test_parse_no_worktree(tmpdir):
 def test_alphanumeric_tags_match(wd):
     wd.commit_testfile()
     wd('git tag newstyle-development-started')
-    assert wd.version.startswith('0.1.dev1+g')
+    assert wd.version.startswith('0.1.dev1+')
diff --git a/testing/test_mercurial.py b/testing/test_mercurial.py
index 1fe6841..100094e 100644
--- a/testing/test_mercurial.py
+++ b/testing/test_mercurial.py
@@ -15,7 +15,7 @@ def wd(wd):
 
 archival_mapping = {
     '1.0': {'tag': '1.0'},
-    '1.1.dev3+h000000000000': {
+    '1.1.dev3+n000000000000': {
         'latesttag': '1.0',
         'latesttagdistance': '3',
         'node': '0'*20,
@@ -91,7 +91,7 @@ def test_version_from_archival(wd):
         'latesttagdistance: 3\n'
     )
 
-    assert wd.version == '0.2.dev3+h000000000000'
+    assert wd.version == '0.2.dev3+n000000000000'
 
 
 @pytest.mark.issue('#72')
diff --git a/testing/test_regressions.py b/testing/test_regressions.py
index 9d24d61..4a067b3 100644
--- a/testing/test_regressions.py
+++ b/testing/test_regressions.py
@@ -18,16 +18,16 @@ def test_pkginfo_noscmroot(tmpdir, monkeypatch):
         'from setuptools import setup;'
         'setup(use_scm_version={"root": ".."})')
 
-    _, stderr, ret = do_ex((sys.executable, 'setup.py', '--version'), p)
+    _, stderr, ret = do_ex('python setup.py --version', p)
     assert 'setuptools-scm was unable to detect version for' in stderr
     assert ret == 1
 
     p.join("PKG-INFO").write('Version: 1.0')
-    res = do((sys.executable, 'setup.py', '--version'), p)
+    res = do('python setup.py --version', p)
     assert res == '1.0'
 
     do('git init', p.dirpath())
-    res = do((sys.executable, 'setup.py', '--version'), p)
+    res = do('python setup.py --version', p)
     assert res == '1.0'
 
 
@@ -64,7 +64,7 @@ setup(use_scm_version=vcfg)
 ''')
     p.join("PKG-INFO").write('Version: 1.0')
 
-    res = do((sys.executable, 'setup.py', '--version'), p)
+    res = do('python setup.py --version', p)
     assert res == '1.0'