import logging
from pathlib import Path
from pkglts.dependency import Dependency
from pkglts.option_object import Option
from pkglts.option_tools import available_options
from pkglts.version import __version__
from . import find_requirements
LOGGER = logging.getLogger(__name__)
[docs]
class OptionReqs(Option):
[docs]
def version(self):
return __version__
[docs]
def root_dir(self):
return Path(__file__).parent
[docs]
def update_parameters(self, cfg):
LOGGER.info("update parameters %s", self._name)
sec = dict(
require=[]
)
cfg[self._name] = sec
[docs]
def check(self, cfg):
invalids = []
req = cfg[self._name]['require']
valid_methods = (None, "pip", "conda", "git")
if any(dep.get('pkg_mng') not in valid_methods for dep in req):
invalids.append("reqs.require")
return invalids
[docs]
def require_option(self, cfg):
return ['base']
[docs]
def environment_extensions(self, cfg):
reqs = requirements(cfg)
def all_intents():
intents = {'install', 'doc', 'dvlpt', 'test'}
for r in reqs:
intents.update(r.intents)
return sorted(intents)
def req(intent=None):
"""For internal use only."""
if intent is None:
return reqs
return [r for r in reqs if intent in r.intents]
def conda_reqs(intents):
return fmt_conda_reqs(reqs, intents)
def pip_reqs(intents):
return fmt_pip_reqs(reqs, intents)
cfg.add_test('is_pip_dep', Dependency.is_pip)
return {
"intents": all_intents,
"requirements": req,
"conda_reqs": conda_reqs,
"pip_reqs": pip_reqs,
}
[docs]
def requirements(cfg):
"""Check all requirements for installed options.
Args:
cfg (Config): current package configuration
Returns:
(list): list of required packages
"""
reqs = {}
for name in cfg.installed_options():
try:
opt = available_options[name]
for dep in opt.require(cfg):
reqs[dep.name] = dep
except KeyError:
raise KeyError(f"option '{name}' does not exists")
for dep_def in cfg['reqs']['require']:
dep = Dependency(**dep_def)
reqs[dep.name] = dep
return [reqs[name] for name in sorted(reqs)]
[docs]
def fmt_conda_reqs(reqs, intents):
"""Produce conda cmd line to install list of requirements.
Args:
reqs (list of Dependency): list of requirements objects
intents (list of str): list of intents for deps
Returns:
(str)
"""
intents = set(intents)
reqs = [r for r in reqs if r.is_conda(strict=False) and len(r.intents & intents) > 0]
if len(reqs) == 0:
return ""
cmd = "conda install"
for channel in sorted(set(r.channel for r in reqs) - {None}):
cmd += f" -c {channel}"
for name in sorted(r.conda_full_name() for r in reqs):
if " " in name:
name = f'"{name}"'
cmd += f" {name}"
return cmd
[docs]
def fmt_pip_reqs(reqs, intents):
"""Produce pip cmd line to install list of requirements.
Args:
reqs (list of Dependency): list of requirements objects
intents (list of str): list of intents for deps
Returns:
(str)
"""
intents = set(intents)
reqs = [r for r in reqs if r.is_pip(strict=True) and len(r.intents & intents) > 0]
if len(reqs) == 0:
return ""
cmd = "pip install"
for name in sorted(r.pip_full_name() for r in reqs):
cmd += f' "{name}"'
return cmd