Skip to content

Commit

Permalink
Merge branch 'dev' into refactor-prettier-invocation
Browse files Browse the repository at this point in the history
  • Loading branch information
fabianegli authored Oct 29, 2022
2 parents cd9d37a + 6bf8f30 commit f173d90
Show file tree
Hide file tree
Showing 46 changed files with 1,416 additions and 703 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/create-lint-wf.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
name: Create a pipeline and run nf-core linting
on: [push, pull_request]
on:
push:
branches:
- dev
pull_request:
release:
types: [published]

# Cancel if a newer run is started
concurrency:
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/create-test-wf.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
name: Create a pipeline and test it
on: [push, pull_request]
on:
push:
branches:
- dev
pull_request:
release:
types: [published]

# Cancel if a newer run is started
concurrency:
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/lint-code.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
name: Lint tools code formatting
on: [push, pull_request]
on:
push:
branches:
- dev
pull_request:
release:
types: [published]

# Cancel if a newer run is started
concurrency:
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ name: Python tests
# Only run if we changed a Python file
on:
push:
branches:
- dev
pull_request:
release:
types: [published]

# Cancel if a newer run is started
concurrency:
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/tools-api-docs-dev.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
name: nf-core/tools dev API docs
# Run on push and PR to test that docs build
on: [pull_request, push]
on:
push:
branches:
- dev
pull_request:
release:
types: [published]

