Skip to content

Commit 20376a2

Browse files
committed
use .org version of lockfile and linting
1 parent 9e5fa26 commit 20376a2

File tree

5 files changed

+136
-99
lines changed

5 files changed

+136
-99
lines changed

.github/workflows/lint.yml

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ on:
55
branches: [ main ]
66
pull_request:
77
branches: [ main ]
8-
# Allows you to run this workflow manually from the Actions tab
98
workflow_dispatch:
109

1110
jobs:

.schema.yml

+20-26
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,9 @@
11
---
22
type: map
33
mapping:
4-
"install_repository_dependencies":
5-
type: bool
6-
default: false
7-
"install_resolver_dependencies":
8-
type: bool
9-
default: false
10-
"install_tool_dependencies":
11-
type: bool
12-
default: false
13-
"tools":
14-
type: seq
15-
sequence:
16-
- type: map
17-
mapping:
18-
"name":
19-
type: str
20-
required: true
21-
"owner":
22-
type: str
23-
required: true
24-
"tool_panel_section_label":
25-
type: str
26-
"tool_panel_section_id":
27-
type: str
28-
enum:
4+
"tool_panel_section_id":
5+
type: str
6+
enum:
297
[
308
"upload_file",
319
"get_data",
@@ -95,7 +73,6 @@ mapping:
9573
"apollo",
9674
"virology",
9775
"metagenomic_analysis",
98-
"single-cell",
9976
"proteomics",
10077
"metabolomics",
10178
"muon_spectroscopy",
@@ -118,3 +95,20 @@ mapping:
11895
"local_tools",
11996
"test_tools",
12097
]
98+
"tool_panel_section_label":
99+
type: str
100+
101+
"tools":
102+
type: seq
103+
sequence:
104+
- type: map
105+
mapping:
106+
"name":
107+
type: str
108+
required: true
109+
"owner":
110+
type: str
111+
required: true
112+
"tool_shed_url":
113+
type: str
114+
required: false

Makefile

+12-7
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,25 @@ CORRECT_YAMLS := $(YAML_FILES:=.fix)
66
INSTALL_YAMLS := $(LOCK_FILES:=.install)
77
UPDATE_TRUSTED_IUC := $(LOCK_FILES:.lock=.update_trusted_iuc)
88

9-
GALAXY_SERVER :=
9+
GALAXY_SERVER :=
10+
TOOLSET := galaxy-qa1.galaxy.cloud.e-infra.cz
1011

1112

1213
help:
1314
@egrep '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-16s\033[0m %s\n", $$1, $$2}'
1415

15-
lint: $(LINTED_YAMLS) ## Lint the yaml files
16+
lint: ## Lint all yaml files
17+
find ./$(TOOLSET) -name '*.yml' ! -path .//.schema.yml | grep '^\./[^/]*/' | xargs -n 1 -P 8 python scripts/fix_lockfile.py
18+
find ./$(TOOLSET) -name '*.yml' ! -path .//.schema.yml | grep '^\./[^/]*/' | xargs -n 1 -P 8 -I{} pykwalify -d '{}' -s .schema.yml
19+
20+
# lint: $(LINTED_YAMLS) ## Lint the yaml files
1621
fix: $(CORRECT_YAMLS) ## Fix any issues (missing hashes, missing lockfiles, etc.)
1722
install: $(INSTALL_YAMLS) ## Install the tools in our galaxy
1823

19-
%.lint: %
20-
python3 scripts/fix-lockfile.py $<
21-
pykwalify -d $< -s .schema.yaml
22-
python3 scripts/identify-unpinned.py $<
24+
# %.lint: %
25+
# python3 scripts/fix-lockfile.py $<
26+
# pykwalify -d $< -s .schema.yaml
27+
# python3 scripts/identify-unpinned.py $<
2328

2429
%.fix: %
2530
@# Generates the lockfile or updates it if it is missing tools
@@ -32,7 +37,7 @@ install: $(INSTALL_YAMLS) ## Install the tools in our galaxy
3237
@-shed-tools install --install_resolver_dependencies --toolsfile $< --galaxy $(GALAXY_SERVER) --api_key $(GALAXY_API_KEY) 2>&1 | tee -a report.log
3338

3439
pr_check:
35-
for changed_yaml in `git diff remotes/origin/master --name-only | grep .yaml$$`; do python scripts/pr-check.py $${changed_yaml} && pykwalify -d $${changed_yaml} -s .schema.yaml ; done
40+
for changed_yaml in `git diff remotes/origin/main --name-only | grep .yaml$$`; do python scripts/pr-check.py $${changed_yaml} && pykwalify -d $${changed_yaml} -s .schema.yaml ; done
3641

3742
update_trusted: $(UPDATE_TRUSTED_IUC) ## Run the update script
3843
@# Missing --without, so this updates all tools in the file.

