diff --git a/.circle/codecov.sh b/.circle/codecov.sh index 84df39c1c2..c71cf1c6f5 100644 --- a/.circle/codecov.sh +++ b/.circle/codecov.sh @@ -9,17 +9,17 @@ set -e # Exit immediately if a command exits with a non-zero status. set -u # Treat unset variables as an error when substituting. set -x # Print command traces before executing command. +mkdir -p ${CIRCLE_TEST_REPORTS}/ +for report in $( ls ~/scratch/*.xml ); do + rname=$( basename $report ) + cp ${report} ${CIRCLE_TEST_REPORTS}/${rname:: -4}_${CIRCLE_NODE_INDEX}.xml +done + # Send coverage data to codecov.io curl -so codecov.io https://codecov.io/bash chmod 755 codecov.io -find "${WORKDIR}/" -name 'coverage*.xml' -maxdepth 1 -print0 | \ +find "${CIRCLE_TEST_REPORTS}/" -name 'coverage*.xml' -print0 | \ xargs -0 -I file ./codecov.io -f file -t "${CODECOV_TOKEN}" -F unittests -find "${WORKDIR}/" -name 'smoketest*.xml' -maxdepth 1 -print0 | \ +find "${CIRCLE_TEST_REPORTS}/" -name 'smoketests*.xml' -print0 | \ xargs -0 -I file ./codecov.io -f file -t "${CODECOV_TOKEN}" -F smoketests - -# Place test and coverage in the tests folder -mkdir -p ${CIRCLE_TEST_REPORTS}/tests/ -cp ${WORKDIR}/pytest*.xml ${CIRCLE_TEST_REPORTS}/tests/ || true -cp ${WORKDIR}/coverage*.xml ${CIRCLE_TEST_REPORTS}/tests/ || true -cp ${WORKDIR}/smoketest*.xml ${CIRCLE_TEST_REPORTS}/tests/ || true diff --git a/.circle/tests.sh b/.circle/tests.sh index 51a7957259..602dddca8b 100644 --- a/.circle/tests.sh +++ b/.circle/tests.sh @@ -17,23 +17,23 @@ fi # They may need to be rebalanced in the future. case ${CIRCLE_NODE_INDEX} in 0) - docker run --rm -it -e FSL_COURSE_DATA="/data/examples/nipype-fsl_course_data" -v $HOME/examples:/data/examples:ro -v $WORKDIR:/work -w /src/nipype nipype/nipype:py27 /usr/bin/run_pytests.sh py27 && \ - docker run --rm -it -e FSL_COURSE_DATA="/data/examples/nipype-fsl_course_data" -v $HOME/examples:/data/examples:ro -v $WORKDIR:/work -w /src/nipype nipype/nipype:py35 /usr/bin/run_pytests.sh py35 && \ - docker run --rm -it -v $WORKDIR:/work -w /src/nipype/doc nipype/nipype:py35 /usr/bin/run_builddocs.sh && \ - docker run --rm -it -v $HOME/examples:/data/examples:ro -v $WORKDIR:/work -w /work nipype/nipype:py35 /usr/bin/run_examples.sh test_spm Linear /data/examples/ workflow3d && \ - docker run --rm -it -v $HOME/examples:/data/examples:ro -v $WORKDIR:/work -w /work nipype/nipype:py35 /usr/bin/run_examples.sh test_spm Linear /data/examples/ workflow4d + docker run --rm -it -e FSL_COURSE_DATA="/root/examples/nipype-fsl_course_data" -v $HOME/examples:/root/examples:ro -v $SCRATCH:/scratch -w /root/src/nipype nipype/nipype_test:py27 /usr/bin/run_pytests.sh py27 && \ + docker run --rm -it -e FSL_COURSE_DATA="/root/examples/nipype-fsl_course_data" -v $HOME/examples:/root/examples:ro -v $SCRATCH:/scratch -w /root/src/nipype nipype/nipype_test:py35 /usr/bin/run_pytests.sh py35 && \ + docker run --rm -it -v $SCRATCH:/scratch -w /root/src/nipype/doc nipype/nipype_test:py35 /usr/bin/run_builddocs.sh && \ + docker run --rm -it -v $HOME/examples:/root/examples:ro -v $SCRATCH:/scratch -w /scratch nipype/nipype_test:py35 /usr/bin/run_examples.sh test_spm Linear /root/examples/ workflow3d && \ + docker run --rm -it -v $HOME/examples:/root/examples:ro -v $SCRATCH:/scratch -w /scratch nipype/nipype_test:py35 /usr/bin/run_examples.sh test_spm Linear /root/examples/ workflow4d ;; 1) - docker run --rm -it -v $HOME/examples:/data/examples:ro -v $WORKDIR:/work -w /work nipype/nipype:py35 /usr/bin/run_examples.sh fmri_spm_dartel Linear /data/examples/ level1 && \ - docker run --rm -it -v $HOME/examples:/data/examples:ro -v $WORKDIR:/work -w /work nipype/nipype:py35 /usr/bin/run_examples.sh fmri_spm_dartel Linear /data/examples/ l2pipeline + docker run --rm -it -v $HOME/examples:/root/examples:ro -v $SCRATCH:/scratch -w /scratch nipype/nipype_test:py35 /usr/bin/run_examples.sh fmri_spm_dartel Linear /root/examples/ level1 && \ + docker run --rm -it -v $HOME/examples:/root/examples:ro -v $SCRATCH:/scratch -w /scratch nipype/nipype_test:py35 /usr/bin/run_examples.sh fmri_spm_dartel Linear /root/examples/ l2pipeline ;; 2) - docker run --rm -it -e NIPYPE_NUMBER_OF_CPUS=4 -v $HOME/examples:/data/examples:ro -v $WORKDIR:/work -w /work nipype/nipype:py27 /usr/bin/run_examples.sh fmri_spm_nested MultiProc /data/examples/ level1 && \ - docker run --rm -it -e NIPYPE_NUMBER_OF_CPUS=4 -v $HOME/examples:/data/examples:ro -v $WORKDIR:/work -w /work nipype/nipype:py35 /usr/bin/run_examples.sh fmri_spm_nested MultiProc /data/examples/ l2pipeline + docker run --rm -it -e NIPYPE_NUMBER_OF_CPUS=4 -v $HOME/examples:/root/examples:ro -v $SCRATCH:/scratch -w /scratch nipype/nipype_test:py27 /usr/bin/run_examples.sh fmri_spm_nested MultiProc /root/examples/ level1 && \ + docker run --rm -it -e NIPYPE_NUMBER_OF_CPUS=4 -v $HOME/examples:/root/examples:ro -v $SCRATCH:/scratch -w /scratch nipype/nipype_test:py35 /usr/bin/run_examples.sh fmri_spm_nested MultiProc /root/examples/ l2pipeline ;; 3) - docker run --rm -it -e NIPYPE_NUMBER_OF_CPUS=4 -v $HOME/examples:/data/examples:ro -v $WORKDIR:/work -w /work nipype/nipype:py35 /usr/bin/run_examples.sh fmri_spm_nested MultiProc /data/examples/ level1 && \ - docker run --rm -it -v $HOME/examples:/data/examples:ro -v $WORKDIR:/work -w /work nipype/nipype:py35 /usr/bin/run_examples.sh fmri_fsl_feeds Linear /data/examples/ l1pipeline && \ - docker run --rm -it -v $HOME/examples:/data/examples:ro -v $WORKDIR:/work -w /work nipype/nipype:py35 /usr/bin/run_examples.sh fmri_fsl_reuse Linear /data/examples/ level1_workflow + docker run --rm -it -e NIPYPE_NUMBER_OF_CPUS=4 -v $HOME/examples:/root/examples:ro -v $SCRATCH:/scratch -w /scratch nipype/nipype_test:py35 /usr/bin/run_examples.sh fmri_spm_nested MultiProc /root/examples/ level1 && \ + docker run --rm -it -v $HOME/examples:/root/examples:ro -v $SCRATCH:/scratch -w /scratch nipype/nipype_test:py35 /usr/bin/run_examples.sh fmri_fsl_feeds Linear /root/examples/ l1pipeline && \ + docker run --rm -it -v $HOME/examples:/root/examples:ro -v $SCRATCH:/scratch -w /scratch nipype/nipype_test:py35 /usr/bin/run_examples.sh fmri_fsl_reuse Linear /root/examples/ level1_workflow ;; esac diff --git a/.coveragerc b/.coveragerc index 80af6f0119..c69c0eef3c 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,5 +1,6 @@ [run] branch = True +source = nipype include = */nipype/* omit = */nipype/external/* diff --git a/Dockerfile b/Dockerfile index 3dd2a98ff9..bca876526b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,70 +30,191 @@ # # Based on https://github.com/poldracklab/fmriprep/blob/9c92a3de9112f8ef1655b876de060a2ad336ffb0/Dockerfile # -FROM nipype/base:latest +FROM ubuntu:xenial-20161213 MAINTAINER The nipype developers https://github.com/nipy/nipype -ARG PYTHON_VERSION_MAJOR=3 +ARG DEBIAN_FRONTEND=noninteractive + +# Pre-cache neurodebian key +COPY docker/files/neurodebian.gpg /root/.neurodebian.gpg + +# Prepare environment +RUN apt-key add /root/.neurodebian.gpg && \ + apt-get update && \ + apt-get install -y --no-install-recommends curl bzip2 ca-certificates xvfb && \ + curl -sSL http://neuro.debian.net/lists/xenial.us-ca.full >> /etc/apt/sources.list.d/neurodebian.sources.list && \ + apt-key adv --refresh-keys --keyserver hkp://ha.pool.sks-keyservers.net 0xA5D32F012649A5A9 || true; \ + apt-get update + +# Installing freesurfer +RUN curl -sSL https://surfer.nmr.mgh.harvard.edu/pub/dist/freesurfer/6.0.0/freesurfer-Linux-centos6_x86_64-stable-pub-v6.0.0.tar.gz | tar zxv -C /opt \ + --exclude='freesurfer/trctrain' \ + --exclude='freesurfer/subjects/fsaverage_sym' \ + --exclude='freesurfer/subjects/fsaverage3' \ + --exclude='freesurfer/subjects/fsaverage4' \ + --exclude='freesurfer/subjects/fsaverage5' \ + --exclude='freesurfer/subjects/fsaverage6' \ + --exclude='freesurfer/subjects/cvs_avg35' \ + --exclude='freesurfer/subjects/cvs_avg35_inMNI152' \ + --exclude='freesurfer/subjects/bert' \ + --exclude='freesurfer/subjects/V1_average' \ + --exclude='freesurfer/average/mult-comp-cor' \ + --exclude='freesurfer/lib/cuda' \ + --exclude='freesurfer/lib/qt' + +ENV FSL_DIR=/usr/share/fsl/5.0 \ + OS=Linux \ + FS_OVERRIDE=0 \ + FIX_VERTEX_AREA= \ + FSF_OUTPUT_FORMAT=nii.gz \ + FREESURFER_HOME=/opt/freesurfer +ENV SUBJECTS_DIR=$FREESURFER_HOME/subjects \ + FUNCTIONALS_DIR=$FREESURFER_HOME/sessions \ + MNI_DIR=$FREESURFER_HOME/mni \ + LOCAL_DIR=$FREESURFER_HOME/local \ + FSFAST_HOME=$FREESURFER_HOME/fsfast \ + MINC_BIN_DIR=$FREESURFER_HOME/mni/bin \ + MINC_LIB_DIR=$FREESURFER_HOME/mni/lib \ + MNI_DATAPATH=$FREESURFER_HOME/mni/data \ + FMRI_ANALYSIS_DIR=$FREESURFER_HOME/fsfast +ENV PERL5LIB=$MINC_LIB_DIR/perl5/5.8.5 \ + MNI_PERL5LIB=$MINC_LIB_DIR/perl5/5.8.5 \ + PATH=$FREESURFER_HOME/bin:$FSFAST_HOME/bin:$FREESURFER_HOME/tktools:$MINC_BIN_DIR:$PATH +RUN echo "cHJpbnRmICJrcnp5c3p0b2YuZ29yZ29sZXdza2lAZ21haWwuY29tXG41MTcyXG4gKkN2dW12RVYzelRmZ1xuRlM1Si8yYzFhZ2c0RVxuIiA+IC9vcHQvZnJlZXN1cmZlci9saWNlbnNlLnR4dAo=" | base64 -d | sh + +# Installing Neurodebian packages (FSL, AFNI, git) +RUN apt-get install -y --no-install-recommends \ + fsl-core=5.0.9-1~nd+1+nd16.04+1 \ + fsl-mni152-templates=5.0.7-2 \ + afni=16.2.07~dfsg.1-2~nd16.04+1 + +ENV FSLDIR=/usr/share/fsl/5.0 \ + FSLOUTPUTTYPE=NIFTI_GZ \ + FSLMULTIFILEQUIT=TRUE \ + POSSUMDIR=/usr/share/fsl/5.0 \ + LD_LIBRARY_PATH=/usr/lib/fsl/5.0:$LD_LIBRARY_PATH \ + FSLTCLSH=/usr/bin/tclsh \ + FSLWISH=/usr/bin/wish \ + AFNI_MODELPATH=/usr/lib/afni/models \ + AFNI_IMSAVE_WARNINGS=NO \ + AFNI_TTATLAS_DATASET=/usr/share/afni/atlases \ + AFNI_PLUGINPATH=/usr/lib/afni/plugins \ + PATH=/usr/lib/fsl/5.0:/usr/lib/afni/bin:$PATH + +# Installing and setting up ANTs +RUN mkdir -p /opt/ants && \ + curl -sSL "https://github.com/stnava/ANTs/releases/download/v2.1.0/Linux_Ubuntu14.04.tar.bz2" \ + | tar -xjC /opt/ants --strip-components 1 + +ENV ANTSPATH=/opt/ants \ + PATH=$ANTSPATH:$PATH + +# Installing and setting up c3d +RUN mkdir -p /opt/c3d && \ + curl -sSL "http://downloads.sourceforge.net/project/c3d/c3d/1.0.0/c3d-1.0.0-Linux-x86_64.tar.gz" \ + | tar -xzC /opt/c3d --strip-components 1 + +ENV C3DPATH=/opt/c3d/ \ + PATH=$C3DPATH/bin:$PATH + +# Install some other required tools +RUN apt-get install -y --no-install-recommends \ + git=1:2.7.4-0ubuntu1 \ + graphviz=2.38.0-12ubuntu2 \ + unzip \ + apt-utils \ + fusefat \ + make \ + ruby=1:2.3.0+1 && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +# Install fake-S3 +ENV GEM_HOME /usr/lib/ruby/gems/2.3 +ENV BUNDLE_PATH="$GEM_HOME" \ + BUNDLE_BIN="$GEM_HOME/bin" \ + BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $BUNDLE_BIN:$PATH +RUN mkdir -p "$GEM_HOME" "$BUNDLE_BIN" && \ + chmod 777 "$GEM_HOME" "$BUNDLE_BIN" + +RUN gem install fakes3 + +# Install Matlab MCR: from the good old install_spm_mcr.sh of @chrisfilo +WORKDIR /opt +RUN echo "destinationFolder=/opt/mcr" > mcr_options.txt && \ + echo "agreeToLicense=yes" >> mcr_options.txt && \ + echo "outputFile=/tmp/matlabinstall_log" >> mcr_options.txt && \ + echo "mode=silent" >> mcr_options.txt && \ + mkdir -p matlab_installer && \ + curl -sSL http://www.mathworks.com/supportfiles/downloads/R2015a/deployment_files/R2015a/installers/glnxa64/MCR_R2015a_glnxa64_installer.zip \ + -o matlab_installer/installer.zip && \ + unzip matlab_installer/installer.zip -d matlab_installer/ && \ + matlab_installer/install -inputFile mcr_options.txt && \ + rm -rf matlab_installer mcr_options.txt + +# Install SPM +RUN curl -sSL http://www.fil.ion.ucl.ac.uk/spm/download/restricted/utopia/dev/spm12_r6472_Linux_R2015a.zip -o spm12.zip && \ + unzip spm12.zip && \ + rm -rf spm12.zip + +ENV MATLABCMD="/opt/mcr/v85/toolbox/matlab" \ + SPMMCRCMD="/opt/spm12/run_spm12.sh /opt/mcr/v85/ script" \ + FORCE_SPMMCR=1 + # Installing and setting up miniconda -RUN curl -sSLO https://repo.continuum.io/miniconda/Miniconda${PYTHON_VERSION_MAJOR}-4.2.12-Linux-x86_64.sh && \ - bash Miniconda${PYTHON_VERSION_MAJOR}-4.2.12-Linux-x86_64.sh -b -p /usr/local/miniconda && \ - rm Miniconda${PYTHON_VERSION_MAJOR}-4.2.12-Linux-x86_64.sh +RUN curl -sSLO https://repo.continuum.io/miniconda/Miniconda3-4.2.12-Linux-x86_64.sh && \ + bash Miniconda3-4.2.12-Linux-x86_64.sh -b -p /usr/local/miniconda && \ + rm Miniconda3-4.2.12-Linux-x86_64.sh ENV PATH=/usr/local/miniconda/bin:$PATH \ LANG=C.UTF-8 \ LC_ALL=C.UTF-8 \ - ACCEPT_INTEL_PYTHON_EULA=yes \ - MKL_NUM_THREADS=1 \ - OMP_NUM_THREADS=1 -# MKL/OMP_NUM_THREADS: unless otherwise specified, each process should -# only use one thread - nipype will handle parallelization + ACCEPT_INTEL_PYTHON_EULA=yes # Installing precomputed python packages -ARG PYTHON_VERSION_MINOR=5 -RUN conda config --add channels conda-forge; sync && \ - conda config --set always_yes yes --set changeps1 no; sync && \ - conda install -y python=${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} \ - mkl \ - numpy \ - scipy \ - scikit-learn \ - matplotlib \ - pandas \ - libxml2 \ - libxslt \ +RUN conda config --add channels conda-forge --add channels intel && \ + chmod +x /usr/local/miniconda/bin/* && \ + conda config --set always_yes yes --set changeps1 no && \ + conda update -q conda && \ + chmod +x /usr/local/miniconda/bin/*; sync && \ + conda install -y mkl=2017.0.1 \ + numpy=1.11.2 \ + scipy=0.18.1 \ + scikit-learn=0.17.1 \ + matplotlib=1.5.3 \ + pandas=0.19.0 \ + libxml2=2.9.4 \ + libxslt=1.1.29 \ traits=4.6.0 \ - psutil \ + psutil=5.0.1 \ icu=58.1 && \ - sync; + find /usr/local/miniconda/ -exec chmod 775 {} + # matplotlib cleanups: set default backend, precaching fonts -RUN sed -i 's/\(backend *: \).*$/\1Agg/g' /usr/local/miniconda/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages/matplotlib/mpl-data/matplotlibrc && \ +RUN sed -i 's/\(backend *: \).*$/\1Agg/g' /usr/local/miniconda/lib/python3.5/site-packages/matplotlib/mpl-data/matplotlibrc && \ python -c "from matplotlib import font_manager" +# Unless otherwise specified each process should only use one thread - nipype +# will handle parallelization +ENV MKL_NUM_THREADS=1 \ + OMP_NUM_THREADS=1 + # Installing dev requirements (packages that are not in pypi) -WORKDIR /src/ +WORKDIR /root/ COPY requirements.txt requirements.txt RUN pip install -r requirements.txt && \ rm -rf ~/.cache/pip # Installing nipype -COPY . /src/nipype -RUN cd /src/nipype && \ +COPY . /root/src/nipype +RUN cd /root/src/nipype && \ pip install -e .[all] && \ rm -rf ~/.cache/pip -# Install CI scripts -COPY docker/files/run_* /usr/bin/ -RUN chmod +x /usr/bin/run_* - -# Replace imglob with a Python3 compatible version -COPY nipype/external/fsl_imglob.py /usr/bin/fsl_imglob.py -RUN rm -rf ${FSLDIR}/bin/imglob && \ - chmod +x /usr/bin/fsl_imglob.py && \ - ln -s /usr/bin/fsl_imglob.py ${FSLDIR}/bin/imglob - -WORKDIR /work/ +WORKDIR /root/ ARG BUILD_DATE ARG VCS_REF diff --git a/circle.yml b/circle.yml index 24eaed8e2d..ac27d71a56 100644 --- a/circle.yml +++ b/circle.yml @@ -7,7 +7,7 @@ machine: DATA_NIPYPE_TUTORIAL_URL: "${OSF_NIPYPE_URL}/57f4739cb83f6901ed94bf21" DATA_NIPYPE_FSL_COURSE: "${OSF_NIPYPE_URL}/57f472cf9ad5a101f977ecfe" DATA_NIPYPE_FSL_FEEDS: "${OSF_NIPYPE_URL}/57f473066c613b01f113e7af" - WORKDIR: "$HOME/work" + SCRATCH: "$HOME/scratch" CODECOV_TOKEN: "ac172a50-8e66-42e5-8822-5373fcf54686" services: - docker @@ -22,25 +22,24 @@ dependencies: # Let CircleCI cache the apt archive - mkdir -p ~/.apt-cache/partial && sudo rm -rf /var/cache/apt/archives && sudo ln -s ~/.apt-cache /var/cache/apt/archives - sudo apt-get -y update && sudo apt-get install -y wget bzip2 - # Create work folder and force group permissions - - mkdir -p $WORKDIR && sudo setfacl -d -m group:ubuntu:rwx $WORKDIR && sudo setfacl -m group:ubuntu:rwx $WORKDIR - - mkdir -p $HOME/docker $HOME/examples $WORKDIR/pytest $WORKDIR/logs + # Create scratch folder and force group permissions + - mkdir -p $SCRATCH && sudo setfacl -d -m group:ubuntu:rwx $SCRATCH && sudo setfacl -m group:ubuntu:rwx $SCRATCH + - mkdir -p $HOME/docker $HOME/examples $SCRATCH/pytest $SCRATCH/logs override: - - if [[ -e $HOME/docker/cache.tar ]]; then docker load --input $HOME/docker/cache.tar; fi : + - if [[ -e $HOME/docker/cache.tar ]]; then docker load --input $HOME/docker/cache.tar; else echo 'No docker image found in cache'; fi : timeout: 6000 - - docker images - - docker pull nipype/base:latest - if [[ ! -d ~/examples/nipype-tutorial ]]; then wget --retry-connrefused --waitretry=5 --read-timeout=20 --timeout=15 -t 0 -q -O nipype-tutorial.tar.bz2 "${DATA_NIPYPE_TUTORIAL_URL}" && tar xjf nipype-tutorial.tar.bz2 -C ~/examples/; fi - if [[ ! -d ~/examples/nipype-fsl_course_data ]]; then wget --retry-connrefused --waitretry=5 --read-timeout=20 --timeout=15 -t 0 -q -O nipype-fsl_course_data.tar.gz "${DATA_NIPYPE_FSL_COURSE}" && tar xzf nipype-fsl_course_data.tar.gz -C ~/examples/; fi - if [[ ! -d ~/examples/feeds ]]; then wget --retry-connrefused --waitretry=5 --read-timeout=20 --timeout=15 -t 0 -q -O fsl-5.0.9-feeds.tar.gz "${DATA_NIPYPE_FSL_FEEDS}" && tar xzf fsl-5.0.9-feeds.tar.gz -C ~/examples/; fi - - if [ "$CIRCLE_TAG" != "" ]; then sed -i -E "s/(__version__ = )'[A-Za-z0-9.-]+'/\1'$CIRCLE_TAG'/" nipype/info.py; fi -# - e=1 && for i in {1..5}; do docker build -f docker/base.Dockerfile --rm=false -t nipype/base:latest . && e=0 && break || sleep 15; done && [ "$e" -eq "0" ] : -# timeout: 21600 - - e=1 && for i in {1..5}; do docker build --rm=false -t nipype/nipype:latest -t nipype/nipype:py35 --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` --build-arg VCS_REF=`git rev-parse --short HEAD` --build-arg VERSION=$CIRCLE_TAG . && e=0 && break || sleep 15; done && [ "$e" -eq "0" ] : - timeout: 6000 - - e=1 && for i in {1..5}; do docker build --rm=false -t nipype/nipype:py27 --build-arg PYTHON_VERSION_MAJOR=2 --build-arg PYTHON_VERSION_MINOR=7 --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` --build-arg VCS_REF=`git rev-parse --short HEAD` --build-arg VERSION=$CIRCLE_TAG-py27 . && e=0 && break || sleep 15; done && [ "$e" -eq "0" ] : - timeout: 6000 - - docker save -o $HOME/docker/cache.tar nipype/base:latest nipype/nipype:py35 nipype/nipype:py27 : + - docker images + - sed -i -E "s/(__version__ = )'[A-Za-z0-9.-]+'/\1'$CIRCLE_TAG'/" nipype/info.py + - e=1 && for i in {1..5}; do docker build --rm=false -t nipype/nipype:latest --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` --build-arg VCS_REF=`git rev-parse --short HEAD` --build-arg VERSION=$CIRCLE_TAG . && e=0 && break || sleep 15; done && [ "$e" -eq "0" ] : + timeout: 21600 + - e=1 && for i in {1..5}; do docker build --rm=false -f docker/Dockerfile_py27 -t nipype/nipype_test:py27 . && e=0 && break || sleep 15; done && [ "$e" -eq "0" ] : + timeout: 1600 + - e=1 && for i in {1..5}; do docker build --rm=false -f docker/Dockerfile_py35 -t nipype/nipype_test:py35 . && e=0 && break || sleep 15; done && [ "$e" -eq "0" ] : + timeout: 1600 + - docker save -o $HOME/docker/cache.tar nipype/nipype:latest nipype/nipype_test:py27 nipype/nipype_test:py35 : timeout: 6000 test: @@ -54,14 +53,14 @@ test: general: artifacts: - - "~/work/docs" - - "~/work/logs" + - "~/scratch/docs" + - "~/scratch/logs" deployment: production: tag: /.*/ commands: - # Deploy to docker hub + # Deploy to docker hub - if [[ -n "$DOCKER_PASS" ]]; then docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS && docker push nipype/nipype:latest; fi : timeout: 21600 - if [[ -n "$DOCKER_PASS" ]]; then docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS && docker tag nipype/nipype nipype/nipype:$CIRCLE_TAG && docker push nipype/nipype:$CIRCLE_TAG; fi : diff --git a/docker/Dockerfile_py27 b/docker/Dockerfile_py27 new file mode 100644 index 0000000000..b1264294c3 --- /dev/null +++ b/docker/Dockerfile_py27 @@ -0,0 +1,47 @@ +# Copyright (c) 2016, The developers of nipype +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of crn_base nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +FROM nipype/nipype:latest +MAINTAINER The nipype developers https://github.com/nipy/nipype + +COPY docker/files/run_* /usr/bin/ +RUN chmod +x /usr/bin/run_* + +# Downgrade python to 2.7 +# matplotlib cleanups: set default backend, precaching fonts +RUN conda install python=2.7 && \ + find /usr/local/miniconda/ -exec chmod 775 {} + && \ + sed -i 's/\(backend *: \).*$/\1Agg/g' /usr/local/miniconda/lib/python2.7/site-packages/matplotlib/mpl-data/matplotlibrc && \ + python -c "from matplotlib import font_manager" + +# Re-install nipype +COPY . /root/src/nipype +RUN cd /root/src/nipype && \ + pip install -e .[all] + +CMD ["/bin/bash"] diff --git a/docker/Dockerfile_py34 b/docker/Dockerfile_py34 new file mode 100644 index 0000000000..88e84841e6 --- /dev/null +++ b/docker/Dockerfile_py34 @@ -0,0 +1,54 @@ +# Copyright (c) 2016, The developers of nipype +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of crn_base nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +FROM nipype/nipype:latest +MAINTAINER The nipype developers https://github.com/nipy/nipype + +# Downgrade python to 3.4 +RUN conda install python=3.4 && \ + conda update --all -y python=3.4 + +COPY docker/files/run_* /usr/bin/ +RUN chmod +x /usr/bin/run_* + +# Replace imglob with a Python3 compatible version +COPY nipype/external/fsl_imglob.py /usr/bin/fsl_imglob.py +RUN rm -r ${FSLDIR}/bin/imglob && \ + chmod +x /usr/bin/fsl_imglob.py && \ + ln -s /usr/bin/fsl_imglob.py ${FSLDIR}/bin/imglob + +# matplotlib cleanups: set default backend, precaching fonts +RUN sed -i 's/\(backend *: \).*$/\1Agg/g' /usr/local/miniconda/lib/python3.4/site-packages/matplotlib/mpl-data/matplotlibrc && \ + python -c "from matplotlib import font_manager" + +# Re-install nipype +COPY . /root/src/nipype +RUN cd /root/src/nipype && \ + pip install -e .[all] + +CMD ["/bin/bash"] \ No newline at end of file diff --git a/docker/Dockerfile_py35 b/docker/Dockerfile_py35 new file mode 100644 index 0000000000..f08c655941 --- /dev/null +++ b/docker/Dockerfile_py35 @@ -0,0 +1,42 @@ +# Copyright (c) 2016, The developers of nipype +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of crn_base nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +FROM nipype/nipype:latest +MAINTAINER The nipype developers https://github.com/nipy/nipype + +# Replace imglob with a Python3 compatible version +COPY nipype/external/fsl_imglob.py /usr/bin/fsl_imglob.py +RUN rm -r ${FSLDIR}/bin/imglob && \ + chmod +x /usr/bin/fsl_imglob.py && \ + ln -s /usr/bin/fsl_imglob.py ${FSLDIR}/bin/imglob +COPY docker/files/run_* /usr/bin/ +RUN chmod +x /usr/bin/run_* + +WORKDIR /root + +CMD ["/bin/bash"] diff --git a/docker/base.Dockerfile b/docker/base.Dockerfile deleted file mode 100644 index e21385e44c..0000000000 --- a/docker/base.Dockerfile +++ /dev/null @@ -1,170 +0,0 @@ -# Copyright (c) 2016, The developers of the Stanford CRN -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# * Neither the name of crn_base nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -# -# Based on https://github.com/poldracklab/fmriprep/blob/9c92a3de9112f8ef1655b876de060a2ad336ffb0/Dockerfile -# -FROM ubuntu:xenial-20161213 -MAINTAINER The nipype developers https://github.com/nipy/nipype - -# Set noninteractive -ENV DEBIAN_FRONTEND=noninteractive - -# Installing requirements for freesurfer installation -RUN apt-get update && \ - apt-get install -y --no-install-recommends curl ca-certificates && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -WORKDIR /opt -# Installing freesurfer -- do it first so that it is cached early -RUN curl -sSL https://surfer.nmr.mgh.harvard.edu/pub/dist/freesurfer/6.0.0/freesurfer-Linux-centos6_x86_64-stable-pub-v6.0.0.tar.gz | tar zxv -C /opt \ - --exclude='freesurfer/trctrain' \ - --exclude='freesurfer/subjects/fsaverage_sym' \ - --exclude='freesurfer/subjects/fsaverage3' \ - --exclude='freesurfer/subjects/fsaverage4' \ - --exclude='freesurfer/subjects/fsaverage5' \ - --exclude='freesurfer/subjects/fsaverage6' \ - --exclude='freesurfer/subjects/cvs_avg35' \ - --exclude='freesurfer/subjects/cvs_avg35_inMNI152' \ - --exclude='freesurfer/subjects/bert' \ - --exclude='freesurfer/subjects/V1_average' \ - --exclude='freesurfer/average/mult-comp-cor' \ - --exclude='freesurfer/lib/cuda' \ - --exclude='freesurfer/lib/qt' - -ENV FSL_DIR=/usr/share/fsl/5.0 \ - OS=Linux \ - FS_OVERRIDE=0 \ - FIX_VERTEX_AREA= \ - FSF_OUTPUT_FORMAT=nii.gz \ - FREESURFER_HOME=/opt/freesurfer -ENV SUBJECTS_DIR=$FREESURFER_HOME/subjects \ - FUNCTIONALS_DIR=$FREESURFER_HOME/sessions \ - MNI_DIR=$FREESURFER_HOME/mni \ - LOCAL_DIR=$FREESURFER_HOME/local \ - FSFAST_HOME=$FREESURFER_HOME/fsfast \ - MINC_BIN_DIR=$FREESURFER_HOME/mni/bin \ - MINC_LIB_DIR=$FREESURFER_HOME/mni/lib \ - MNI_DATAPATH=$FREESURFER_HOME/mni/data \ - FMRI_ANALYSIS_DIR=$FREESURFER_HOME/fsfast -ENV PERL5LIB=$MINC_LIB_DIR/perl5/5.8.5 \ - MNI_PERL5LIB=$MINC_LIB_DIR/perl5/5.8.5 \ - PATH=$FREESURFER_HOME/bin:$FSFAST_HOME/bin:$FREESURFER_HOME/tktools:$MINC_BIN_DIR:$PATH -RUN echo "cHJpbnRmICJrcnp5c3p0b2YuZ29yZ29sZXdza2lAZ21haWwuY29tXG41MTcyXG4gKkN2dW12RVYzelRmZ1xuRlM1Si8yYzFhZ2c0RVxuIiA+IC9vcHQvZnJlZXN1cmZlci9saWNlbnNlLnR4dAo=" | base64 -d | sh - -# Enable neurodebian -COPY docker/files/neurodebian.gpg /etc/apt/neurodebian.gpg -RUN curl -sSL http://neuro.debian.net/lists/xenial.us-ca.full >> /etc/apt/sources.list.d/neurodebian.sources.list && \ - apt-key add /etc/apt/neurodebian.gpg && \ - apt-key adv --refresh-keys --keyserver hkp://ha.pool.sks-keyservers.net 0xA5D32F012649A5A9 || true - -# Installing general Debian utilities and Neurodebian packages (FSL, AFNI, git) -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - fsl-core=5.0.9-1~nd+1+nd16.04+1 \ - fsl-mni152-templates=5.0.7-2 \ - afni=16.2.07~dfsg.1-2~nd16.04+1 \ - bzip2 \ - ca-certificates \ - xvfb \ - git=1:2.7.4-0ubuntu1 \ - graphviz=2.38.0-12ubuntu2 \ - unzip \ - apt-utils \ - fusefat \ - make \ - ruby=1:2.3.0+1 && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -ENV FSLDIR=/usr/share/fsl/5.0 \ - FSLOUTPUTTYPE=NIFTI_GZ \ - FSLMULTIFILEQUIT=TRUE \ - POSSUMDIR=/usr/share/fsl/5.0 \ - LD_LIBRARY_PATH=/usr/lib/fsl/5.0:$LD_LIBRARY_PATH \ - FSLTCLSH=/usr/bin/tclsh \ - FSLWISH=/usr/bin/wish \ - AFNI_MODELPATH=/usr/lib/afni/models \ - AFNI_IMSAVE_WARNINGS=NO \ - AFNI_TTATLAS_DATASET=/usr/share/afni/atlases \ - AFNI_PLUGINPATH=/usr/lib/afni/plugins \ - PATH=/usr/lib/fsl/5.0:/usr/lib/afni/bin:$PATH - -# Installing and setting up ANTs -RUN mkdir -p /opt/ants && \ - curl -sSL "https://github.com/stnava/ANTs/releases/download/v2.1.0/Linux_Ubuntu14.04.tar.bz2" \ - | tar -xjC /opt/ants --strip-components 1 - -ENV ANTSPATH=/opt/ants \ - PATH=$ANTSPATH:$PATH - -# Installing and setting up c3d -RUN mkdir -p /opt/c3d && \ - curl -sSL "http://downloads.sourceforge.net/project/c3d/c3d/1.0.0/c3d-1.0.0-Linux-x86_64.tar.gz" \ - | tar -xzC /opt/c3d --strip-components 1 - -ENV C3DPATH=/opt/c3d/ \ - PATH=$C3DPATH/bin:$PATH - -# Install fake-S3 -ENV GEM_HOME /usr/lib/ruby/gems/2.3 -ENV BUNDLE_PATH="$GEM_HOME" \ - BUNDLE_BIN="$GEM_HOME/bin" \ - BUNDLE_SILENCE_ROOT_WARNING=1 \ - BUNDLE_APP_CONFIG="$GEM_HOME" -ENV PATH $BUNDLE_BIN:$PATH -RUN mkdir -p "$GEM_HOME" "$BUNDLE_BIN" && \ - chmod 777 "$GEM_HOME" "$BUNDLE_BIN" - -RUN gem install fakes3 - -# Install Matlab MCR: from the good old install_spm_mcr.sh of @chrisfilo -RUN echo "destinationFolder=/opt/mcr" > mcr_options.txt && \ - echo "agreeToLicense=yes" >> mcr_options.txt && \ - echo "outputFile=/tmp/matlabinstall_log" >> mcr_options.txt && \ - echo "mode=silent" >> mcr_options.txt && \ - mkdir -p matlab_installer && \ - curl -sSL http://www.mathworks.com/supportfiles/downloads/R2015a/deployment_files/R2015a/installers/glnxa64/MCR_R2015a_glnxa64_installer.zip \ - -o matlab_installer/installer.zip && \ - unzip matlab_installer/installer.zip -d matlab_installer/ && \ - matlab_installer/install -inputFile mcr_options.txt && \ - rm -rf matlab_installer mcr_options.txt - -# Install SPM -RUN curl -sSL http://www.fil.ion.ucl.ac.uk/spm/download/restricted/utopia/dev/spm12_r6472_Linux_R2015a.zip -o spm12.zip && \ - unzip spm12.zip && \ - rm -rf spm12.zip - -ENV MATLABCMD="/opt/mcr/v85/toolbox/matlab" \ - SPMMCRCMD="/opt/spm12/run_spm12.sh /opt/mcr/v85/ script" \ - FORCE_SPMMCR=1 - -WORKDIR /work - diff --git a/docker/files/run_builddocs.sh b/docker/files/run_builddocs.sh index fb6111c9ea..ce289206d8 100644 --- a/docker/files/run_builddocs.sh +++ b/docker/files/run_builddocs.sh @@ -3,9 +3,7 @@ set -e set -x set -u -WORKDIR=${WORK:-/work} - -mkdir -p ${WORKDIR}/docs -make html 2>&1 | tee ${WORKDIR}/builddocs.log -cp -r /src/nipype/doc/_build/html/* ${WORKDIR}/docs/ -cat ${WORKDIR}/builddocs.log && if grep -q "ERROR" ${WORKDIR}/builddocs.log; then false; else true; fi +mkdir -p /scratch/docs +make html 2>&1 | tee /scratch/builddocs.log +cp -r /root/src/nipype/doc/_build/html/* /scratch/docs/ +cat /scratch/builddocs.log && if grep -q "ERROR" /scratch/builddocs.log; then false; else true; fi diff --git a/docker/files/run_examples.sh b/docker/files/run_examples.sh index e30ca221c6..43a94a2649 100644 --- a/docker/files/run_examples.sh +++ b/docker/files/run_examples.sh @@ -3,37 +3,15 @@ set -e set -x set -u -WORKDIR=${WORK:-/work} +mkdir -p /root/.nipype +echo '[logging]' > /root/.nipype/nipype.cfg +echo 'workflow_level = DEBUG' >> /root/.nipype/nipype.cfg +echo 'interface_level = DEBUG' >> /root/.nipype/nipype.cfg +echo 'filemanip_level = DEBUG' >> /root/.nipype/nipype.cfg +echo 'log_to_file = true' >> /root/.nipype/nipype.cfg +echo 'log_directory = /scratch/logs/' >> /root/.nipype/nipype.cfg + +coverage run /root/src/nipype/tools/run_examples.py $@ arr=$@ tmp_var=$( IFS=$' '; echo "${arr[*]}" ) -example_id=${tmp_var//[^A-Za-z0-9_-]/_} - -mkdir -p ${HOME}/.nipype ${WORKDIR}/logs/example_${example_id} -echo "[logging]" > ${HOME}/.nipype/nipype.cfg -echo "workflow_level = DEBUG" >> ${HOME}/.nipype/nipype.cfg -echo "interface_level = DEBUG" >> ${HOME}/.nipype/nipype.cfg -echo "filemanip_level = DEBUG" >> ${HOME}/.nipype/nipype.cfg -echo "log_to_file = true" >> ${HOME}/.nipype/nipype.cfg -echo "log_directory = ${WORKDIR}/logs/example_${example_id}" >> ${HOME}/.nipype/nipype.cfg - -# Set up coverage -echo "[run]" >> .coveragerc -echo "branch = True" >> .coveragerc -echo "source = /src/nipype" >> .coveragerc -echo "include = */nipype/*" >> .coveragerc -echo "omit =" >> .coveragerc -echo " */nipype/external/*" >> .coveragerc -echo " */nipype/fixes/*" >> .coveragerc -echo " */setup.py" >> .coveragerc - - -parallel="" -if [ "$2" == "MultiProc" ]; then - parallel="--concurrency=multiprocessing" -fi - -coverage run ${parallel} /src/nipype/tools/run_examples.py $@ -test_exit=$? -coverage xml -o "${WORKDIR}/smoketest_${example_id}.xml" - -exit $test_exit \ No newline at end of file +coverage xml -o "/scratch/smoketest_${tmp_var//[^A-Za-z0-9_-]/_}.xml" diff --git a/docker/files/run_pytests.sh b/docker/files/run_pytests.sh index 3b4b99786f..3ad4cfd28c 100644 --- a/docker/files/run_pytests.sh +++ b/docker/files/run_pytests.sh @@ -3,37 +3,36 @@ set -e set -x set -u -WORKDIR=${WORK:-/work} PYTHON_VERSION=$( python -c "import sys; print('{}{}'.format(sys.version_info[0], sys.version_info[1]))" ) # Create necessary directories -mkdir -p ${WORKDIR}/crashfiles ${WORKDIR}/logs/py${PYTHON_VERSION} +mkdir -p /scratch/pytest /scratch/crashfiles /scratch/logs/py${PYTHON_VERSION} # Create a nipype config file -mkdir -p ${HOME}/.nipype -echo '[logging]' > ${HOME}/.nipype/nipype.cfg -echo 'log_to_file = true' >> ${HOME}/.nipype/nipype.cfg -echo "log_directory = ${WORKDIR}/logs/py${PYTHON_VERSION}" >> ${HOME}/.nipype/nipype.cfg +mkdir -p /root/.nipype +echo '[logging]' > /root/.nipype/nipype.cfg +echo 'log_to_file = true' >> /root/.nipype/nipype.cfg +echo "log_directory = /scratch/logs/py${PYTHON_VERSION}" >> /root/.nipype/nipype.cfg # Enable profile_runtime tests only for python 2.7 if [[ "${PYTHON_VERSION}" -lt "30" ]]; then - echo '[execution]' >> ${HOME}/.nipype/nipype.cfg - echo 'profile_runtime = true' >> ${HOME}/.nipype/nipype.cfg + echo '[execution]' >> /root/.nipype/nipype.cfg + echo 'profile_runtime = true' >> /root/.nipype/nipype.cfg fi -cd /src/nipype/ -make clean # Run tests using pytest -py.test -n ${CIRCLE_NCPUS:-4} --doctest-modules --junitxml=${WORKDIR}/pytests_py${PYTHON_VERSION}.xml --cov-report xml:${WORKDIR}/coverage_py${PYTHON_VERSION}.xml --cov=nipype nipype +cd /root/src/nipype/ +make clean +py.test --doctest-modules --cov-report xml:/scratch/coverage_py${PYTHON_VERSION}.xml --cov=nipype nipype # Workaround: run here the profiler tests in python 3 if [[ "${PYTHON_VERSION}" -ge "30" ]]; then - echo '[execution]' >> ${HOME}/.nipype/nipype.cfg - echo 'profile_runtime = true' >> ${HOME}/.nipype/nipype.cfg - py.test -n ${CIRCLE_NCPUS:-4} --junitxml=${WORKDIR}/pytests_py${PYTHON_VERSION}_profiler.xml --cov-report xml:${WORKDIR}/coverage_py${PYTHON_VERSION}_profiler.xml --cov=nipype nipype/interfaces/tests/test_runtime_profiler.py - py.test -n ${CIRCLE_NCPUS:-4} --junitxml=${WORKDIR}/pytests_py${PYTHON_VERSION}_multiproc.xml --cov-report xml:${WORKDIR}/coverage_py${PYTHON_VERSION}_multiproc.xml --cov=nipype nipype/pipeline/plugins/tests/test_multiproc*.py + echo '[execution]' >> /root/.nipype/nipype.cfg + echo 'profile_runtime = true' >> /root/.nipype/nipype.cfg + py.test --cov-report xml:/scratch/coverage_py${PYTHON_VERSION}_profiler.xml --cov=nipype nipype/interfaces/tests/test_runtime_profiler.py + py.test --cov-report xml:/scratch/coverage_py${PYTHON_VERSION}_multiproc.xml --cov=nipype nipype/pipeline/plugins/tests/test_multiproc*.py fi # Copy crashfiles to scratch -find /src/nipype/ -name "crash-*" -exec cp {} ${WORKDIR}/crashfiles/ \; +for i in $(find /root/src/nipype/ -name "crash-*" ); do cp $i /scratch/crashfiles/; done diff --git a/nipype/info.py b/nipype/info.py index c170d3800c..b990d67a05 100644 --- a/nipype/info.py +++ b/nipype/info.py @@ -5,11 +5,13 @@ from __future__ import print_function, division, unicode_literals, absolute_import -# nipype version information. An empty version_extra corresponds to a -# full release. '.dev' as a version_extra string means this is a development +# nipype version information. An empty _version_extra corresponds to a +# full release. '.dev' as a _version_extra string means this is a development # version -# Remove -dev for release -__version__ = '0.13.0-dev' +_version_major = 0 +_version_minor = 13 +_version_micro = 0 +_version_extra = '-dev' # Remove -dev for release def get_nipype_gitversion(): @@ -41,10 +43,16 @@ def get_nipype_gitversion(): ver = o.decode().strip().split('-')[-1] return ver -if __version__.endswith('-dev'): +if '-dev' in _version_extra: gitversion = get_nipype_gitversion() if gitversion: - __version__ = __version__.replace('-dev', '-' + gitversion + '.dev') + _version_extra = '-' + gitversion + '.dev' + +# Format expected by setup.py and doc/source/conf.py: string of form 'X.Y.Z' +__version__ = '%s.%s.%s%s' % (_version_major, + _version_minor, + _version_micro, + _version_extra) CLASSIFIERS = ['Development Status :: 5 - Production/Stable', 'Environment :: Console', @@ -118,11 +126,10 @@ def get_nipype_gitversion(): AUTHOR = 'nipype developers' AUTHOR_EMAIL = 'neuroimaging@python.org' PLATFORMS = 'OS Independent' -MAJOR = __version__.split('.')[0] -MINOR = __version__.split('.')[1] -MICRO = __version__.replace('-', '.').split('.')[2] -ISRELEASE = (len(__version__.replace('-', '.').split('.')) == 3 or - 'post' in __version__.replace('-', '.').split('.')[-1]) +MAJOR = _version_major +MINOR = _version_minor +MICRO = _version_micro +ISRELEASE = _version_extra == '' VERSION = __version__ PROVIDES = ['nipype'] REQUIRES = [ @@ -144,7 +151,6 @@ def get_nipype_gitversion(): TESTS_REQUIRES = [ 'pytest>=%s' % PYTEST_MIN_VERSION, 'pytest-cov', - 'pytest-xdist', 'mock', 'codecov', 'dipy',