Skip to content

Commit 55beea6

Browse files
committed
prepare new library config
1 parent c0dd263 commit 55beea6

File tree

2 files changed

+144
-24
lines changed

2 files changed

+144
-24
lines changed

.generator/cli.py

Lines changed: 85 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -114,31 +114,103 @@ def _write_json_file(path: str, updated_content: Dict):
114114
with open(path, "w") as f:
115115
json.dump(updated_content, f, indent=2)
116116
f.write("\n")
117-
117+
118+
def _add_new_library_source_roots(library_config: Dict, library_id: str) -> None:
119+
"""Adds the default source_roots to the library configuration if not present.
120+
121+
Args:
122+
library_config(Dict): The library configuration.
123+
library_id(str): The id of the library.
124+
"""
125+
if library_config["source_roots"] is None:
126+
library_config["source_roots"] = [f"packages/{library_id}"]
127+
128+
129+
def _add_new_library_preserve_regex(library_config: Dict, library_id: str) -> None:
130+
"""Adds the default preserve_regex to the library configuration if not present.
131+
132+
Args:
133+
library_config(Dict): The library configuration.
134+
library_id(str): The id of the library.
135+
"""
136+
if library_config["preserve_regex"] is None:
137+
library_config["preserve_regex"] = [
138+
f"packages/{library_id}/CHANGELOG.md",
139+
"docs/CHANGELOG.md",
140+
"docs/README.rst",
141+
"samples/README.txt",
142+
"tar.gz",
143+
"gapic_version.py",
144+
"scripts/client-post-processing",
145+
"samples/snippets/README.rst",
146+
"tests/system",
147+
]
148+
149+
150+
def _add_new_library_remove_regex(library_config: Dict, library_id: str) -> None:
151+
"""Adds the default remove_regex to the library configuration if not present.
152+
153+
Args:
154+
library_config(Dict): The library configuration.
155+
library_id(str): The id of the library.
156+
"""
157+
if library_config["remove_regex"] is None:
158+
library_config["remove_regex"] = [f"packages/{library_id}"]
159+
160+
161+
def _add_new_library_tag_format(library_config: Dict) -> None:
162+
"""Adds the default tag_format to the library configuration if not present.
163+
164+
Args:
165+
library_config(Dict): The library configuration.
166+
"""
167+
if "tag_format" not in library_config:
168+
library_config["tag_format"] = "{{id}}-v{{version}}"
169+
170+
118171
def _get_new_library_config(request_data: Dict) -> Dict:
119-
"""Returns the configuration for a new library.
172+
"""Finds and returns the configuration for a new library.
120173
121174
Args:
122175
request_data(Dict): The request data from which to extract the new
123176
library config.
124177
125178
Returns:
126-
Dict: The configuration of a new library.
179+
Dict: The unmodified configuration of a new library, or an empty
180+
dictionary if not found.
127181
"""
128-
new_library_config = {}
129182
for library_config in request_data.get("libraries", []):
130183
all_apis = library_config.get("apis", [])
131184
for api in all_apis:
132185
if api.get("status") == "new":
133-
new_library_config = library_config
134-
break
135-
186+
return library_config
187+
return {}
188+
189+
190+
def _prepare_new_library_config(library_config: Dict) -> Dict:
191+
"""
192+
Prepares the new library's configuration by removing temporary keys and
193+
adding default values.
194+
195+
Args:
196+
library_config (Dict): The raw library configuration.
197+
198+
Returns:
199+
Dict: The prepared library configuration.
200+
"""
136201
# remove status key from new library config.
137-
all_apis = new_library_config.get("apis", [])
202+
all_apis = library_config.get("apis", [])
138203
for api in all_apis:
139-
del api["status"]
140-
141-
return new_library_config
204+
if "status" in api:
205+
del api["status"]
206+
207+
library_id = _get_library_id(library_config)
208+
_add_new_library_source_roots(library_config, library_id)
209+
_add_new_library_preserve_regex(library_config, library_id)
210+
_add_new_library_remove_regex(library_config, library_id)
211+
_add_new_library_tag_format(library_config)
212+
213+
return library_config
142214

143215

144216
def handle_configure(
@@ -174,9 +246,10 @@ def handle_configure(
174246
# configure-request.json contains the library definitions.
175247
request_data = _read_json_file(f"{librarian}/{CONFIGURE_REQUEST_FILE}")
176248
new_library_config = _get_new_library_config(request_data)
249+
prepared_config = _prepare_new_library_config(new_library_config)
177250

178251
# Write the new library configuration to configure-response.json.
179-
_write_json_file(f"{librarian}/configure-response.json", new_library_config)
252+
_write_json_file(f"{librarian}/configure-response.json", prepared_config)
180253

181254
except Exception as e:
182255
raise ValueError("Configuring a new library failed.") from e

.generator/test_cli.py

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
_get_libraries_to_prepare_for_release,
4747
_get_new_library_config,
4848
_get_previous_version,
49+
_prepare_new_library_config,
4950
_process_changelog,
5051
_process_version_file,
5152
_read_bazel_build_py_rule,
@@ -267,36 +268,39 @@ def mock_state_file(tmp_path, monkeypatch):
267268
return request_file
268269

269270

270-
def test_handle_configure(mock_configure_request_file, mocker):
271+
def test_handle_configure_success(mock_configure_request_file, mocker):
271272
"""Tests the successful execution path of handle_configure."""
272273
mock_write_json = mocker.patch("cli._write_json_file")
274+
mock_prepare_config = mocker.patch(
275+
"cli._prepare_new_library_config", return_value={"id": "prepared"}
276+
)
273277

274278
handle_configure()
275279

276-
# Verify that the correct configuration is written to the response file.
277-
expected_config = {
278-
"id": "google-cloud-language",
279-
"apis": [{"path": "google/cloud/language/v1"}],
280-
}
280+
mock_prepare_config.assert_called_once()
281281
mock_write_json.assert_called_once_with(
282-
f"{LIBRARIAN_DIR}/configure-response.json", expected_config
282+
f"{LIBRARIAN_DIR}/configure-response.json", {"id": "prepared"}
283283
)
284284

285285

286-
def test_handle_configure_failure(mocker):
287-
"""Tests that handle_configure raises ValueError on failure."""
286+
def test_handle_configure_no_new_library(mocker):
287+
"""Tests that handle_configure fails if no new library is found."""
288+
mocker.patch("cli._read_json_file", return_value={"libraries": []})
289+
# The call to _prepare_new_library_config with an empty dict will raise a ValueError
290+
# because _get_library_id will fail.
288291
with pytest.raises(ValueError, match="Configuring a new library failed."):
289292
handle_configure()
290293

291294

292-
def test_get_new_library_config_new_library_found(mock_configure_request_data):
295+
def test_get_new_library_config_found(mock_configure_request_data):
293296
"""Tests that the new library configuration is returned when found."""
294297
config = _get_new_library_config(mock_configure_request_data)
295298
assert config["id"] == "google-cloud-language"
296-
assert "status" not in config["apis"][0]
299+
# Assert that the config is NOT modified
300+
assert "status" in config["apis"][0]
297301

298302

299-
def test_get_new_library_config_no_new_library():
303+
def test_get_new_library_config_not_found():
300304
"""Tests that an empty dictionary is returned when no new library is found."""
301305
request_data = {
302306
"libraries": [
@@ -313,6 +317,49 @@ def test_get_new_library_config_empty_input():
313317
assert config == {}
314318

315319

320+
def test_prepare_new_library_config():
321+
"""Tests the preparation of a new library's configuration."""
322+
raw_config = {
323+
"id": "google-cloud-language",
324+
"apis": [{"path": "google/cloud/language/v1", "status": "new"}],
325+
"source_roots": None,
326+
"preserve_regex": None,
327+
"remove_regex": None,
328+
}
329+
330+
prepared_config = _prepare_new_library_config(raw_config)
331+
332+
# Check that status is removed
333+
assert "status" not in prepared_config["apis"][0]
334+
# Check that defaults are added
335+
assert prepared_config["source_roots"] == ["packages/google-cloud-language"]
336+
assert "packages/google-cloud-language/CHANGELOG.md" in prepared_config["preserve_regex"]
337+
assert prepared_config["remove_regex"] == ["packages/google-cloud-language"]
338+
assert prepared_config["tag_format"] == "{{id}}-v{{version}}"
339+
340+
341+
def test_prepare_new_library_config_preserves_existing_values():
342+
"""Tests that existing values in the config are not overwritten."""
343+
raw_config = {
344+
"id": "google-cloud-language",
345+
"apis": [{"path": "google/cloud/language/v1", "status": "new"}],
346+
"source_roots": ["packages/google-cloud-language-custom"],
347+
"preserve_regex": ["custom/regex"],
348+
"remove_regex": ["custom/remove"],
349+
"tag_format": "custom-format-{{version}}",
350+
}
351+
352+
prepared_config = _prepare_new_library_config(raw_config)
353+
354+
# Check that status is removed
355+
assert "status" not in prepared_config["apis"][0]
356+
# Check that existing values are preserved
357+
assert prepared_config["source_roots"] == ["packages/google-cloud-language-custom"]
358+
assert prepared_config["preserve_regex"] == ["custom/regex"]
359+
assert prepared_config["remove_regex"] == ["custom/remove"]
360+
assert prepared_config["tag_format"] == "custom-format-{{version}}"
361+
362+
316363
def test_get_library_id_success():
317364
"""Tests that _get_library_id returns the correct ID when present."""
318365
request_data = {"id": "test-library", "name": "Test Library"}

0 commit comments

Comments
 (0)