Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
- switch changelog bot trigger only on comments ([#4241](https://github.com/nf-core/tools/pull/4241))
- fix indentation in generated api docs ([#4245](https://github.com/nf-core/tools/pull/4245))

### Linting

- Store `EDAM.tsv` in `NFCORE_CACHE_DIR` and fix yaml comment loss ([#4242](https://github.com/nf-core/tools/pull/4242))
Comment thread
LouisLeNezet marked this conversation as resolved.
Outdated

### Modules

- Allow task.ext.prefix2 in modules linting ([#4234](https://github.com/nf-core/tools/pull/4234))
Expand Down
25 changes: 20 additions & 5 deletions nf_core/modules/lint/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -611,13 +611,21 @@ def _add_edam_ontologies(section, edam_formats, desc):
section["ontologies"] = []
log.debug(f"expected ontologies for {desc}: {expected_ontologies}")
log.debug(f"current ontologies for {desc}: {current_ontologies}")
for ontology, ext in expected_ontologies:
if ontology not in current_ontologies:
for ontology_url, ext in expected_ontologies:
comment_text = edam_formats[ext][1]
if ontology_url not in current_ontologies:
try:
section["ontologies"].append(ruamel.yaml.comments.CommentedMap({"edam": ontology}))
section["ontologies"][-1].yaml_add_eol_comment(f"{edam_formats[ext][1]}", "edam")
cm = ruamel.yaml.comments.CommentedMap()
cm["edam"] = ontology_url
cm.yaml_add_eol_comment(comment_text, key="edam")
section["ontologies"].append(cm)
except KeyError:
log.warning(f"Could not add ontologies in {desc}")
else:
for item in section["ontologies"]:
if isinstance(item, ruamel.yaml.comments.CommentedMap) and item.get("edam") == ontology_url:
item.yaml_add_eol_comment(comment_text, key="edam")
break

# EDAM ontologies
edam_formats = nf_core.modules.modules_utils.load_edam()
Expand Down Expand Up @@ -681,7 +689,14 @@ def _add_edam_ontologies(section, edam_formats, desc):

def _ensure_string_keys(obj):
"""Recursively ensure all dict keys are strings (e.g., convert 1.2 -> "1.2")"""
if isinstance(obj, dict):
# This first block is needed to keep the comments in the yml
if isinstance(obj, ruamel.yaml.comments.CommentedMap):
Comment thread
LouisLeNezet marked this conversation as resolved.
for key in list(obj.keys()):
value = obj.pop(key)
new_key = str(key) if not isinstance(key, str) else key
obj[new_key] = _ensure_string_keys(value)
return obj
elif isinstance(obj, dict):
return {str(k) if not isinstance(k, str) else k: _ensure_string_keys(v) for k, v in obj.items()}
elif isinstance(obj, list):
return [_ensure_string_keys(item) for item in obj]
Expand Down
31 changes: 23 additions & 8 deletions nf_core/modules/modules_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import requests

from nf_core.utils import NFCORE_CACHE_DIR

from ..components.nfcore_component import NFCoreComponent

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -99,15 +101,28 @@ def get_installed_modules(directory: Path, repo_type="modules") -> tuple[list[st
def load_edam():
"""Load the EDAM ontology from the nf-core repository"""
edam_formats = {}
try:
response = requests.get("https://edamontology.org/EDAM.tsv")
Comment thread
LouisLeNezet marked this conversation as resolved.
except requests.exceptions.RequestException as e:
log.warning(f"Failed to load EDAM ontology: {e}")
return edam_formats
for line in response.content.splitlines():
cache_path = Path(NFCORE_CACHE_DIR) / "EDAM.tsv"
if not cache_path.exists():
log.debug("EDAM.tsv file not found in NFCORE_CACHE_DIR")
try:
response = requests.get("https://edamontology.org/EDAM.tsv", timeout=15)
data_bytes = response.content
with open(cache_path, "wb") as fh:
fh.write(data_bytes)
except requests.exceptions.RequestException:
return edam_formats
else:
log.debug("EDAM.tsv file found in NFCORE_CACHE_DIR")
try:
with cache_path.open("rb") as f:
data_bytes = f.read()
except (FileNotFoundError, OSError) as e:
Comment thread
LouisLeNezet marked this conversation as resolved.
Outdated
log.warning(f"Failed to load EDAM ontology: {e}")
return edam_formats
for line in data_bytes.splitlines():
fields = line.decode("utf-8").split("\t")
if fields[0].split("/")[-1].startswith("format") and fields[14]: # We choose an already provided extension
extensions = fields[14].split("|")
if fields[0].split("/")[-1].startswith("format") and fields[2]: # We choose an already provided extension
extensions = fields[2].split("|")
for extension in extensions:
if extension not in edam_formats:
edam_formats[extension] = (fields[0], fields[1]) # URL, name
Expand Down
7 changes: 7 additions & 0 deletions tests/modules/test_modules_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,10 @@ def test_filter_modules_by_name_empty_list(self):

filtered = nf_core.modules.modules_utils.filter_modules_by_name(modules, "fastqc")
assert len(filtered) == 0

def test_load_edam(self):
"""Test edam ontology loading"""
edam_formats = nf_core.modules.modules_utils.load_edam()
assert len(edam_formats) == 67
first_item = next(iter(edam_formats))
assert len(first_item) == 2
Loading