1
+ """Post-generation project setup and cleanup script.
2
+
3
+ This script runs after cookiecutter generates the project template.
4
+ It removes unnecessary files based on user choices and initializes the project.
5
+ """
6
+
1
7
import os
2
8
import shutil
3
9
import subprocess
10
+ import sys
11
+ from pathlib import Path
12
+ from typing import List , Union
13
+
14
+
15
+ class ProjectCleaner :
16
+ """Handles removal of unnecessary files and directories based on cookiecutter choices."""
17
+
18
+ def __init__ (self ):
19
+ self .project_slug = "{{cookiecutter.project_slug}}"
20
+ self .use_cli = "{{cookiecutter.include_cli}}" == "yes"
21
+ self .use_github_actions = "{{cookiecutter.use_github_actions}}" == "yes"
22
+ self .use_podman = "{{cookiecutter.use_podman}}" == "yes"
23
+
24
+ def _safe_remove (self , path : Union [str , Path ]) -> bool :
25
+ """Safely remove a file or directory.
26
+
27
+ Args:
28
+ path: Path to remove
29
+
30
+ Returns:
31
+ bool: True if removed successfully, False otherwise
32
+ """
33
+ try :
34
+ path = Path (path )
35
+ if not path .exists ():
36
+ return False
37
+
38
+ if path .is_file ():
39
+ path .unlink ()
40
+ print (f"Removed file: { path } " )
41
+ elif path .is_dir ():
42
+ shutil .rmtree (path )
43
+ print (f"Removed directory: { path } " )
44
+ return True
45
+ except Exception as e :
46
+ print (f"Warning: Failed to remove { path } : { e } " )
47
+ return False
48
+
49
+ def _remove_files (self , files : List [Union [str , Path ]]) -> None :
50
+ """Remove multiple files or directories.
51
+
52
+ Args:
53
+ files: List of file/directory paths to remove
54
+ """
55
+ for file_path in files :
56
+ self ._safe_remove (file_path )
57
+
58
+ def clean_cli_files (self ) -> None :
59
+ """Remove CLI related files if CLI is not needed."""
60
+ if self .use_cli :
61
+ return
62
+
63
+ cli_files = [
64
+ Path (self .project_slug ) / "cli.py"
65
+ ]
66
+ print ("Removing CLI files..." )
67
+ self ._remove_files (cli_files )
68
+
69
+ def clean_container_files (self ) -> None :
70
+ """Remove container related files if Podman is not used."""
71
+ if self .use_podman :
72
+ return
73
+
74
+ container_files = [
75
+ ".dockerignore" ,
76
+ "container" ,
77
+ Path (".github" ) / "workflows" / "container-release.yaml"
78
+ ]
79
+ print ("Removing container files..." )
80
+ self ._remove_files (container_files )
81
+
82
+ def clean_github_actions_files (self ) -> None :
83
+ """Remove GitHub Actions and documentation files if not needed."""
84
+ if self .use_github_actions :
85
+ return
86
+
87
+ github_files = [
88
+ ".github" ,
89
+ "mkdocs.yml" ,
90
+ "docs"
91
+ ]
92
+ print ("Removing GitHub Actions and documentation files..." )
93
+ self ._remove_files (github_files )
94
+
95
+
96
+ class ProjectInitializer :
97
+ """Handles project initialization tasks."""
98
+
99
+ def __init__ (self ):
100
+ self .project_slug = "{{cookiecutter.project_slug}}"
101
+
102
+ def setup_environment (self ) -> None :
103
+ """Initialize project dependencies and environment."""
104
+ project_dir = Path (self .project_slug ).resolve ()
105
+
106
+ if not project_dir .exists ():
107
+ print (f"Error: Project directory { project_dir } does not exist" )
108
+ sys .exit (1 )
109
+
110
+ print (f"Changing to project directory: { project_dir } " )
111
+ os .chdir (project_dir )
112
+
113
+ try :
114
+ print ("Installing project dependencies..." )
115
+ subprocess .run (["task" , "init" ], check = True )
116
+ print ("✅ Dependencies installed successfully" )
117
+ except subprocess .CalledProcessError as e :
118
+ print (f"❌ Failed to install dependencies: { e } " )
119
+ sys .exit (1 )
120
+ except FileNotFoundError :
121
+ print ("❌ uv not found. Please install uv first: https://docs.astral.sh/uv/" )
122
+ sys .exit (1 )
123
+
124
+
125
+ def main () -> None :
126
+ """Main execution function."""
127
+ print ("🚀 Starting post-generation project setup..." )
128
+
129
+ # Initialize cleaner and perform cleanup
130
+ cleaner = ProjectCleaner ()
131
+
132
+ print ("\n 📁 Cleaning up unnecessary files..." )
133
+ cleaner .clean_cli_files ()
134
+ cleaner .clean_container_files ()
135
+ cleaner .clean_github_actions_files ()
4
136
137
+ # Initialize project
138
+ print ("\n 🔧 Initializing project..." )
139
+ initializer = ProjectInitializer ()
140
+ initializer .setup_environment ()
5
141
6
- def remove_cli ():
7
- """Remove CLI related files if not needed."""
8
- cli_file = os .path .join ("{{cookiecutter.project_slug}}" , "cli.py" )
9
- if os .path .exists (cli_file ):
10
- os .remove (cli_file )
11
-
12
- def remove_docker ():
13
- """Remove GitHub Actions configuration if not needed."""
14
- file_name = [".dockerignore" , "docker" , ".github/workflows/docker_release.yaml" ]
15
- if "{{cookiecutter.use_github_actions}}" == "no" :
16
- for item in file_name :
17
- if os .path .exists (item ):
18
- if os .path .isfile (item ):
19
- os .remove (item )
20
- elif os .path .isdir (item ):
21
- shutil .rmtree (item )
22
-
23
-
24
- def remove_github_actions ():
25
- """Remove GitHub Actions configuration if not needed."""
26
- if "{{cookiecutter.use_github_actions}}" == "no" :
27
- github_dir = os .path .join (".github" )
28
- if os .path .exists (github_dir ):
29
- shutil .rmtree (github_dir )
30
-
31
-
32
- def remove_docs ():
33
- """Remove documentation related files if GitHub Actions is not used."""
34
- if "{{cookiecutter.use_github_actions}}" == "no" :
35
- # 删除 mkdocs.yml
36
- if os .path .exists ("mkdocs.yml" ):
37
- os .remove ("mkdocs.yml" )
38
- # 删除 docs 目录
39
- docs_dir = "docs"
40
- if os .path .exists (docs_dir ):
41
- shutil .rmtree (docs_dir )
42
-
43
-
44
- def init_project_depends ():
45
- """Initialize project dependencies using uv."""
46
- project_dir = os .path .abspath ("{{cookiecutter.project_slug}}" )
47
- os .chdir (project_dir )
48
-
49
- # 安装基础开发依赖
50
- subprocess .run (["uv" , "sync" ], check = True )
142
+ print ("\n ✨ Project setup completed successfully!" )
143
+ print (f"📂 Your project is ready at: {{cookiecutter.project_slug}}" )
51
144
52
145
53
146
if __name__ == "__main__" :
54
- if "{{cookiecutter.include_cli}}" == "no" :
55
- remove_cli ()
56
-
57
- if "{{cookiecutter.use_github_actions}}" == "no" :
58
- remove_github_actions ()
59
- remove_docs ()
60
-
61
- if "{{cookiecutter.use_docker}}" == "no" :
62
- remove_docker ()
63
-
64
- init_project_depends ()
147
+ main ()
0 commit comments