summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRonny Pfannschmidt <opensource@ronnypfannschmidt.de>2016-10-11 10:43:20 +0200
committerGitHub <noreply@github.com>2016-10-11 10:43:20 +0200
commitd041864fc414512a6772a90ba978826318a75a62 (patch)
tree65501a5bc61d3e5e24c800f19aca90864c15023c
parent9f360e6f70b3818275580d3f4ca285a81a5b86ce (diff)
parent23b8d745cad48c6cc002feb8804d7f230fa0dd29 (diff)
downloadsetuptools-scm-d041864fc414512a6772a90ba978826318a75a62.tar.gz
fix issue #86 - detect dirty git workdirs even in the absence of tagsv1.13.1
-rw-r--r--CHANGELOG.rst5
-rw-r--r--setuptools_scm/git.py77
-rw-r--r--setuptools_scm/utils.py6
-rw-r--r--testing/test_git.py12
4 files changed, 74 insertions, 26 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index ef96782..4d2e62f 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,3 +1,8 @@
+v1.13.1
+=======
+
+* fix issue #86 - detect dirty git workdir without tags
+
v1.13.0
=======
diff --git a/setuptools_scm/git.py b/setuptools_scm/git.py
index 6864f96..10280e5 100644
--- a/setuptools_scm/git.py
+++ b/setuptools_scm/git.py
@@ -1,40 +1,69 @@
-from .utils import do, do_ex, trace
+from .utils import do_ex, trace
from .version import meta
from os.path import abspath, normcase, realpath
FILES_COMMAND = 'git ls-files'
-DEFAULT_DESCRIBE = 'git describe --dirty --tags --long --match *.*'
+DEFAULT_DESCRIBE = 'git describe --tags --long --match *.*'
+
+
+def _normalized(path):
+ return normcase(abspath(realpath(path)))
+
+
+class GitWorkdir(object):
+ def __init__(self, path):
+ self.path = path
+
+ def do_ex(self, cmd):
+ return do_ex(cmd, cwd=self.path)
+
+ @classmethod
+ def from_potential_worktree(cls, wd):
+ real_wd, _, ret = do_ex('git rev-parse --show-toplevel', wd)
+ if ret:
+ return
+ trace('real root', real_wd)
+ if _normalized(real_wd) != _normalized(wd):
+ return
+
+ return cls(real_wd)
+
+ def is_dirty(self):
+ out, _, _ = self.do_ex("git status --porcelain")
+ return bool(out)
+
+ def node(self):
+ rev_node, _, ret = self.do_ex('git rev-parse --verify --quiet HEAD')
+ if not ret:
+ return rev_node[:7]
+
+ def count_all_nodes(self):
+ revs, _, _ = self.do_ex('git rev-list HEAD')
+ return revs.count('\n') + 1
def parse(root, describe_command=DEFAULT_DESCRIBE):
- real_root, _, ret = do_ex('git rev-parse --show-toplevel', root)
- if ret:
- return
- trace('real root', real_root)
- if (normcase(abspath(realpath(real_root))) !=
- normcase(abspath(realpath(root)))):
- return
- rev_node, _, ret = do_ex('git rev-parse --verify --quiet HEAD', root)
- if ret:
- return meta('0.0')
- rev_node = rev_node[:7]
+ wd = GitWorkdir(root)
+
+ rev_node = wd.node()
+ dirty = wd.is_dirty()
+
+ if rev_node is None:
+ return meta('0.0', dirty=dirty)
+
out, err, ret = do_ex(describe_command, root)
- if '-' not in out and '.' not in out:
- revs = do('git rev-list HEAD', root)
- count = revs.count('\n')
- if ret:
- out = rev_node
- return meta('0.0', distance=count + 1, node=out)
if ret:
- return
- dirty = out.endswith('-dirty')
- if dirty:
- out = out.rsplit('-', 1)[0]
+ return meta(
+ '0.0',
+ distance=wd.count_all_nodes(),
+ node=rev_node,
+ dirty=dirty,
+ )
tag, number, node = out.rsplit('-', 2)
number = int(number)
if number:
return meta(tag, distance=number, node=node, dirty=dirty)
else:
- return meta(tag, dirty=dirty, node=node)
+ return meta(tag, node=node, dirty=dirty)
diff --git a/setuptools_scm/utils.py b/setuptools_scm/utils.py
index 5623ff0..7ea068d 100644
--- a/setuptools_scm/utils.py
+++ b/setuptools_scm/utils.py
@@ -43,8 +43,11 @@ def _always_strings(env_dict):
def do_ex(cmd, cwd='.'):
trace('cmd', repr(cmd))
+ if not isinstance(cmd, (list, tuple)):
+ cmd = shlex.split(cmd)
+
p = subprocess.Popen(
- shlex.split(cmd),
+ cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
cwd=str(cwd),
@@ -70,7 +73,6 @@ def do_ex(cmd, cwd='.'):
def do(cmd, cwd='.'):
out, err, ret = do_ex(cmd, cwd)
if ret:
- trace('ret', ret)
print(err)
return out
diff --git a/testing/test_git.py b/testing/test_git.py
index 5401b66..0819fad 100644
--- a/testing/test_git.py
+++ b/testing/test_git.py
@@ -1,5 +1,6 @@
from setuptools_scm import integration
import pytest
+from datetime import date
@pytest.fixture
@@ -32,6 +33,17 @@ def test_version_from_git(wd):
assert wd.version.startswith('0.2')
+@pytest.mark.issue(86)
+def test_git_dirty_notag(wd):
+ wd.commit_testfile()
+ wd.write('test.txt', 'test2')
+ wd("git add test.txt")
+ assert wd.version.startswith('0.1.dev1')
+ today = date.today()
+ # we are dirty, check for the tag
+ assert today.strftime('.d%Y%m%d') in wd.version
+
+
def test_find_files_stop_at_root_git(wd):
wd.commit_testfile()
wd.cwd.ensure('project/setup.cfg')