Skip to content

Commit 633eb89

Browse files
authored
Optimize the bootstrapper and tests (#2)
* Changes for the upcoming release * optimize cloning sequence * fix tests * add pre-commit checks * update pre-commit.yaml * Update .github/workflows/tests.yaml * Optimized folder discovery and creation * Make the logger customizable
1 parent 4f8193f commit 633eb89

File tree

7 files changed

+72
-67
lines changed

7 files changed

+72
-67
lines changed

.github/workflows/pre-commit.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: pre-commit checks
2+
3+
on: [push, pull_request, workflow_dispatch]
4+
5+
permissions:
6+
contents: read
7+
8+
jobs:
9+
check:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- uses: actions/checkout@v4
14+
- uses: actions/setup-python@v4
15+
with:
16+
python-version: "3.x"
17+
- uses: pre-commit/action@v3.0.0

.github/workflows/tests.yaml

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
name: Tests
2-
on:
3-
workflow_dispatch:
4-
push:
5-
branches:
6-
- "**"
7-
pull_request:
8-
branches:
9-
- "**"
2+
3+
on: [push, pull_request, workflow_dispatch]
104

115
jobs:
126
test:
@@ -15,11 +9,12 @@ jobs:
159
strategy:
1610
matrix:
1711
os: [macos-latest, windows-latest, ubuntu-latest]
18-
python-version: ["3.10", "3.11", "3.12-dev"]
12+
python-version: ["3.11", "3.12"]
13+
build-version: ["3.11", "3.12"]
1914

2015
steps:
2116
- name: Checkout repo
22-
uses: actions/checkout@v3
17+
uses: actions/checkout@v4
2318

2419
- name: Set up Python
2520
uses: actions/setup-python@v4
@@ -41,8 +36,8 @@ jobs:
4136
- name: Install the package
4237
run: pip install .
4338

44-
- name: Run the package
45-
run: bootstrapper tr -b 3.12
39+
- name: Run the bootstrapper
40+
run: bootstrapper tr -b ${{ matrix.build-version }}
4641

4742
- name: See results (non-Windows)
4843
if: matrix.os != 'windows-latest'

.pre-commit-config.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ repos:
99
rev: 23.10.1
1010
hooks:
1111
- id: black
12-
name: black (python)
1312

1413
- repo: https://github.com/pre-commit/pre-commit-hooks
1514
rev: v4.5.0
1615
hooks:
16+
- id: check-case-conflict
17+
- id: check-merge-conflict
1718
- id: check-toml
1819
- id: check-yaml
1920
- id: end-of-file-fixer

bootstrapper/bootstrapper.py

Lines changed: 42 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,16 @@ def emit(self, record):
2121
self.flush()
2222

2323

24-
logger = logging.getLogger()
25-
logger.setLevel(logging.INFO)
26-
handler = _NoNewLine()
27-
handler.setFormatter(logging.Formatter("%(message)s"))
28-
logger.addHandler(handler)
29-
30-
3124
class Bootstrapper:
32-
def __init__(self, language: str, branch: str = "3.12") -> None:
25+
def __init__(
26+
self,
27+
language: str,
28+
branch: str = "3.12",
29+
logger: logging.Logger = logging.getLogger(),
30+
) -> None:
3331
self.language = language
3432
self.branch = branch
33+
self.logger = logger
3534
self.translation_repo = f"python-docs-{self.language}"
3635
self.cpython_repo = f"{self.translation_repo}/venv/cpython"
3736
self.readme_url = "https://raw.githubusercontent.com/egeakman/python-docs-bootstrapper/master/bootstrapper/data/README.md"
@@ -43,36 +42,36 @@ def _request(self, url: str) -> str:
4342
return response.read().decode()
4443

4544
def create_dirs(self) -> None:
46-
logger.info("Creating directories...")
45+
self.logger.info("Creating directories...")
4746
os.makedirs(self.translation_repo, exist_ok=True)
4847
os.makedirs(self.cpython_repo, exist_ok=True)
49-
print("✅")
48+
self.logger.info("✅\n")
5049

5150
def setup_cpython_repo(self) -> None:
5251
if not os.path.exists(f"{self.cpython_repo}/.git") and not os.path.isdir(
5352
f"{self.cpython_repo}/.git"
5453
):
55-
logger.info("Cloning CPython repo...")
54+
self.logger.info("Cloning CPython repo...")
5655
subprocess.run(
5756
[
5857
"git",
5958
"clone",
6059
"https://github.com/python/cpython.git",
6160
self.cpython_repo,
61+
f"--branch={self.branch}",
6262
"-q",
6363
],
6464
check=True,
6565
)
66-
print("✅")
66+
self.logger.info("✅\n")
6767

68-
subprocess.run(
69-
["git", "-C", self.cpython_repo, "checkout", self.branch, "-q"], check=True
70-
)
68+
self.logger.info("Updating CPython repo...")
7169
subprocess.run(
7270
["git", "-C", self.cpython_repo, "pull", "--ff-only", "-q"], check=True
7371
)
72+
self.logger.info("✅\n")
7473

75-
logger.info("Building gettext files...")
74+
self.logger.info("Building gettext files...")
7675
subprocess.run(
7776
[
7877
"sphinx-build",
@@ -85,21 +84,18 @@ def setup_cpython_repo(self) -> None:
8584
cwd=self.cpython_repo,
8685
check=True,
8786
)
88-
print("✅")
87+
self.logger.info("✅\n")
8988

9089
def setup_translation_repo(self) -> None:
91-
logger.info("Initializing translation repo...")
90+
self.logger.info("Initializing translation repo...")
9291
subprocess.run(["git", "init", "-q"], cwd=self.translation_repo, check=True)
9392
subprocess.run(
9493
["git", "branch", "-m", self.branch], cwd=self.translation_repo, check=True
9594
)
96-
print("✅")
97-
98-
logger.info("Copying gettext files...")
99-
files = glob.glob(f"{self.cpython_repo}/pot/**/*.pot") + glob.glob(
100-
f"{self.cpython_repo}/pot/*.pot"
101-
)
95+
self.logger.info("✅\n")
10296

97+
self.logger.info("Copying gettext files...")
98+
files = glob.glob(f"{self.cpython_repo}/pot/**/*.pot", recursive=True)
10399
files = [path.replace("\\", "/") for path in files]
104100

105101
for file in files:
@@ -108,69 +104,62 @@ def setup_translation_repo(self) -> None:
108104
".pot", ".po"
109105
)
110106
)
111-
112-
if len(file.split("/")) > 5:
113-
os.makedirs("/".join(dest_path.split("/")[:2]), exist_ok=True)
114-
107+
os.makedirs(os.path.dirname(dest_path), exist_ok=True)
115108
shutil.copyfile(file, dest_path)
116109
files[files.index(file)] = dest_path
117-
print("✅")
110+
self.logger.info("✅\n")
118111

