Skip to content

Commit 4e233e3

Browse files
committed
Add tool to auto update stepXXX-next branches
1 parent 2ca38cd commit 4e233e3

1 file changed

Lines changed: 164 additions & 0 deletions

File tree

tools/autoupdate_next_branches.py

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
"""
2+
This script automatically replaces the "stepXXX-next" branches of the
3+
LearnWebGPU-Code repo with the tangled result.
4+
Usage:
5+
1. Run make tangle to make sure it is up to date (optionally run make clean first)
6+
2. Run this script. It may prompt several time for your ssh passphrase
7+
"""
8+
9+
import os
10+
import re
11+
import json
12+
import subprocess
13+
import shutil
14+
15+
from pathlib import Path
16+
17+
def main():
18+
guide_dir = Path(__file__).parent.parent
19+
root_dir = guide_dir.joinpath("_build", "tangle")
20+
git_dir = root_dir.joinpath("git-repo")
21+
repo_url = "https://github.com/eliemichel/LearnWebGPU-Code"
22+
23+
setupAndUpdateGitClone(git_dir, repo_url)
24+
25+
with open(root_dir.joinpath("metadata.json"), 'r') as f:
26+
metadata = json.load(f)
27+
28+
branches_to_push = []
29+
30+
for tangle_root in metadata["roots"]:
31+
tangle_dir = root_dir.joinpath(tangle_root)
32+
branch_name = buildBranchName(tangle_root)
33+
if not branch_name.endswith("-next"):
34+
# We only deal with "next" branches here. Other branches are manually released.
35+
continue
36+
37+
switchToBranch(git_dir, branch_name)
38+
clearWorkingCopy(git_dir)
39+
copyContents(tangle_dir, git_dir)
40+
commitAllChanges(git_dir, message="Auto update from '" + getLatestCommitName(guide_dir) + "'")
41+
branches_to_push.append(branch_name)
42+
43+
runCmd(
44+
[ "git", "push", "-u", "origin", *branches_to_push ],
45+
cwd=str(git_dir)
46+
)
47+
48+
#################################################
49+
50+
def copyContents(src_dir, dst_dir):
51+
"""Copy the content of src_dir into dst_dir"""
52+
for child in src_dir.iterdir():
53+
if child.name.startswith("build") or child.name == ".vscode":
54+
continue
55+
if child.is_dir():
56+
shutil.copytree(child, dst_dir.joinpath(child.name))
57+
else:
58+
shutil.copy(child, dst_dir.joinpath(child.name))
59+
60+
#################################################
61+
62+
def buildBranchName(tangle_root):
63+
step_index, name, *variants = tangle_root.split(" - ")
64+
tokens = [ f"step{step_index}" ] + sortVariants([ normalizeVariant(var) for var in variants ])
65+
return "-".join(tokens)
66+
67+
def normalizeVariant(var):
68+
var = var.lower()
69+
var = re.sub(' (.)', lambda m: m.group(1).upper(), var)
70+
return var
71+
72+
def sortVariants(variants):
73+
return sorted(variants, key=lambda x: x == "next")
74+
75+
#################################################
76+
77+
def setupAndUpdateGitClone(git_dir, repo_url):
78+
if git_dir.is_dir():
79+
runCmd(
80+
[ "git", "reset", "--hard" ],
81+
cwd=str(git_dir)
82+
)
83+
runCmd(
84+
[ "git", "checkout", "main" ],
85+
cwd=str(git_dir)
86+
)
87+
runCmd(
88+
[ "git", "pull" ],
89+
cwd=str(git_dir)
90+
)
91+
else:
92+
runCmd(
93+
[ "git", "clone", repo_url, git_dir.name ],
94+
cwd=str(git_dir.parent)
95+
)
96+
97+
#################################################
98+
99+
def switchToBranch(git_dir, branch_name):
100+
try:
101+
runCmd(
102+
[ "git", "checkout", branch_name ],
103+
cwd=str(git_dir)
104+
)
105+
except subprocess.CalledProcessError:
106+
runCmd(
107+
[ "git", "checkout", "main" ],
108+
cwd=str(git_dir)
109+
)
110+
runCmd(
111+
[ "git", "checkout", "-b", branch_name ],
112+
cwd=str(git_dir)
113+
)
114+
115+
#################################################
116+
117+
def commitAllChanges(git_dir, message=None):
118+
runCmd(
119+
[ "git", "add", "." ],
120+
cwd=str(git_dir)
121+
)
122+
cmd = [ "git", "commit" ]
123+
if message is not None:
124+
cmd += [ "-m", message ]
125+
try:
126+
runCmd(
127+
cmd,
128+
cwd=str(git_dir)
129+
)
130+
except subprocess.CalledProcessError:
131+
pass # probably because nothing to commit (TODO: check)
132+
133+
#################################################
134+
135+
def clearWorkingCopy(git_dir):
136+
"""Remove everything by .git"""
137+
for child in git_dir.iterdir():
138+
if child.name == ".git":
139+
continue
140+
elif child.is_dir():
141+
shutil.rmtree(child)
142+
else:
143+
child.unlink()
144+
145+
#################################################
146+
147+
def getLatestCommitName(git_dir):
148+
proc = runCmd(
149+
[ "git", "show", "-s", "--format=%s" ],
150+
cwd=str(git_dir),
151+
capture_output=True,
152+
)
153+
return proc.stdout.decode().strip()
154+
155+
#################################################
156+
157+
def runCmd(cmd, **kwargs):
158+
print(cmd)
159+
return subprocess.run(cmd, check=True, **kwargs)
160+
161+
#################################################
162+
163+
if __name__ == "__main__":
164+
main()

0 commit comments

Comments
 (0)