openCARP
Doxygen code documentation for the open cardiac electrophysiology simulator openCARP
build_info.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 # use encoding=utf8
3 # SPDX-FileCopyrightText: Copyright (c) NumeriCor GmbH
4 # SPDX-License-Identifier: LicenseRef-APL-1.1
5 
6 """
7 Generate a C header file defining some information about the build.
8 """
9 
10 import os
11 import sys
12 import subprocess
13 
14 def run(cmd, env=None):
15  """
16  Run a command with subprocess and return the stdout.
17 
18  Avoiding use of subprocess.check_output to maintain backwards
19  compatibility.
20  """
21  proc = subprocess.Popen(cmd, env=env, stdout=subprocess.PIPE)
22  out = proc.communicate()
23  if proc.returncode != 0:
24  tpl = 'execution of command "{0}" failed'
25  raise Exception(tpl.format(' '.join(cmd)))
26  return out[0]
27 
28 def locale():
29  """
30  Determine the locale to use in SVN.
31  """
32 
33  de = None
34 
35  for line in run(['locale', '-a']).split('\n'):
36 
37  entry = line.strip()
38 
39  if entry.startswith('en'):
40  return entry
41 
42  if entry.startswith('de'):
43  de = entry
44 
45  # German a good fallback as 'revision' and 'relative url' are the same
46  if de is not None:
47  return de
48 
49  # If all else fails
50  return 'C'
51 
52 SVN_NAME_MAPPING = {'RĂ©vision': 'Revision'}
53 
54 def svn(directory='.'):
55  """
56  Get information about the SVN repository.
57 
58  Uses the --show-item syntax instead of parsing the normal svn info output
59  to avoid issues with language locales.
60  """
61 
62  start_wd = os.getcwd()
63 
64  os.chdir(directory)
65  result = run(['svn', 'info'], env={'LC_MESSAGES': locale()})
66  os.chdir(start_wd)
67 
68  info = {}
69 
70  for line in result.split('\n'):
71 
72  try:
73  name, value = line.split(': ')
74  except ValueError:
75  continue
76 
77  # Translate where necessary
78  name = SVN_NAME_MAPPING.get(name.strip(), name.strip())
79  name = name.lower().replace(' ', '-')
80 
81  info[name] = value.strip()
82 
83  if name == 'revision':
84  info['commit'] = info[name]
85 
86  return info
87 
88 def git(directory='.'):
89  start_wd = os.getcwd()
90  os.chdir(directory)
91  info = {}
92 
93  # get the git revision count
94  result = run(['git', 'rev-list', '--all', '--count'])
95  info['revision'] = str(int(result));
96 
97  # get commit hash
98  result = run(['git', 'rev-parse', 'HEAD'])
99  result = result[0:len(result)-1]
100  info['commit'] = result.decode('ascii')
101 
102  # get the git tag
103  result = run(['git', 'describe', '--tags', '--always'])
104  result = result[0:len(result)-1]
105  info['tag'] = result.decode('ascii')
106 
107  # get the git remote url
108  result = run(['git', 'remote', '-v'])
109 
110  for line in result.decode('ascii').split('\n'):
111  line = ' '.join(line.split())
112 
113  try:
114  alias, path, direction = line.split(' ')
115  except ValueError:
116  continue
117 
118  if alias == 'origin':
119  info['url'] = path
120 
121  # the subrepo is just '.'
122  info['subrepo'] = '.'
123 
124  os.chdir(start_wd)
125 
126  return info
127 
128 
129 
130 TEMPLATE = """// SPDX-FileCopyrightText: Copyright (c) NumeriCor GmbH
131 // SPDX-License-Identifier: LicenseRef-APL-1.1
132 
133 #ifndef __BUILD_INFO__
134 #define __BUILD_INFO__
135 
136 #define GIT_COMMIT_TAG "{tag}"
137 #define GIT_COMMIT_HASH "{commit}"
138 #define GIT_COMMIT_COUNT {revision}
139 #define GIT_PATH "{url}"
140 
141 #define SUBREPO_REVISIONS "{subrepo}"
142 
143 #define SUBREPO_COMMITS "{subrepocommit}"
144 
145 #endif
146 """
147 
148 def generate():
149 
150  # check whether we are in a git repo
151  if subprocess.call(["git", "branch"], stderr=subprocess.STDOUT, stdout=open(os.devnull, 'w')) == 0:
152  info = git(os.path.dirname(os.path.abspath(__file__)))
153 
154  # Get subrepo info
155  repo_versions = []
156  repo_commits = []
157 
158  # we currently have no sub-repos. still, we leave the mechanism in here for later
159  # repo_versions.append(('slimfem', git('../fem/slimfem')['revision']))
160  # repo_commits.append(( 'slimfem', git('../fem/slimfem')['commit']))
161 
162  info['subrepo'] = ','.join(['{0[0]}={0[1]}'.format(v) for v in repo_versions])
163 
164  # Assemble commit hashes / revisions
165  newline = '," \\\n' + ' ' * 24 + '"'
166  info['subrepocommit'] = newline.join(['{0[0]}={0[1]}'.format(v) for v in repo_commits])
167 
168  else:
169  info = {}
170  info['tag'] = "built outside a repository"
171  info['commit'] = "built outside a repository"
172  info['revision'] = 0
173  info['url'] = "https://git.opencarp.org/openCARP/openCARP.git"
174  info['subrepo'] = ""
175  info['subrepocommit'] = ""
176 
177  return TEMPLATE.format(**info)
178 
179 def print_build_info(filename):
180  """
181  print build info
182  """
183  git_info = generate()
184  update_file = True
185 
186  # check if there's a change of the build info if the file already exists
187  if os.path.isfile(filename):
188  with open(filename, 'r') as myfile:
189  info_h = myfile.read()
190  if info_h == git_info:
191  update_file = False
192 
193  # write build info file
194  if update_file:
195  f = open(filename, "w")
196  f.write(git_info)
197 
198 if __name__ == '__main__':
199  if(len(sys.argv) > 1):
200  filename = sys.argv[1]
201  else:
202  filename = 'build_info.h'
203  print_build_info(filename)
def generate()
Definition: build_info.py:148
def git(directory='.')
Definition: build_info.py:88
def svn(directory='.')
Definition: build_info.py:54
def locale()
Definition: build_info.py:28
def run(cmd, env=None)
Definition: build_info.py:14
def print_build_info(filename)
Definition: build_info.py:179