Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
galaxyproject
GitHub Repository: galaxyproject/training-material
Path: blob/main/bin/knit-frog.py
1677 views
1
#!/usr/bin/env python
2
import shutil
3
import os
4
import argparse
5
import re
6
import sys
7
import knittingneedles as knit
8
9
10
# read in a tutorial, and check the structure of it.
11
parser = argparse.ArgumentParser(
12
description="Extract specially formatted diffs from tutorials as a series of patches to apply"
13
)
14
parser.add_argument("tutorial", type=argparse.FileType("r"), help="Input tutorial")
15
parser.add_argument(
16
"prefix", help="Some prefix for the output commit files to keep them separate"
17
)
18
args = parser.parse_args()
19
20
21
fnparts = args.tutorial.name.split('/')
22
fn_topic = fnparts[fnparts.index('tutorials') - 1]
23
fn_tutorial = fnparts[fnparts.index('tutorials') + 1]
24
25
diffs = []
26
current = None
27
currentCmd = None
28
currentTest = None
29
for line, text in enumerate(args.tutorial.read().split("\n")):
30
m = re.match(knit.BOXES, text)
31
if m:
32
depth = m.group(1).count(">")
33
else:
34
depth = 0
35
36
(unprefixed, prefix) = knit.stripN(text, depth)
37
m1 = re.match(knit.BOX_OPEN, unprefixed)
38
m2 = re.match(knit.BOX_CLOSE, unprefixed)
39
c1 = re.match(knit.CMD_OPEN, unprefixed)
40
c2 = re.match(knit.CMD_CLOSE, unprefixed)
41
t1 = re.match(knit.TEST_OPEN, unprefixed)
42
t2 = re.match(knit.TEST_CLOSE, unprefixed)
43
44
if m1:
45
if current is not None:
46
diffs.append(current)
47
current = []
48
elif current is not None:
49
current.append(unprefixed)
50
51
if c1:
52
if currentCmd is not None:
53
diffs.append(currentCmd)
54
currentCmd = []
55
elif currentCmd is not None:
56
currentCmd.append(unprefixed)
57
58
if t1:
59
if currentTest is not None:
60
diffs.append(currentTest)
61
currentTest = []
62
elif currentTest is not None:
63
currentTest.append(unprefixed)
64
65
if current and len(current) > 2 and current[-2].strip() == "```" and not m2:
66
current = None
67
68
if currentCmd and len(currentCmd) > 2 and currentCmd[-2].strip() == "```" and not c2:
69
currentCmd = None
70
71
if currentTest and len(currentTest) > 2 and currentTest[-2].strip() == "```" and not t2:
72
currentTest = None
73
74
# Tests are known short, same with commands. If we haven't exited by now, it's an issue..
75
if currentTest and len(currentTest) > 4:
76
currentTest = None
77
78
# interesting = (t1, t2, currentCmd, currentTest)
79
# if any([x is not None for x in interesting]):
80
# print(*interesting)
81
82
if m2:
83
diffs.append(current)
84
current = None
85
86
if c2:
87
diffs.append(currentCmd)
88
currentCmd = None
89
90
if t2:
91
diffs.append(currentTest)
92
currentTest = None
93
94
postfix = ["--", "2.25.1", "", ""]
95
96
# import sys; sys.exit()
97
98
99
GITGAT = os.path.dirname(args.prefix)
100
BASE = os.path.basename(args.prefix)
101
BASE_PARTS = BASE.split('-')
102
103
cmdhandle = open(f"{GITGAT}/.scripts/{BASE}-run.sh", 'w')
104
cmdhandle.write("#!/bin/bash\n")
105
cmdhandle.write("set -ex\n\n")
106
cmdhandle.write("# Install dependencies before changing commits\n")
107
cmdhandle.write(f"find .scripts -name requirements.txt | xargs --no-run-if-empty -n 1 pip install -r\n")
108
cmdhandle.write('cat hosts | sed "s/^gat.*/$(hostname -f) ansible_connection=local ansible_user=$(whoami)/g" > ~/.hosts\n')
109
110
cmdhandle.write('export GALAXY_HOSTNAME="$(hostname -f)"\n')
111
cmdhandle.write('export GALAXY_API_KEY=adminkey\n')
112
cmdhandle.write("## The students should use a random password, we override with 'password' for reproducibility\n")
113
cmdhandle.write("echo 'password' > ~/.vault-password.txt;\n")
114
cmdhandle.write("## And one in this directory, it can contain garbage\n")
115
cmdhandle.write("echo 'garbage' > ./.vault-password.txt;\n")
116
# If it's after the ansible-galaxy tutorial
117
if int(BASE_PARTS[0]) > 10:
118
cmdhandle.write("## Ensure the galaxy user is setup\n")
119
cmdhandle.write("sudo -u galaxy /srv/galaxy/venv/bin/python /usr/bin/galaxy-create-user -c /srv/galaxy/config/galaxy.yml --user [email protected] --password password --key adminkey --username admin\n")
120
121
lastCommit = None
122
for idx, diff in enumerate(diffs):
123
if 'data-commit' in diff[-1]:
124
commit_msg = knit.extractCommitMsg(diff)
125
safe_commit = re.sub("[^a-z0-9-]", "-", commit_msg.lower())
126
127
prefix = [
128
"From: The Galaxy Training Network <[email protected]>",
129
"Date: Mon, 15 Feb 2021 14:06:56 +0100",
130
f"Subject: {fn_topic}/{fn_tutorial}/{idx:04d}: {commit_msg}",
131
"",
132
"",
133
]
134
135
lastCommit = f"{fn_topic}/{fn_tutorial}/{idx:04d}"
136
137
(_, diff) = knit.removeWhitespacePrefix(diff)
138
139
patch_id = diff[-1]
140
# Remove patch id, ```
141
diff = diff[0:-2]
142
if diff[-1] == "{% endraw %}":
143
diff = diff[0:-1]
144
145
fn = f"{args.prefix}-commit-{idx:04d}-{safe_commit}.patch"
146
with open(fn, "w") as handle:
147
print(fn)
148
handle.write("\n".join(prefix + diff + postfix))
149
elif 'data-cmd' in diff[-1]:
150
cmdhandle.write("\n# CMD\n")
151
if lastCommit is not None:
152
cmdhandle.write(f'## Checkout\ngit checkout $(git log main --pretty=oneline | grep "{lastCommit}" | cut -c1-40)\n')
153
for line in diff[0:-2]:
154
cmdhandle.write("## Run command\n")
155
if 'ansible-playbook' in line:
156
cmdhandle.write("if [[ -z ${GALAXY_VERSION} ]]; then\n")
157
cmdhandle.write(line.strip() + " -i ~/.hosts --vault-password-file ~/.vault-password.txt\n")
158
cmdhandle.write("else\n")
159
cmdhandle.write(line.strip() + " -i ~/.hosts --vault-password-file ~/.vault-password.txt -e galaxy_commit_id=${GALAXY_VERSION}\n")
160
cmdhandle.write("fi\n")
161
else:
162
line = line.strip()
163
line = line.replace('https://your-galaxy', 'https://$(hostname -f)')
164
line = line.replace('https://galaxy.example.org', 'https://$(hostname -f)')
165
line = line.replace('<api-key>', 'adminkey')
166
cmdhandle.write(line + "\n")
167
elif 'data-test' in diff[-1]:
168
cmdhandle.write("\n# TEST\n")
169
if lastCommit is not None:
170
cmdhandle.write(f'## Checkout\ngit checkout $(git log main --pretty=oneline | grep "{lastCommit}" | cut -c1-40)\n')
171
for line in diff[0:-2]:
172
testdir = f"topics/{fn_topic}/tutorials/{fn_tutorial}/tests"
173
gittestdir = f"{GITGAT}/.scripts/{BASE}-test"
174
if os.path.exists(testdir) and not os.path.exists(gittestdir):
175
shutil.copytree(testdir, gittestdir)
176
177
cmdhandle.write("## Run test case\n")
178
cmdhandle.write(f"./.scripts/{BASE}-test/{line.strip()}\n")
179
else:
180
print("Unknown!")
181
182
cmdhandle.write("# Done!\ngit checkout main\n")
183
184