Skip to content
forked from conda/conda

Commit

Permalink
Merge pull request conda#9093 from forrestwaters/fw_DSNC1492
Browse files Browse the repository at this point in the history
Add ability to create environment spec from explicit specs in history
  • Loading branch information
jjhelmus committed Aug 13, 2019
2 parents 5ea3e1d + a93788c commit aaad747
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 2 deletions.
10 changes: 9 additions & 1 deletion conda_env/cli/main_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ def configure_parser(sub_parsers):
required=False,
help='Do not include channel names with package names.')
add_parser_json(p)

p.add_argument(
'--from-history',
default=False,
action='store_true',
required=False,
help='Build environment spec from explicit specs in history'
)
p.set_defaults(func='.main_export.execute')


Expand All @@ -91,7 +99,7 @@ def execute(args, parser):
name = args.name
prefix = get_prefix(args)
env = from_environment(name, prefix, no_builds=args.no_builds,
ignore_channels=args.ignore_channels)
ignore_channels=args.ignore_channels, from_history=args.from_history)

if args.override_channels:
env.remove_channels()
Expand Down
9 changes: 8 additions & 1 deletion conda_env/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from conda.models.prefix_graph import PrefixGraph
from conda_env.yaml import dump
from . import compat, exceptions, yaml
from conda.history import History

try:
from cytoolz.itertoolz import concatv, groupby
Expand Down Expand Up @@ -79,18 +80,24 @@ def load_from_directory(directory):


# TODO tests!!!
def from_environment(name, prefix, no_builds=False, ignore_channels=False):
def from_environment(name, prefix, no_builds=False, ignore_channels=False, from_history=False):
"""
Get environment object from prefix
Args:
name: The name of environment
prefix: The path of prefix
no_builds: Whether has build requirement
ignore_channels: whether ignore_channels
from_history: Whether environment file should be based on explicit specs in history
Returns: Environment object
"""
# requested_specs_map = History(prefix).get_requested_specs_map()
if from_history:
history = History(prefix).get_requested_specs_map()
deps = [str(package) for package in history.values()]
return Environment(name=name, dependencies=deps, channels=list(context.channels),
prefix=prefix)
pd = PrefixData(prefix, pip_interop_enabled=True)

precs = tuple(PrefixGraph(pd.iter_records()).graph)
Expand Down
27 changes: 27 additions & 0 deletions tests/conda_env/test_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from conda.core.prefix_data import PrefixData
from conda.base.context import conda_tests_ctxt_mgmt_def_pol
from conda.models.match_spec import MatchSpec
from conda.common.io import env_vars
from conda.common.serialize import yaml_load
from conda.install import on_win
Expand All @@ -15,6 +16,13 @@
from .utils import make_temp_envs_dir, Commands, run_command
from tests.test_utils import is_prefix_activated_PATHwise

from conda_env.env import from_environment

try:
from unittest.mock import patch
except ImportError:
from mock import patch


PYTHON_BINARY = 'python.exe' if on_win else 'bin/python'

Expand Down Expand Up @@ -383,3 +391,22 @@ def test_create_advanced_pip(self):
with open(out_file) as f:
d = yaml_load(f)
assert {'pip': ['argh==0.26.2']} in d['dependencies']


class TestFromEnvironment(unittest.TestCase):
def test_from_history(self):
# We're not testing that get_requested_specs_map() actually works
# assume it gives us back a dict of MatchSpecs
with patch('conda.history.History.get_requested_specs_map') as m:
m.return_value = {
'python': MatchSpec('python=3'),
'pytest': MatchSpec('pytest!=3.7.3'),
'mock': MatchSpec('mock'),
'yaml': MatchSpec('yaml>=0.1')
}
out = from_environment('mock_env', 'mock_prefix', from_history=True)
assert "yaml[version='>=0.1']" in out.to_dict()['dependencies']
assert "pytest!=3.7.3" in out.to_dict()['dependencies']
assert len(out.to_dict()['dependencies']) == 4

m.assert_called()

0 comments on commit aaad747

Please sign in to comment.