22import yaml
33import os
44import shutil
5- from typing import Any
65from fastapi_forge .logger import logger
76
87
9- def git_init () -> None :
10- subprocess .run (["git" , "init" ])
11- subprocess .run (["git" , "add" , "." ])
8+ def run_command (command : list [str ]) -> None :
9+ subprocess .run (command , check = True )
1210
1311
1412def uv_init () -> None :
15- subprocess . run (["uv" , "lock" ])
13+ run_command (["uv" , "lock" ])
1614
1715
1816def lint () -> None :
19- subprocess . run (["make" , "lint" ])
17+ run_command (["make" , "lint" ])
2018
2119
2220def make_env () -> None :
23- subprocess .run (["cp" , ".env.example" , ".env" ])
21+ run_command (["cp" , ".env.example" , ".env" ])
22+
23+
24+ def _process_paths (paths : list [str ], cwd : str ) -> tuple [list [str ], list [str ]]:
25+ files = []
26+ folders = []
27+ for path in paths :
28+ if not path :
29+ continue
30+ full_path = os .path .join (cwd , path )
31+ if path .endswith ((".py" , ".yaml" )):
32+ files .append (full_path )
33+ else :
34+ folders .append (full_path )
35+ return files , folders
2436
2537
2638def _get_delete_flagged () -> tuple [list [str ], list [str ]]:
27- conf_fn = "forge-config.yaml"
28- with open (conf_fn ) as stream :
29- y = yaml .safe_load (stream )
30- cwd = os .getcwd ()
31- files = [os .path .join (cwd , conf_fn )]
32- folders = []
33- config : dict [str , Any ] = y ["config" ]
34-
35- for _ , v in config .items ():
36- item_type = v ["type" ]
37- if item_type != "bool" :
38- continue
39- value : bool = v ["value" ]
40- if value is True :
41- continue
42- paths : list [str ] = v ["paths" ]
43- if not paths :
44- continue
45- for path in paths :
46- full_path = os .path .join (cwd , path )
47- if path .endswith (".py" ) or path .endswith (".yaml" ):
48- files .append (full_path )
49- else :
50- folders .append (full_path )
39+ files = []
40+ folders = []
41+ cwd = os .getcwd ()
42+
43+ try :
44+ with open ("forge-config.yaml" ) as stream :
45+ config = yaml .safe_load (stream ) or {}
46+ paths_config = config .get ("paths" , {})
47+
48+ for item in paths_config .values ():
49+ if "enabled" in item and not item ["enabled" ]:
50+ new_files , new_folders = _process_paths (item .get ("paths" , []), cwd )
51+ files .extend (new_files )
52+ folders .extend (new_folders )
53+
54+ if "requires_all" in item :
55+ conditions_met = all (
56+ paths_config .get (req , {}).get ("enabled" , False ) is False
57+ for req in item ["requires_all" ]
58+ )
59+ if conditions_met :
60+ new_files , new_folders = _process_paths (
61+ item .get ("paths" , []), cwd
62+ )
63+ files .extend (new_files )
64+ folders .extend (new_folders )
65+
66+ except Exception as e :
67+ logger .error (f"Error reading config file: { e } " )
5168
5269 return files , folders
5370
5471
55- def delete_empty_init_folders (root_dir : str = "src" ) -> None :
56- """Delete folders that only contain empty __init__.py files."""
57- for dirpath , dirnames , filenames in os .walk (root_dir , topdown = False ):
58- if dirpath == root_dir :
59- continue
72+ def _is_empty_init (dirpath : str ) -> bool :
73+ init_file = os .path .join (dirpath , "__init__.py" )
74+ try :
75+ with open (init_file , "r" ) as f :
76+ return not any (
77+ line .strip () and not line .strip ().startswith ("#" )
78+ for line in f .read ().splitlines ()
79+ )
80+ except OSError :
81+ return False
6082
61- if set (filenames ) == {"__init__.py" } and not dirnames :
62- init_file = os .path .join (dirpath , "__init__.py" )
6383
64- try :
65- with open (init_file , "r" ) as f :
66- content = f .read ()
67- has_code = any (
68- line .strip () and not line .strip ().startswith ("#" )
69- for line in content .splitlines ()
70- )
71- if not has_code :
72- os .remove (init_file )
73- os .rmdir (dirpath )
74- logger .info (f"Deleted empty package: { dirpath } " )
75- else :
76- logger .info (f"Keeping package with code: { dirpath } " )
77- except OSError as exc :
78- logger .info (f"Error processing package { dirpath } : { exc } " )
84+ def delete_empty_init_folders (root_dir : str = "src" ) -> None :
85+ for dirpath , dirnames , filenames in os .walk (root_dir , topdown = False ):
86+ if dirpath != root_dir and set (filenames ) == {"__init__.py" } and not dirnames :
87+ if _is_empty_init (dirpath ):
88+ os .remove (os .path .join (dirpath , "__init__.py" ))
89+ os .rmdir (dirpath )
90+ logger .info (f"Deleted empty package: { dirpath } " )
7991
8092
81- def cleanup ():
93+ def cleanup () -> None :
8294 files , folders = _get_delete_flagged ()
8395
84- for file_path in files :
96+ for path in files :
8597 try :
86- os .remove (file_path )
87- logger .info (f"Deleted file: { file_path } " )
98+ if os .path .exists (path ):
99+ os .remove (path )
100+ logger .info (f"Deleted file: { path } " )
88101 except OSError as exc :
89- logger .info (f"Error deleting file { file_path } : { exc } " )
102+ logger .error (f"Error deleting file { path } : { exc } " )
90103
91- for folder_path in folders :
104+ for path in folders :
92105 try :
93- shutil .rmtree (folder_path )
94- logger .info (f"Deleted folder: { folder_path } " )
106+ if os .path .exists (path ):
107+ shutil .rmtree (path )
108+ logger .info (f"Deleted folder: { path } " )
95109 except OSError as exc :
96- logger .info (f"Error deleting folder { folder_path } : { exc } " )
110+ logger .error (f"Error deleting folder { path } : { exc } " )
97111
98112 delete_empty_init_folders ()
99113
@@ -103,4 +117,3 @@ def cleanup():
103117 uv_init ()
104118 make_env ()
105119 lint ()
106- # git_init()
0 commit comments