119-
logger.info("Cleaning up gettext files...")
112+
self.logger.info("Cleaning up gettext files...")
120113
for file in files:
121114
with open(file, "r", encoding="utf-8") as f:
122115
contents = f.read()
123116
contents = re.sub("^#: .*Doc/", "#: ", contents, flags=re.M)
124117
with open(file, "w", encoding="utf-8") as f:
125118
f.write(contents)
126-
print("✅")
119+
self.logger.info("✅\n")
127120

128121
def create_readme(self) -> None:
129-
logger.info("Creating README.md...")
122+
self.logger.info("Creating README.md...")
130123
try:
131124
readme = self._request(self.readme_url)
132125
except (urllib.error.HTTPError, urllib.error.URLError):
133-
logger.warning(
126+
self.logger.warning(
134127
"\n ⚠️ Failed to fetch README.md from GitHub, using local copy..."
135128
)
136129
readme = Path(f"{os.path.dirname(__file__)}/data/README.md").read_text(
137130
encoding="utf-8"
138131
)
139-
140132
readme = readme.replace("{{translation.language}}", self.language)
141-
142133
with open(f"{self.translation_repo}/README.md", "w", encoding="utf-8") as f:
143134
f.write(readme)
144-
print("✅")
135+
self.logger.info("✅\n")
145136

146137
def create_gitignore(self) -> None:
147-
logger.info("Creating .gitignore...")
138+
self.logger.info("Creating .gitignore...")
148139
try:
149140
gitignore = self._request(self.gitignore_url)
150141
except (urllib.error.HTTPError, urllib.error.URLError):
151-
logger.warning(
142+
self.logger.warning(
152143
"\n ⚠️ Failed to fetch .gitignore from GitHub, using local copy..."
153144
)
154145
gitignore = Path(f"{os.path.dirname(__file__)}/data/.gitignore").read_text(
155146
encoding="utf-8"
156147
)
157-
158148
with open(f"{self.translation_repo}/.gitignore", "w", encoding="utf-8") as f:
159149
f.write(gitignore)
160-
print("✅")
150+
self.logger.info("✅\n")
161151

162152
def create_makefile(self) -> None:
163-
logging.info("Creating .makefile...")
153+
logging.info("Creating Makefile...")
164154
try:
165155
makefile = self._request(self.makefile_url)
166156
except (urllib.error.HTTPError, urllib.error.URLError):
167-
logger.warning(
157+
self.logger.warning(
168158
"\n ⚠️ Failed to fetch Makefile from GitHub, using local copy..."
169159
)
170160
makefile = Path(f"{os.path.dirname(__file__)}/data/Makefile").read_text(
171161
encoding="utf-8"
172162
)
173-
174163
head = (
175164
subprocess.run(
176165
["git", "-C", self.cpython_repo, "rev-parse", "HEAD"],
@@ -180,14 +169,12 @@ def create_makefile(self) -> None:
180169
.stdout.strip()
181170
.decode()
182171
)
183-
184172
makefile = makefile.replace("{{translation.language}}", self.language)
185173
makefile = makefile.replace("{{translation.branch}}", self.branch)
186174
makefile = makefile.replace("{{translation.head}}", head)
187-
188175
with open(f"{self.translation_repo}/Makefile", "w", encoding="utf-8") as f:
189176
f.write(makefile)
190-
print("✅")
177+
self.logger.info("✅\n")
191178

192179
def run(self) -> None:
193180
try:
@@ -197,9 +184,11 @@ def run(self) -> None:
197184
self.create_readme()
198185
self.create_gitignore()
199186
self.create_makefile()
200-
logger.info(f"🎉 Done bootstrapping the {self.language} translation ✅\n")
187+
self.logger.info(
188+
f"🎉 Done bootstrapping the {self.language} translation ✅\n"
189+
)
201190
except Exception as e:
202-
logger.critical(
191+
self.logger.critical(
203192
f"❌ Bootstrapping of the {self.language} translation failed: {e}\n"
204193
)
205194
sys.exit(1)
@@ -218,6 +207,11 @@ def main() -> None:
218207
"-b", "--branch", type=str, default="3.12", help="CPython branch (e.g. 3.12)"
219208
)
220209
args = parser.parse_args()
210+
logger = logging.getLogger()
211+
logger.setLevel(logging.INFO)
212+
handler = _NoNewLine()
213+
handler.setFormatter(logging.Formatter("%(message)s"))
214+
logger.addHandler(handler)
221215
Bootstrapper(args.language.lower().replace("_", "-"), args.branch).run()
222216

223217

bootstrapper/data/Makefile

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@
1010
# - make clean # To remove build artifacts
1111
# - make fuzzy # To find fuzzy strings
1212
#
13-
# Modes are: autobuild-stable, autobuild-dev, and autobuild-html,
14-
# documented in gen/src/3.6/Doc/Makefile as we're only delegating the
15-
# real work to the Python Doc Makefile.
13+
# Modes are: autobuild-stable, autobuild-dev, and autobuild-html
1614

1715
# Configuration
1816

bootstrapper/data/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Hello! This is the repository of the {{translation.language}} translation of the Python documentation.
44

5-
You can refer to the following resources throughout this journey:
5+
**You can refer to the following resources throughout this journey:**
66

77
- [DevGuide Translating Section](https://devguide.python.org/documentation/translating/) (add your translation to the list!)
88
- [PEP 545](https://www.python.org/dev/peps/pep-0545/) (the PEP that describes the translation process)
@@ -14,4 +14,4 @@ Python's documentation is maintained using a global network of volunteers. By po
1414

1515
You signify acceptance of this agreement by submitting your work to the PSF for inclusion in the documentation.
1616

17-
**Do not forget to replace this file with your own README that describes your translation and community!**
17+
***Do not forget to replace this file with your own README that describes your translation and community, while keeping the above agreement!***

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ dependencies = [
3939
"sphinx==4.5",
4040
]
4141
[project.urls]
42-
Releases = "https://github.com/egeakman/python-docs-bootstrapper/releases"
4342
Homepage = "https://github.com/egeakman/python-docs-bootstrapper"
4443
Issues = "https://github.com/egeakman/python-docs-bootstrapper/issues"
44+
Releases = "https://github.com/egeakman/python-docs-bootstrapper/releases"
4545
[project.scripts]
4646
bootstrapper = "bootstrapper.bootstrapper:main"
4747

0 commit comments

Comments
 (0)