33import pathlib
44import re
55import sys
6+ import urllib .request
7+ import json
68
79INIT_FILE = pathlib .Path ("socketsecurity/__init__.py" )
810PYPROJECT_FILE = pathlib .Path ("pyproject.toml" )
911
1012VERSION_PATTERN = re .compile (r"__version__\s*=\s*['\"]([^'\"]+)['\"]" )
1113PYPROJECT_PATTERN = re .compile (r'^version\s*=\s*".*"$' , re .MULTILINE )
14+ PYPI_API = "https://test.pypi.org/pypi/socketsecurity/json"
1215
1316def read_version_from_init (path : pathlib .Path ) -> str :
1417 content = path .read_text ()
@@ -28,12 +31,30 @@ def read_version_from_git(path: str) -> str:
2831 except subprocess .CalledProcessError :
2932 return None
3033
31- def bump_dev_version (version : str ) -> str :
34+ def bump_patch_version (version : str ) -> str :
3235 if ".dev" in version :
33- base , dev = version .split (".dev" )
34- return f"{ base } .dev{ int (dev )+ 1 } "
35- else :
36- return f"{ version } .dev1"
36+ version = version .split (".dev" )[0 ]
37+ parts = version .split ("." )
38+ parts [- 1 ] = str (int (parts [- 1 ]) + 1 )
39+ return "." .join (parts )
40+
41+ def fetch_existing_versions () -> set :
42+ try :
43+ with urllib .request .urlopen (PYPI_API ) as response :
44+ data = json .load (response )
45+ return set (data .get ("releases" , {}).keys ())
46+ except Exception as e :
47+ print (f"⚠️ Warning: Failed to fetch existing versions from Test PyPI: { e } " )
48+ return set ()
49+
50+ def find_next_available_dev_version (base_version : str ) -> str :
51+ existing_versions = fetch_existing_versions ()
52+ for i in range (1 , 100 ):
53+ candidate = f"{ base_version } .dev{ i } "
54+ if candidate not in existing_versions :
55+ return candidate
56+ print ("❌ Could not find available .devN slot after 100 attempts." )
57+ sys .exit (1 )
3758
3859def inject_version (version : str ):
3960 print (f"🔁 Updating version to: { version } " )
@@ -52,13 +73,18 @@ def inject_version(version: str):
5273 PYPROJECT_FILE .write_text (new_pyproject )
5374
5475def main ():
76+ dev_mode = "--dev" in sys .argv
5577 current_version = read_version_from_init (INIT_FILE )
5678 previous_version = read_version_from_git ("socketsecurity/__init__.py" )
5779
5880 print (f"Current: { current_version } , Previous: { previous_version } " )
5981
6082 if current_version == previous_version :
61- new_version = bump_dev_version (current_version )
83+ if dev_mode :
84+ base_version = current_version .split (".dev" )[0 ] if ".dev" in current_version else current_version
85+ new_version = find_next_available_dev_version (base_version )
86+ else :
87+ new_version = bump_patch_version (current_version )
6288 inject_version (new_version )
6389 print ("⚠️ Version was unchanged — auto-bumped. Please git add + commit again." )
6490 sys .exit (1 )
0 commit comments