scripts/fix-lockfile.py

-65
This file was deleted.

scripts/fix_lockfile.py

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import yaml
2+
import os
3+
import copy
4+
import argparse
5+
import logging
6+
import string
7+
8+
logging.basicConfig(level=logging.INFO)
9+
10+
11+
def section_id_chr(c):
12+
return (c if c in string.ascii_letters + string.digits else '_').lower()
13+
14+
15+
def section_label_to_id(label):
16+
return ''.join(map(section_id_chr, label))
17+
18+
19+
def update_file(fn, install_repository_dependencies, install_resolver_dependencies):
20+
with open(fn, 'r') as handle:
21+
unlocked = yaml.safe_load(handle)
22+
# If a lock file exists, load it from that file
23+
if os.path.exists(fn + '.lock'):
24+
with open(fn + '.lock', 'r') as handle:
25+
locked = yaml.safe_load(handle)
26+
else:
27+
# Otherwise just clone the "unlocked" list.
28+
locked = copy.deepcopy(unlocked)
29+
30+
# We will place entries in a cleaned lockfile, removing defunct entries, etc.
31+
clean_lockfile = copy.deepcopy(locked)
32+
clean_lockfile['tools'] = []
33+
34+
# As here we add any new tools in.
35+
for tool in unlocked['tools']:
36+
# If we have an existing locked copy, we'll just use that.
37+
locked_tools = [x for x in locked['tools'] if x['name'] == tool['name'] and x['owner'] == tool['owner']]
38+
39+
# If there are no copies of it seen in the lockfile, we'll just copy it
40+
# over directly, without a reivision. Another script will fix that.
41+
if len(locked) == 0:
42+
# new tool, just add directly.
43+
clean_lockfile['tools'].append(tool)
44+
continue
45+
46+
# Otherwise we have one or more locked versions so we'll harmonise +
47+
# reduce. Revisions are the only thing that could be variable.
48+
# Name/section/owner should not be. If they are, we take original human
49+
# edited .yaml file as source of truth.
50+
revisions = []
51+
for locked_tool in locked_tools:
52+
for revision in locked_tool.get('revisions', []):
53+
revisions.append(revision)
54+
55+
new_tool = {
56+
'name': tool['name'],
57+
'owner': tool['owner'],
58+
'revisions': sorted(list(set(map(str, revisions)))), # Cast to list for yaml serialization
59+
}
60+
61+
if 'tool_shed_url' in tool:
62+
ts_url = tool['tool_shed_url']
63+
logging.warning('Non-default Tool Shed URL for %s/%s: %s', tool['owner'], tool['name'], ts_url)
64+
new_tool['tool_shed_url'] = ts_url
65+
66+
# Set the section - id supercedes label/name
67+
if 'tool_panel_section_id' in unlocked:
68+
new_tool['tool_panel_section_id'] = unlocked['tool_panel_section_id']
69+
elif 'tool_panel_section_label' in unlocked:
70+
new_tool['tool_panel_section_id'] = section_label_to_id(unlocked['tool_panel_section_label'])
71+
72+
for section_definition in ('tool_panel_section_id', 'tool_panel_section_label'):
73+
if section_definition in unlocked:
74+
new_tool[section_definition] = unlocked[section_definition]
75+
break
76+
else:
77+
raise Exception(
78+
"Unlocked tool definition must include 'tool_panel_section_id' or "
79+
"'tool_panel_section_label': %s" % str(unlocked)
80+
)
81+
82+
clean_lockfile['tools'].append(new_tool)
83+
84+
# Set appropriate installation flags to true
85+
clean_lockfile.update({
86+
"install_repository_dependencies": install_repository_dependencies,
87+
"install_resolver_dependencies": install_resolver_dependencies,
88+
"install_tool_dependencies": False, # These are TS deps, not Conda
89+
})
90+
91+
with open(fn + '.lock', 'w') as handle:
92+
yaml.dump(clean_lockfile, handle, default_flow_style=False)
93+
94+
95+
if __name__ == '__main__':
96+
parser = argparse.ArgumentParser()
97+
parser.add_argument('--no-install-repository-dependencies', action='store_true', default=False,
98+
help="Don't install TS repository dependencies")
99+
parser.add_argument('--no-install-resolver-dependencies', action='store_true', default=True,
100+
help="Don't install tool dependencies via Galaxy dependency resolver (e.g. conda)")
101+
parser.add_argument('fn', type=argparse.FileType('r'), help="Tool.yaml file")
102+
args = parser.parse_args()
103+
logging.info("Processing %s", args.fn.name)
104+
update_file(args.fn.name, not args.no_install_repository_dependencies, not args.no_install_resolver_dependencies)

0 commit comments

Comments
 (0)