1
+ """
2
+ This module offers a way of getting a version string using git and returns nothing if git isn't used.
3
+
4
+ I first thought of using setup.py to put the version string and the idea came from here:
5
+ https://blog.mozilla.org/warner/2012/01/31/version-string-management-in-python-introducing-python-versioneer/
6
+
7
+ but then I reckoned using setup.py is cumbersome for python web applications to keep in sync.
8
+ Also, setup.py should not contain explicit versions but mostly implicit version ranges.
9
+
10
+ Requirements.txt is a better fit to recreate an explicit environment. With that, I'm not using source distributions or
11
+ other tarballs for deploying, but just use git to update a remote deployment fast.
12
+
13
+ Basically, this module is a stripped down version of Brian Warner's python-versioneer and assumes you only want to
14
+ install using pip install -r requirements.txt. Distutils or similar simply won't work (but are broken anyway).
15
+
16
+ """
17
+
18
+ __version__ = '0.1-alpha'
19
+
20
+ import sys
21
+ import subprocess
22
+ import errno
23
+
24
+ def run_command (commands , args , cwd = None , verbose = False , hide_stderr = False ):
25
+ assert isinstance (commands , list )
26
+ p = None
27
+ for c in commands :
28
+ try :
29
+ # remember shell=False, so use git.cmd on windows, not just git
30
+ p = subprocess .Popen ([c ] + args , cwd = cwd , stdout = subprocess .PIPE ,
31
+ stderr = (subprocess .PIPE if hide_stderr
32
+ else None ))
33
+ break
34
+ except EnvironmentError :
35
+ e = sys .exc_info ()[1 ]
36
+ if e .errno == errno .ENOENT :
37
+ continue
38
+ if verbose :
39
+ print ("unable to run %s" % args [0 ])
40
+ print (e )
41
+ return None
42
+ else :
43
+ if verbose :
44
+ print ("unable to find command, tried %s" % (commands ,))
45
+ return None
46
+ stdout = p .communicate ()[0 ].strip ()
47
+ if sys .version >= '3' :
48
+ stdout = stdout .decode ()
49
+ if p .returncode != 0 :
50
+ if verbose :
51
+ print ("unable to run %s (error)" % args [0 ])
52
+ return None
53
+ return stdout
54
+
55
+
56
+ def versions_from_git (tag_prefix = "" , verbose = False ):
57
+ """
58
+ Returns a dictionary with a version and a full version.
59
+
60
+ A 'version' is based on git describe and strips 'tag_prefix'.
61
+ A 'full version' is simply the complete revision number with '-dirty' attached if we are in between commits.
62
+
63
+ @param tag_prefix: strip this tag_prefix to get version eg: for v0.1 return 0.1
64
+ @param verbose:
65
+ @return: {'version': version, 'full': fullversion}
66
+ """
67
+
68
+ GITS = ["git" ]
69
+ if sys .platform == "win32" :
70
+ GITS = ["git.cmd" , "git.exe" ]
71
+ stdout = run_command (GITS , ["describe" , "--tags" , "--dirty" , "--always" ])
72
+ if stdout is None :
73
+ return {}
74
+ if not stdout .startswith (tag_prefix ):
75
+ # simply don't strip the prefix
76
+ if verbose :
77
+ print ("tag '%s' doesn't start with prefix '%s'" % (stdout , tag_prefix ))
78
+ tag = stdout
79
+ else :
80
+ tag = stdout [len (tag_prefix ):]
81
+ stdout = run_command (GITS , ["rev-parse" , "HEAD" ])
82
+ if stdout is None :
83
+ return {}
84
+ full = stdout .strip ()
85
+ if tag .endswith ("-dirty" ):
86
+ full += "-dirty"
87
+ return {"version" : tag , "full" : full }
0 commit comments