Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions .generator/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
BUILD_REQUEST_FILE = "build-request.json"
GENERATE_REQUEST_FILE = "generate-request.json"
CONFIGURE_REQUEST_FILE = "configure-request.json"
RELEASE_INIT_REQUEST_FILE = "release-init-request.json"
RELEASE_STAGE_REQUEST_FILE = "release-stage-request.json"
STATE_YAML_FILE = "state.yaml"

INPUT_DIR = "input"
Expand Down Expand Up @@ -1433,38 +1433,38 @@ def _is_mono_repo(repo: str) -> bool:
return Path(f"{repo}/packages").exists()


def handle_release_init(
def handle_release_stage(
librarian: str = LIBRARIAN_DIR, repo: str = REPO_DIR, output: str = OUTPUT_DIR
):
"""The main coordinator for the release preparation process.

This function prepares for the release of client libraries by reading a
`librarian/release-init-request.json` file. The primary responsibility is
`librarian/release-stage-request.json` file. The primary responsibility is
to update all required files with the new version and commit information
for libraries that have the `release_triggered` field set to `True`.

See https://github.com/googleapis/librarian/blob/main/doc/container-contract.md#generate-container-command

Args:
librarian(str): Path to the directory in the container which contains
the `release-init-request.json` file.
the `release-stage-request.json` file.
repo(str): This directory will contain all directories that make up a
library, the .librarian folder, and any global file declared in
the config.yaml.
output(str): Path to the directory in the container where modified
code should be placed.

Raises:
ValueError: if the version in `release-init-request.json` is
ValueError: if the version in `release-stage-request.json` is
the same as the version in state.yaml or if the
`release-init-request.json` file in the given
`release-stage-request.json` file in the given
librarian directory cannot be read.
"""
try:
is_mono_repo = _is_mono_repo(repo)

# Read a release-init-request.json file
request_data = _read_json_file(f"{librarian}/{RELEASE_INIT_REQUEST_FILE}")
# Read a release-stage-request.json file
request_data = _read_json_file(f"{librarian}/{RELEASE_STAGE_REQUEST_FILE}")
libraries_to_prep_for_release = _get_libraries_to_prepare_for_release(
request_data
)
Expand All @@ -1488,7 +1488,7 @@ def handle_release_init(
previous_version = _get_previous_version(library_id, librarian)
if previous_version == version:
raise ValueError(
f"The version in {RELEASE_INIT_REQUEST_FILE} is the same as the version in {STATE_YAML_FILE}\n"
f"The version in {RELEASE_STAGE_REQUEST_FILE} is the same as the version in {STATE_YAML_FILE}\n"
f"{library_id} version: {previous_version}\n"
)

Expand All @@ -1506,9 +1506,9 @@ def handle_release_init(
)

except Exception as e:
raise ValueError(f"Release init failed: {e}") from e
raise ValueError(f"Release stage failed: {e}") from e

logger.info("'release-init' command executed.")
logger.info("'release-stage' command executed.")


if __name__ == "__main__": # pragma: NO COVER
Expand All @@ -1522,14 +1522,14 @@ def handle_release_init(
"configure": handle_configure,
"generate": handle_generate,
"build": handle_build,
"release-init": handle_release_init,
"release-stage": handle_release_stage,
}

for command_name, help_text in [
("configure", "Onboard a new library or an api path to Librarian workflow."),
("generate", "generate a python client for an API."),
("build", "Run unit tests via nox for the generated library."),
("release-init", "Prepare to release a given set of libraries"),
("release-stage", "Prepare to release a given set of libraries"),
]:
parser_cmd = subparsers.add_parser(command_name, help=help_text)
parser_cmd.set_defaults(func=handler_map[command_name])
Expand Down Expand Up @@ -1588,7 +1588,7 @@ def handle_release_init(
)
elif args.command == "build":
args.func(librarian=args.librarian, repo=args.repo)
elif args.command == "release-init":
elif args.command == "release-stage":
args.func(librarian=args.librarian, repo=args.repo, output=args.output)
else:
args.func()
46 changes: 23 additions & 23 deletions .generator/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
GENERATE_REQUEST_FILE,
BUILD_REQUEST_FILE,
CONFIGURE_REQUEST_FILE,
RELEASE_INIT_REQUEST_FILE,
RELEASE_STAGE_REQUEST_FILE,
SOURCE_DIR,
STATE_YAML_FILE,
LIBRARIAN_DIR,
Expand Down Expand Up @@ -75,7 +75,7 @@
handle_build,
handle_configure,
handle_generate,
handle_release_init,
handle_release_stage,
)


Expand Down Expand Up @@ -235,10 +235,10 @@ def mock_generate_request_data_for_nox():


@pytest.fixture
def mock_release_init_request_file(tmp_path, monkeypatch):
def mock_release_stage_request_file(tmp_path, monkeypatch):
"""Creates the mock request file at the correct path inside a temp dir."""
# Create the path as expected by the script: .librarian/release-request.json
request_path = f"{LIBRARIAN_DIR}/{RELEASE_INIT_REQUEST_FILE}"
request_path = f"{LIBRARIAN_DIR}/{RELEASE_STAGE_REQUEST_FILE}"
request_dir = tmp_path / os.path.dirname(request_path)
request_dir.mkdir()
request_file = request_dir / os.path.basename(request_path)
Expand Down Expand Up @@ -876,34 +876,34 @@ def test_clean_up_files_after_post_processing_success(mocker, is_mono_repo):
_clean_up_files_after_post_processing("output", "library_id", is_mono_repo)


def test_get_libraries_to_prepare_for_release(mock_release_init_request_file):
def test_get_libraries_to_prepare_for_release(mock_release_stage_request_file):
"""
Tests that only libraries with the `release_triggered` field set to `True` are
returned.
"""
request_data = _read_json_file(f"{LIBRARIAN_DIR}/{RELEASE_INIT_REQUEST_FILE}")
request_data = _read_json_file(f"{LIBRARIAN_DIR}/{RELEASE_STAGE_REQUEST_FILE}")
libraries_to_prep_for_release = _get_libraries_to_prepare_for_release(request_data)
assert len(libraries_to_prep_for_release) == 1
assert "google-cloud-language" in libraries_to_prep_for_release[0]["id"]
assert libraries_to_prep_for_release[0]["release_triggered"]


def test_handle_release_init_success(mocker, mock_release_init_request_file):
def test_handle_release_stage_success(mocker, mock_release_stage_request_file):
"""
Simply tests that `handle_release_init` runs without errors.
Simply tests that `handle_release_stage` runs without errors.
"""
mocker.patch("cli._update_global_changelog", return_value=None)
mocker.patch("cli._update_version_for_library", return_value=None)
mocker.patch("cli._get_previous_version", return_value=None)
mocker.patch("cli._update_changelog_for_library", return_value=None)
handle_release_init()
handle_release_stage()


def test_handle_release_init_is_generated_success(
mocker, mock_release_init_request_file
def test_handle_release_stage_is_generated_success(
mocker, mock_release_stage_request_file
):
"""
Tests that `handle_release_init` calls `_update_global_changelog` when the
Tests that `handle_release_stage` calls `_update_global_changelog` when the
`packages` directory exists.
"""
mocker.patch("pathlib.Path.exists", return_value=True)
Expand All @@ -912,23 +912,23 @@ def test_handle_release_init_is_generated_success(
mocker.patch("cli._get_previous_version", return_value="1.2.2")
mocker.patch("cli._update_changelog_for_library")

handle_release_init()
handle_release_stage()

mock_update_global_changelog.assert_called_once()


def test_handle_release_init_fail_value_error_file():
def test_handle_release_stage_fail_value_error_file():
"""
Tests that handle_release_init fails to read `librarian/release-init-request.json`.
Tests that handle_release_stage fails to read `librarian/release-stage-request.json`.
"""
with pytest.raises(ValueError, match="No such file or directory"):
handle_release_init()
handle_release_stage()


def test_handle_release_init_fail_value_error_version(mocker):
def test_handle_release_stage_fail_value_error_version(mocker):
m = mock_open()

mock_release_init_request_content = {
mock_release_stage_request_content = {
"libraries": [
{
"id": "google-cloud-language",
Expand All @@ -942,17 +942,17 @@ def test_handle_release_init_fail_value_error_version(mocker):
with unittest.mock.patch("cli.open", m):
mocker.patch(
"cli._get_libraries_to_prepare_for_release",
return_value=mock_release_init_request_content["libraries"],
return_value=mock_release_stage_request_content["libraries"],
)
mocker.patch("cli._get_previous_version", return_value="1.2.2")
mocker.patch("cli._process_changelog", return_value=None)
mocker.patch(
"cli._read_json_file", return_value=mock_release_init_request_content
"cli._read_json_file", return_value=mock_release_stage_request_content
)
with pytest.raises(
ValueError, match="is the same as the version in state.yaml"
):
handle_release_init()
handle_release_stage()


def test_read_valid_text_file(mocker):
Expand Down Expand Up @@ -1009,13 +1009,13 @@ def test_write_json_file():
assert written_content == expected_output


def test_update_global_changelog(mocker, mock_release_init_request_file):
def test_update_global_changelog(mocker, mock_release_stage_request_file):
"""Tests that the global changelog is updated
with the new version for a given library.
See https://docs.python.org/3/library/unittest.mock.html#mock-open
"""
m = mock_open()
request_data = _read_json_file(f"{LIBRARIAN_DIR}/{RELEASE_INIT_REQUEST_FILE}")
request_data = _read_json_file(f"{LIBRARIAN_DIR}/{RELEASE_STAGE_REQUEST_FILE}")
libraries = _get_libraries_to_prepare_for_release(request_data)

with unittest.mock.patch("cli.open", m):
Expand Down
Loading