ReFRACtor
version_util.py
Go to the documentation of this file.
1 from __future__ import print_function
2 try:
3  from builtins import str
4 except ImportError:
5  # We might not have future installed yet, but this means we are using python 2.7 and
6  # can ignore this
7  pass
8 import re
9 import os
10 import sys
11 import subprocess
12 
13 class VersionError(Exception):
14  pass
15 
16 def _which(program):
17  import os
18  def is_exe(fpath):
19  return os.path.exists(fpath) and os.access(fpath, os.X_OK)
20 
21  fpath, fname = os.path.split(program)
22  if fpath:
23  if is_exe(program):
24  return program
25  else:
26  for path in os.environ["PATH"].split(os.pathsep):
27  exe_file = os.path.join(path, program)
28  if is_exe(exe_file):
29  return exe_file
30 
31  return None
32 
33 def _get_svn_version(source_path):
34  "Get version information for a Subversion checkout. Due to the slow speed of svnversion, this will not return any indication if the source has been modified."
35 
36  # Make sure we can query commandline tools
37  if _which("svn") == None:
38  raise VersionError("svn command not found")
39 
40  svn_path = None
41  svn_revision = None
42  try:
43  info_process = subprocess.Popen(["svn", "info", source_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
44  info_process.wait()
45 
46  for ver_line in info_process.stdout.readlines():
47  if ver_line.find(b'URL:') >= 0:
48  svn_path = ver_line.replace(b'URL: ',b'').strip()
49  if ver_line.find(b'Revision:') >= 0:
50  svn_revision = ver_line.replace(b'Revision: ',b'').strip()
51  info_process.stdout.close()
52  except Exception as exc:
53  raise VersionError("Error querying svn command: %s" % str(exc))
54 
55  if svn_path == None:
56  return None
57 
58  tag_match = re.search(b'tags/([^/]+)(/[^/]*)*$', svn_path)
59  if tag_match:
60  tag_name = tag_match.group(1)
61  else:
62  tag_name = None
63 
64  branch_match = re.search(b'branches/([^/]+)(/[^/]*)*$', svn_path)
65  if branch_match:
66  branch_name = branch_match.group(1)
67  else:
68  branch_name = None
69 
70  tag_branch = ''
71  if tag_name != None:
72  tag_branch = tag_name
73  elif branch_name != None:
74  tag_branch = branch_name
75 
76  rev_str = None
77  if len(tag_branch) > 0:
78  rev_str = tag_branch + b'-' + svn_revision
79  else:
80  rev_str = svn_revision
81 
82  return b'SVN-' + rev_str
83 
84 def _get_git_version(source_path):
85  "Get version information for a git clone"
86 
87  # Make sure we can query commandline tools
88  if _which("git") == None:
89  raise VersionError("git command not found")
90 
91  prev_dir = os.getcwd()
92  # git rev-parse works from cwd
93  os.chdir(source_path)
94  try:
95  git_process = subprocess.Popen(["git", "rev-parse", "--verify", "HEAD", "--short"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
96  git_process.wait()
97 
98  git_ver = git_process.stdout.readline().strip()
99  except OSError:
100  git_ver = None
101 
102  # Try and get branch version
103  git_branch = '(no branch)'
104  try:
105  git_process = subprocess.Popen(["git", "symbolic-ref", "HEAD"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
106  git_process.wait()
107 
108  if git_process.returncode == 0:
109  git_branch = git_process.stdout.readline().strip().replace(b"refs/heads/", b"")
110  except OSError:
111  git_branch = None
112 
113  # See if working directorty has been modified
114  wdir_modified = b'?'
115  try:
116  git_process = subprocess.Popen(["git", "status", "--porcelain", "-uno"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
117  git_process.wait()
118 
119  status_ret = git_process.stdout.readline().strip()
120  if len(status_ret) > 0:
121  wdir_modified = b'M'
122  else:
123  wdir_modified = b''
124  except OSError:
125  wdir_modified = None
126 
127  os.chdir(prev_dir)
128  return b"GIT-" + git_branch + b'-' + git_ver + wdir_modified
129 
130 def source_version(source_path):
131  "Retrieves version information for a GIT or Subversion directory. The returned string includes branch names as well as a revision number or hash. We first check if the path is a git clone, failing that we try subversion."
132 
133  if not os.path.exists(source_path):
134  return None
135 
136  # Detect if we are using Git for referenced file
137  prev_dir = os.getcwd()
138  os.chdir(source_path)
139  if _which("git") != None:
140  # Send stdout to a PIPE so it is not seen
141  ret_code = subprocess.call(["git", "rev-parse", "--git-dir"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
142  else:
143  ret_code = None
144 
145  os.chdir(prev_dir)
146 
147  if ret_code != None and ret_code == 0:
148  return _get_git_version(source_path)
149  else:
150  return _get_svn_version(source_path)
151 
152 def binary_version(binary_filename):
153  "Query a L2 binary to get the compiled in version information"
154 
155  process = subprocess.Popen([binary_filename, "-v"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
156  ret_code = process.wait()
157 
158  if ret_code == 0:
159  # L2 spits out several lines of version information when called with -v
160  # If the first line is not as expected then this is not a l2 binary
161  first_line = process.stdout.readline()
162  if not first_line.find(b"Major version:") == 0:
163  return None
164 
165  major_version = first_line.split(b":")[1].strip()
166  cm_version = process.stdout.readline().split(b":")[1].strip()
167  lua_version = process.stdout.readline()
168  if len(lua_version) > 0:
169  lua_version = lua_version.split(b":")[1].strip()
170  else:
171  lua_version = None
172 
173  return major_version, cm_version, lua_version
174  else:
175  return None
176 
177 if __name__ == "__main__":
178  if len(sys.argv) < 2:
179  print("Please supply a path to a Git or Subversion repository", file=sys.stderr)
180  sys.exit(1)
181 
182  if sys.version_info > (3,):
183  print(source_version(sys.argv[1]).decode('utf-8'))
184  else:
185  print(source_version(sys.argv[1]))
def source_version(source_path)
def binary_version(binary_filename)

Copyright © 2017, California Institute of Technology.
ALL RIGHTS RESERVED.
U.S. Government Sponsorship acknowledged.
Generated Fri Aug 24 2018 15:44:10