Merge pull request #34 from axxel/master

Add support for optional custom command and replace_string parameter of vcs_tag.
pull/43/head
jpakkane 10 years ago
commit 7c074fd953
  1. 31
      interpreter.py
  2. 19
      mesonlib.py
  3. 6
      test cases/common/73 vcstag/meson.build
  4. 53
      vcstagger.py

@ -20,6 +20,7 @@ import mlog
import build import build
import optinterpreter import optinterpreter
import wrap import wrap
import mesonlib
import os, sys, platform, subprocess, shutil, uuid import os, sys, platform, subprocess, shutil, uuid
class InterpreterException(coredata.MesonException): class InterpreterException(coredata.MesonException):
@ -1107,14 +1108,32 @@ class Interpreter():
return self.build_target(node, args, kwargs, JarHolder) return self.build_target(node, args, kwargs, JarHolder)
def func_vcs_tag(self, node, args, kwargs): def func_vcs_tag(self, node, args, kwargs):
fallback = kwargs.get('fallback', None) fallback = kwargs.pop('fallback', None)
if not isinstance(fallback, str): if not isinstance(fallback, str):
raise InterpreterException('Keyword argument must exist and be a string.') raise InterpreterException('Keyword argument must exist and be a string.')
del kwargs['fallback'] replace_string = kwargs.pop('replace_string', '@VCS_TAG@')
scriptfile = os.path.join(os.path.split(__file__)[0], 'vcstagger.py') regex_selector = '(.*)' # default regex selector for custom command: use complete output
kwargs['command'] = [sys.executable, scriptfile, '@INPUT@', '@OUTPUT@', fallback] vcs_cmd = kwargs.get('command', None)
kwargs['build_always'] = True if vcs_cmd and not isinstance(vcs_cmd, list):
return self.func_custom_target(node, ['vcstag'], kwargs) vcs_cmd = [vcs_cmd]
# source_dir = os.path.split(os.path.abspath(kwargs.get('infile')))[0]
source_dir = os.path.join(self.environment.get_source_dir(), self.subdir)
if vcs_cmd:
# Is the command an executable in path or maybe a script in the source tree?
vcs_cmd[0] = shutil.which(vcs_cmd[0]) or os.path.join(source_dir, vcs_cmd[0])
else:
vcs = mesonlib.detect_vcs(source_dir)
if vcs:
mlog.log('Found %s repository at %s' % (vcs['name'], vcs['wc_dir']))
vcs_cmd = vcs['get_rev'].split()
regex_selector = vcs['rev_regex']
else:
vcs_cmd = [' '] # executing this cmd will fail in vcstagger.py and force to use the fallback string
scriptfile = os.path.join(self.environment.get_script_dir(), 'vcstagger.py')
# vcstagger.py parameters: infile, outfile, fallback, source_dir, replace_string, regex_selector, command...
kwargs['command'] = [sys.executable, scriptfile, '@INPUT0@', '@OUTPUT0@', fallback, source_dir, replace_string, regex_selector] + vcs_cmd
kwargs.setdefault('build_always', True)
return self.func_custom_target(node, [kwargs['output']], kwargs)
def func_custom_target(self, node, args, kwargs): def func_custom_target(self, node, args, kwargs):
if len(args) != 1: if len(args) != 1:

