Skip to content

Commit 5b9fd80

Browse files
committed
Setup test-download script
1 parent 8aaffbf commit 5b9fd80

File tree

3 files changed

+164
-1
lines changed

3 files changed

+164
-1
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,4 +191,6 @@ cython_debug/
191191
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
192192
# refer to https://docs.cursor.com/context/ignore-files
193193
.cursorignore
194-
.cursorindexingignore
194+
.cursorindexingignore
195+
196+
test-downloads/

test-download.py

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
import subprocess
2+
import json
3+
import os
4+
from pathlib import Path
5+
import sys
6+
import shutil
7+
from typing import Dict, Any
8+
9+
10+
def get_username() -> str:
11+
result = subprocess.run(
12+
["gh", "api", "user", "-q", ".login"], capture_output=True, text=True
13+
)
14+
15+
if result.returncode == 0:
16+
username = result.stdout.splitlines()[0]
17+
return username
18+
return ""
19+
20+
21+
def has_fork(fork_name: str) -> bool:
22+
result = subprocess.run(
23+
["gh", "repo", "view", fork_name, "--json", "isFork", "--jq", ".isFork"],
24+
capture_output=True,
25+
text=True,
26+
env=dict(os.environ, **{"GH_PAGER": "cat"}),
27+
)
28+
return result.returncode == 0 and result.stdout.strip() == "true"
29+
30+
31+
def fork(repository_name: str, fork_name: str) -> None:
32+
subprocess.run(
33+
[
34+
"gh",
35+
"repo",
36+
"fork",
37+
repository_name,
38+
"--default-branch-only",
39+
"--fork-name",
40+
fork_name,
41+
],
42+
capture_output=True,
43+
text=True,
44+
)
45+
46+
47+
def clone_with_custom_name(repository_name: str, name: str) -> None:
48+
subprocess.run(
49+
["gh", "repo", "clone", repository_name, name], capture_output=True, text=True
50+
)
51+
52+
53+
def init() -> None:
54+
subprocess.run(
55+
["git", "init", "--initial-branch=main"], capture_output=True, text=True
56+
)
57+
58+
59+
def add_all() -> None:
60+
subprocess.run(["git", "add", "."], capture_output=True, text=True)
61+
62+
63+
def commit(message: str) -> None:
64+
subprocess.run(["git", "commit", "-m", message], capture_output=True, text=True)
65+
66+
67+
def empty_commit(message: str) -> None:
68+
subprocess.run(
69+
["git", "commit", "-m", message, "--allow-empty"],
70+
capture_output=True,
71+
text=True,
72+
)
73+
74+
75+
def main(exercise_folder_name: str) -> None:
76+
os.makedirs("test-downloads", exist_ok=True)
77+
test_folder_name = os.path.join("test-downloads", exercise_folder_name)
78+
shutil.rmtree(test_folder_name, ignore_errors=True)
79+
os.makedirs(test_folder_name, exist_ok=True)
80+
81+
starting_files = [".gitmastery-exercise.json", "README.md"]
82+
for file in starting_files:
83+
shutil.copyfile(
84+
os.path.join(exercise_folder_name, file),
85+
os.path.join(test_folder_name, file),
86+
)
87+
88+
config = {}
89+
with open(
90+
os.path.join(exercise_folder_name, ".gitmastery-exercise.json"), "r"
91+
) as exercise_config_file:
92+
config = json.load(exercise_config_file)
93+
94+
base_files = config["base_files"]
95+
for resource, path in base_files.items():
96+
os.makedirs(Path(path).parent, exist_ok=True)
97+
shutil.copyfile(
98+
os.path.join(exercise_folder_name, "res", resource),
99+
os.path.join(test_folder_name, path),
100+
)
101+
102+
repo_name = config["exercise_repo"]["repo_name"]
103+
repo_title = config["exercise_repo"]["repo_title"]
104+
if config["exercise_repo"]["repo_type"] == "local":
105+
os.makedirs(os.path.join(test_folder_name, repo_name), exist_ok=True)
106+
else:
107+
username = get_username()
108+
exercise_repo = f"git-mastery/{repo_title}"
109+
if config["exercise_repo"]["create_fork"]:
110+
fork_name = f"{username}-gitmastery-{repo_title}"
111+
if not has_fork(fork_name):
112+
fork(exercise_repo, fork_name)
113+
cur_dir = os.getcwd()
114+
os.chdir(os.path.join(test_folder_name))
115+
clone_with_custom_name(f"{username}/{fork_name}", repo_name)
116+
os.chdir(cur_dir)
117+
else:
118+
clone_with_custom_name(exercise_repo, repo_name)
119+
120+
namespace: Dict[str, Any] = {}
121+
with open(
122+
os.path.join(exercise_folder_name, "download.py"), "r"
123+
) as download_script_file:
124+
contents = download_script_file.read()
125+
exec(contents, namespace)
126+
127+
download_resources = namespace.get("__resources__", {})
128+
if download_resources:
129+
for resource, path in download_resources.items():
130+
os.makedirs(Path(path).parent, exist_ok=True)
131+
shutil.copyfile(
132+
os.path.join(exercise_folder_name, "res", resource),
133+
os.path.join(test_folder_name, repo_name, path),
134+
)
135+
136+
os.chdir(os.path.join(test_folder_name, repo_name))
137+
if config["exercise_repo"]["init"]:
138+
init()
139+
if download_resources:
140+
add_all()
141+
commit("Initial commit")
142+
else:
143+
empty_commit("Initial commit")
144+
145+
if "setup" in namespace:
146+
namespace["setup"]()
147+
148+
149+
if __name__ == "__main__":
150+
if len(sys.argv) != 2:
151+
print("Missing exercise folder name: ./test-download.py <exercise folder name>")
152+
sys.exit(1)
153+
154+
if not os.path.isdir(sys.argv[1]):
155+
print("Invalid exercise folder name")
156+
sys.exit(1)
157+
158+
main(sys.argv[1])

test-download.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/bash
2+
3+
python test-download.py $1

0 commit comments

Comments
 (0)