diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | delivery_merge/cli/merge.py | 10 | ||||
-rw-r--r-- | delivery_merge/merge.py | 37 | ||||
-rw-r--r-- | setup.py | 2 | ||||
-rw-r--r-- | tests/test_merge.py | 19 |
5 files changed, 65 insertions, 5 deletions
@@ -2,6 +2,8 @@ *.sh *.sk __pycache__ +build +dist results src miniconda* diff --git a/delivery_merge/cli/merge.py b/delivery_merge/cli/merge.py index 6cf421e..45adf64 100644 --- a/delivery_merge/cli/merge.py +++ b/delivery_merge/cli/merge.py @@ -1,6 +1,11 @@ import os from ..conda import conda, conda_installer, conda_init_path -from ..merge import env_combine, testable_packages, integration_test +from ..merge import ( + env_combine, + testable_packages, + integration_test, + force_yaml_channels +) from argparse import ArgumentParser @@ -53,6 +58,9 @@ def main(): print("Exporting yaml configuration...") conda('env', 'export', '-n', name, '--file', yamlfile) + print("Fix up yaml channel order...") + force_yaml_channels(yamlfile, channels) + print("Exporting explicit dump...") with open(specfile, 'w+') as spec: proc = conda('list', '--explicit', '-n', name) diff --git a/delivery_merge/merge.py b/delivery_merge/merge.py index 64aec8a..f99c542 100644 --- a/delivery_merge/merge.py +++ b/delivery_merge/merge.py @@ -1,10 +1,11 @@ import os import re -import yaml +import sys from .conda import conda, conda_env_load, conda_cmd_channels from .utils import comment_find, git, pushd, sh from configparser import ConfigParser from glob import glob +from ruamel.yaml import YAML DMFILE_RE = re.compile(r'^(?P<name>[A-z\-_l]+)(?:[=<>\!]+)?(?P<version>[A-z0-9. ]+)?') # noqa @@ -94,6 +95,7 @@ def testable_packages(filename, prefix): """ pkgdir = os.path.join(prefix, 'pkgs') paths = [] + yaml = YAML(typ='safe') for record in dmfile(filename): # Reconstruct ${package}-${version} format (when possible) @@ -121,8 +123,7 @@ def testable_packages(filename, prefix): continue with open(os.path.join(recipe_d, 'meta.yaml')) as yaml_data: - source = yaml.load(yaml_data.read(), - Loader=yaml.SafeLoader)['source'] + source = yaml.load(yaml_data)['source'] if not isinstance(source, dict): continue @@ -181,6 +182,7 @@ def integration_test(pkg_data, conda_env, results_root='.'): proc_pip.check_returncode() proc_pytest = sh("pytest", f"-v --basetemp=.tmp --junitxml={results}") + print(proc_pytest.stdout.decode()) if proc_pytest.returncode: print(proc_pytest.stderr.decode()) @@ -188,6 +190,9 @@ def integration_test(pkg_data, conda_env, results_root='.'): def force_xunit2(project='.'): + """ Set project configuration to emit xunit2 regardless of orignal settings + :param project: str: path project (i.e. source directory) + """ configs = [os.path.abspath(os.path.join(project, x)) for x in ['pytest.ini', 'setup.cfg']] @@ -208,3 +213,29 @@ def force_xunit2(project='.'): cfg.write(data) return + +def force_yaml_channels(yamlfile, channels): + """ Replace the `channels:` block with `channels` + :param yamlfile: str: path to yaml file + :param channels: list: channel URLs + """ + if not isinstance(channels, list): + raise TypeError("Expecting a list of URLs") + + yaml = YAML() + yaml.default_flow_style = False + yaml.indent(offset=2) + + with open(yamlfile) as yaml_data: + result = yaml.load(yaml_data) + + if not result.get('channels'): + print(f"{yamlfile} has no channels", file=sys.stderr) + return + + # Assuming there's a reason to change the file... + if result['channels'] != channels: + result['channels'] = channels + + with open(yamlfile, 'w') as fp: + yaml.dump(result, fp) @@ -11,7 +11,7 @@ setup( }, install_requires=[ 'requests', - 'pyyaml', + 'ruamel.yaml', ], extras_require={ 'test': [ diff --git a/tests/test_merge.py b/tests/test_merge.py index b6a885f..8ffe383 100644 --- a/tests/test_merge.py +++ b/tests/test_merge.py @@ -1,6 +1,7 @@ import os import pytest from delivery_merge import conda, merge +from ruamel.yaml import YAML CHANNELS = ['http://ssb.stsci.edu/astroconda', @@ -28,6 +29,16 @@ https://repo.anaconda.com/pkgs/main/linux-64/setuptools-41.0.1-py37_0.tar.bz2 https://repo.anaconda.com/pkgs/main/linux-64/wheel-0.33.1-py37_0.tar.bz2 https://repo.anaconda.com/pkgs/main/linux-64/pip-19.1-py37_0.tar.bz2 """ +BASE_YML = """name: simple_env +channels: + - this + - order + - i + - want +dependencies: + - some_package=1.2.3 +""" +CHANNELS_YML = ['i', 'want', 'this', 'order'] COMMENTS_DELIM = [';', '#'] COMMENTS = """; comment ; comment ; comment @@ -67,6 +78,7 @@ class TestMerge: self.input_file = 'sample.dm' self.input_file_invalid = 'sample_invalid.dm' self.input_file_empty = 'sample_empty.dm' + self.yaml = YAML() open(self.input_file, 'w+').write(DMFILE) open(self.input_file_invalid, 'w+').write(DMFILE_INVALID) open(self.input_file_empty, 'w+').write("") @@ -156,3 +168,10 @@ class TestMerge: assert 'junit_family = xunit2' in open('setup.cfg').read() os.remove('setup.cfg') + def test_force_yaml_channels(self): + filename = 'channels.yml' + open(filename, 'w+').write(BASE_YML) + assert self.yaml.load(open(filename))['channels'] + merge.force_yaml_channels('channels.yml', CHANNELS_YML) + assert self.yaml.load(open(filename))['channels'] == CHANNELS_YML + |