@@ -47,7 +47,7 @@ def _validate_inputs(name: str, description: str, author: str, email: str, githu
4747 ]:
4848 if len (value ) > 100 :
4949 raise UsageError (f"Invalid { label } : maximum length is 100 characters." )
50- if any ( not c .isprintable () for c in value ):
50+ if not value .isprintable ():
5151 raise UsageError (f"Invalid { label } : control characters are not allowed." )
5252 if label != "description" and '"' in value :
5353 raise UsageError (f"Invalid { label } : double quotes are not allowed." )
@@ -73,31 +73,39 @@ def toml_escape(s: str) -> str:
7373 escaped_author = toml_escape (author )
7474 escaped_email = toml_escape (email )
7575
76- replacements = [
77- ("docs/reference/app.md" , r"^::: project\.app" , f"::: { source } .app" ),
78- ("mkdocs.yml" , r"^repo_name: .*" , f"repo_name: { github } /{ name } " ),
79- ("mkdocs.yml" , r"^repo_url: .*" , f"repo_url: https://github.com/{ github } /{ name } " ),
80- ("pyproject.toml" , r"^source = \[.*\]" , f'source = ["{ source } "]' ),
81- ("pyproject.toml" , r'^app = "project\.app:main"' , f'app = "{ source } .app:main"' ),
82- ("pyproject.toml" , r'^name = ".*"' , f'name = "{ source } "' ),
83- ("pyproject.toml" , r'^description = ".*"' , f'description = "{ escaped_description } "' ),
84- ("pyproject.toml" , r"^authors = \[.*\]" , f'authors = ["{ escaped_author } <{ escaped_email } >"]' ),
85- ("docs/README.md" , r"^# .*" , f"# { description } " ),
86- (".github/CODEOWNERS" , r"@.*" , f"@{ github } " ),
87- (".github/FUNDING.yml" , r"^github: \[.*\]" , f"github: [{ github } ]" ),
88- ]
89-
90- for filepath , pattern , replacement in replacements :
76+ replacements = {
77+ "docs/reference/app.md" : [(r"^::: project\.app" , f"::: { source } .app" )],
78+ "mkdocs.yml" : [
79+ (r"^repo_name: .*" , f"repo_name: { github } /{ name } " ),
80+ (r"^repo_url: .*" , f"repo_url: https://github.com/{ github } /{ name } " ),
81+ ],
82+ "pyproject.toml" : [
83+ (r"^source = \[.*\]" , f'source = ["{ source } "]' ),
84+ (r'^app = "project\.app:main"' , f'app = "{ source } .app:main"' ),
85+ (r'^name = ".*"' , f'name = "{ source } "' ),
86+ (r'^description = ".*"' , f'description = "{ escaped_description } "' ),
87+ (r"^authors = \[.*\]" , f'authors = ["{ escaped_author } <{ escaped_email } >"]' ),
88+ ],
89+ "docs/README.md" : [(r"^# .*" , f"# { description } " )],
90+ ".github/CODEOWNERS" : [(r"@.*" , f"@{ github } " )],
91+ ".github/FUNDING.yml" : [(r"^github: \[.*\]" , f"github: [{ github } ]" )],
92+ }
93+
94+ for filepath , file_replacements in replacements .items ():
9195 path = Path (filepath )
9296 if not path .exists ():
9397 secho (f" Warning: File { filepath } not found, skipping. ⚠️" , fg = "yellow" )
9498 continue
9599
96100 content = path .read_text ()
97- # Use a lambda for replacement to avoid regex backreference injection
98- new_content = re .sub (pattern , lambda _ , r = replacement : r , content , flags = re .MULTILINE )
99- path .write_text (new_content )
100- secho (f" Updated { filepath } ✅" , fg = "blue" )
101+ new_content = content
102+ for pattern , replacement in file_replacements :
103+ # Use a lambda for replacement to avoid regex backreference injection
104+ new_content = re .sub (pattern , lambda _ , r = replacement : r , new_content , flags = re .MULTILINE )
105+
106+ if new_content != content :
107+ path .write_text (new_content )
108+ secho (f" Updated { filepath } ✅" , fg = "blue" )
101109
102110
103111@command (context_settings = {"help_option_names" : ["-h" , "--help" ]})
0 commit comments