Skip to content

Commit 514d6dc

Browse files
committed
feat: create a docs index rst file
1 parent 2eaa21d commit 514d6dc

File tree

2 files changed

+109
-2
lines changed

2 files changed

+109
-2
lines changed

.generator/cli.py

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import subprocess
2424
import sys
2525
import tempfile
26+
import textwrap
2627
import yaml
2728
from datetime import datetime
2829
from pathlib import Path
@@ -223,12 +224,68 @@ def _prepare_new_library_config(library_config: Dict) -> Dict:
223224
return library_config
224225

225226

227+
def _update_docs_index_rst(output: str, new_library_config: Dict):
228+
"""Creates or updates the docs/index.rst file for a library.
229+
230+
If the file does not exist, it will be created. If it exists, a new
231+
API reference section will be appended.
232+
233+
Args:
234+
output(str): Path to the directory where code should be generated.
235+
new_library_config(Dict): The configuration of the new library.
236+
"""
237+
library_id = _get_library_id(new_library_config)
238+
# a library can have multiple apis, but we'll use the first one to get the version
239+
api_version = Path(new_library_config["apis"][0]["path"]).name.replace("_", "-")
240+
docs_dir = Path(output) / "packages" / library_id / "docs"
241+
os.makedirs(docs_dir, exist_ok=True)
242+
index_rst_path = docs_dir / "index.rst"
243+
244+
new_api_reference = textwrap.dedent(f"""\
245+
API Reference
246+
-------------
247+
.. toctree::
248+
:maxdepth: 2
249+
250+
{api_version}/services
251+
{api_version}/types
252+
""")
253+
254+
if not index_rst_path.exists():
255+
content = textwrap.dedent(f"""\
256+
.. include:: README.rst
257+
258+
.. include:: multiprocessing.rst
259+
260+
{new_api_reference}
261+
262+
Changelog
263+
---------
264+
265+
For a list of all ``{library_id}`` releases:
266+
267+
.. toctree::
268+
:maxdepth: 2
269+
270+
CHANGELOG
271+
""")
272+
_write_text_file(str(index_rst_path), content)
273+
else:
274+
content = _read_text_file(str(index_rst_path))
275+
# a changelog is guaranteed to exist
276+
changelog_section = "Changelog\n---------"
277+
parts = content.split(changelog_section)
278+
# insert api reference before the changelog
279+
# The prepended newline is important for formatting.
280+
content = parts[0] + "\n" + new_api_reference + changelog_section + parts[1]
281+
_write_text_file(str(index_rst_path), content)
282+
226283
def handle_configure(
227284
librarian: str = LIBRARIAN_DIR,
228285
source: str = SOURCE_DIR,
229286
repo: str = REPO_DIR,
230287
input: str = INPUT_DIR,
231-
output: str = OUTPUT_DIR
288+
output: str = OUTPUT_DIR,
232289
):
233290
"""Onboards a new library by completing its configuration.
234291
@@ -259,13 +316,14 @@ def handle_configure(
259316
# configure-request.json contains the library definitions.
260317
request_data = _read_json_file(f"{librarian}/{CONFIGURE_REQUEST_FILE}")
261318
new_library_config = _get_new_library_config(request_data)
262-
319+
263320
_update_global_changelog(
264321
f"{repo}/CHANGELOG.md",
265322
f"{output}/CHANGELOG.md",
266323
[new_library_config],
267324
)
268325
prepared_config = _prepare_new_library_config(new_library_config)
326+
_update_docs_index_rst(output, new_library_config)
269327

270328
# Write the new library configuration to configure-response.json.
271329
_write_json_file(f"{librarian}/configure-response.json", prepared_config)

.generator/test_cli.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
_stage_gapic_library,
6565
_stage_proto_only_library,
6666
_update_changelog_for_library,
67+
_update_docs_index_rst,
6768
_update_global_changelog,
6869
_update_version_for_library,
6970
_verify_library_dist_name,
@@ -1514,3 +1515,51 @@ def test_stage_gapic_library(mocker):
15141515
mock_shutil_copytree.assert_called_once_with(
15151516
tmp_dir, staging_dir, dirs_exist_ok=True
15161517
)
1518+
1519+
1520+
class TestUpdateDocsIndexRst:
1521+
@pytest.fixture
1522+
def mock_new_library_config(self):
1523+
return {
1524+
"id": "google-cloud-test",
1525+
"apis": [{"path": "google/cloud/test/v1"}],
1526+
}
1527+
1528+
def test_creates_new_file_when_not_exists(
1529+
self, mocker, mock_new_library_config
1530+
):
1531+
mocker.patch("os.makedirs")
1532+
mock_path_exists = mocker.patch("pathlib.Path.exists", return_value=False)
1533+
mock_write_text_file = mocker.patch("cli._write_text_file")
1534+
1535+
_update_docs_index_rst("output", mock_new_library_config)
1536+
1537+
mock_path_exists.assert_called_once()
1538+
mock_write_text_file.assert_called_once()
1539+
# Verify that the content contains the expected sections
1540+
written_content = mock_write_text_file.call_args[0][1]
1541+
assert "API Reference" in written_content
1542+
assert "v1/services" in written_content
1543+
assert "Changelog" in written_content
1544+
1545+
def test_updates_existing_file(self, mocker, mock_new_library_config):
1546+
mocker.patch("os.makedirs")
1547+
mock_path_exists = mocker.patch("pathlib.Path.exists", return_value=True)
1548+
mock_read_text_file = mocker.patch(
1549+
"cli._read_text_file",
1550+
return_value=".. include:: README.rst\n\nChangelog\n---------",
1551+
)
1552+
mock_write_text_file = mocker.patch("cli._write_text_file")
1553+
1554+
_update_docs_index_rst("output", mock_new_library_config)
1555+
1556+
mock_path_exists.assert_called_once()
1557+
mock_read_text_file.assert_called_once()
1558+
mock_write_text_file.assert_called_once()
1559+
# Verify that the new API reference is inserted before the changelog
1560+
written_content = mock_write_text_file.call_args[0][1]
1561+
assert "API Reference" in written_content
1562+
assert "v1/services" in written_content
1563+
assert written_content.find("API Reference") < written_content.find(
1564+
"Changelog"
1565+
)

0 commit comments

Comments
 (0)