Skip to content

Commit 0c3bc44

Browse files
committed
Add mgration script
Signed-off-by: Leandro Lucarella <[email protected]>
1 parent 1019f6a commit 0c3bc44

File tree

1 file changed

+109
-2
lines changed

1 file changed

+109
-2
lines changed

cookiecutter/migrate.py

Lines changed: 109 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
And remember to follow any manual instructions for each run.
2121
""" # noqa: E501
2222

23+
import hashlib
2324
import os
2425
import subprocess
2526
import tempfile
@@ -30,8 +31,8 @@
3031
def main() -> None:
3132
"""Run the migration steps."""
3233
add_default_pytest_options()
33-
34-
# Add a separation line like this one after each migration step.
34+
print("=" * 72)
35+
migrate_mkdocs_macros()
3536
print("=" * 72)
3637

3738

@@ -64,6 +65,92 @@ def add_default_pytest_options() -> None:
6465
)
6566

6667

68+
def migrate_mkdocs_macros() -> None:
69+
"""Migrate from custom macros.py to standard module."""
70+
macros_file = Path("docs/_scripts/macros.py")
71+
mkdocs_yaml = Path("mkdocs.yaml")
72+
if not mkdocs_yaml.exists():
73+
mkdocs_yaml = Path("mkdocs.yml")
74+
75+
known_hashes = {
76+
"47a991286132471b6cb666577beb89e78c0f5d4975c53f0dcb319c4338a2c3cb",
77+
"6bb960c72b370ac77918f49d7a35f39c0ddb58fe52cf2d12caa2577098fd8469",
78+
"7351276ac314955a343bab09d1602e50300887291f841643e9fb79c94acc923c",
79+
"8fa5f9f3fd928e17f590e3ab056434474633259d615971404db0d2f3034adb62",
80+
"ba3ff5f1612b3dd22372a8ca95394b8ea468f18dcefc494c73811c8433fcb880",
81+
"dd32e8759abc43232bb3db5b33c0a7cf8d8442db6135c594968c499d8bae0ce5",
82+
}
83+
84+
print("Checking if docs/_scripts/macros.py can be migrated...")
85+
86+
file_hash = calculate_file_sha256_skip_lines(macros_file, 2)
87+
if not file_hash:
88+
return
89+
90+
if file_hash not in known_hashes:
91+
manual_step("The macros.py file seems to be customized. You have two options:")
92+
manual_step("")
93+
manual_step(
94+
"1. Switch to the standard module (if you don't have custom macros):"
95+
)
96+
manual_step(" a. Update mkdocs.yaml to use the standard module:")
97+
manual_step(
98+
' module_name: docs/_scripts/macros -> modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"]' # noqa: E501
99+
)
100+
manual_step(" b. Remove docs/_scripts/macros.py")
101+
manual_step("")
102+
manual_step("2. Keep your custom macros but use the standard functionality:")
103+
manual_step(" a. Update mkdocs.yaml:")
104+
manual_step(" - Keep using module_name: docs/_scripts/macros")
105+
manual_step(" b. Update your macros.py to be minimal:")
106+
manual_step(" ```python")
107+
manual_step(
108+
" from frequenz.repo.config.mkdocs.mkdocstrings_macros import hook_env_with_everything" # noqa: E501
109+
)
110+
manual_step("")
111+
manual_step(" def define_env(env):")
112+
manual_step(" # Add your custom variables, filters, and macros here")
113+
manual_step(" env.variables.my_var = 'Example'")
114+
manual_step(" env.filters.my_filter = lambda x: x.upper()")
115+
manual_step("")
116+
manual_step(
117+
" # This must be at the end to enable all standard features"
118+
)
119+
manual_step(" hook_env_with_everything(env)")
120+
manual_step(" ```")
121+
manual_step("")
122+
manual_step("See the docs for more details:")
123+
manual_step(
124+
"https://frequenz-floss.github.io/frequenz-repo-config-python/v0.12/reference/frequenz/repo/config/mkdocs/mkdocstrings_macros/" # noqa: E501
125+
)
126+
return
127+
128+
if not mkdocs_yaml.exists():
129+
print("mkdocs.yaml/yml not found, skipping macros migration")
130+
return
131+
132+
content = mkdocs_yaml.read_text(encoding="utf-8")
133+
if "module_name: docs/_scripts/macros" not in content:
134+
print("Custom macros configuration not found in mkdocs.yaml")
135+
return
136+
137+
print("Updating mkdocs.yaml to use standard module...")
138+
new_content = content.replace(
139+
"module_name: docs/_scripts/macros",
140+
'modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"]',
141+
)
142+
new_content = new_content.replace(
143+
"# inside docstrings. See the comment in `docs/_scripts/macros.py` for more\n"
144+
" # details\n",
145+
"# inside docstrings.\n",
146+
)
147+
148+
replace_file_contents_atomically(mkdocs_yaml, content, new_content)
149+
150+
print("Removing docs/_scripts/macros.py...")
151+
macros_file.unlink()
152+
153+
67154
def apply_patch(patch_content: str) -> None:
68155
"""Apply a patch using the patch utility."""
69156
subprocess.run(["patch", "-p1"], input=patch_content.encode(), check=True)
@@ -134,5 +221,25 @@ def manual_step(message: str) -> None:
134221
print(f"\033[0;33m>>> {message}\033[0m")
135222

136223

224+
def calculate_file_sha256_skip_lines(filepath: Path, skip_lines: int) -> str | None:
225+
"""Calculate SHA256 of file contents excluding the first N lines.
226+
227+
Args:
228+
filepath: Path to the file to hash
229+
skip_lines: Number of lines to skip at the beginning
230+
231+
Returns:
232+
The SHA256 hex digest, or None if the file doesn't exist
233+
"""
234+
if not filepath.exists():
235+
return None
236+
237+
# Read file and normalize line endings to LF
238+
content = filepath.read_text(encoding="utf-8").replace("\r\n", "\n")
239+
# Skip first N lines and ensure there's a trailing newline
240+
remaining_content = "\n".join(content.splitlines()[skip_lines:]) + "\n"
241+
return hashlib.sha256(remaining_content.encode()).hexdigest()
242+
243+
137244
if __name__ == "__main__":
138245
main()

0 commit comments

Comments
 (0)