Skip to content

Commit 42c941d

Browse files
author
tdayris
committed
3.9.3
1 parent fb84e16 commit 42c941d

33 files changed

+458
-187
lines changed

.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,14 @@
88
.test/benchmark.tsv
99
.test/black.txt
1010
.test/report.txt
11+
.test/docs_update.txt
12+
.test/wrappers_update.txt
13+
.test/conda_update.txt
14+
.test/update_docs.txt
1115
.test/.*
1216
.snakemake
17+
sandbox/
18+
diagrams_conda/
1319
reference
1420
tmp
1521
logs

.test/tasks.py

+252
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
# coding: utf-8
2+
3+
from invoke import task
4+
from github import Github
5+
from datetime import datetime
6+
7+
import os.path as op
8+
import os
9+
import yaml
10+
11+
12+
def get_latest_release(address: str) -> str:
13+
git = Github()
14+
repo = git.get_repo(address)
15+
releases = repo.get_releases()
16+
return releases[0].tag_name
17+
18+
19+
snakemake_wrappers_version = os.environ.get("SNAKEMAKE_WRAPPERS_VERSION")
20+
if not snakemake_wrappers_version:
21+
print("Searching snakemake wrappers version on the web...")
22+
snakemake_wrappers_version = get_latest_release("snakemake/snakemake-wrappers")
23+
24+
fair_genome_indexer_version = os.environ.get("FAIR_GENOME_INDEXER_VERSION")
25+
if not fair_genome_indexer_version:
26+
print("Searching fair-genome-indexer version on the web...")
27+
fair_genome_indexer_version = get_latest_release("tdayris/fair_genome_indexer")
28+
29+
locations = {
30+
"snakefile": "../workflow/Snakefile",
31+
"rules": "../workflow/rules/",
32+
"scripts": "../workflow/scripts",
33+
"envs": "../workflow/envs",
34+
"changelog": "../CHANGELOG.md",
35+
"cff": "../citation.cff",
36+
}
37+
for location in locations.values():
38+
if not op.exists(location):
39+
raise FileNotFoundError(f"Could not find {location=}")
40+
41+
42+
def get_future_version(
43+
changelog: str = locations["changelog"],
44+
) -> str:
45+
with open(changelog, "r") as changelog_stream:
46+
line = next(changelog_stream)
47+
version = line.strip("#").strip()
48+
49+
print(f"Future version is: {version=}")
50+
return version
51+
52+
53+
future_version = get_future_version()
54+
55+
56+
@task
57+
def clean(
58+
c,
59+
conda: bool = False,
60+
extra: str = "",
61+
):
62+
patterns = [
63+
"black.txt",
64+
"format.txt",
65+
"linter_info.txt",
66+
"pipeline.txt",
67+
"results",
68+
"resources",
69+
"report.txt",
70+
"report.zip",
71+
"resources.md",
72+
"resources.tsv",
73+
"resources.txt",
74+
"summary.tsv",
75+
"summary_small.tsv",
76+
"docs_update.txt",
77+
"logs",
78+
"reference",
79+
"report",
80+
"tmp",
81+
"Snakefile",
82+
"wrappers_update.txt",
83+
"conda_update.txt",
84+
"docs_update.txt",
85+
]
86+
if conda:
87+
patterns.append(".snakemake")
88+
patterns.append(".conda")
89+
90+
for pattern in patterns:
91+
if op.exists(pattern):
92+
print(f"Removing {pattern=}")
93+
c.run(f"rm -rf '{pattern}'")
94+
else:
95+
print(f"Skipping {pattern=}")
96+
97+
98+
@task
99+
def update_docs_cff(
100+
c,
101+
to: str = future_version,
102+
cff_path: str = locations["cff"],
103+
):
104+
today = datetime.today().strftime("%Y-%m-%d")
105+
cff = {
106+
"cff-version": "1.2.0",
107+
"message": "If you use this software, please cite it as below.",
108+
"authors": [
109+
{
110+
"family-names": "Dayris",
111+
"given-names": "Thibault",
112+
"orcid": "https://orcid.org/0009-0009-2758-8450",
113+
}
114+
],
115+
"title": "fair-genome-indexer",
116+
"version": future_version,
117+
"date-released": today,
118+
"url": "https://github.com/tdayris/fair_genome_indexer",
119+
}
120+
print(cff)
121+
with open(cff_path, "w") as yaml_cff_stream:
122+
yaml.dump(cff, yaml_cff_stream, default_flow_style=False)
123+
124+
125+
@task(update_docs_cff)
126+
def update_docs_wrappers(c, to: str = snakemake_wrappers_version):
127+
regex = rf"s|v[0-9]\+\.[0-9]\+\.[0-9]\+/wrappers|{to}/wrappers|g"
128+
print(f"Updating snakemake wrappers in README.md to {to=}")
129+
c.run(f"sed -i '{regex}' ../README.md >> docs_update.txt 2>&1")
130+
131+
for root, dirs, files in os.walk("../workflow/reports"):
132+
for file in files:
133+
if file.endswith(".rst"):
134+
print(f"Updating snakemake wrappers in '{root}/{file}'...")
135+
c.run(f"sed -i '{regex}' '{root}/{file}' >> docs_update.txt")
136+
137+
regex = (
138+
's|snakemake_wrappers_prefix: str = "v4.5.0"|'
139+
f'snakemake_wrappers_prefix: str = "{to}"|g'
140+
)
141+
print("Updating '../workflow/rules/common.smk'...")
142+
c.run(f"sed -i '{regex}' '../workflow/rules/common.smk' >> update_docs.txt")
143+
144+
145+
@task(update_docs_wrappers)
146+
def update_wrappers_rules(
147+
c,
148+
to: str = snakemake_wrappers_version,
149+
snakefile: str = locations["snakefile"],
150+
rules: str = locations["rules"],
151+
):
152+
print(f"Updating {snakefile=}...")
153+
c.run(
154+
"snakedeploy update-snakemake-wrappers "
155+
f"--git-ref '{snakemake_wrappers_version}' '{snakefile}' "
156+
">> wrappers_update.txt 2>&1"
157+
)
158+
159+
for root, dirs, files in os.walk(rules):
160+
for file in files:
161+
if file.endswith(".smk"):
162+
print(f"Updating '{root}/{file}'...")
163+
c.run(
164+
"snakedeploy update-snakemake-wrappers --git-ref "
165+
f"'{snakemake_wrappers_version}' '{root}/{file}' "
166+
">> wrappers_update.txt 2>&1"
167+
)
168+
else:
169+
print(f"Skipping '{root}/{file}'...")
170+
171+
172+
@task(update_wrappers_rules)
173+
def update_conda(
174+
c,
175+
envs: str = locations["envs"],
176+
):
177+
for root, dirs, files in os.walk(envs):
178+
for file in files:
179+
if file.endswith(".yaml"):
180+
print(f"Updating '{root}/{file}'. This may take some time...")
181+
c.run(
182+
"snakedeploy update-conda-envs --conda-frontend mamba "
183+
f"--pin-envs '{root}/{file}' > conda_update.txt 2>&1"
184+
)
185+
186+
187+
@task
188+
def black(c, scripts: str = locations["scripts"]):
189+
log: str = "black.txt"
190+
for root, dirs, files in os.walk(scripts):
191+
for file in files:
192+
if file.endswith(".py"):
193+
print(f"Formatting '{root}/{file}'...")
194+
c.run(f"black '{root}/{file}' >> {log} 2>&1")
195+
196+
197+
@task(black)
198+
def snakefmt(
199+
c,
200+
snakefile: str = locations["snakefile"],
201+
rules: str = locations["rules"],
202+
):
203+
log: str = "format.txt"
204+
print(f"Formatting {snakefile=}...")
205+
c.run(f"snakefmt '{snakefile}' >> '{log}' 2>&1")
206+
207+
for root, dirs, files in os.walk(rules):
208+
for file in files:
209+
if file.endswith(".smk"):
210+
print(f"Formatting '{root}/{file}'...")
211+
c.run(f"snakefmt '{root}/{file}' >> '{log}' 2>&1")
212+
213+
214+
@task(snakefmt)
215+
def linter(
216+
c,
217+
snakefile: str = locations["snakefile"],
218+
):
219+
print(f"Linting {snakefile=}...")
220+
c.run(f"snakemake --lint -s '{snakefile}' > linter_info.txt 2>&1")
221+
222+
223+
@task(linter)
224+
def pipeline(
225+
c,
226+
snakefile: str = locations["snakefile"],
227+
):
228+
print("Running pipeline...")
229+
cmd = (
230+
f"snakemake -s '{snakefile}' "
231+
"--cores 7 --restart-times 0 "
232+
"--rerun-incomplete --printshellcmds "
233+
"--shadow-prefix 'tmp' --rerun-triggers 'mtime' "
234+
"--software-deployment-method conda "
235+
"--benchmark-extended > pipeline.txt 2>&1"
236+
)
237+
print(cmd)
238+
c.run(cmd)
239+
240+
241+
@task(pipeline)
242+
def report(
243+
c,
244+
snakefile: str = locations["snakefile"],
245+
):
246+
print("Building test report...")
247+
c.run(f"snakemake -s '{snakefile}' --report report.zip > report.txt 2>&1")
248+
249+
@task(clean, update_conda, report)
250+
def all(c):
251+
print("All done.")
252+

CHANGELOG.md

+12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
# 3.9.3
2+
3+
## Features:
4+
5+
* Easy snakemake-wrappers update
6+
* Easy conda envs update
7+
* New testing pipeline with additional format checks
8+
9+
## Doc:
10+
11+
* Citation cff file
12+
113
# 3.9.2
214

315
## Features:

0 commit comments

Comments
 (0)