@ -14,7 +14,7 @@
"""A library of random helper functionality.""" """A library of random helper functionality."""
import platform, subprocess, operator import platform, subprocess, operator, os, shutil
def is_osx(): def is_osx():
return platform.system().lower() == 'darwin' return platform.system().lower() == 'darwin'
@ -42,6 +42,23 @@ def exe_exists(arglist):
pass pass
return False return False
def detect_vcs(source_dir):
vcs_systems = [
dict(name = 'git', cmd = 'git', repo_dir = '.git', get_rev = 'git describe --dirty=+', rev_regex = '(.*)', dep = '.git/logs/HEAD'),
dict(name = 'mercurial', cmd = 'hg', repo_dir = '.hg', get_rev = 'hg id -n', rev_regex = '(.*)', dep = '.hg/dirstate'),
dict(name = 'subversion', cmd = 'svn', repo_dir = '.svn', get_rev = 'svn info', rev_regex = 'Revision: (.*)', dep = '.svn/wc.db'),
dict(name = 'bazaar', cmd = 'bzr', repo_dir = '.bzr', get_rev = 'bzr revno', rev_regex = '(.*)', dep = '.bzr'),
]
segs = source_dir.replace('\\', '/').split('/')
for i in range(len(segs), -1, -1):
curdir = '/'.join(segs[:i])
for vcs in vcs_systems:
if os.path.isdir(os.path.join(curdir, vcs['repo_dir'])) and shutil.which(vcs['cmd']):
vcs['wc_dir'] = curdir
return vcs
return None
def version_compare(vstr1, vstr2): def version_compare(vstr1, vstr2):
if vstr2.startswith('>='): if vstr2.startswith('>='):
cmpop = operator.ge cmpop = operator.ge

@ -4,5 +4,11 @@ version_src = vcs_tag(input : 'vcstag.c.in',
output : 'vcstag.c', output : 'vcstag.c',
fallback : '1.0.0') fallback : '1.0.0')
version_src_custom = vcs_tag(input : 'vcstag.c.in',
output : 'vcstag-custom.c',
command : ['git', 'show-ref', '-s', 'refs/heads/master'],
fallback : '1.0.0')
executable('tagprog', 'tagprog.c', version_src) executable('tagprog', 'tagprog.c', version_src)
executable('tagprog-custom', 'tagprog.c', version_src_custom)

@ -14,49 +14,20 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import sys, os, subprocess import sys, os, subprocess, re
def tag(infile, outfile, fallback): def config_vcs_tag(infile, outfile, fallback, source_dir, replace_string, regex_selector, cmd):
tagid = get_string(infile, fallback)
newdata = open(infile).read().replace('@VCS_TAG@', tagid)
try: try:
olddata = open(outfile).read() output = subprocess.check_output(cmd, cwd=source_dir)
if olddata == newdata: new_string = re.search(regex_selector, output.decode()).group(1).strip()
return
except Exception: except Exception:
pass new_string = fallback
open(outfile, 'w').write(newdata)
new_data = open(infile).read().replace(replace_string, new_string)
def get_string(infile, fallback): if (not os.path.exists(outfile)) or (open(outfile).read() != new_data):
absfile = os.path.join(os.getcwd(), infile) open(outfile, 'w').write(new_data)
directory = os.path.split(absfile)[0]
segs = directory.replace('\\', '/').split('/')
for i in range(len(segs), -1, -1):
curdir = '/'.join(segs[:i])
if os.path.isdir(os.path.join(curdir, '.git')):
output = subprocess.check_output(['git', 'describe'],
cwd = directory)
return output.decode().strip()
elif os.path.isdir(os.path.join(curdir, '.hg')):
output = subprocess.check_output(['hg', 'identify'],
cwd=directory)
return output.decode().strip()
elif os.path.isdir(os.path.join(curdir, '.bzr')):
output = subprocess.check_output(['bzr', 'revno'],
cwd=directory)
return output.decode().strip()
elif os.path.isdir(os.path.join(curdir, '.svn')):
output = subprocess.check_output(['svn', 'info'],
cwd=directory)
for line in output.decode().split('\n'):
(k, v) = line.split(':', 1)
if k.strip() == 'Revision':
return v.strip()
raise RuntimeError('Svn output malformed.')
return fallback
if __name__ == '__main__': if __name__ == '__main__':
infile = sys.argv[1] infile, outfile, fallback, source_dir, replace_string, regex_selector = sys.argv[1:7]
outfile = sys.argv[2] command = sys.argv[7:]
fallback = sys.argv[3] config_vcs_tag(infile, outfile, fallback, source_dir, replace_string, regex_selector, command)
tag(infile, outfile, fallback)

Loading…
Cancel
Save