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 0000000..13037eb
Binary files /dev/null and b/docs/_static/logo.png differ
diff --git a/docs/about.md b/docs/about.rst
similarity index 89%
rename from docs/about.md
rename to docs/about.rst
index f69e513..37c1ab3 100644
--- a/docs/about.md
+++ b/docs/about.rst
@@ -1,3 +1,6 @@
+About
+*****
+
* **Author**: Simon Kallfass
* **Homepage**: https://www.ouroboros.info
* **Email**: skallfass@ouroboros.info
diff --git a/docs/cenv_tool.rst b/docs/cenv_tool.rst
new file mode 100644
index 0000000..5752b61
--- /dev/null
+++ b/docs/cenv_tool.rst
@@ -0,0 +1,54 @@
+cenv\_tool package
+==================
+
+Submodules
+----------
+
+cenv\_tool.init\_cenv module
+----------------------------
+
+.. automodule:: cenv_tool.init_cenv
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+cenv\_tool.project module
+-------------------------
+
+.. automodule:: cenv_tool.project
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+cenv\_tool.rules module
+-----------------------
+
+.. automodule:: cenv_tool.rules
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+cenv\_tool.schemata module
+--------------------------
+
+.. automodule:: cenv_tool.schemata
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+cenv\_tool.utils module
+-----------------------
+
+.. automodule:: cenv_tool.utils
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+
+Module contents
+---------------
+
+.. automodule:: cenv_tool
+ :members:
+ :undoc-members:
+ :show-inheritance:
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000..3b131fc
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,70 @@
+# -*- coding: utf-8 -*-
+import sys
+import datetime as dt
+import pytz
+from pathlib import Path
+
+sys.path.insert(0, str(Path.cwd().parent))
+from cenv_tool import __version__
+
+
+NOW = dt.datetime.utcnow()
+PROJECT_NAME = 'cenv'
+HOMEPAGE = 'https://www.ouroboros.info'
+
+
+project = PROJECT_NAME
+copyright = f'{NOW.year}, Simon Kallfass'
+author = 'Simon Kallfass'
+version = __version__
+release = str(NOW.year)
+extensions = [
+ 'sphinx.ext.autodoc',
+ 'sphinx.ext.viewcode',
+ 'sphinx.ext.napoleon',
+ 'sphinx_autodoc_typehints',
+]
+templates_path = ['_templates']
+source_suffix = '.rst'
+master_doc = 'index'
+language = None
+exclude_patterns = []
+pygments_style = None
+
+
+html_theme = 'sphinx_rtd_theme'
+html_static_path = ['_static']
+htmlhelp_basename = f'{PROJECT_NAME}doc'
+html_logo = '_static/logo.png'
+html_title = PROJECT_NAME
+html_short_title = PROJECT_NAME
+html_last_updated_fmt = NOW.replace(tzinfo=pytz.utc).isoformat()
+html_show_sourcelink = False
+
+
+html_theme_options = {
+ 'canonical_url': HOMEPAGE,
+ 'analytics_id': '',
+ 'logo_only': False,
+ 'display_version': True,
+ 'prev_next_buttons_location': 'bottom',
+ 'style_external_links': False,
+ # Toc options
+ 'collapse_navigation': False,
+ 'sticky_navigation': True,
+ 'navigation_depth': 4,
+ 'includehidden': True,
+ 'titles_only': False,
+ 'display_version': True,
+}
+
+
+napoleon_include_private_with_doc = True
+napoleon_include_special_with_doc = True
+napoleon_include_init_with_doc = True
+napoleon_use_admonition_for_notes = True
+napoleon_use_admonition_for_examples = True
+napoleon_use_param = True
+napoleon_use_keyword = True
+napoleon_use_rtype = False
+napoleon_use_ivar = True
diff --git a/docs/configuration.md b/docs/configuration.rst
similarity index 80%
rename from docs/configuration.md
rename to docs/configuration.rst
index 7dc99ed..ca7caa9 100644
--- a/docs/configuration.md
+++ b/docs/configuration.rst
@@ -1,14 +1,17 @@
+Configuration
+*************
+
`cenv` uses the path `/opt/conda` as default conda-installation-folder
and `/shared/conda/envs` as default conda-environments-folder.
You can overwrite these settings with a `cenv.yml` at
`~/.config/cenv/cenv.yml` with the following content:
-```yaml
-conda_folder: /opt/conda
-env_folder: /shared/conda/envs
-export_environment_yml: false
-```
+.. code:: yaml
+
+ conda_folder: /opt/conda
+ env_folder: /shared/conda/envs
+ export_environment_yml: false
There you can define your own conda-installation-path and the
conda-environments-folder.
diff --git a/docs/img/logo.png b/docs/img/logo.png
deleted file mode 100644
index 9d4447f..0000000
Binary files a/docs/img/logo.png and /dev/null differ
diff --git a/docs/impressum.md b/docs/impressum.rst
similarity index 92%
rename from docs/impressum.md
rename to docs/impressum.rst
index ea00793..1cb27d8 100644
--- a/docs/impressum.md
+++ b/docs/impressum.rst
@@ -1,4 +1,8 @@
-## Legal Disclosure
+Impressum
+*********
+
+Legal Disclosure
+================
Information in accordance with section 5 TMG
@@ -7,14 +11,16 @@ Information in accordance with section 5 TMG
* 76139 Karlsruhe
-## Contact
+Contact
+-------
* Telephone: +49 177 176 7126
* E-Mail: skallfass@ouroboros.info
* Homepage: https://www.ouroboros.info
-## Disclaimer
+Disclaimer
+----------
Accountability for content
The contents of our pages have been created with the utmost care. However, we
@@ -28,7 +34,8 @@ under generally applicable laws remain unaffected by this as per §§ 8 to 10
of the Telemedia Act (TMG).
-## Accountability for links
+Accountability for links
+------------------------
Responsibility for the content of external links (to web pages of third
parties) lies solely with the operators of the linked pages. No violations
@@ -36,7 +43,8 @@ were evident to us at the time of linking. Should any legal infringement
become known to us, we will remove the respective link immediately.
-## Copyright
+Copyright
+---------
Our web pages and their contents are subject to German copyright law.
Unless expressly permitted by law (§ 44a et seq. of the copyright law),
@@ -48,10 +56,12 @@ Unauthorized utilization of copyrighted works is punishable
(§ 106 of the copyright law).
-# Privacy Statement
+Privacy Statement
+=================
-## General
+General
+-------
Your personal data (e.g. title, name, house address, e-mail address,
phone number, bank details, credit card number) are processed by us only in
@@ -62,7 +72,8 @@ web pages. If links on our pages route you to other pages, please inquire
there about how your data are handled in such cases.
-## Inventory data
+Inventory data
+--------------
1. Your personal data, insofar as these are necessary for this contractual
relationship (inventory data) in terms of its establishment, organization
@@ -77,7 +88,8 @@ there about how your data are handled in such cases.
their further use.
-## Disclosure
+Disclosure
+----------
According to the Federal Data Protection Act, you have a right to
free-of-charge information about your stored data, and possibly entitlement
diff --git a/docs/index.md b/docs/index.md
deleted file mode 100644
index 81eaa96..0000000
--- a/docs/index.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# conda-env-manager: cenv
-
-![coverage](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/)
-
-![logo](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
-for the conda-environment during development and for production), `cenv`
-(short form for `conda-env-manager`) was created to make the `meta.yaml`
-the only relevant file and to create and update conda-environment from the
-definition inside this `meta.yaml`.
-The name of the conda-environment to create / update is defined in the section
-`extra` and the variable `env_name` inside the `meta.yaml` (at
-`conda-build/meta.yaml`).
-
-The steps run by cenv:
-
-* creation of a backup if the environment already exists followed by the
- removal of the previous environment.
-* creation of the environment as defined in the `meta.yaml`.
- If any failures occurred during creation and the backup was created, the
- command to reset the backup-version can be used.
-* if enabled in the config file the environment.yml is exported after creation
- / update of the environment.
-
-
-The usage of cenv reduces the conda commands to use to the following:
-
-* `conda activate ...` to activate the environment
-* `conda deactivate` to deactivate an environment
-* `conda info` to show information about the currently activated environment
-* `conda search ...` to search for availability of a package in the conda
- channels.
-* `conda remove -n ... --all` to remove an environment
-* `cenv` to create / update an environment
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 0000000..eacf9d1
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,68 @@
+cenv
+****
+
+.. image:: _static/coverage.svg
+
+.. image:: https://badge.fury.io/py/cenv-tool.svg
+ :target: https://pypi.python.org/pypi/cenv-tool/
+
+.. image:: https://img.shields.io/pypi/pyversions/cenv-tool.svg
+ :target: https://pypi.python.org/pypi/cenv-tool/
+
+.. image:: https://img.shields.io/badge/License-MIT-blue.svg
+ :target: https://lbesson.mit-license.org/
+
+.. image:: https://readthedocs.org/projects/cenv-tool/badge/?version=latest
+ :target: https://cenv-tool.readthedocs.io/en/latest/?badge=latest
+
+
+Tool to create / update conda environments from ``meta.yaml``.
+
+Due to the redundant dependency information inside the ``meta.yaml`` (required
+to create the conda-package) and the ``environment.yml`` (as definition file
+for the conda-environment during development and for production), ``cenv``
+(short form for ``conda-env-manager``) was created to make the ``meta.yaml``
+the only relevant file and to create and update conda-environment from the
+definition inside this ``meta.yaml``.
+The name of the conda-environment to create / update is defined in the section
+``extra`` and the variable ``env_name`` inside the ``meta.yaml`` (at
+``conda-build/meta.yaml``).
+
+The steps run by cenv:
+
+
+ * creation of a backup if the environment already exists followed by the
+ removal of the previous environment.
+ * creation of the environment as defined in the ``meta.yaml``.
+ If any failures occurred during creation and the backup was created, the
+ command to reset the backup-version can be used.
+ * if enabled in the config file the environment.yml is exported after
+ creation / update of the environment.
+
+
+
+The usage of cenv reduces the conda commands to use to the following:
+
+ * ``conda activate ...`` to activate the environment
+ * ``conda deactivate`` to deactivate an environment
+ * ``conda info`` to show information about the currently activated
+ environment
+ * ``conda search ...`` to search for availability of a package in the conda
+ channels.
+ * ``conda remove -n ... --all`` to remove an environment
+ * ``cenv`` to create / update an environment
+
+
+Table of contents
+*****************
+
+.. toctree::
+ :maxdepth: 2
+
+ installation.rst
+ configuration.rst
+ usage.rst
+ modules_base.rst
+ about.rst
+ license.rst
+ impressum.rst
diff --git a/docs/installation.md b/docs/installation.rst
similarity index 70%
rename from docs/installation.md
rename to docs/installation.rst
index 09f5747..55564c7 100644
--- a/docs/installation.md
+++ b/docs/installation.rst
@@ -1,35 +1,45 @@
+Installation
+************
+
To install cenv simply run:
-```bash
-pip3 install cenv_tool
-```
+
+.. code:: bash
+
+ 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`.
-# autoactivate and autoupdate
+autoactivate and autoupdate
+===========================
Per default these features are deactivated, even if added to your shell by
running `init_cenv`.
-## autoactivate-feature
+autoactivate-feature
+--------------------
The autoactivate-feature activates the conda-environment as named
`extra`-section in the meta.yaml located at `conda-build/meta.yaml`, if the
environment exists.
To activate the autoactivate-features run:
-```bash
-autoactivate_toggle
-```
-## autoupdate-feature
+.. code:: bash
+
+ autoactivate_toggle
+
+
+autoupdate-feature
+------------------
The autoupdate checks if the content of the meta.yaml changed.
The current state is stored as a md5sum in `conda-build/meta.md5`.
If it changed the cenv-process is called.
For the autoupdate-feature run:
-```bash
-autoupdate_toggle
-```
+
+.. code:: bash
+
+ autoupdate_toggle
diff --git a/docs/license.md b/docs/license.rst
similarity index 98%
rename from docs/license.md
rename to docs/license.rst
index 268f2a9..970f144 100644
--- a/docs/license.md
+++ b/docs/license.rst
@@ -1,3 +1,6 @@
+License
+*******
+
MIT License
Copyright (c) 2019 Simon Kallfass
diff --git a/docs/modules.rst b/docs/modules.rst
new file mode 100644
index 0000000..94ba6f0
--- /dev/null
+++ b/docs/modules.rst
@@ -0,0 +1,7 @@
+cenv_tool
+=========
+
+.. toctree::
+ :maxdepth: 4
+
+ cenv_tool
diff --git a/docs/modules_base.rst b/docs/modules_base.rst
new file mode 100644
index 0000000..f05a06a
--- /dev/null
+++ b/docs/modules_base.rst
@@ -0,0 +1,7 @@
+Code documentation
+******************
+
+.. toctree::
+ :maxdepth: 4
+
+ modules.rst
diff --git a/docs/usage.md b/docs/usage.md
deleted file mode 100644
index 5ac1ff5..0000000
--- a/docs/usage.md
+++ /dev/null
@@ -1,110 +0,0 @@
-All steps required to create or update the projects conda environment are
-run automatically running:
-```bash
-cenv
-```
-
-**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`.
-
-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')