-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinit_project.py
More file actions
134 lines (101 loc) · 3.8 KB
/
init_project.py
File metadata and controls
134 lines (101 loc) · 3.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
"""Renames a Python project by replacing the template name in files and directories."""
import sys
import pathlib
OLD_NAME = "python-app-template"
FILES_TO_UPDATE = (
"cloudbuild.yaml",
"CONTRIBUTING.md",
"docker-compose.yml",
"Makefile",
"pyproject.toml",
"README.md",
"requirements.txt",
"tests/test_assets.py",
"tests/test_version.py",
)
VERSION_FILE_TPL = "{src_dir}/{old_name}/version.py"
SOURCE_DIR = pathlib.Path("src")
class Name:
"""Encapsulates a project name with methods to convert between dash and underscore styles."""
def __init__(self, raw: str):
"""Initialize Name with a raw string.
Strips leading/trailing whitespace and replaces spaces with dashes.
"""
self._raw = raw.strip().replace(" ", "-")
@property
def with_dashes(self) -> str:
"""Return the project name with dashes instead of underscores."""
return self._raw.replace("_", "-")
@property
def with_underscores(self) -> str:
"""Returns the project name with underscores instead of dashes."""
return self._raw.replace("-", "_")
def __str__(self):
"""Returns a string representation showing both dash and underscore versions."""
return f"{self.with_dashes} / {self.with_underscores}"
def _replace_in_file(filepath: pathlib.Path, old_new_pairs: list[tuple[str, str]]) -> None:
content = filepath.read_text(encoding="utf-8")
for old, new in old_new_pairs:
content = content.replace(old, new)
filepath.write_text(content, encoding="utf-8")
def _rename_package_dir(src_dir: pathlib.Path, old_name: str, new_name: str) -> None:
old_path = src_dir / old_name
new_path = src_dir / new_name
if not old_path.exists():
print(f"⚠️ Warning: {old_path} does not exist.")
return
if new_path.exists():
print(f"⚠️ Warning: {new_path} already exists.")
return
old_path.rename(new_path)
print(f"📁 Renamed package dir: {old_path} → {new_path}")
def update_project_name(
old_name: Name,
new_name: Name,
src_dir: pathlib.Path,
files_to_update: tuple[str, ...] = (),
) -> None:
"""Updates the project name in all relevant files and rename the source directory."""
replacements = [
(old_name.with_dashes, new_name.with_dashes),
(old_name.with_underscores, new_name.with_underscores),
]
print("🔁 Replacing names:")
for o, n in replacements:
print(f" {o} → {n}")
for file in files_to_update:
path = pathlib.Path(file)
if path.exists():
_replace_in_file(path, replacements)
print(f"✅ Updated: {file}")
else:
print(f"⏭️ Skipped (not found): {file}")
_rename_package_dir(src_dir, old_name.with_underscores, new_name.with_underscores)
print("\n✅ Done!")
print(f"🎉 Project renamed to: {new_name.with_dashes}.")
def main(
args: list[str] = sys.argv,
old_name: str = OLD_NAME,
files_to_update: tuple[str, ...] = FILES_TO_UPDATE,
src_dir: pathlib.Path = SOURCE_DIR
):
"""Entry point for the script.
Expects a single command-line argument: the new project name (with dashes or underscores).
"""
example = Name("my-project-name")
if len(args) != 2:
print(f"Usage: python {args[0]} {example.with_dashes} OR {example.with_underscores}")
sys.exit(1)
old_name = Name(old_name)
new_name = Name(args[1])
files_to_update = list(files_to_update)
version_file = VERSION_FILE_TPL.format(src_dir=src_dir, old_name=old_name.with_underscores)
files_to_update.append(version_file)
update_project_name(
old_name=old_name,
new_name=new_name,
files_to_update=tuple(files_to_update),
src_dir=src_dir
)
if __name__ == "__main__":
main()