# Cancel if a newer run is started
concurrency:
Expand Down
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
- Don't remove local copy of modules repo, only update it with fetch ([#1881](https://github.com/nf-core/tools/pull/1881))
- Add subworkflow commands create-test-yml, create and install ([#1897](https://github.com/nf-core/tools/pull/1897))
- Update subworkflows install so it installs also imported modules and subworkflows ([#1904](https://github.com/nf-core/tools/pull/1904))
- Improve test coverage of sync.py
- Improve test coverage of `sync.py` and `__main__.py` ([#1936](https://github.com/nf-core/tools/pull/1936), [#1965](https://github.com/nf-core/tools/pull/1965))
- `check_up_to_date()` function from `modules_json` also checks for subworkflows.
- The default branch can now be specified when creating a new pipeline repo [#1959](https://github.com/nf-core/tools/pull/1959).
- Only warn when checking that the pipeline directory contains a `main.nf` and a `nextflow.config` file if the pipeline is not an nf-core pipeline [#1964](https://github.com/nf-core/tools/pull/1964)
Expand Down Expand Up @@ -365,7 +365,7 @@ Please note that there are many excellent integrations for Prettier available, f

### Modules

- Fixed typo in `module_utils.py`.
- Fixed typo in `modules_utils.py`.
- Fixed failing lint test when process section was missing from module. Also added the local failing tests to the warned section of the output table. ([#1235](https://github.com/nf-core/tools/issues/1235))
- Added `--diff` flag to `nf-core modules update` which shows the diff between the installed files and the versions
- Update `nf-core modules create` help texts which were not changed with the introduction of the `--dir` flag
Expand Down
7 changes: 4 additions & 3 deletions nf_core/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,13 @@ def download(pipeline, revision, outdir, compress, force, container, singularity
@click.option("--json", is_flag=True, default=False, help="Print output in JSON")
def licences(pipeline, json):
"""
List software licences for a given workflow.
List software licences for a given workflow (DSL1 only).
Checks the pipeline environment.yml file which lists all conda software packages.
Checks the pipeline environment.yml file which lists all conda software packages, which is not available for DSL2 workflows. Therefore, this command only supports DSL1 workflows (for now).
Each of these is queried against the anaconda.org API to find the licence.
Package name, version and licence is printed to the command line.
"""

lic = nf_core.licences.WorkflowLicences(pipeline)
lic.as_json = json
try:
Expand Down Expand Up @@ -827,7 +828,7 @@ def bump_versions(ctx, tool, dir, all, show_all):
ctx.obj["modules_repo_no_pull"],
)
version_bumper.bump_versions(module=tool, all_modules=all, show_uptodate=show_all)
except nf_core.modules.module_utils.ModuleException as e:
except nf_core.modules.modules_utils.ModuleException as e:
log.error(e)
sys.exit(1)
except (UserWarning, LookupError) as e:
Expand Down
Empty file added nf_core/components/__init__.py
Empty file.
159 changes: 159 additions & 0 deletions nf_core/components/components_command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import logging
import os
import shutil
from pathlib import Path

import yaml

from nf_core.modules.modules_json import ModulesJson
from nf_core.modules.modules_repo import ModulesRepo

from .components_utils import get_repo_type

log = logging.getLogger(__name__)


class ComponentCommand:
"""
Base class for the 'nf-core modules' and 'nf-core subworkflows' commands
"""

def __init__(self, component_type, dir, remote_url=None, branch=None, no_pull=False, hide_progress=False):
"""
Initialise the ComponentClass object
"""
self.component_type = component_type
self.dir = dir
self.modules_repo = ModulesRepo(remote_url, branch, no_pull, hide_progress)
self.hide_progress = hide_progress
self.default_modules_path = Path("modules", "nf-core")
self.default_tests_path = Path("tests", "modules", "nf-core")
self.default_subworkflows_path = Path("subworkflows", "nf-core")
self.default_subworkflows_tests_path = Path("tests", "subworkflows", "nf-core")
try:
if self.dir:
self.dir, self.repo_type = get_repo_type(self.dir)
else:
self.repo_type = None
except LookupError as e:
raise UserWarning(e)

def get_local_components(self):
"""
Get the local modules/subworkflows in a pipeline
"""
local_component_dir = Path(self.dir, self.component_type, "local")
return [
str(path.relative_to(local_component_dir)) for path in local_component_dir.iterdir() if path.suffix == ".nf"
]

def get_components_clone_modules(self):
"""
Get the modules/subworkflows repository available in a clone of nf-core/modules
"""
if self.component_type == "modules":
component_base_path = Path(self.dir, self.default_modules_path)
elif self.component_type == "subworkflows":
component_base_path = Path(self.dir, self.default_subworkflows_path)
return [
str(Path(dir).relative_to(component_base_path))
for dir, _, files in os.walk(component_base_path)
if "main.nf" in files
]

def has_valid_directory(self):
"""Check that we were given a pipeline or clone of nf-core/modules"""
if self.repo_type == "modules":
return True
if self.dir is None or not os.path.exists(self.dir):
log.error(f"Could not find directory: {self.dir}")
return False
main_nf = os.path.join(self.dir, "main.nf")
nf_config = os.path.join(self.dir, "nextflow.config")
if not os.path.exists(main_nf) and not os.path.exists(nf_config):
if Path(self.dir).resolve().parts[-1].startswith("nf-core"):
raise UserWarning(f"Could not find a 'main.nf' or 'nextflow.config' file in '{self.dir}'")
log.warning(f"Could not find a 'main.nf' or 'nextflow.config' file in '{self.dir}'")
return True

def has_modules_file(self):
"""Checks whether a module.json file has been created and creates one if it is missing"""
modules_json_path = os.path.join(self.dir, "modules.json")
if not os.path.exists(modules_json_path):
log.info("Creating missing 'module.json' file.")
ModulesJson(self.dir).create()

def clear_component_dir(self, component_name, component_dir):
"""Removes all files in the module/subworkflow directory"""
try:
shutil.rmtree(component_dir)
if self.component_type == "modules":
# Try cleaning up empty parent if tool/subtool and tool/ is empty
if component_name.count("/") > 0:
parent_dir = os.path.dirname(component_dir)
try:
os.rmdir(parent_dir)
except OSError:
log.debug(f"Parent directory not empty: '{parent_dir}'")
else:
log.debug(f"Deleted orphan tool directory: '{parent_dir}'")
log.debug(f"Successfully removed {component_name} {self.component_type[:-1]}")
return True
except OSError as e:
log.error(f"Could not remove {self.component_type[:-1]}: {e}")
return False

def components_from_repo(self, install_dir):
"""
Gets the modules/subworkflows installed from a certain repository
Args:
install_dir (str): The name of the directory where modules/subworkflows are installed
Returns:
[str]: The names of the modules/subworkflows
"""
repo_dir = Path(self.dir, self.component_type, install_dir)
if not repo_dir.exists():
raise LookupError(f"Nothing installed from {install_dir} in pipeline")

return [
str(Path(dir_path).relative_to(repo_dir)) for dir_path, _, files in os.walk(repo_dir) if "main.nf" in files
]

def install_component_files(self, component_name, component_version, modules_repo, install_dir):
"""
Installs a module/subworkflow into the given directory
Args:
component_name (str): The name of the module/subworkflow
component_version (str): Git SHA for the version of the module/subworkflow to be installed
modules_repo (ModulesRepo): A correctly configured ModulesRepo object
install_dir (str): The path to where the module/subworkflow should be installed (should be the 'modules/' or 'subworkflows/' dir of the pipeline)
Returns:
(bool): Whether the operation was successful of not
"""
return modules_repo.install_component(component_name, install_dir, component_version, self.component_type)

def load_lint_config(self):
"""Parse a pipeline lint config file.
Look for a file called either `.nf-core-lint.yml` or
`.nf-core-lint.yaml` in the pipeline root directory and parse it.
(`.yml` takes precedence).
Add parsed config to the `self.lint_config` class attribute.
"""
config_fn = os.path.join(self.dir, ".nf-core-lint.yml")

# Pick up the file if it's .yaml instead of .yml
if not os.path.isfile(config_fn):
config_fn = os.path.join(self.dir, ".nf-core-lint.yaml")

# Load the YAML
try:
with open(config_fn, "r") as fh:
self.lint_config = yaml.safe_load(fh)
except FileNotFoundError:
log.debug(f"No lint config file found: {config_fn}")
Loading

0 comments on commit f173d90

Please sign in to comment.