Skip to content

Commit

Permalink
Merge pull request nf-core#33 from ewels/master
Browse files Browse the repository at this point in the history
New lint test for Dockerfile that builds from conda
  • Loading branch information
sven1103 authored Mar 28, 2018
2 parents 4025e90 + 9ed58dd commit 4773254
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 3 deletions.
35 changes: 34 additions & 1 deletion nf_core/lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def __init__(self, pipeline_dir):
self.files = []
self.config = {}
self.pipeline_name = None
self.dockerfile = []
self.conda_config = {}
self.passed = []
self.warned = []
Expand Down Expand Up @@ -67,7 +68,8 @@ def lint_pipeline(self, release=False):
'check_nextflow_config',
'check_ci_config',
'check_readme',
'check_conda_env_yaml'
'check_conda_env_yaml',
'check_conda_dockerfile'
]
if release:
self.releaseMode = True
Expand Down Expand Up @@ -150,6 +152,7 @@ def check_docker(self):
# Implicitely also checks if empty.
if 'FROM ' in content:
self.passed.append((2, "Dockerfile check passed"))
self.dockerfile = content.splitlines()
return

self.failed.append((2, "Dockerfile check failed"))
Expand Down Expand Up @@ -445,6 +448,36 @@ def check_conda_env_yaml(self, api_timeout=10):
else:
self.failed.append((8, "Could not find Conda dependency using the Anaconda API: {}".format(dep)))

def check_conda_dockerfile(self):
""" Check that the Docker build file looks right, if working with conda
Make sure that a name is given and is consistent with the pipeline name
Check that depedency versions are pinned
Warn if dependency versions are not the latest available """

if 'environment.yml' not in self.files or len(self.dockerfile) == 0:
return

expected_strings = [
'FROM continuumio/miniconda',
'ENV PATH /opt/conda/envs/{}/bin:$PATH'.format(self.conda_config['name']),
'COPY environment.yml /',
'RUN conda update -n base conda && \\',
' conda env create -f /environment.yml && \\',
' conda clean -a'
]
found_strings = [False for x in expected_strings]
for l in self.dockerfile:
for idx, s in enumerate(expected_strings):
if l == s:
found_strings[idx] = True
if all(found_strings):
self.passed.append((9, "Found all expected strings in Dockerfile"))
else:
for idx, s in enumerate(expected_strings):
if not found_strings[idx]:
self.failed.append((9, "Could not find Dockerfile string: {}".format(s)))

def print_results(self):
# Print results
rl = "\n Using --release mode linting tests" if self.releaseMode else ''
Expand Down
11 changes: 10 additions & 1 deletion tests/lint_examples/minimal_working_example/Dockerfile
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
FROM busybox
FROM continuumio/miniconda
MAINTAINER Phil Ewels <[email protected]>
LABEL authors="[email protected]" \
description="Docker image containing all requirements for the nf-core tools pipeline"

COPY environment.yml /
RUN conda update -n base conda && \
conda env create -f /environment.yml && \
conda clean -a
ENV PATH /opt/conda/envs/nfcore-tools/bin:$PATH
30 changes: 29 additions & 1 deletion tests/test_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def pf(wd, path):
pf(WD, 'lint_examples/license_incomplete_example')]

# The maximum sum of passed tests currently possible
MAX_PASS_CHECKS = 52
MAX_PASS_CHECKS = 53
# The additional tests passed for releases
ADD_PASS_RELEASE = 1

Expand Down Expand Up @@ -283,3 +283,31 @@ def test_conda_env_skip(self):
lint_obj.check_conda_env_yaml()
expectations = {"failed": 0, "warned": 0, "passed": 0}
self.assess_lint_status(lint_obj, **expectations)

def test_conda_dockerfile_pass(self):
""" Tests the conda Dockerfile test works with a working example """
lint_obj = nf_core.lint.PipelineLint(PATH_WORKING_EXAMPLE)
lint_obj.files = ['environment.yml']
with open(os.path.join(PATH_WORKING_EXAMPLE, 'Dockerfile'), 'r') as fh:
lint_obj.dockerfile = fh.read().splitlines()
lint_obj.conda_config['name'] = 'nfcore-tools'
lint_obj.check_conda_dockerfile()
expectations = {"failed": 0, "warned": 0, "passed": 1}
self.assess_lint_status(lint_obj, **expectations)

def test_conda_dockerfile_fail(self):
""" Tests the conda Dockerfile test fails with a bad example """
lint_obj = nf_core.lint.PipelineLint(PATH_WORKING_EXAMPLE)
lint_obj.files = ['environment.yml']
lint_obj.conda_config['name'] = 'nfcore-tools'
lint_obj.dockerfile = ['fubar']
lint_obj.check_conda_dockerfile()
expectations = {"failed": 6, "warned": 0, "passed": 0}
self.assess_lint_status(lint_obj, **expectations)

def test_conda_dockerfile_skip(self):
""" Tests the conda Dockerfile test is skipped when not needed """
lint_obj = nf_core.lint.PipelineLint(PATH_WORKING_EXAMPLE)
lint_obj.check_conda_dockerfile()
expectations = {"failed": 0, "warned": 0, "passed": 0}
self.assess_lint_status(lint_obj, **expectations)

0 comments on commit 4773254

Please sign in to comment.