From 135cbe618c38619cf986479fa617634d1385398f Mon Sep 17 00:00:00 2001 From: Simon Kallfass Date: Wed, 11 Sep 2019 08:32:38 +0200 Subject: [PATCH] minor bugfixes, replaced mkdocs documentation with sphinx, additional docstrings and documentation added. --- .gitignore | 2 + .pre-commit-config.yaml | 2 +- .python-version | 2 +- README.md | 38 ++++- README.rst | 52 ++++-- cenv_tool/__init__.py | 3 +- cenv_tool/init_cenv.py | 6 +- cenv_tool/project.py | 76 ++++----- cenv_tool/rules.py | 37 +++-- cenv_tool/schemata.py | 118 ++++--------- cenv_tool/utils.py | 48 +++--- docs/{img => _static}/coverage.svg | 0 docs/_static/logo.png | Bin 0 -> 52736 bytes docs/{about.md => about.rst} | 3 + docs/cenv_tool.rst | 54 ++++++ docs/conf.py | 70 ++++++++ docs/{configuration.md => configuration.rst} | 13 +- docs/img/logo.png | Bin 44298 -> 0 bytes docs/{impressum.md => impressum.rst} | 30 +++- docs/index.md | 39 ----- docs/index.rst | 68 ++++++++ docs/{installation.md => installation.rst} | 34 ++-- docs/{license.md => license.rst} | 3 + docs/modules.rst | 7 + docs/modules_base.rst | 7 + docs/usage.md | 110 ------------- docs/usage.rst | 165 +++++++++++++++++++ pyproject.toml | 46 ++++-- setup.py | 21 ++- tests/__init__.py | 0 tests/init_cenv_test.py | 6 +- tests/missing_meta_yaml/dummy.txt | 0 tests/project_test.py | 39 ++++- tests/testproject/conda-build/meta.yaml | 2 +- tests/utils_test.py | 15 ++ 35 files changed, 730 insertions(+), 386 deletions(-) rename docs/{img => _static}/coverage.svg (100%) create mode 100644 docs/_static/logo.png rename docs/{about.md => about.rst} (89%) create mode 100644 docs/cenv_tool.rst create mode 100644 docs/conf.py rename docs/{configuration.md => configuration.rst} (80%) delete mode 100644 docs/img/logo.png rename docs/{impressum.md => impressum.rst} (92%) delete mode 100644 docs/index.md create mode 100644 docs/index.rst rename docs/{installation.md => installation.rst} (70%) rename docs/{license.md => license.rst} (98%) create mode 100644 docs/modules.rst create mode 100644 docs/modules_base.rst delete mode 100644 docs/usage.md create mode 100644 docs/usage.rst create mode 100644 tests/__init__.py create mode 100644 tests/missing_meta_yaml/dummy.txt diff --git a/.gitignore b/.gitignore index 324395c..a777acc 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ dist *.egg-info .coverage htmlcov +.dephell_report +docs/build diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4b7e0bd..f233921 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -65,7 +65,7 @@ repos: - id: coverage-badge name: coverage-badge description: create the coverage badge - entry: bash -c "$VIRTUAL_ENV/bin/coverage-badge -f -o docs/img/coverage.svg" + entry: bash -c "$VIRTUAL_ENV/bin/coverage-badge -f -o docs/_static/coverage.svg" language: system types: [python] pass_filenames: false diff --git a/.python-version b/.python-version index c1e43e6..0833a98 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.7.3 +3.7.4 diff --git a/README.md b/README.md index f97fffe..6344ec5 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ # conda-env-manager: cenv -![coverage](docs/img/coverage.svg) +![coverage](https://github.com/skallfass/cenv_tool/blob/master/docs/img/coverage.svg) [![PyPI version fury.io](https://badge.fury.io/py/cenv-tool.svg)](https://pypi.python.org/pypi/cenv-tool/) [![PyPI pyversions](https://img.shields.io/pypi/pyversions/cenv-tool.svg)](https://pypi.python.org/pypi/cenv-tool/) [![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/) +[![Documentation Status](https://readthedocs.org/projects/cenv-tool/badge/?version=latest)](https://cenv-tool.readthedocs.io/en/latest/?badge=latest) +[![Powered by DepHell](https://github.com/dephell/dephell/blob/master/assets/badge.svg)](https://github.com/dephell/dephell) -![logo](docs/img/logo.png) +![logo](https://github.com/skallfass/cenv_tool/blob/master/docs/img/logo.png) Due to the redundant dependency information inside the `meta.yaml` (required to create the conda-package) and the `environment.yml` (as definition file @@ -40,14 +42,14 @@ The usage of cenv reduces the conda commands to use to the following: ## Documentation For complete documentation see -[cenv documentation](https://cenv.ouroboros.info/). +[readthedocs](https://cenv-tool.readthedocs.io/en/latest/). ## Installation Install `cenv` using pip: ```bash -pip3 install cenv_tool +pip install cenv_tool ``` Now run `init_cenv` to create the relevant config-files and add the @@ -187,12 +189,30 @@ If you want to turn this functionality on you need to modify your Example for the output of the `cenv` command: +On create: ```bash - ┣━━ Cloning existing env as backup ... - ┣━━ Removing existing env ... - ┣━━ Creating env ... - ┣━━ Removing backup ... - ┗━━ Exporting env to environment.yml ... +Creating cenv_dev + ├── Create environment + │  └── Created + ├── write md5sum of meta.yaml + │  └── updated + └── Done +``` + +On update: +```bash +Updating cenv_dev + ├── Create backup + │  └── Created + ├── Remove existing env + │  └── Removed + ├── Create environment + │  ├── Clear backup + │  │  └── Cleared + │  └── Created + ├── write md5sum of meta.yaml + │  └── updated + └── Done ``` # Development of cenv diff --git a/README.rst b/README.rst index faaee6c..75fa121 100644 --- a/README.rst +++ b/README.rst @@ -3,8 +3,8 @@ conda-env-manager: cenv ======================= -.. image:: docs/img/coverage.svg - :target: docs/img/coverage.svg +.. image:: https://github.com/skallfass/cenv_tool/blob/master/docs/img/coverage.svg + :target: https://github.com/skallfass/cenv_tool/blob/master/docs/img/coverage.svg :alt: coverage @@ -23,9 +23,19 @@ conda-env-manager: cenv :alt: MIT license +.. image:: https://readthedocs.org/projects/cenv-tool/badge/?version=latest + :target: https://cenv-tool.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status -.. image:: docs/img/logo.png - :target: docs/img/logo.png + +.. image:: https://github.com/dephell/dephell/blob/master/assets/badge.svg + :target: https://github.com/dephell/dephell + :alt: Powered by DepHell + + + +.. image:: https://github.com/skallfass/cenv_tool/blob/master/docs/img/logo.png + :target: https://github.com/skallfass/cenv_tool/blob/master/docs/img/logo.png :alt: logo @@ -64,7 +74,7 @@ Documentation ------------- For complete documentation see -`cenv documentation `_. +`readthedocs `_. Installation ------------ @@ -73,7 +83,7 @@ Install ``cenv`` using pip: .. code-block:: bash - pip3 install cenv_tool + pip install cenv_tool Now run ``init_cenv`` to create the relevant config-files and add the autoactivate- and autoupdate-shell-function to your ``.bashrc`` / ``.zshrc``. @@ -229,13 +239,33 @@ If you want to turn this functionality on you need to modify your Example for the output of the ``cenv`` command: +On create: + +.. code-block:: bash + + Creating cenv_dev + ├── Create environment + │  └── Created + ├── write md5sum of meta.yaml + │  └── updated + └── Done + +On update: + .. code-block:: bash - ┣━━ Cloning existing env as backup ... - ┣━━ Removing existing env ... - ┣━━ Creating env ... - ┣━━ Removing backup ... - ┗━━ Exporting env to environment.yml ... + Updating cenv_dev + ├── Create backup + │  └── Created + ├── Remove existing env + │  └── Removed + ├── Create environment + │  ├── Clear backup + │  │  └── Cleared + │  └── Created + ├── write md5sum of meta.yaml + │  └── updated + └── Done Development of cenv =================== diff --git a/cenv_tool/__init__.py b/cenv_tool/__init__.py index c8c3ccc..f43f250 100644 --- a/cenv_tool/__init__.py +++ b/cenv_tool/__init__.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- """Conda environment creation and update from meta.yaml.""" from pkg_resources import get_distribution +from pkg_resources import DistributionNotFound try: __version__ = get_distribution('cenv_tool').version -except AttributeError: +except (AttributeError, DistributionNotFound): __version__ = '' diff --git a/cenv_tool/init_cenv.py b/cenv_tool/init_cenv.py index ed57115..6cc5f1f 100644 --- a/cenv_tool/init_cenv.py +++ b/cenv_tool/init_cenv.py @@ -42,13 +42,13 @@ def initialize_cenv( zshrc: Path, bashrc: Path, ) -> NoReturn: - """Install user-config and cenv.sh for autoactivate and autoupdate. + """ + Install user-config and cenv.sh for autoactivate and autoupdate. Parameters: config_path: the path for cenv config-stuff. autoenv_script_path: the path to install the cenv.sh script to. - autoenv_script_source_path: the path where to get the cenv.sh script - from + autoenv_script_source_path: the path where to get the cenv.sh script from config_file: the path to install the user-config into. config_file_source: the path where to get the config file from. zshrc: the path to the users .zshrc diff --git a/cenv_tool/project.py b/cenv_tool/project.py index af75354..50190db 100644 --- a/cenv_tool/project.py +++ b/cenv_tool/project.py @@ -1,19 +1,20 @@ # -*- coding: utf-8 -*- -"""Contain the processing for creating conda environments from the meta.yaml. +"""Contain the logic for conda environment creation from ``meta.yaml``. -cenv is a tool to handle conda-environment creation and update from the -dependency-definition inside the meta.yaml file. +cenv is a tool to handle conda environment creation and update from the +dependency-definition inside the ``meta.yaml`` file. As default conda has two files for dependency management: -* the environment.yml -* and the meta.yaml +* the ``environment.yml`` +* and the ``meta.yaml`` -In the environment.yml the environment-definition is stored. -In the meta.yaml the required information to build a conda-package are -stored. This means redundant information. +In the ``environment.yml`` the environment-definition is stored. +In the ``meta.yaml`` the required information to build a conda-package are +stored. +This means redundant information. cenv collects the dependency-information and all project-specific settings -from the meta.yaml-file. +from the ``meta.yaml``. The collected information is used to create / update the projects conda environment. @@ -41,11 +42,11 @@ @attr.s(slots=True, auto_attribs=True) class Project: - """Contain a python-project using conda-environments. + """Contain a python-project using conda environments. Containing methods to display information to current project and methods to update the projects conda-environment from the settings defined in the - projects meta.yaml file. + projects ``meta.yaml``. """ rules: Rules @@ -85,13 +86,13 @@ def __attrs_post_init__(self): } def collect_available_envs(self) -> List[str]: - """Collect the names of the conda-environments currently installed. + """Collect the names of the conda environments currently installed. Parameters: conda_folder: the path where conda is installed. Returns: - List of currently installed conda-environments + list of currently installed conda-environments """ return run_in_bash( @@ -100,7 +101,7 @@ def collect_available_envs(self) -> List[str]: ).split('\n') def write_new_md5sum(self): - """Write the new md5sum of the meta.yaml to conda-build/meta.md5.""" + """Write new md5sum of ``meta.yaml`` to ``conda-build/meta.md5``.""" message(text='write md5sum of meta.yaml', color='bold', special='row') command = ( 'echo "$(md5sum $PWD/conda-build/meta.yaml)" | ' @@ -110,13 +111,13 @@ def write_new_md5sum(self): message(text='updated', color='green', special='end', indent=2) def export_environment_definition(self) -> NoReturn: - """Export the projects environment definition to an environment.yml.""" + """Export projects environment definition to an ``environment.yml``.""" message(text='Export environment.yml ...', color='bold', special='row') run_in_bash(cmd=self.cmds.export.format(**self.cmd_kwargs)) message(text='Exported', color='green', special='end', indent=2) def remove_backup_environment(self) -> NoReturn: - """Remove backup cloned from original environment.""" + """Remove backup environment cloned from original environment.""" run_in_bash(cmd=self.cmds.clean.format(**self.cmd_kwargs)) def restore_environment_from_backup(self, cloned: bool) -> NoReturn: @@ -185,10 +186,10 @@ def create_environment(self, cloned: bool) -> NoReturn: """Create the environment for the project. Try to create the environment for the project. If the environment - already existed and a backup was made and any error occurs, the backup - environment is restored. - If everything worked correctly the backup (if made) is finally - removed. + already existed and a backup was made and any error occure, restore the + backup environment. + If everything worked correctly finally remove the backup (if one was + made). Parameters: cloned: indicates if the environment already existed and a backup @@ -201,7 +202,7 @@ def create_environment(self, cloned: bool) -> NoReturn: run_in_bash(cmd=self.cmds.create.format(**self.cmd_kwargs)) except CenvProcessError: self.restore_environment_from_backup(cloned=cloned) - raise + exit(1) if cloned: message(text='Clear backup', color='bold', special='row', indent=2) @@ -211,18 +212,17 @@ def create_environment(self, cloned: bool) -> NoReturn: message(text='Created', color='green', special='end', indent=2) def update(self) -> NoReturn: - """Create / recreate the conda-environment of the current project. + """Create / recreate the conda environment of the current project. - If the conda-environment already exists the user is aked for - confirmation to continue. Then the environment will be cloned as a - backup and the original environment will be removed. Now the new - conda-environment will be created. If a backup was created it is + If the conda environment already exists, clone the environment as a + backup and then remove original environment. Then create the new + conda environment. If a backup was created it is removed afterwards. If any errors occurs during creation of the new - environment the old environment will be recreated from backup and - then the backup will be removed. If activated in the config-file, the - environment-definition of the created environment is exported to an - environment.yml file. Finally the md5sum of the meta.yaml is stored - for the autoupdate feature. + environment, recreate the old environment from backup and remove the + backup afterwards. If activated in the config-file, export the + environment-definition of the created environment to an + ``environment.yml`` file. Finally store the md5sum of the meta.yaml for + the autoupdate feature. """ if self.is_env: message(text=f'Updating {self.env_name}', color='cyan') @@ -241,11 +241,11 @@ def update(self) -> NoReturn: message(text='Done', color='green', special='end') -def build_arguments() -> Namespace: +def build_arguments() -> ArgumentParser: """Create arguments for the cenv-tool. Returns: - The parsed arguments + the parsed arguments. """ parser = ArgumentParser( @@ -260,14 +260,14 @@ def build_arguments() -> Namespace: default=False, help='Show current version of cenv and exit.', ) - args = parser.parse_args() - return args + return parser def main() -> NoReturn: - """Collect the required args, initializing and running the Project.""" - args = build_arguments() - if args.version: + """Collect the required args, initialize and run the Project.""" + parser = build_arguments() + options = parser.parse_args() + if options.version: print(__version__) else: Project(rules=RULES).update() diff --git a/cenv_tool/rules.py b/cenv_tool/rules.py index 2f430f3..968ba8f 100644 --- a/cenv_tool/rules.py +++ b/cenv_tool/rules.py @@ -74,16 +74,33 @@ ) -@attr.s(slots=True) +@attr.s(slots=True, auto_attribs=True) class CondaCmdFormats: - """Contain the formats for the conda commands to use inside cenv.""" + """Contain the formats for the conda commands to use inside cenv. + + Attributes: + remove: command to remove a conda environment. + export: command to use to export a conda environment to an + environment definition file (environment.yml). + create: command to use for conda environment creation. + clone: command to use to clone a conda environment. + restore: command to use to recreate a conda environment from backup + conda environment (clone). + clean: command to use to remove the backup conda environment. + """ - remove = '{conda} remove -n {name} --all -y' - export = '{conda} env export -n {name} > conda-build/environment.yml' - create = '{conda} create -n {name} {pkgs} -y' - clone = '{conda} create -n {name}_backup --clone {name} -y' - restore = '{conda} create -n {name} --clone {name}_backup -y' - clean = '{conda} remove -n {name}_backup --all -y' + remove: str = attr.ib(default='{conda} remove -n {name} --all -y') + export: str = attr.ib( + default='{conda} env export -n {name} > conda-build/environment.yml' + ) + create: str = attr.ib(default='{conda} create -n {name} {pkgs} -y') + clone: str = attr.ib( + default='{conda} create -n {name}_backup --clone {name} -y' + ) + restore: str = attr.ib( + default='{conda} create -n {name} --clone {name}_backup -y' + ) + clean: str = attr.ib(default='{conda} remove -n {name}_backup --all -y') def conda_bin(self, conda_folder): """Combine the path of conda-folder with subpath of conda-bin. @@ -99,8 +116,8 @@ def conda_bin(self, conda_folder): class Rules: """Contain the rules required by cenv-tool.""" - conda_cmds = CondaCmdFormats() - git_folder = '.git' + conda_cmds: CondaCmdFormats = CondaCmdFormats() + git_folder: str = '.git' RULES = Rules() diff --git a/cenv_tool/schemata.py b/cenv_tool/schemata.py index 31d46a3..fd55d13 100644 --- a/cenv_tool/schemata.py +++ b/cenv_tool/schemata.py @@ -6,50 +6,33 @@ class SNPackage(Schema): - """Contain the package-section inside a meta.yaml.""" + """Contain the ``package``-section inside a ``meta.yaml``.""" - name = fields.String( - strict=True, - required=True, - ) - version = fields.String( - strict=True, - required=True, - ) + name = fields.String(strict=True, required=True) + version = fields.String(strict=True, required=True) class SNSource(Schema): - """Contain the source-section inside a meta.yaml.""" + """Contain the ``source``-section inside a ``meta.yaml``.""" - path = fields.String( - strict=True, - required=True, - ) + path = fields.String(strict=True, required=True) class SNBuild(Schema): - """Contain the build-section inside a meta.yaml. + """Contain the ``build``-section inside a ``meta.yaml``. - Schema for the build-section inside a meta.yaml file, to check this section - of a given meta.yaml file in cenv, to be valid. - The build-section requires to define the build-number, if the egg-dir + The ``build``-section requires to define the build-number, if the egg-dir should be preserved, the script to run on installation and if any entrypoints are defined for the package. """ - build = fields.String( - strict=True, - required=True, - ) + build = fields.String(strict=True, required=True) preserve_egg_dir = fields.String( strict=True, required=True, validate=validate.OneOf(['True', 'False']), ) - script = fields.String( - strict=True, - required=True, - ) + script = fields.String(strict=True, required=True) entry_points = fields.List( fields.String(strict=True, required=False), strict=True, @@ -58,18 +41,13 @@ class SNBuild(Schema): class SNRequirements(Schema): - """Contain requirements-section inside a meta.yaml. + """Contain ``requirements``-section inside a ``meta.yaml``. - Schema for the requirements-section inside a meta.yaml file, to check this - section of a given meta.yaml file in cenv, to be valid. - The underlying build- and run-sections have to be valid! + The underlying ``build``- and ``run``-sections have to be valid! """ build = fields.List( - fields.String( - strict=True, - required=True, - ), + fields.String(strict=True, required=True), strict=True, required=True, ) @@ -86,38 +64,26 @@ class SNRequirements(Schema): class SNTest(Schema): - """Contain tests-section inside a meta.yaml. - - Schema for the test-section inside a meta.yaml file, to check this section - of a given meta.yaml file in cenv, to be valid. - """ + """Contain ``tests``-section inside a ``meta.yaml``.""" imports = fields.List( - fields.String( - strict=True, - required=False, - ), + fields.String(strict=True, required=False), strict=True, required=False, ) commands = fields.List( - fields.String( - strict=True, - required=False, - ), + fields.String(strict=True, required=False), strict=True, required=False, ) class SNExtra(Schema): - """Contain the extra-section inside a meta.yaml. + """Contain the ``extra``-section inside a ``meta.yaml``. - Schema for the extra-section inside a meta.yaml file, to check this - section of a given meta.yaml file in cenv, to be valid. - The extra-section has to contains the information where to find the - conda-folder, the name of the conda-environment to use for the current - project and the cenv-version used when the meta.yaml file was created. + The ``extra``-section has to contains the information where to find the + conda-folder, the name of the conda environment to use for the current + project and the cenv-version used when the ``meta.yaml`` file was created. """ env_name = fields.String( @@ -139,41 +105,17 @@ class SNExtra(Schema): class SMetaYaml(Schema): - """Contain the representable of a complete meta.yaml file. + """Contain the representable of a complete ``meta.yaml`` file. - Schema for a meta.yaml file to be used for cenv. - Ensures the meta.yaml to load contains the relevant information about - the package, source, build, requirements and extra. - The test-section is optional. + Schema for a ``meta.yaml`` file to be used for cenv. + Ensure the meta.yaml to load contains the relevant information about + the ``package``, ``source``, ``build``, ``requirements`` and ``extra``. + The ``test``-section is optional. """ - package = fields.Nested( - SNPackage, - strict=True, - required=True, - ) - source = fields.Nested( - SNSource, - strict=True, - required=True, - ) - build = fields.Nested( - SNBuild, - strict=True, - required=True, - ) - requirements = fields.Nested( - SNRequirements, - strict=True, - required=True, - ) - test = fields.Nested( - SNTest, - strict=True, - required=False, - ) - extra = fields.Nested( - SNExtra, - strict=True, - required=True, - ) + package = fields.Nested(SNPackage, strict=True, required=True) + source = fields.Nested(SNSource, strict=True, required=True) + build = fields.Nested(SNBuild, strict=True, required=True) + requirements = fields.Nested(SNRequirements, strict=True, required=True) + test = fields.Nested(SNTest, strict=True, required=False) + extra = fields.Nested(SNExtra, strict=True, required=True) diff --git a/cenv_tool/utils.py b/cenv_tool/utils.py index e10cf7c..19da0bd 100644 --- a/cenv_tool/utils.py +++ b/cenv_tool/utils.py @@ -10,7 +10,7 @@ import jinja2 import six from marshmallow import ValidationError -from ruamel.yaml import YAML +import yaml from cenv_tool.schemata import SMetaYaml @@ -28,10 +28,14 @@ class CenvProcessError(Exception): def message( *, text: str, color: str, special: str = None, indent: int = 1 ) -> NoReturn: - """Print the passed text in the passed color on terminal. + """Print passed ``text`` in the passed ``color`` on terminal. Parameters: - text: The text to print colored on terminal + text: the text to print colored on terminal. + color: the color of the text to print. + special: special kind of message to print. Available are ``'row'`` and + ``'end'``. + indent: the indent to use for the text. """ color_mapping = { @@ -57,7 +61,7 @@ def message( def run_in_bash(cmd: str) -> str: - """Run passed cmd inside bash using the subprocess.check_output-function. + """Run passed ``cmd`` inside bash using :func:`subprocess.check_output`. Parameters: cmd: the command to execute. @@ -68,16 +72,20 @@ def run_in_bash(cmd: str) -> str: """ try: result = check_output([cmd], shell=True, stderr=STDOUT) - except CalledProcessError: - raise CenvProcessError() + except CalledProcessError as err: + error_message = err.output.decode('utf8').split('\n') + message(text='the following error occured:', color='red') + for line in error_message: + message(text=line, color='bold') + raise CenvProcessError(str(err.output)) return result.strip().decode('ascii') class NullUndefined(jinja2.Undefined): - """Handle jinja2-variables with undefined content inside the meta.yaml.""" + """Handle jinja2-variables with undefined content of ``meta.yaml.``""" def __unicode__(self): - """Replace uncode dunder of this class.""" + """Replace unicode dunder of this class.""" return six.text_type(self._undefined_name) def __getattr__(self, attribute_name: str): @@ -90,7 +98,7 @@ def __getitem__(self, attribute_name: str): class StrDict(dict): - """Handle dictionaries for jinja2-variables inside the meta.yaml.""" + """Handle dictionaries for jinja2-variables of ``meta.yaml``.""" def __getitem__(self, key: str, default: str = '') -> str: """Replace getitem dunder of this class.""" @@ -100,17 +108,16 @@ def __getitem__(self, key: str, default: str = '') -> str: def read_meta_yaml(path: Path) -> dict: """Read the meta.yaml file. - The file is read from relative path conda-build/meta.yaml inside - the current path, validates the meta.yaml using the marshmallow-schema, - extracts the dependency-information and the project-settings and returns - these information. + The file is read from relative path ``conda-build/meta.yaml`` inside + the current path, validate the ``meta.yaml`` using the marshmallow-schema, + :class:`SMetaYaml`, extract the dependency-information and the + project-settings and return these information. Parameters: - path: The current working directory + path: the current working directory. Returns: - List containing the project-settings as a dict and the dependencies - also as a dict + list containing the project-settings and the dependencies (both dicts) """ # load the meta.yaml-content @@ -123,7 +130,7 @@ def read_meta_yaml(path: Path) -> dict: 'load_setup_py_data': StrDict, } rendered_myaml = jinja2_loaded_myaml.render(**render_kwargs) - loaded_myaml = YAML(typ='base').load(rendered_myaml) + loaded_myaml = yaml.safe_load(rendered_myaml) # validate the content of loaded meta.yaml try: @@ -139,8 +146,7 @@ def read_meta_yaml(path: Path) -> dict: if meta_yaml_content['extra'].get('dev_requirements'): dependencies.extend(meta_yaml_content['extra']['dev_requirements']) - # combine the collected project-settings and the collected dependencies - # to one output of this function + # return combined collected project-settings and collected dependencies return meta_yaml_content, dependencies @@ -157,11 +163,11 @@ def read_config(): default_config_path = Path(__file__).parent / 'cenv.yml' # Collect settings from config file .cenv.yml - main_config = YAML(typ='safe').load(default_config_path.open().read()) + main_config = yaml.safe_load(default_config_path.open().read()) # if a user-config-file exists, read the content and update the main-config if user_config_path.exists(): - user_config = YAML(typ='safe').load(user_config_path.open().read()) + user_config = yaml.safe_load(user_config_path.open().read()) main_config.update(user_config) return main_config diff --git a/docs/img/coverage.svg b/docs/_static/coverage.svg similarity index 100% rename from docs/img/coverage.svg rename to docs/_static/coverage.svg diff --git a/docs/_static/logo.png b/docs/_static/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..13037eb22d987e8ad7a7fd530aa26b70d086b9ad GIT binary patch literal 52736 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 O0000 If you use cenv, each environment should only be created, updated and -> modified using `cenv`! -> This means the commands `conda install`, `conda remove` are not used -> anymore. -> Changes of the dependencies of the environment are defined inside the -> `meta.yaml` and are applied by using `cenv`. -> -> This means: -> -> * new dependency required => add it in `meta.yaml` and run `cenv`. -> * dependency not needed anymore => remove it from `meta.yaml` and run -> `cenv`. -> * need of another version of dependency => change the version of dependency -> in `meta.yaml` and run `cenv`. - -The required information about the projects conda environment are extracted -from the meta.yaml. -This meta.yaml should be located inside the project folder at -`./conda-build/meta.yaml`. -The project-configuration is defined in the `extra` section of the `meta.yaml`. -There you can define the name of the projects conda-environment at -`env_name`. -Also you can define requirements only needed during development but not to be -included into the resulting conda package. -These requirements have to be defined in the `dev_requirements`-section. - -All other parts of the `meta.yaml` have to be defined as default. - -A meta.yaml valid for cenv should look like the following: -```yaml - {% set data = load_setup_py_data() %} - - package: - name: "example_package" - version: {{ data.get("version") }} - - source: - path: .. - - build: - build: {{ environ.get('GIT_DESCRIBE_NUMBER', 0) }} - preserve_egg_dir: True - script: python -m pip install --no-deps --ignore-installed . - - requirements: - build: - - python 3.6.8 - - pip - - setuptools - run: - - python 3.6.8 - - attrs >=18.2 - - jinja2 >=2.10 - - ruamel.yaml >=0.15.23 - - six >=1.12.0 - - yaml >=0.1.7 - - marshmallow >=3.0.0rc1* - - test: - imports: - - example_package - - extra: - env_name: example - dev_requirements: - - ipython >=7 -``` - -**ATTENTION**: -> In the `requirements-run-section` the minimal version of each package -> has to be defined! -> The same is required for the `dev_requirements`-section. -> Not defining a version will not create or update a conda-environment, -> because this is not the purpose of the conda-usage. -> The validity of the `meta.yaml` is checked in `cenv` using the -> `marshmallow` package. -> You can additionally add upper limits for the version like the following: -> `- package >=0.1,<0.3` - -If cenv is run the environment is created / updated from the definition inside -this `meta.yaml`. -The creation of the backup of the previous environment ensures to undo changes -if any error occurs during recreation of the environment. - - -**ATTENTION**: -> `cenv` can only update the environment if it is not activated. -> So ensure the environment to be deactivated before running `cenv`. - -Per default exporting the conda environment definition into an environment.yml -is turned off. -If you want to turn this functionality on you need to modify your -`~/.config/cenv.yml` as described in [configuration](configuration.md). - -Example for the output of the `cenv` command: - -```bash - ┣━━ Cloning existing env as backup ... - ┣━━ Removing existing env ... - ┣━━ Creating env ... - ┣━━ Removing backup ... - ┗━━ Exporting env to environment.yml ... -``` diff --git a/docs/usage.rst b/docs/usage.rst new file mode 100644 index 0000000..004ed8f --- /dev/null +++ b/docs/usage.rst @@ -0,0 +1,165 @@ +Usage +***** + +All steps required to create or update the projects conda environment are +run automatically running ``cenv`` inside the project folder: + + +.. attention:: + If you use cenv, each environment should only be created, updated and + modified using `cenv`! + This means the commands `conda install`, `conda remove` are not used + anymore. + Changes of the dependencies of the environment are defined inside the + `meta.yaml` and are applied by using `cenv`. + + This means: + + * new dependency required => add it in `meta.yaml` and run `cenv`. + * dependency not needed anymore => remove it from `meta.yaml` and run + `cenv`. + * need of another version of dependency => change the version of dependency + in `meta.yaml` and run `cenv`. + + +Project structure +================= + +A project using cenv needs at minimum the following folder structure: + +.. code:: bash + + + ├── conda-build + │  └── meta.yaml + ├── + ├── README.md + └── setup.py + + +meta.yaml +========= + +The required information about the projects conda environment are extracted +from the meta.yaml. +This meta.yaml should be located inside the project folder at +``./conda-build/meta.yaml``. + +The project-configuration is defined in the ``extra`` section of the +``meta.yaml``. +There you can define the name of the projects conda-environment at +``extra:env_name``. +Also you can define requirements only needed during development but not to be +included into the resulting conda package. +These requirements have to be defined in the +``extra:dev_requirements``-section. + +All other parts of the ``meta.yaml`` have to be defined as default. + +A meta.yaml valid for cenv should look like the following: + +.. code:: yaml+jinja + + {% set data = load_setup_py_data() %} + + package: + name: "example_package" + version: {{ data.get("version") }} + + source: + path: .. + + build: + build: {{ environ.get('GIT_DESCRIBE_NUMBER', 0) }} + preserve_egg_dir: True + script: python -m pip install --no-deps --ignore-installed . + + requirements: + build: + - python 3.6.8 + - pip + - setuptools + run: + - python 3.6.8 + - attrs >=18.2,<19 + - jinja2 >=2.10 + - six >=1.12.0 + - yaml >=0.1.7 + + test: + imports: + - example_package + + extra: + env_name: example + dev_requirements: + - ipython >=7 + + +.. attention:: + In the ``requirements:run``-section the minimal version of each package + has to be defined like the following: + + .. code:: yaml + + - package >=0.1 + + The same is required for the ``extra:dev_requirements``-section. + Not defining a version will not create or update a conda-environment, + because this is not the purpose of the conda-usage. + The validity of the ``meta.yaml`` is checked in ``cenv`` using the + `marshmallow` package. + You can additionally add upper limits for the version like the following: + + .. code:: yaml + + - package >=0.1,<0.3 + +If cenv is run the environment is created / updated from the definition inside +this ``meta.yaml``. +The creation of the backup of the previous environment ensures to undo changes +if any error occurs during recreation of the environment. + + +.. attention:: + ``cenv`` can only update the environment if it is not activated. + So ensure the environment to be deactivated before running ``cenv``. + +Per default exporting the conda environment definition into an environment.yml +is turned off. +If you want to turn this functionality on you need to modify your +``~/.config/cenv.yml`` as described in `configuration `_. + + +Running cenv +============ + +Example for the output of the ``cenv`` command: + +On create: + +.. code:: bash + + Creating cenv_dev + ├── Create environment + │  └── Created + ├── write md5sum of meta.yaml + │  └── updated + └── Done + +On update: + +.. code:: bash + + Updating cenv_dev + ├── Create backup + │  └── Created + ├── Remove existing env + │  └── Removed + ├── Create environment + │  ├── Clear backup + │  │  └── Cleared + │  └── Created + ├── write md5sum of meta.yaml + │  └── updated + └── Done diff --git a/pyproject.toml b/pyproject.toml index dc5e553..e95fb6a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "cenv_tool" -version = "1.0.2" +version = "1.1.0" description = "conda environment creation and update from meta.yaml" license = "MIT" authors = ["Simon Kallfass "] @@ -16,25 +16,26 @@ classifiers = [ [tool.poetry.dependencies] -python = "^3.7" +python = "==3.*,>=3.7.0" attrs = "~19" jinja2 = ">=2" -"ruamel.yaml" = ">=0.15" +pyyaml = "^5" six = ">=1.12" marshmallow = ">=2.19,<3" [tool.poetry.dev-dependencies] -coverage-badge = "~1" +coverage-badge = "==1.*,>=1.0.0" ipython = ">=7" -mkdocs = "~1" monkeytype = ">=19" -pydoc-markdown = "~2" pylint = ">=2" -pytest = "^3.0" -pytest-cov = '~2' -pytest-datafiles = '~2' +pytest = "==5.*,>=5.0.0" +pytest-cov = "==2.*,>=2.0.0" +pytest-datafiles = "==2.*,>=2.0.0" yapf = ">=0" +sphinx = "==2.*,>=2.0.0" +sphinx-autodoc-typehints = "==1.*,>=1.0.0" +sphinx_rtd_theme = "==0.*,>=0.0.0" [tool.poetry.scripts] @@ -42,13 +43,12 @@ cenv = "cenv_tool.project:main" init_cenv = "cenv_tool.init_cenv:main" -[build-system] -requires = ["poetry>=0.12"] -build-backend = "poetry.masonry.api" +[tool.poetry.extras] +docs = ["sphinx", "sphinx-autodoc-typehints"] +tests = ["pytest", "pytest-cov", "pytest-datafiles"] + -[tool.poetry.extras] -docs = ["mkdocs", "pydoc-markdown"] [tool.dephell.main] @@ -70,6 +70,20 @@ to = {format = "poetrylock", path = "poetry.lock"} # read dependencies from poetry format from = {format = "poetry", path = "pyproject.toml"} # install only `docs` extra dependencies -envs = ["docs"] +envs = ["main", "devs", "docs"] # run this command: -command = "mkdocs build" +# command = "mkdocs build" +command = "sphinx-apidoc -f -o docs/source cenv_tool && sphinx-build -W docs/source docs/build" + + +[tool.dephell.pytest] +# read dependencies from setup.py +from = {format = "poetry", path = "pyproject.toml"} +# install main dependencies and `tests` extra dependencies +envs = ["main", "tests"] +tests = ["tests", "cenv_tool", "setup.cfg"] +# run command `pytest` +command = "pytest -c setup.cfg --cache-clear" +[build-system] +requires = ["poetry>=0.12"] +build-backend = "poetry.masonry.api" diff --git a/setup.py b/setup.py index 82c835f..a98db80 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ setup( long_description=readme, name='cenv_tool', - version='1.0.2', + version='1.1.0', description='conda environment creation and update from meta.yaml', python_requires='==3.*,>=3.7.0', project_urls={ @@ -46,15 +46,22 @@ package_data={'cenv_tool': ['*.sh', '*.yml']}, install_requires=[ 'attrs==19.*,>=19.0.0', 'jinja2>=2', 'marshmallow<3,>=2.19', - 'ruamel.yaml>=0.15', 'six>=1.12' + 'pyyaml==5.*,>=5.0.0', 'six>=1.12' ], extras_require={ 'dev': [ - 'coverage-badge==1.*,>=1.0.0', 'ipython>=7', 'mkdocs==1.*,>=1.0.0', - 'monkeytype>=19', 'pydoc-markdown==2.*,>=2.0.0', 'pylint>=2', - 'pytest==3.*,>=3.0.0', 'pytest-cov==2.*,>=2.0.0', - 'pytest-datafiles==2.*,>=2.0.0', 'yapf>=0' + 'coverage-badge==1.*,>=1.0.0', 'ipython>=7', 'monkeytype>=19', + 'pylint>=2', 'pytest==5.*,>=5.0.0', 'pytest-cov==2.*,>=2.0.0', + 'pytest-datafiles==2.*,>=2.0.0', 'sphinx==2.*,>=2.0.0', + 'sphinx-autodoc-typehints==1.*,>=1.0.0', + 'sphinx-rtd-theme==0.*,>=0.0.0', 'yapf>=0' ], - 'docs': ['mkdocs==1.*,>=1.0.0', 'pydoc-markdown==2.*,>=2.0.0'] + 'tests': [ + 'pytest==5.*,>=5.0.0', 'pytest-cov==2.*,>=2.0.0', + 'pytest-datafiles==2.*,>=2.0.0' + ], + 'docs': [ + 'sphinx==2.*,>=2.0.0', 'sphinx-autodoc-typehints==1.*,>=1.0.0' + ] }, ) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/init_cenv_test.py b/tests/init_cenv_test.py index d3072be..5e5e870 100644 --- a/tests/init_cenv_test.py +++ b/tests/init_cenv_test.py @@ -15,13 +15,15 @@ def test_initialize_cenv(datafiles): autoenv_script_path = config_path / 'cenv.sh' zshrc = Path(datafiles) / '.zshrc' bashrc = Path(datafiles) / '.bashrc' + autoenv_script_source_path = Path('cenv_tool/cenv.sh') + config_file_source = Path('cenv_tool/cenv.yml') for _ in range(2): initialize_cenv( config_path=config_path, autoenv_script_path=autoenv_script_path, - autoenv_script_source_path=Path('cenv_tool/cenv.sh'), + autoenv_script_source_path=autoenv_script_source_path, config_file=config_file, - config_file_source=Path('cenv_tool/cenv.yml'), + config_file_source=config_file_source, zshrc=zshrc, bashrc=bashrc, ) diff --git a/tests/missing_meta_yaml/dummy.txt b/tests/missing_meta_yaml/dummy.txt new file mode 100644 index 0000000..e69de29 diff --git a/tests/project_test.py b/tests/project_test.py index 91e372f..e101274 100644 --- a/tests/project_test.py +++ b/tests/project_test.py @@ -5,38 +5,73 @@ import pytest from cenv_tool.project import Project +from cenv_tool.project import build_arguments from cenv_tool.rules import RULES def test_project_collect_available_envs(): + """Test if available_envs can be collected.""" current_path = Path.cwd() testfolder = Path('tests/testproject') os.chdir(str(testfolder)) project = Project(rules=RULES) os.chdir(str(current_path)) - available_envs = project.collect_available_envs() - print(available_envs) + assert project.collect_available_envs() @pytest.mark.datafiles('tests/testproject') def test_project_update(datafiles): + """Test the project environment creation, update, backup and cleanup.""" created_env = Path('/shared/conda/envs/cenv_testing_project0001') environment_yml = Path(datafiles) / 'conda-build/environment.yml' current_folder = Path.cwd() + + # test creation of environment os.chdir(datafiles) project = Project(rules=RULES) + assert 'cenv_testing_project0001' not in project.collect_available_envs() + project.update() assert created_env.exists() + assert 'cenv_testing_project0001' in project.collect_available_envs() + + + # test update of environment and the export of the environment.yml project = Project(rules=RULES) + project.export_environment_yml = True project.update() assert created_env.exists() + assert 'cenv_testing_project0001' in project.collect_available_envs() + + + # test remaining methods for project environment project = Project(rules=RULES) project.remove_previous_environment() project.remove_backup_environment() project.create_environment(cloned=False) project.export_environment_definition() assert environment_yml.exists() + + + # clean everything after tests environment_yml.unlink() project.remove_previous_environment() project.remove_backup_environment() os.chdir(str(current_folder)) + + +@pytest.mark.datafiles('tests/missing_meta_yaml') +def test_no_meta_yaml(datafiles): + """Test if exit if no meta.yaml is found.""" + current_folder = Path.cwd() + os.chdir(datafiles) + with pytest.raises(SystemExit): + project = Project(rules=RULES) + os.chdir(str(current_folder)) + + +def test_build_arguments(): + """Test if the option --version is parsable.""" + parser = build_arguments() + options = parser.parse_args(['--v']) + assert options.version diff --git a/tests/testproject/conda-build/meta.yaml b/tests/testproject/conda-build/meta.yaml index 966901d..b2e2778 100644 --- a/tests/testproject/conda-build/meta.yaml +++ b/tests/testproject/conda-build/meta.yaml @@ -34,6 +34,6 @@ test: - cenv_testing_project0001 -v extra: - env_name: cenv_testing_project0001 + env_name: "cenv_testing_project0001" dev_requirements: - pylint >=2.2.2 diff --git a/tests/utils_test.py b/tests/utils_test.py index 8931748..115f4e6 100644 --- a/tests/utils_test.py +++ b/tests/utils_test.py @@ -8,6 +8,7 @@ from cenv_tool.utils import CenvProcessError from cenv_tool.utils import read_meta_yaml from cenv_tool.utils import run_in_bash +from cenv_tool.utils import StrDict @pytest.mark.parametrize( @@ -93,3 +94,17 @@ def test_run_in_bash_fails(): """Test if run_in_bash works as expected.""" with pytest.raises(CenvProcessError): run_in_bash(cmd='ls-a tests/testproject/conda-build') + + +def test_strdict(): + example_dict = StrDict({ + 'a': 1, + 'b': { + 'c': 'test' + }, + 'd': '' + }) + assert example_dict.get('a') == 1 + assert example_dict.get('b') == {'c': 'test'} + assert not example_dict.get('d') + assert not example_dict.get('e')