Skip to content

Commit

Permalink
Merge pull request #63 from chenruduan/master
Browse files Browse the repository at this point in the history
Modularize Travis CI workflow
  • Loading branch information
ralf-meyer authored Apr 26, 2022
2 parents 26896b2 + c75fa73 commit b83ade6
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 44 deletions.
70 changes: 29 additions & 41 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,49 +1,37 @@
dist: xenial
language: python
python:
# We don't actually use the Travis Python, but this keeps it organized.
- "3.6"

# Run jobs on container-based infrastructure, can be overridden per job

matrix:
include:
# Extra includes for OSX since python language is not available by default on OSX
- os: linux
language: generic # No need to set Python version since its conda
env: PYTHON_VER=3.7

before_install:
# Additional info about the build
- uname -a
- df -h
- ulimit -a

# Install the Python environment
- source devtools/travis-ci/before_install.sh
- python -V

install:
- sudo apt-get update
# We do this conditionally because it saves us some downloading if the
# version is the same.
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
wget https://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh -O miniconda.sh;
else
wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh;
fi
- bash miniconda.sh -b -p $HOME/miniconda
- export PATH="$HOME/miniconda/bin:$PATH"
- hash -r
- conda config --set always_yes yes --set changeps1 no
- conda update -q conda
# - conda install conda-build
# Useful for debugging any issues with conda
- conda info -a

# Replace dep1 dep2 ... with your dependencies
- conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION
- source activate test-environment
- conda config --add channels hjkgroup
- conda config --add channels anaconda
- conda config --add channels conda-forge
- conda config --add channels defaults
- conda install pyyaml
- conda install tensorflow=1.14.0
- conda install keras=2.3.1
- conda install pandas
- conda install scikit-learn=0.20.3
- conda install xtb
- conda install -c hjkgroup openbabel
# - conda build conda-recipe -c hjkgroup
- conda install molsimplify --use-local
# Needed for testing without Pybrain
- conda install pytest

# Create test environment for package
- python devtools/scripts/create_conda_env.py -n=mols_test -p=$PYTHON_VER devtools/conda-envs/mols.yml
# Activate the test environment
- conda activate mols_test
# Build and install package
- pip install -e .


script:
# Your test script goes here
- python setup.py test
# - molsimplify -h
- molsimplify -h

