Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
giswqs
GitHub Repository: giswqs/geemap
Path: blob/master/scripts/bump_geemap_version.py
2313 views
1
#!/usr/bin/env python3
2
"""Bump version numbers in pyproject.toml and geemap/__init__.py.
3
4
This script updates the version in two places in pyproject.toml:
5
1. [project] section: version = "..."
6
2. [tool.bumpversion] section: current_version = "..."
7
8
And updates __version__ in geemap/__init__.py:
9
__version__ = "..."
10
11
Usage:
12
python scripts/bump_geemap_version.py NEW_VERSION
13
14
Example:
15
python scripts/bump_geemap_version.py 0.36.5
16
"""
17
18
import pathlib
19
import re
20
import sys
21
22
23
def update_pyproject_toml(file_path: pathlib.Path, new_version: str) -> bool:
24
"""Update version in pyproject.toml (two occurrences)."""
25
content = file_path.read_text()
26
original_content = content
27
28
# Pattern 1: [project] section version
29
project_pattern = r'(^\[project\](?:.*?\n)*?version\s*=\s*)"([^"]+)"'
30
# Pattern 2: [tool.bumpversion] section current_version
31
bumpversion_pattern = (
32
r'(^\[tool\.bumpversion\](?:.*?\n)*?current_version\s*=\s*)"([^"]+)"'
33
)
34
35
# Check if both patterns exist
36
project_match = re.search(project_pattern, content, re.MULTILINE | re.DOTALL)
37
bumpversion_match = re.search(
38
bumpversion_pattern, content, re.MULTILINE | re.DOTALL
39
)
40
41
if not project_match:
42
print(
43
"ERROR: Could not find 'version = \"...\"' in [project] section of "
44
"pyproject.toml"
45
)
46
return False
47
48
if not bumpversion_match:
49
print(
50
"ERROR: Could not find 'current_version = \"...\"' in "
51
"[tool.bumpversion] section of pyproject.toml"
52
)
53
return False
54
55
old_project_version = project_match.group(2)
56
old_bumpversion = bumpversion_match.group(2)
57
58
print(f"Found project version: {old_project_version}")
59
print(f"Found bumpversion: {old_bumpversion}")
60
61
# Replace both occurrences
62
# Use a more targeted approach to replace only the specific lines
63
lines = content.split("\n")
64
new_lines = []
65
in_project = False
66
in_bumpversion = False
67
project_replaced = False
68
bumpversion_replaced = False
69
70
for line in lines:
71
stripped_line = line.strip()
72
73
# State tracking for sections
74
if stripped_line == "[project]":
75
in_project = True
76
in_bumpversion = False
77
elif stripped_line == "[tool.bumpversion]":
78
in_bumpversion = True
79
in_project = False
80
elif stripped_line.startswith("["): # End of previous section
81
in_project = False
82
in_bumpversion = False
83
84
# --- Replacement Logic ---
85
# 1. Replace in [project] section
86
if (
87
in_project
88
and not project_replaced
89
and re.match(r'^version\s*=\s*"', stripped_line)
90
):
91
new_lines.append(f'version = "{new_version}"')
92
project_replaced = True
93
94
# 2. Replace in [tool.bumpversion] section
95
elif (
96
in_bumpversion
97
and not bumpversion_replaced
98
and re.match(r'^current_version\s*=\s*"', stripped_line)
99
):
100
new_lines.append(f'current_version = "{new_version}"')
101
bumpversion_replaced = True
102
103
else:
104
new_lines.append(line)
105
106
if not project_replaced or not bumpversion_replaced:
107
print("ERROR: Failed to replace version strings in pyproject.toml")
108
return False
109
110
new_content = "\n".join(new_lines)
111
112
if new_content != original_content:
113
file_path.write_text(new_content)
114
print(f"✓ Updated pyproject.toml to {new_version}")
115
return True
116
else:
117
print("ERROR: No changes made to pyproject.toml")
118
return False
119
120
121
def update_init_py(file_path: pathlib.Path, new_version: str) -> bool:
122
"""Update __version__ in geemap/__init__.py."""
123
content = file_path.read_text()
124
original_content = content
125
126
# Pattern: __version__ = "..."
127
pattern = r'^__version__\s*=\s*"([^"]+)"'
128
129
if not re.search(pattern, content, re.MULTILINE):
130
print("ERROR: Could not find '__version__ = \"...\"' in geemap/__init__.py")
131
return False
132
133
# Replace the version
134
new_content = re.sub(
135
pattern, f'__version__ = "{new_version}"', content, flags=re.MULTILINE
136
)
137
138
if new_content != original_content:
139
file_path.write_text(new_content)
140
print(f"✓ Updated geemap/__init__.py to {new_version}")
141
return True
142
else:
143
print("ERROR: No changes made to geemap/__init__.py")
144
return False
145
146
147
def update_version(new_version: str) -> bool:
148
"""Updates the version number in pyproject.toml and geemap/__init__.py.
149
150
Args:
151
new_version: The new version string to set.
152
153
Returns:
154
True if the version was successfully updated in both files, False otherwise.
155
"""
156
# Validate version format (basic check)
157
if not re.match(r"^\d+\.\d+\.\d+(rc\d+|\.post\d+)*$", new_version):
158
print(f"ERROR: Invalid version format: {new_version}")
159
print("Expected format: X.Y.Z, X.Y.ZrcN, or X.Y.Z.postN (e.g., 0.36.5.post0)")
160
return False
161
162
print(f"\nBumping version to: {new_version}\n")
163
164
# Get repository root (assuming script is in scripts/ directory)
165
repo_root = pathlib.Path(__file__).parent.parent
166
167
pyproject_path = repo_root / "pyproject.toml"
168
init_path = repo_root / "geemap" / "__init__.py"
169
170
# Check files exist
171
if not pyproject_path.exists():
172
print(f"ERROR: pyproject.toml not found at {pyproject_path}")
173
return False
174
175
if not init_path.exists():
176
print(f"ERROR: geemap/__init__.py not found at {init_path}")
177
return False
178
179
# --- FAIL FAST Implementation ---
180
# Update pyproject.toml and exit if failed
181
if not update_pyproject_toml(pyproject_path, new_version):
182
print("\n✗ Version bump failed in pyproject.toml! Halting.")
183
return False
184
185
# Update geemap/__init__.py and exit if failed
186
if not update_init_py(init_path, new_version):
187
print("\n✗ Version bump failed in geemap/__init__.py! Halting.")
188
return False
189
190
print("\n✓ Version bump completed successfully!")
191
return True
192
193
194
def main() -> None:
195
if len(sys.argv) != 2:
196
print("Usage: python scripts/bump_geemap_version.py NEW_VERSION")
197
print("Example: python scripts/bump_geemap_version.py 0.36.5")
198
sys.exit(1)
199
200
new_version = sys.argv[1]
201
202
if not update_version(new_version):
203
sys.exit(1)
204
205
206
if __name__ == "__main__":
207
main()
208
209