diff --git a/conda/conda-bootstrap.py b/conda/conda-bootstrap.py new file mode 100755 index 0000000000000000000000000000000000000000..47a0e77771862cca8e80c531beaca5227c2f0556 --- /dev/null +++ b/conda/conda-bootstrap.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +# vim: set fileencoding=utf-8 : + +# Uses the conda render API to render a recipe and install an environment +# containing all build/host, run and test dependencies of a package. + +import os +import re +import sys +import copy +import shutil +import tempfile +import argparse +import subprocess + +try: + import yaml +except ImportError: + print('The package pyyaml must be installed alongside python') + sys.exit(1) + + +if not hasattr(shutil, 'which'): + print('This program only runs with python v3.3 or above') + sys.exit(1) + + +CONDA=shutil.which('conda') +if CONDA is None: + print('You must have the "conda" command available on your shell') + print(' -- also, make sure to have installed the conda-build package') + sys.exit(1) + + +BASEDIR=os.path.realpath(os.path.dirname(sys.argv[0])) + + +def get_condarc(): + rcpath = os.path.join(BASEDIR, 'build-condarc') + return os.environ.get('CONDARC', rcpath) + + +def get_buildopt(python): + return [ + '--variant-config-files', os.path.join(os.path.dirname(BASEDIR), + 'gitlab', 'conda_build_config.yaml'), + '--python', python, + ] + + +def get_rendered_recipe(python, path): + if path.endswith('meta.yaml'): + path = os.path.dirname(path) + + with tempfile.NamedTemporaryFile(dir=path, mode='wt', suffix='.yaml') as f: + + # writes a temporary recipe with an injected version of bob-devel + orig = os.path.join(path, 'meta.yaml') + contents = open(orig).read() + import pdb; pdb.set_trace() + result = re.search(r'^requirements:.*run:\s*\n', contents, re.MULTILINE) + contents = contents[:result.end()] + \ + ' - bob-devel {{ bob_devel }}.*\n' + \ + contents[result.end():] + f.write(contents) + f.flush() + + cmd = [CONDA, 'render'] + get_buildopt(python) + [f.name] + print('$ ' + ' '.join(cmd)) + env = copy.copy(os.environ) + env['CONDARC'] = get_condarc() + output = subprocess.check_output(cmd, env=env) + return yaml.load(output) + + +def parse_dependencies(python, path): + recipe = get_rendered_recipe(python, path) + return recipe['requirements'].get('host', []) + \ + recipe['requirements'].get('build', []) + \ + recipe.get('test', {}).get('requires', []) + + +def conda_install(subcmd, env, packages): + packages = [k.replace(' ', '=') for k in packages] + cmd = [CONDA, subcmd, '--yes', '--name', env] + packages + print('$ ' + ' '.join(cmd)) + env = copy.copy(os.environ) + env['CONDARC'] = get_condarc() + status = subprocess.call(cmd, env=env) + return status + + +def main(): + + parser = argparse.ArgumentParser(description='Creates a new conda environment with the build/run/test dependencies of a package') + parser.add_argument('name', help='name of the target environment to create') + parser.add_argument('python', help='version of python to build the environment for', nargs='?', default='3.6') + parser.add_argument('path', help='path to the directory containing the conda recipe', nargs='?', default='conda') + + args = parser.parse_args() + + deps = parse_dependencies(args.python, args.path) + status = conda_install('create', args.name, deps) + sys.exit(status) + + +if __name__ == '__main__': + main()