Skip to content

Commit

Permalink
Enable easy local testing of mulled-build (bioconda#8537)
Browse files Browse the repository at this point in the history
* be very specific about which conda

* add default env vars

* clean up miniconda.sh when done

* only fetch when not bootstrapping

* add bootstrap.py

* build bump to test code changes

* revert build number bump
  • Loading branch information
daler authored Apr 5, 2018
1 parent 252c409 commit 063d3d1
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 11 deletions.
29 changes: 18 additions & 11 deletions .circleci/setup.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#!/bin/bash
set -eu

WORKSPACE=`pwd`
set +u
[[ -z $WORKSPACE ]] && WORKSPACE=`pwd`
[[ -z $BASH_ENV ]] && BASH_ENV=`tempfile`
[[ -z $BOOTSTRAP ]] && BOOTSTRAP=false
set -u

# Common definitions from latest bioconda-utils master have to be downloaded before setup.sh is executed.
# This file can be used to set BIOCONDA_UTILS_TAG and MINICONDA_VER.
Expand Down Expand Up @@ -30,7 +34,7 @@ if [[ $OSTYPE == linux* && ${CIRCLE_JOB-} != build ]]; then
docker tag continuumio/miniconda3:4.3.27 continuumio/miniconda3:latest
fi

if ! type bioconda-utils > /dev/null; then
if ! type bioconda-utils > /dev/null || [[ $BOOTSTRAP == "true" ]]; then
echo "Setting up bioconda-utils..."

# setup conda and bioconda-utils if not loaded from cache
Expand All @@ -49,22 +53,25 @@ if ! type bioconda-utils > /dev/null; then
bash miniconda.sh -b -p $WORKSPACE/miniconda

# step 2: setup channels
conda config --system --add channels defaults
conda config --system --add channels conda-forge
conda config --system --add channels bioconda
$WORKSPACE/miniconda/bin/conda config --system --add channels defaults
$WORKSPACE/miniconda/bin/conda config --system --add channels conda-forge
$WORKSPACE/miniconda/bin/conda config --system --add channels bioconda

# step 3: install bioconda-utils
conda install -y git pip --file https://raw.githubusercontent.com/bioconda/bioconda-utils/$BIOCONDA_UTILS_TAG/bioconda_utils/bioconda_utils-requirements.txt
pip install git+https://github.com/bioconda/bioconda-utils.git@$BIOCONDA_UTILS_TAG
$WORKSPACE/miniconda/bin/conda install -y git pip --file https://raw.githubusercontent.com/bioconda/bioconda-utils/$BIOCONDA_UTILS_TAG/bioconda_utils/bioconda_utils-requirements.txt
$WORKSPACE/miniconda/bin/pip install git+https://github.com/bioconda/bioconda-utils.git@$BIOCONDA_UTILS_TAG

# step 4: configure local channel
conda index $WORKSPACE/miniconda/conda-bld/linux-64 $WORKSPACE/miniconda/conda-bld/osx-64 $WORKSPACE/miniconda/conda-bld/noarch
conda config --system --add channels file://$WORKSPACE/miniconda/conda-bld
$WORKSPACE/miniconda/bin/conda index $WORKSPACE/miniconda/conda-bld/linux-64 $WORKSPACE/miniconda/conda-bld/osx-64 $WORKSPACE/miniconda/conda-bld/noarch
$WORKSPACE/miniconda/bin/conda config --system --add channels file://$WORKSPACE/miniconda/conda-bld

# step 5: cleanup
conda clean -y --all
$WORKSPACE/miniconda/bin/conda clean -y --all
rm miniconda.sh
fi

# Fetch the master branch for comparison (this can fail locally, if git remote
# is configured via ssh and this is executed in a container).
git fetch origin +master:master || true
if [[ $BOOTSTRAP != "true" ]]; then
git fetch origin +master:master || true
fi
112 changes: 112 additions & 0 deletions bootstrap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#!/usr/bin/env python

import os
import sys
import subprocess as sp
import argparse

if sys.version_info.major == 3:
PY3 = True
from urllib.request import urlretrieve

else:
PY3 = True
from urllib import urlretrieve

usage = """
The easy way to test recipes is by using `circleci build`. However this does
not allow local testing recipes using mulled-build (due to the technicalities
of running docker within docker and the CircleCI client).
This script makes it easy to do mulled-build tests. It works by using the same
code used in the .circleci/setup.sh script to build an isolated Miniconda
environment and a custom `activate` script.
Set up the environment like this:
./bootstrap.py /tmp/miniconda
It creates an activate script at ~/.config/bioconda/activate. So you can then use:
source ~/.config/bioconda/activate
and then use that isolated root environment independent of any other conda
installations you might have.
"""

ap = argparse.ArgumentParser(usage)
ap.add_argument('bootstrap', help='''Location to which a new Miniconda
installation plus bioconda-utils should be installed. This will
be separate from any existing conda installations.''')
args = ap.parse_args()

# This is the "common" step in the CircleCI config which gets the versions of
# Miniconda and bioconda-utils that we're using.
urlretrieve(
'https://raw.githubusercontent.com/bioconda/bioconda-common/master/common.sh',
filename='.circleci/common.sh')


local_config_path = os.path.expanduser('~/.config/bioconda/activate')

def _write_custom_activate(install_path):
"""
Once the isolated Miniconda version has been installed, copy its activate
script over to a custom location, and then hard-code the paths and PS1. We
don't need a matching `deactivate` because the activate script properly
keeps track of the new location.
"""
config_dir = os.path.dirname(local_config_path)
if not os.path.exists(config_dir):
os.makedirs(config_dir)

activate = os.path.join(install_path, 'miniconda/bin/activate')
lines = [i.rstrip() for i in open(activate)]

# Exact matches to lines we want to replace in the activate script, leading
# space included.
substitutions = [
(
'_CONDA_DIR=$(dirname "$_SCRIPT_LOCATION")',
'_CONDA_DIR="{0}/miniconda/bin"'.format(install_path)
),
(
' export PS1="(${CONDA_DEFAULT_ENV}) $PS1"',
' export PS1="(BIOCONDA-UTILS) $PS1"',
)
]

for orig, sub in substitutions:
# Be very picky so that we'll know if/when the activate script changes.
try:
pos = lines.index(orig)
except ValueError:
raise ValueError(
"Expecting '{0}' to be in {1} but couldn't find it"
.format(orig, activate)
)
lines[pos] = sub

with open(local_config_path, 'w') as fout:
for line in lines:
fout.write(line + '\n')


env = {'WORKSPACE': args.bootstrap, 'BOOTSTRAP': "true"}
sp.check_call(['.circleci/setup.sh'], env=env)
_write_custom_activate(args.bootstrap)

print("""
An isolated version of bioconda-utils has been installed to {1}. This is
separate from any other conda installations you might have.
To use it, source this custom activate script:
source ~/.config/bioconda/activate
When done:
source deactivate
""")

0 comments on commit 063d3d1

Please sign in to comment.