1616
1717def parse_version (version : str ) -> tuple [int , int , int , int , int ]:
1818 """Parse a version string into its components.
19-
19+
2020 Args:
2121 version: Version string (e.g., "1.3.1", "1.3.2.rc3" or "1.3.1.post2")
22-
22+
2323 Returns:
2424 Tuple of (major, minor, patch, post, rc)
25-
25+
2626 Raises:
2727 ValueError: If version format is invalid
2828 """
2929 match = VERSION_RE .match (version )
3030 if not match :
3131 raise ValueError (f"Invalid version format: { version } (expected X.Y.Z, X.Y.Z.rcM or X.Y.Z.postN)" )
32-
32+
3333 major , minor , patch , rc , post = match .groups ()
3434 return int (major ), int (minor ), int (patch ), int (post or 0 ), int (rc or 0 )
3535
3636
3737def format_version (major : int , minor : int , patch : int , post : int = 0 , rc : int = 0 ) -> str :
3838 """Format version components into a version string.
39-
39+
4040 Args:
4141 major: Major version number
42- minor: Minor version number
42+ minor: Minor version number
4343 patch: Patch version number
4444 post: Post-release number
4545 rc: RC number
46-
46+
4747 Returns:
4848 Formatted version string
4949 """
@@ -59,31 +59,31 @@ def format_version(major: int, minor: int, patch: int, post: int = 0, rc: int =
5959
6060def git_tag_to_pep440 (git_tag : str ) -> str :
6161 """Convert git tag format to PEP440 format.
62-
62+
6363 Args:
6464 git_tag: Git tag (e.g., "v1.3.1", "v1.3.1-post1")
65-
65+
6666 Returns:
6767 PEP440 version string (e.g., "1.3.1", "1.3.1.post1")
6868 """
6969 # Remove 'v' prefix if present
7070 version = git_tag [1 :] if git_tag .startswith ('v' ) else git_tag
71-
71+
7272 if "-post" in version :
7373 assert 'rc' not in version
7474 version = version .replace ("-post" , ".post" )
7575 elif '-rc' in version :
7676 version = version .replace ("-rc" , "rc" )
77-
77+
7878 return version
7979
8080
8181def pep440_to_git_tag (version : str ) -> str :
8282 """Convert PEP440 version to git tag format.
83-
83+
8484 Args:
8585 version: PEP440 version string (e.g., "1.3.1.post1" or "1.3.1rc2")
86-
86+
8787 Returns:
8888 Git tag format (e.g., "v1.3.1-post1")
8989 """
@@ -98,7 +98,7 @@ def pep440_to_git_tag(version: str) -> str:
9898
9999def get_current_version () -> Optional [str ]:
100100 """Get the current version from git tags.
101-
101+
102102 Returns:
103103 Current version string or None if no tags exist
104104 """
@@ -149,16 +149,21 @@ def strip_post_from_version(version: str) -> str:
149149 return re .sub (r"[\.-]post[0-9]+" , "" , version )
150150
151151
152- def get_git_describe (repo_path : Optional [pathlib .Path ] = None ) -> Optional [str ]:
152+ def get_git_describe (repo_path : Optional [pathlib .Path ] = None , since_major = False , since_minor = False ) -> Optional [str ]:
153153 """Get git describe output for version determination.
154-
154+
155155 Returns:
156156 Git describe output or None if no tags exist
157157 """
158158 cwd = repo_path if repo_path is not None else None
159+ pattern = "v*.*.*"
160+ if since_major :
161+ pattern = "v*.0.0"
162+ elif since_minor :
163+ pattern = "v*.*.0"
159164 try :
160165 result = subprocess .run (
161- ["git" , "describe" , "--tags" , "--long" , "--match" , "v*.*.*" ],
166+ ["git" , "describe" , "--tags" , "--long" , "--match" , pattern ],
162167 capture_output = True ,
163168 text = True ,
164169 check = True ,
@@ -167,4 +172,4 @@ def get_git_describe(repo_path: Optional[pathlib.Path] = None) -> Optional[str]:
167172 result .check_returncode ()
168173 return result .stdout .strip ()
169174 except FileNotFoundError :
170- raise RuntimeError ("git executable can't be found" )
175+ raise RuntimeError ("git executable can't be found" )
0 commit comments