Skip to content
This repository has been archived by the owner on Apr 27, 2022. It is now read-only.

Commit

Permalink
Fix env.spec update in manifest branch (#29)
Browse files Browse the repository at this point in the history
* Fix env.spec update in manifest branch
  • Loading branch information
bjlittle authored and marqh committed Feb 10, 2017
1 parent c682218 commit 2baea8c
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 18 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ install:

# Now do the things we need to do to install it.
- conda install --file requirements.txt nose mock python=${PYTHON} --yes --quiet -c conda-forge
- conda list
- python setup.py install

script:
Expand Down
38 changes: 31 additions & 7 deletions conda_gitenv/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,14 @@ def create_env(pkgs, target, pkg_cache):
# The downside is that we are not verifying that each package is installed correctly.
return

try:
# Support conda>4.1
from conda.models.channel import prioritize_channels
except ImportError:
prioritize_channels = lambda nop: nop

for source, pkg in pkgs:
index = conda.fetch.fetch_index([source], use_cache=False)
index = conda.fetch.fetch_index(prioritize_channels([source]), use_cache=False)
# Deal with the fact that a recent conda includes the source in the index key.
index = {pkg['fn']: pkg for pkg in index.values()}

Expand Down Expand Up @@ -103,16 +109,28 @@ def create_env(pkgs, target, pkg_cache):
conda.install.link(target, schannel_dist_name)


def deploy_repo(repo, target, desired_env_labels=('*')):
def deploy_repo(repo, target, desired_env_labels=None):
# Set pkgs_dirs location to be the specified pkg_cache.
# Cache settings to be reinstated at the end.
import conda
orig_package_cache_ = conda.install.package_cache_
orig_pkgs_dirs = conda.install.pkgs_dirs
pkg_cache = os.path.join(target, '.pkg_cache')
try:
# Support conda=4.1.*
orig_pkgs_dirs = conda.install.pkgs_dirs
conda.install.pkgs_dirs = [pkg_cache]
except AttributeError:
# Support conda>4.1
@property
def mocker(self):
return [pkg_cache]
import conda.base.context
orig_pkgs_dirs = conda.base.context.Context.pkgs_dirs
# Monkey patch the context instance property.
conda.base.context.Context.pkgs_dirs = mocker

# Empty package cache so that it will reinitialised.
conda.install.package_cache_ = {}
# Set pkgs_dirs location to be the specified pkg_cache.
pkg_cache = os.path.join(target, '.pkg_cache')
conda.install.pkgs_dirs = [pkg_cache]

env_tags = tags_by_env(repo)
for branch in repo.branches:
Expand All @@ -135,6 +153,8 @@ def deploy_repo(repo, target, desired_env_labels=('*')):

# Only deploy environments that match the given pattern.
labelled_tags = {}
if desired_env_labels is None:
desired_env_labels = ['*']
for label, tag in all_labelled_tags.items():
if any([fnmatch.fnmatch('{}/{}'.format(branch.name, label),
env_label) for env_label in desired_env_labels]):
Expand All @@ -158,7 +178,11 @@ def deploy_repo(repo, target, desired_env_labels=('*')):
os.symlink(label_target, label_location)

conda.install.package_cache_ = orig_package_cache_
conda.install.pkgs_dirs = orig_pkgs_dirs
if isinstance(orig_pkgs_dirs, property):
# Support conda>4.1
conda.base.context.Context.pkgs_dirs = orig_pkgs_dirs
else:
conda.install.pkgs_dirs = orig_pkgs_dirs


def configure_parser(parser):
Expand Down
2 changes: 2 additions & 0 deletions conda_gitenv/lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ def __init__(self, directory_to_lock):
"""
dirname, basename = os.path.split(directory_to_lock.rstrip(os.pathsep))
path = os.path.join(dirname, '.conda-lock_' + basename)
if not os.path.isdir(dirname):
os.makedirs(dirname)
return conda.lock.Locked.__init__(self, path)
8 changes: 7 additions & 1 deletion conda_gitenv/resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ def build_manifest_branches(repo):
continue
with open(spec_fname, 'r') as fh:
pkgs = resolve_spec(fh)
# Cache the contents of the env.spec file from the source branch.
fh.seek(0)
spec_lines = fh.readlines()
manifest_branch_name = '{}{}'.format(manifest_branch_prefix, name)
if manifest_branch_name in repo.branches:
manifest_branch = repo.branches[manifest_branch_name]
Expand All @@ -69,7 +72,10 @@ def build_manifest_branches(repo):
manifest_path = os.path.join(repo.working_dir, 'env.manifest')
with open(manifest_path, 'w') as fh:
fh.write('\n'.join(pkgs))
repo.index.add([manifest_path])
# Write the env.spec from the source branch into the manifest branch.
with open(spec_fname, 'w') as fh:
fh.writelines(spec_lines)
repo.index.add([manifest_path, spec_fname])
if repo.is_dirty():
repo.index.commit('Manifest update from {:%Y-%m-%d %H:%M:%S}.'
''.format(datetime.datetime.now()))
Expand Down
10 changes: 6 additions & 4 deletions conda_gitenv/tests/integration/setup_samples.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,20 @@ def add_env(repo, name, spec):
return branch


def update_env(repo, branch, spec):
def update_env(repo, branch, spec, comment=None):
branch.checkout()
env_spec = os.path.join(repo.working_dir, 'env.spec')
with open(env_spec, 'w') as fh:
fh.write(textwrap.dedent(spec))
repo.index.add([env_spec])
repo.index.commit('Add {} spec'.format(branch.name))
if comment is None:
comment = 'Add {} spec'.format(branch.name)
repo.index.commit(comment)


def basic_repo():
def basic_repo(name='basic'):
# The simplest kind of repo. One env defined under the name "master"
repo = create_repo('basic')
repo = create_repo(name)
branch = add_env(repo, 'master', """
env:
- python
Expand Down
38 changes: 34 additions & 4 deletions conda_gitenv/tests/integration/test_resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,48 @@


class Test_full_build(unittest.TestCase):
def test_basic_env(self):
repo = setup_samples.basic_repo()
def check_env(self, name):
repo = setup_samples.basic_repo(name)
self.assertNotIn('manifest/master', repo.branches)
check_call(['conda', 'gitenv', 'resolve', repo.working_dir])
self.assertIn('manifest/master', repo.branches)
manifest_branch = repo.branches['manifest/master']
manifest_branch.checkout()
with open(os.path.join(repo.working_dir, 'env.manifest'), 'r') as fh:
manifest_contents = fh.readlines()
pkg_names = [pkg.split('\t', 1)[1].split('-')[0] for pkg in manifest_contents]
env_manifest = fh.readlines()
pkg_names = [pkg.split('\t', 1)[1].split('-')[0]
for pkg in env_manifest]
self.assertIn('python', pkg_names)
self.assertIn('zlib', pkg_names)
return repo

def test_env_basic(self):
self.check_env('basic')

def test_env_update(self):
repo = self.check_env('update')
master = repo.branches['master']
spec = """
env:
- python
- numpy
channels:
- defaults
"""
comment = 'Update the env.spec'
setup_samples.update_env(repo, master, spec, comment)
self.assertIn('manifest/master', repo.branches)
check_call(['conda', 'gitenv', 'resolve', repo.working_dir])
manifest = repo.branches['manifest/master']
manifest.checkout()
with open(os.path.join(repo.working_dir, 'env.manifest'), 'r') as fh:
env_manifest = fh.readlines()
pkg_names = [pkg.split('\t', 1)[1].split('-')[0]
for pkg in env_manifest]
self.assertIn('numpy', pkg_names)
with open(os.path.join(repo.working_dir, 'env.spec'), 'r') as fh:
env_spec = [entry.strip() for entry in fh.readlines()]
self.assertIn('- numpy', env_spec)


if __name__ == '__main__':
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
gitpython
pyyaml
conda-build-all
conda-build-all !=1.0.2
conda-build ==2.0.6
requests !=2.12.0
requests <2.12.0

0 comments on commit 2baea8c

Please sign in to comment.