bazel_roller: Move some logic to bazel module
Bug: b/245397913
Change-Id: Ie97605a26859ef59d601c3ed77f61e2f228a4851
Reviewed-on: https://pigweed-review.googlesource.com/c/infra/recipes/+/208531
Lint: Lint 🤖 <android-build-ayeaye@system.gserviceaccount.com>
Reviewed-by: Ted Pudlik <tpudlik@google.com>
Commit-Queue: Rob Mohr <mohrr@google.com>
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/recipe_modules/bazel/api.py b/recipe_modules/bazel/api.py
index 6c77bcd..597d1c5 100644
--- a/recipe_modules/bazel/api.py
+++ b/recipe_modules/bazel/api.py
@@ -13,14 +13,18 @@
# the License.
"""Bazel-related functions."""
+from __future__ import annotations
+
import dataclasses
-from typing import Any
+import re
+from typing import Any, Sequence, TypeVar, TYPE_CHECKING
from PB.recipe_modules.pigweed.bazel.options import Options
-from RECIPE_MODULES.pigweed.checkout import api as checkout_api
-
from recipe_engine import config_types, recipe_api
+if TYPE_CHECKING: # pragma: no cover
+ from RECIPE_MODULES.pigweed.checkout import api as checkout_api
+
# This is copied from bazel.json in Pigweed, but there's no need to keep it
# up-to-date.
@@ -109,14 +113,135 @@
self.api.step(name, [self.ensure(), *invocation.args], **kwargs)
+def nwise(iterable, n):
+ # nwise('ABCDEFG', 3) → ABC BCD CDE DEF EFG
+ # See also
+ # https://docs.python.org/3/library/itertools.html#itertools.pairwise
+ iterator = iter(iterable)
+ initial_items = [None]
+ for i in range(1, n):
+ initial_items.append(next(iterator, None))
+ items = tuple(initial_items)
+ for x in iterator:
+ items = (*items[1:], x)
+ yield items
+
+
+T = TypeVar('T')
+
+
+def proximity_sort_nearby_lines(lines: Sequence[T]) -> list[T]:
+ # Shift the order to be center-out instead of ascending.
+ lines = [(abs(len(lines) // 2 - i), x) for i, x in enumerate(lines)]
+ return [x[1] for x in sorted(lines)]
+
+
+@dataclasses.dataclass
+class UpdateCommitHashResult:
+ old_revision: str
+ project_name: str | None
+
+
class BazelApi(recipe_api.RecipeApi):
"""Bazel utilities."""
BazelRunner = BazelRunner
+ UpdateCommitHashResult = UpdateCommitHashResult
def new_runner(
self,
checkout: checkout_api.CheckoutContext,
- options: Options,
+ options: Options | None,
) -> BazelRunner:
return BazelRunner(self.m, checkout.root, options)
+
+ def update_commit_hash(
+ self,
+ *,
+ checkout: checkout_api.CheckoutContext,
+ project_remote: str,
+ new_revision: str,
+ num_nearby_lines: int = 2,
+ path: config_types.Path | None,
+ ) -> UpdateCommitHashResult:
+ if not path:
+ path = checkout.root / 'WORKSPACE'
+
+ lines = [''] * num_nearby_lines
+ lines.extend(
+ self.m.file.read_text(
+ f'read old {path.name}',
+ path,
+ test_data=self.m.bazel.test_api.TEST_WORKSPACE_FILE,
+ )
+ .strip()
+ .splitlines()
+ )
+ lines.extend([''] * num_nearby_lines)
+
+ for nearby_lines in nwise(enumerate(lines), num_nearby_lines * 2 + 1):
+ i, curr = nearby_lines[len(nearby_lines) // 2]
+ match = re.search(
+ r'^\s*remote\s*=\s*"(?P<remote>[^"]+)",?\s*$', curr
+ )
+ if not match:
+ continue
+
+ match_remote = match.group('remote')
+
+ step = self.m.step.empty(f'found remote {match_remote!r}')
+ if checkout.remotes_equivalent(match_remote, project_remote):
+ step.presentation.step_summary_text = 'equivalent'
+ break
+ step.presentation.step_summary_text = 'not equivalent'
+
+ else:
+ self.m.step.empty(
+ f'could not find remote {project_remote} in {path}',
+ status='FAILURE',
+ )
+
+ nearby_lines = proximity_sort_nearby_lines(nearby_lines)
+
+ commit_rx = re.compile(
+ r'^(?P<prefix>\s*commit\s*=\s*")'
+ r'(?P<commit>[0-9a-f]{40})'
+ r'(?P<suffix>",?\s*)$'
+ )
+
+ for i, line in nearby_lines:
+ if match := commit_rx.search(line):
+ idx = i
+ break
+ else:
+ self.m.step.empty(
+ f'could not find commit line adjacent to {curr!r} in {path}',
+ status='FAILURE',
+ )
+
+ old_revision = match.group('commit')
+
+ prefix = match.group("prefix")
+ suffix = match.group("suffix")
+ lines[idx] = f'{prefix}{new_revision}{suffix}'
+
+ project_name: str | None = None
+ for i, line in nearby_lines:
+ if match := re.search(
+ r'^\s*name\s*=\s*"(?P<name>[^"]+)",?\s*$', line
+ ):
+ project_name = match.group('name')
+ break
+
+ self.m.file.write_text(
+ f'write new {path.name}',
+ path,
+ ''.join(
+ f'{x}\n' for x in lines[num_nearby_lines:-num_nearby_lines]
+ ),
+ )
+
+ return UpdateCommitHashResult(
+ old_revision=old_revision,
+ project_name=project_name,
+ )
diff --git a/recipe_modules/bazel/test_api.py b/recipe_modules/bazel/test_api.py
index 4a9dcdd..53a0bbc 100644
--- a/recipe_modules/bazel/test_api.py
+++ b/recipe_modules/bazel/test_api.py
@@ -19,9 +19,32 @@
from recipe_engine import recipe_test_api
+TEST_WORKSPACE_FILE = """
+git_repository(
+ name = "other-repo"
+ remote = "https://pigweed.googlesource.com/other/repo.git",
+ commit = "invalid commit line won't be found",
+)
+
+git_repository(
+ name = "pigweed",
+ commit = "1111111111111111111111111111111111111111",
+ remote = "https://pigweed.googlesource.com/pigweed/pigweed.git",
+)
+
+git_repository(
+ name = "missing final quote/comma so will miss this line
+ remote = "https://pigweed.googlesource.com/third/repo.git",
+ commit = "2222222222222222222222222222222222222222",
+)
+"""
+
+
class BazelTestApi(recipe_test_api.RecipeTestApi):
"""Test API for Bazel."""
+ TEST_WORKSPACE_FILE = TEST_WORKSPACE_FILE
+
def options(
self,
*,
diff --git a/recipe_modules/bazel/tests/update_commit_hash.expected/success.json b/recipe_modules/bazel/tests/update_commit_hash.expected/success.json
new file mode 100644
index 0000000..9225313
--- /dev/null
+++ b/recipe_modules/bazel/tests/update_commit_hash.expected/success.json
@@ -0,0 +1,584 @@
+[
+ {
+ "cmd": [],
+ "name": "checkout super"
+ },
+ {
+ "cmd": [],
+ "name": "checkout super.options",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_SUMMARY_TEXT@remote: \"https://pigweed.googlesource.com/super\"\n@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout super.options with defaults",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_SUMMARY_TEXT@remote: \"https://pigweed.googlesource.com/super\"\nmanifest_file: \"default.xml\"\nrepo_init_timeout_sec: 20\nrepo_sync_timeout_sec: 120\nnumber_of_attempts: 3\nsubmodule_timeout_sec: 600\n@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout super.not matching branch names",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout super.cache",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_SUMMARY_TEXT@miss@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "ensure-directory",
+ "--mode",
+ "0o777",
+ "[CACHE]/git"
+ ],
+ "infra_step": true,
+ "name": "checkout super.cache.ensure git cache dir",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "copy",
+ "",
+ "[CACHE]/git/.GUARD_FILE"
+ ],
+ "infra_step": true,
+ "name": "checkout super.cache.write git cache guard file",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "ensure-directory",
+ "--mode",
+ "0o777",
+ "[CACHE]/git/pigweed.googlesource.com-super"
+ ],
+ "infra_step": true,
+ "name": "checkout super.cache.makedirs",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "init"
+ ],
+ "cwd": "[CACHE]/git/pigweed.googlesource.com-super",
+ "infra_step": true,
+ "name": "checkout super.cache.git init",
+ "timeout": 300.0,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "config",
+ "remote.origin.url",
+ "https://pigweed.googlesource.com/super"
+ ],
+ "cwd": "[CACHE]/git/pigweed.googlesource.com-super",
+ "infra_step": true,
+ "name": "checkout super.cache.remote set-url",
+ "timeout": 300.0,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "config",
+ "fetch.uriprotocols",
+ "https"
+ ],
+ "cwd": "[CACHE]/git/pigweed.googlesource.com-super",
+ "infra_step": true,
+ "name": "checkout super.cache.set fetch.uriprotocols",
+ "timeout": 300.0,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout super.cache.timeout 10s",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "fetch",
+ "--prune",
+ "--tags",
+ "--jobs",
+ "4",
+ "origin",
+ "--no-recurse-submodules"
+ ],
+ "cwd": "[CACHE]/git/pigweed.googlesource.com-super",
+ "infra_step": true,
+ "name": "checkout super.cache.git fetch",
+ "timeout": 1200.0,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "merge",
+ "FETCH_HEAD"
+ ],
+ "cwd": "[CACHE]/git/pigweed.googlesource.com-super",
+ "infra_step": true,
+ "name": "checkout super.cache.git merge",
+ "timeout": 600.0,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout super.cache.timeout 10s (2)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "submodule",
+ "update",
+ "--recursive",
+ "--force",
+ "--jobs",
+ "4"
+ ],
+ "cwd": "[CACHE]/git/pigweed.googlesource.com-super",
+ "infra_step": true,
+ "name": "checkout super.cache.git submodule update",
+ "timeout": 600,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "remove",
+ "[CACHE]/git/.GUARD_FILE"
+ ],
+ "infra_step": true,
+ "name": "checkout super.cache.remove git cache guard file",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "copytree",
+ "--symlinks",
+ "[CACHE]/git/pigweed.googlesource.com-super",
+ "[START_DIR]/co"
+ ],
+ "infra_step": true,
+ "name": "checkout super.copy from cache",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout super.git checkout",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout super.git checkout.timeout 10s",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "ensure-directory",
+ "--mode",
+ "0o777",
+ "[START_DIR]/co"
+ ],
+ "infra_step": true,
+ "luci_context": {
+ "deadline": {
+ "grace_period": 30.0,
+ "soft_deadline": 1337000019.0
+ }
+ },
+ "name": "checkout super.git checkout.makedirs",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "init"
+ ],
+ "cwd": "[START_DIR]/co",
+ "infra_step": true,
+ "name": "checkout super.git checkout.git init",
+ "timeout": 300.0,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "remote",
+ "add",
+ "origin",
+ "https://pigweed.googlesource.com/super"
+ ],
+ "cwd": "[START_DIR]/co",
+ "infra_step": true,
+ "name": "checkout super.git checkout.git remote",
+ "timeout": 600.0,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "config",
+ "core.longpaths",
+ "true"
+ ],
+ "cwd": "[START_DIR]/co",
+ "infra_step": true,
+ "name": "checkout super.git checkout.set core.longpaths",
+ "timeout": 300.0,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "config",
+ "fetch.uriprotocols",
+ "https"
+ ],
+ "cwd": "[START_DIR]/co",
+ "infra_step": true,
+ "name": "checkout super.git checkout.set fetch.uriprotocols",
+ "timeout": 300.0,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "fetch",
+ "--tags",
+ "--jobs",
+ "4",
+ "origin",
+ "main"
+ ],
+ "cwd": "[START_DIR]/co",
+ "infra_step": true,
+ "name": "checkout super.git checkout.git fetch",
+ "timeout": 1200.0,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "checkout",
+ "-f",
+ "FETCH_HEAD"
+ ],
+ "cwd": "[START_DIR]/co",
+ "infra_step": true,
+ "name": "checkout super.git checkout.git checkout",
+ "timeout": 600.0,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "rev-parse",
+ "HEAD"
+ ],
+ "cwd": "[START_DIR]/co",
+ "infra_step": true,
+ "name": "checkout super.git checkout.git rev-parse",
+ "timeout": 300.0,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "clean",
+ "-f",
+ "-d",
+ "-x"
+ ],
+ "cwd": "[START_DIR]/co",
+ "infra_step": true,
+ "name": "checkout super.git checkout.git clean",
+ "timeout": 600.0,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout super.git log",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "log",
+ "--oneline",
+ "-n",
+ "10"
+ ],
+ "cwd": "[START_DIR]/co",
+ "name": "checkout super.git log.[START_DIR]/co",
+ "timeout": 600.0,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "ensure-directory",
+ "--mode",
+ "0o777",
+ "[START_DIR]/snapshot"
+ ],
+ "infra_step": true,
+ "name": "checkout super.mkdir",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "submodule",
+ "status",
+ "--recursive"
+ ],
+ "cwd": "[START_DIR]/co",
+ "name": "checkout super.submodule-status",
+ "timeout": 600.0,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "copy",
+ "submodule status filler text",
+ "[START_DIR]/snapshot/submodules.log"
+ ],
+ "infra_step": true,
+ "name": "checkout super.write submodule snapshot",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LOG_LINE@submodules.log@submodule status filler text@@@",
+ "@@@STEP_LOG_END@submodules.log@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "log",
+ "--oneline",
+ "-n",
+ "10"
+ ],
+ "cwd": "[START_DIR]/co",
+ "name": "checkout super.log",
+ "timeout": 600.0,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "copy",
+ "",
+ "[START_DIR]/snapshot/git.log"
+ ],
+ "infra_step": true,
+ "name": "checkout super.write git log",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LOG_END@git.log@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "copy",
+ "[START_DIR]/co/WORKSPACE",
+ "/path/to/tmp/"
+ ],
+ "infra_step": true,
+ "name": "read old WORKSPACE",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@WORKSPACE@@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"other-repo\"@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/other/repo.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"invalid commit line won't be found\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"pigweed\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"1111111111111111111111111111111111111111\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"missing final quote/comma so will miss this line@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/third/repo.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
+ "@@@STEP_LOG_END@WORKSPACE@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "found remote 'https://pigweed.googlesource.com/other/repo.git'",
+ "~followup_annotations": [
+ "@@@STEP_SUMMARY_TEXT@not equivalent@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "found remote 'https://pigweed.googlesource.com/pigweed/pigweed.git'",
+ "~followup_annotations": [
+ "@@@STEP_SUMMARY_TEXT@equivalent@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "copy",
+ "git_repository(\n name = \"other-repo\"\n remote = \"https://pigweed.googlesource.com/other/repo.git\",\n commit = \"invalid commit line won't be found\",\n)\n\ngit_repository(\n name = \"pigweed\",\n commit = \"ffffffffffffffffffffffffffffffffffffffff\",\n remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",\n)\n\ngit_repository(\n name = \"missing final quote/comma so will miss this line\n remote = \"https://pigweed.googlesource.com/third/repo.git\",\n commit = \"2222222222222222222222222222222222222222\",\n)\n",
+ "[START_DIR]/co/WORKSPACE"
+ ],
+ "infra_step": true,
+ "name": "write new WORKSPACE",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"other-repo\"@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/other/repo.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"invalid commit line won't be found\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"pigweed\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"ffffffffffffffffffffffffffffffffffffffff\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"missing final quote/comma so will miss this line@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/third/repo.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
+ "@@@STEP_LOG_END@WORKSPACE@@@"
+ ]
+ },
+ {
+ "name": "$result"
+ }
+]
\ No newline at end of file
diff --git a/recipe_modules/bazel/tests/update_commit_hash.proto b/recipe_modules/bazel/tests/update_commit_hash.proto
new file mode 100644
index 0000000..84123ca
--- /dev/null
+++ b/recipe_modules/bazel/tests/update_commit_hash.proto
@@ -0,0 +1,25 @@
+// Copyright 2024 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+syntax = "proto3";
+
+package recipe_modules.pigweed.bazel.tests;
+
+message UpdateCommitHashProperties {
+ // The path of the WORKSPACE file to update. Default: WORKSPACE.
+ string workspace_path = 1;
+
+ // Repository referred to by the WORKSPACE file.
+ string project_remote = 2;
+}
diff --git a/recipe_modules/bazel/tests/update_commit_hash.py b/recipe_modules/bazel/tests/update_commit_hash.py
new file mode 100644
index 0000000..92a2df6
--- /dev/null
+++ b/recipe_modules/bazel/tests/update_commit_hash.py
@@ -0,0 +1,87 @@
+# Copyright 2024 The Pigweed Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+"""Full test of bazel module's update_commit_hash() method."""
+
+from typing import Generator
+
+import dataclasses
+from typing import Optional
+from PB.recipe_modules.pigweed.bazel.tests.update_commit_hash import (
+ UpdateCommitHashProperties,
+)
+from PB.recipe_modules.pigweed.checkout.options import (
+ Options as CheckoutOptions,
+)
+from recipe_engine import config_types, post_process, recipe_test_api
+
+DEPS = [
+ 'pigweed/bazel',
+ 'pigweed/checkout',
+ 'recipe_engine/path',
+ 'recipe_engine/properties',
+]
+
+PROPERTIES = UpdateCommitHashProperties
+
+
+@dataclasses.dataclass
+class _FakeCheckoutContext:
+ root: config_types.Path
+
+
+def RunSteps(api, props):
+ options = CheckoutOptions(remote="https://pigweed.googlesource.com/super")
+ checkout = api.checkout(options)
+
+ # For coverage.
+ path: config_types.Path | None = None
+ if 'bar' in props.project_remote:
+ path = api.path.start_dir / 'WORKSPACE'
+
+ update_result = api.bazel.update_commit_hash(
+ checkout=checkout,
+ project_remote=props.project_remote,
+ new_revision='ffffffffffffffffffffffffffffffffffffffff',
+ path=path,
+ )
+
+
+def GenTests(api) -> Generator[recipe_test_api.TestData, None, None]:
+ def properties(**kwargs):
+ return api.properties(UpdateCommitHashProperties(**kwargs))
+
+ def _url(x: str = 'pigweed/pigweed'):
+ assert ':' not in x
+ return f'https://pigweed.googlesource.com/{x}'
+
+ yield api.test(
+ 'success',
+ properties(project_remote=_url('pigweed/pigweed')),
+ )
+
+ yield api.test(
+ 'remote-not-found',
+ properties(project_remote=_url('bar')),
+ api.post_process(post_process.MustRunRE, r'could not find remote.*'),
+ api.post_process(post_process.DropExpectation),
+ status='FAILURE',
+ )
+
+ yield api.test(
+ 'commit-not-found',
+ properties(project_remote=_url('other/repo')),
+ api.post_process(post_process.MustRunRE, r'could not find commit.*'),
+ api.post_process(post_process.DropExpectation),
+ status='FAILURE',
+ )
diff --git a/recipes/bazel_roller.expected/backwards.json b/recipes/bazel_roller.expected/backwards.json
index a569357..3aa8bcc 100644
--- a/recipes/bazel_roller.expected/backwards.json
+++ b/recipes/bazel_roller.expected/backwards.json
@@ -1464,24 +1464,23 @@
"name": "read old WORKSPACE",
"~followup_annotations": [
"@@@STEP_LOG_LINE@WORKSPACE@@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"other-repo\"@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/other/repo.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"invalid commit line won't be found\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"other-repo\"@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/other/repo.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"invalid commit line won't be found\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_LINE@WORKSPACE@@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"pigweed\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"1111111111111111111111111111111111111111\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"pigweed\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"1111111111111111111111111111111111111111\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_LINE@WORKSPACE@@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"missing final quote/comma so will miss this line@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/third/repo.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ @@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"missing final quote/comma so will miss this line@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/third/repo.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_END@WORKSPACE@@@"
]
},
@@ -1507,29 +1506,29 @@
"--json-output",
"/path/to/tmp/json",
"copy",
- "git_repository(\n name = \"other-repo\"\n remote = \"https://pigweed.googlesource.com/other/repo.git\",\n commit = \"invalid commit line won't be found\",\n )\n\n git_repository(\n name = \"pigweed\",\n commit = \"2222222222222222222222222222222222222222\",\n remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",\n )\n\n git_repository(\n name = \"missing final quote/comma so will miss this line\n remote = \"https://pigweed.googlesource.com/third/repo.git\",\n commit = \"2222222222222222222222222222222222222222\",\n )\n",
+ "git_repository(\n name = \"other-repo\"\n remote = \"https://pigweed.googlesource.com/other/repo.git\",\n commit = \"invalid commit line won't be found\",\n)\n\ngit_repository(\n name = \"pigweed\",\n commit = \"2222222222222222222222222222222222222222\",\n remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",\n)\n\ngit_repository(\n name = \"missing final quote/comma so will miss this line\n remote = \"https://pigweed.googlesource.com/third/repo.git\",\n commit = \"2222222222222222222222222222222222222222\",\n)\n",
"[START_DIR]/co/WORKSPACE"
],
"infra_step": true,
"name": "write new WORKSPACE",
"~followup_annotations": [
"@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"other-repo\"@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/other/repo.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"invalid commit line won't be found\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"other-repo\"@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/other/repo.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"invalid commit line won't be found\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_LINE@WORKSPACE@@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"pigweed\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"pigweed\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_LINE@WORKSPACE@@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"missing final quote/comma so will miss this line@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/third/repo.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"missing final quote/comma so will miss this line@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/third/repo.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_END@WORKSPACE@@@"
]
},
diff --git a/recipes/bazel_roller.expected/no-trigger.json b/recipes/bazel_roller.expected/no-trigger.json
index dae2915..638f8b2 100644
--- a/recipes/bazel_roller.expected/no-trigger.json
+++ b/recipes/bazel_roller.expected/no-trigger.json
@@ -1464,24 +1464,23 @@
"name": "read old WORKSPACE",
"~followup_annotations": [
"@@@STEP_LOG_LINE@WORKSPACE@@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"other-repo\"@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/other/repo.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"invalid commit line won't be found\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"other-repo\"@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/other/repo.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"invalid commit line won't be found\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_LINE@WORKSPACE@@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"pigweed\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"1111111111111111111111111111111111111111\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"pigweed\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"1111111111111111111111111111111111111111\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_LINE@WORKSPACE@@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"missing final quote/comma so will miss this line@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/third/repo.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ @@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"missing final quote/comma so will miss this line@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/third/repo.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_END@WORKSPACE@@@"
]
},
@@ -1507,29 +1506,29 @@
"--json-output",
"/path/to/tmp/json",
"copy",
- "git_repository(\n name = \"other-repo\"\n remote = \"https://pigweed.googlesource.com/other/repo.git\",\n commit = \"invalid commit line won't be found\",\n )\n\n git_repository(\n name = \"pigweed\",\n commit = \"2222222222222222222222222222222222222222\",\n remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",\n )\n\n git_repository(\n name = \"missing final quote/comma so will miss this line\n remote = \"https://pigweed.googlesource.com/third/repo.git\",\n commit = \"2222222222222222222222222222222222222222\",\n )\n",
+ "git_repository(\n name = \"other-repo\"\n remote = \"https://pigweed.googlesource.com/other/repo.git\",\n commit = \"invalid commit line won't be found\",\n)\n\ngit_repository(\n name = \"pigweed\",\n commit = \"2222222222222222222222222222222222222222\",\n remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",\n)\n\ngit_repository(\n name = \"missing final quote/comma so will miss this line\n remote = \"https://pigweed.googlesource.com/third/repo.git\",\n commit = \"2222222222222222222222222222222222222222\",\n)\n",
"[START_DIR]/co/WORKSPACE"
],
"infra_step": true,
"name": "write new WORKSPACE",
"~followup_annotations": [
"@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"other-repo\"@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/other/repo.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"invalid commit line won't be found\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"other-repo\"@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/other/repo.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"invalid commit line won't be found\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_LINE@WORKSPACE@@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"pigweed\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"pigweed\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_LINE@WORKSPACE@@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"missing final quote/comma so will miss this line@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/third/repo.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"missing final quote/comma so will miss this line@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/third/repo.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_END@WORKSPACE@@@"
]
},
diff --git a/recipes/bazel_roller.expected/success.json b/recipes/bazel_roller.expected/success.json
index 1a4d83d..2edb9e3 100644
--- a/recipes/bazel_roller.expected/success.json
+++ b/recipes/bazel_roller.expected/success.json
@@ -2289,24 +2289,23 @@
"name": "read old WORKSPACE",
"~followup_annotations": [
"@@@STEP_LOG_LINE@WORKSPACE@@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"other-repo\"@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/other/repo.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"invalid commit line won't be found\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"other-repo\"@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/other/repo.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"invalid commit line won't be found\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_LINE@WORKSPACE@@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"pigweed\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"1111111111111111111111111111111111111111\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"pigweed\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"1111111111111111111111111111111111111111\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_LINE@WORKSPACE@@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"missing final quote/comma so will miss this line@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/third/repo.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ @@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"missing final quote/comma so will miss this line@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/third/repo.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_END@WORKSPACE@@@"
]
},
@@ -2332,7 +2331,7 @@
"--json-output",
"/path/to/tmp/json",
"copy",
- "git_repository(\n name = \"other-repo\"\n remote = \"https://pigweed.googlesource.com/other/repo.git\",\n commit = \"invalid commit line won't be found\",\n )\n\n git_repository(\n name = \"pigweed\",\n commit = \"2d72510e447ab60a9728aeea2362d8be2cbd7789\",\n remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",\n )\n\n git_repository(\n name = \"missing final quote/comma so will miss this line\n remote = \"https://pigweed.googlesource.com/third/repo.git\",\n commit = \"2222222222222222222222222222222222222222\",\n )\n",
+ "git_repository(\n name = \"other-repo\"\n remote = \"https://pigweed.googlesource.com/other/repo.git\",\n commit = \"invalid commit line won't be found\",\n)\n\ngit_repository(\n name = \"pigweed\",\n commit = \"2d72510e447ab60a9728aeea2362d8be2cbd7789\",\n remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",\n)\n\ngit_repository(\n name = \"missing final quote/comma so will miss this line\n remote = \"https://pigweed.googlesource.com/third/repo.git\",\n commit = \"2222222222222222222222222222222222222222\",\n)\n",
"[START_DIR]/co/WORKSPACE"
],
"infra_step": true,
@@ -2351,22 +2350,22 @@
"name": "write new WORKSPACE",
"~followup_annotations": [
"@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"other-repo\"@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/other/repo.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"invalid commit line won't be found\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"other-repo\"@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/other/repo.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"invalid commit line won't be found\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_LINE@WORKSPACE@@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"pigweed\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2d72510e447ab60a9728aeea2362d8be2cbd7789\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"pigweed\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2d72510e447ab60a9728aeea2362d8be2cbd7789\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/pigweed/pigweed.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_LINE@WORKSPACE@@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ git_repository(@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ name = \"missing final quote/comma so will miss this line@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/third/repo.git\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
- "@@@STEP_LOG_LINE@WORKSPACE@ )@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@git_repository(@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ name = \"missing final quote/comma so will miss this line@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ remote = \"https://pigweed.googlesource.com/third/repo.git\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@ commit = \"2222222222222222222222222222222222222222\",@@@",
+ "@@@STEP_LOG_LINE@WORKSPACE@)@@@",
"@@@STEP_LOG_END@WORKSPACE@@@"
]
},
diff --git a/recipes/bazel_roller.proto b/recipes/bazel_roller.proto
index 2a75922..f5717ca 100644
--- a/recipes/bazel_roller.proto
+++ b/recipes/bazel_roller.proto
@@ -42,5 +42,4 @@
// Forge the author so rolls of single commits are attributed to the original
// commit author.
bool forge_author = 7;
-
}
diff --git a/recipes/bazel_roller.py b/recipes/bazel_roller.py
index 8641623..17bea13 100644
--- a/recipes/bazel_roller.py
+++ b/recipes/bazel_roller.py
@@ -35,7 +35,7 @@
import itertools
import re
-from typing import Generator, Sequence, TypeVar, TYPE_CHECKING
+from typing import Generator, Sequence, TypeVar
import attrs
from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2
@@ -45,11 +45,9 @@
)
from recipe_engine import post_process, recipe_api, recipe_test_api
-if TYPE_CHECKING: # pragma: no cover
- from RECIPE_MODULES.pigweed.checkout import api as checkout_api
-
DEPS = [
'fuchsia/auto_roller',
+ 'pigweed/bazel',
'pigweed/checkout',
'pigweed/roll_util',
'recipe_engine/buildbucket',
@@ -62,136 +60,6 @@
PROPERTIES = InputProperties
-def nwise(iterable, n):
- # nwise('ABCDEFG', 3) → ABC BCD CDE DEF EFG
- # See also
- # https://docs.python.org/3/library/itertools.html#itertools.pairwise
- iterator = iter(iterable)
- initial_items = [None]
- for i in range(1, n):
- initial_items.append(next(iterator, None))
- items = tuple(initial_items)
- for x in iterator:
- items = (*items[1:], x)
- yield items
-
-
-T = TypeVar('T')
-
-
-def _proximity_sort_nearby_lines(lines: Sequence[T]) -> list[T]:
- # Shift the order to be center-out instead of ascending.
- lines = [(abs(len(lines) // 2 - i), x) for i, x in enumerate(lines)]
- lines.sort()
- return [x[1] for x in lines]
-
-
-@attrs.define
-class UpdateCommitHashResult:
- old_revision: str
- project_name: str | None
-
-
-def _update_commit_hash(
- api: recipe_api.RecipeScriptApi,
- props: InputProperties,
- checkout: checkout_api.CheckoutContext,
- new_revision: str,
- num_nearby_lines: int,
- path: config_types.Path,
-) -> UpdateCommitHashResult:
- lines = [''] * num_nearby_lines
- lines.extend(
- api.file.read_text(
- f'read old {path.name}',
- path,
- test_data='''
- git_repository(
- name = "other-repo"
- remote = "https://pigweed.googlesource.com/other/repo.git",
- commit = "invalid commit line won't be found",
- )
-
- git_repository(
- name = "pigweed",
- commit = "1111111111111111111111111111111111111111",
- remote = "https://pigweed.googlesource.com/pigweed/pigweed.git",
- )
-
- git_repository(
- name = "missing final quote/comma so will miss this line
- remote = "https://pigweed.googlesource.com/third/repo.git",
- commit = "2222222222222222222222222222222222222222",
- )
- ''',
- )
- .strip()
- .splitlines()
- )
- lines.extend([''] * num_nearby_lines)
-
- for nearby_lines in nwise(enumerate(lines), num_nearby_lines * 2 + 1):
- i, curr = nearby_lines[len(nearby_lines) // 2]
- match = re.search(r'^\s*remote\s*=\s*"(?P<remote>[^"]+)",?\s*$', curr)
- if not match:
- continue
-
- match_remote = match.group('remote')
-
- step = api.step.empty(f'found remote {match_remote!r}')
- if checkout.remotes_equivalent(match_remote, props.project_remote):
- step.presentation.step_summary_text = 'equivalent'
- break
- step.presentation.step_summary_text = 'not equivalent'
-
- else:
- api.step.empty(
- f'could not find remote {props.project_remote} in {path}',
- status='FAILURE',
- )
-
- nearby_lines = _proximity_sort_nearby_lines(nearby_lines)
-
- commit_rx = re.compile(
- r'^(?P<prefix>\s*commit\s*=\s*")'
- r'(?P<commit>[0-9a-f]{40})'
- r'(?P<suffix>",?\s*)$'
- )
-
- for i, line in nearby_lines:
- if match := commit_rx.search(line):
- idx = i
- break
- else:
- api.step.empty(
- f'could not find commit line adjacent to {curr!r} in {path}',
- status='FAILURE',
- )
-
- old_revision = match.group('commit')
-
- prefix = match.group("prefix")
- suffix = match.group("suffix")
- lines[idx] = f'{prefix}{new_revision}{suffix}'
-
- project_name: str | None = None
- for i, line in nearby_lines:
- if match := re.search(r'^\s*name\s*=\s*"(?P<name>[^"]+)",?\s*$', line):
- project_name = match.group('name')
- break
-
- api.file.write_text(
- f'write new {path.name}',
- path,
- ''.join(f'{x}\n' for x in lines[num_nearby_lines:-num_nearby_lines]),
- )
-
- return UpdateCommitHashResult(
- old_revision=old_revision,
- project_name=project_name,
- )
-
-
def RunSteps( # pylint: disable=invalid-name
api: recipe_api.RecipeScriptApi,
props: InputProperties,
@@ -256,12 +124,10 @@
full_workspace_path = checkout.root / workspace_path
- update_result = _update_commit_hash(
- api=api,
- props=props,
+ update_result = api.bazel.update_commit_hash(
checkout=checkout,
+ project_remote=props.project_remote,
new_revision=new_revision,
- num_nearby_lines=2,
path=full_workspace_path,
)
@@ -358,24 +224,6 @@
)
yield api.test(
- 'remote-not-found',
- properties(project_remote=_url('bar')),
- trigger('bar'),
- api.post_process(post_process.MustRunRE, r'could not find remote.*'),
- api.post_process(post_process.DropExpectation),
- status='FAILURE',
- )
-
- yield api.test(
- 'commit-not-found',
- properties(project_remote=_url('other/repo')),
- trigger('other/repo'),
- api.post_process(post_process.MustRunRE, r'could not find commit.*'),
- api.post_process(post_process.DropExpectation),
- status='FAILURE',
- )
-
- yield api.test(
'name-not-found',
properties(project_remote=_url('third/repo')),
trigger('third/repo'),