notifications:
slack:
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ We currently recommend installation via the [Conda](https://conda.io/docs/) pack
git clone https://github.com/hjkgrp/molSimplify.git
```

3. Go to the folder root folder for molSimplify, create the conda environment from the yaml file (`conda_envs/mols.yml`). **For M1 Macs, use mols_m1.yml instead.** This step will help you get all the dependencies correct in a newly created conda environment named "mols_test". You can specify a different name for this environment at the first line of the yaml file.
3. Go to the folder root folder for molSimplify, create the conda environment from the yaml file (`devtools/conda-envs/mols.yml`). **For M1 Macs, use** `mols_m1.yml` **instead.** This step will help you get all the dependencies correct in a newly created conda environment named "mols_test". You can specify a different name for this environment at the first line of the yaml file.

```bash
cd molSimplify/conda-envs
cd molSimplify/devtools/conda-envs
conda env create -f mols.yml
```
4. Activate the conda environment you just created. Go back to the root directory of molSimplify (where the setup.py file locates). Local install with pip.
Expand All @@ -29,7 +29,7 @@ We currently recommend installation via the [Conda](https://conda.io/docs/) pack
cd ..
pip install -e .
```
5. **(For M1 Macs only)** Install the M1-compatible version of Tensorflow by running `source conda_envs/install_tensorflow_m1.sh`.
5. **(For M1 Macs only)** Install the M1-compatible version of Tensorflow by running `source devtools/conda-envs/install_tensorflow_m1.sh`.
6. To test your installation, you can run the command below at the root directory of molSimplify. You are good to go if all the tests are passed!
```bash
python setup.py test
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
96 changes: 96 additions & 0 deletions devtools/scripts/create_conda_env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import argparse
import os
import re
import glob
import shutil
import subprocess as sp
from tempfile import TemporaryDirectory
from contextlib import contextmanager
# YAML imports
try:
import yaml # PyYAML
loader = yaml.safe_load
except ImportError:
try:
import ruamel_yaml as yaml # Ruamel YAML
except ImportError:
try:
# Load Ruamel YAML from the base conda environment
from importlib import util as import_util
CONDA_BIN = os.path.dirname(os.environ['CONDA_EXE'])
ruamel_yaml_path = glob.glob(os.path.join(CONDA_BIN, '..',
'lib', 'python*.*', 'site-packages',
'ruamel_yaml', '__init__.py'))[0]
# Based on importlib example, but only needs to load_module since its the whole package, not just
# a module
spec = import_util.spec_from_file_location('ruamel_yaml', ruamel_yaml_path)
yaml = spec.loader.load_module()
except (KeyError, ImportError, IndexError):
raise ImportError("No YAML parser could be found in this or the conda environment. "
"Could not find PyYAML or Ruamel YAML in the current environment, "
"AND could not find Ruamel YAML in the base conda environment through CONDA_EXE path. "
"Environment not created!")
loader = yaml.YAML(typ="safe").load # typ="safe" avoids odd typing on output


@contextmanager
def temp_cd():
"""Temporary CD Helper"""
cwd = os.getcwd()
with TemporaryDirectory() as td:
try:
os.chdir(td)
yield
finally:
os.chdir(cwd)


# Args
parser = argparse.ArgumentParser(description='Creates a conda environment from file for a given Python version.')
parser.add_argument('-n', '--name', type=str,
help='The name of the created Python environment')
parser.add_argument('-p', '--python', type=str,
help='The version of the created Python environment')
parser.add_argument('conda_file',
help='The file for the created Python environment')

args = parser.parse_args()

# Open the base file
with open(args.conda_file, "r") as handle:
yaml_script = loader(handle.read())
print("YAML SCRIPT: ", yaml_script)

python_replacement_string = "python {}*".format(args.python)

try:
for dep_index, dep_value in enumerate(yaml_script['dependencies']):
if re.match('python([ ><=*]+[0-9.*]*)?$', dep_value): # Match explicitly 'python' and its formats
yaml_script['dependencies'].pop(dep_index)
break # Making the assumption there is only one Python entry, also avoids need to enumerate in reverse
except (KeyError, TypeError):
# Case of no dependencies key, or dependencies: None
yaml_script['dependencies'] = []
finally:
# Ensure the python version is added in. Even if the code does not need it, we assume the env does
yaml_script['dependencies'].insert(0, python_replacement_string)

# Figure out conda path
if "CONDA_EXE" in os.environ:
conda_path = os.environ["CONDA_EXE"]
else:
conda_path = shutil.which("conda")
if conda_path is None:
raise RuntimeError("Could not find a conda binary in CONDA_EXE variable or in executable search path")

print("CONDA ENV NAME {}".format(args.name))
print("PYTHON VERSION {}".format(args.python))
print("CONDA FILE NAME {}".format(args.conda_file))
print("CONDA PATH {}".format(conda_path))

# Write to a temp directory which will always be cleaned up
with temp_cd():
temp_file_name = "temp_script.yaml"
with open(temp_file_name, 'w') as f:
f.write(yaml.dump(yaml_script))
sp.call("{} env create -n {} -f {}".format(conda_path, args.name, temp_file_name), shell=True)
41 changes: 41 additions & 0 deletions devtools/travis-ci/before_install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Temporarily change directory to $HOME to install software
pushd .
cd $HOME
# Make sure some level of pip is installed
python -m ensurepip

# Install Miniconda
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
# Make OSX md5 mimic md5sum from linux, alias does not work
md5sum () {
command md5 -r "$@"
}
MINICONDA=Miniconda3-latest-MacOSX-x86_64.sh
else
MINICONDA=Miniconda3-latest-Linux-x86_64.sh
fi
MINICONDA_HOME=$HOME/miniconda
MINICONDA_MD5=$(wget -qO- https://repo.anaconda.com/miniconda/ | grep -A3 $MINICONDA | sed -n '4p' | sed -n 's/ *<td>\(.*\)<\/td> */\1/p')
wget -q https://repo.anaconda.com/miniconda/$MINICONDA
if [[ $MINICONDA_MD5 != $(md5sum $MINICONDA | cut -d ' ' -f 1) ]]; then
echo "Miniconda MD5 mismatch"
exit 1
fi
bash $MINICONDA -b -p $MINICONDA_HOME

# Configure miniconda
export PIP_ARGS="-U"
# New to conda >=4.4
echo ". $MINICONDA_HOME/etc/profile.d/conda.sh" >> ~/.bashrc # Source the profile.d file
echo "conda activate" >> ~/.bashrc # Activate conda
source ~/.bashrc # source file to get new commands
#export PATH=$MINICONDA_HOME/bin:$PATH # Old way, should not be needed anymore

conda config --add channels conda-forge

conda config --set always_yes yes
conda install conda conda-build jinja2 anaconda-client
conda update --quiet --all

# Restore original directory
popd

0 comments on commit b83ade6

Please sign in to comment.