Skip to content

Commit 3d65c78

Browse files
fix: manual preservation of Version.java files (#12862)
### Description This PR addresses an issue where `Version.java` files were either incorrectly preserved or not generated during a library's initial generation due to an overly relaxed `deep-preserve-regex` rule in the OwlBot configuration templates. To fix this edge case, we are moving the responsibility of preserving existing `Version.java` files away from the OwlBot YAML regex and directly into our hermetic build scripts. ### Implementation Details 1. **Removed Obsolete Regex**: Removed the `deep-preserve-regex` rule targeting `Version.java` from `owlbot.yaml.monorepo.j2`. 2. **Conditional Backup/Restore**: Extracted new backup and restore utilities into `utilities.sh` and invoked them in `postprocess_library.sh`. The script now dynamically scans for existing `Version.java` files, backs them up to a temporary directory before executing `owl-bot copy-code`, and restores them immediately after. ### Why this approach? - **First Generation**: Since there are no existing `Version.java` files, the script does nothing, allowing OwlBot to generate and retain the new file as intended. - **Release Please Interoperability**: Release Please regularly updates the version string inside existing `Version.java` files. Because our `backup_version_java` utility copies the *existing* file out of the repository *before* `owl-bot copy-code` executes, the file containing the updated Release Please version string is safely stored in `mktemp -d`. After `owl-bot copy-code` writes the newly generated, generic `Version.java` file to the repo, `restore_version_java` overwrites it with our backup. This guarantees the Release Please version updates are perfectly preserved. - **Hermetic Safety**: The backups are stored in `mktemp -d` which guarantees they are unaffected by OwlBot's `deep-remove-regex` folder wipes. ### Testing - [x] Added unit tests - [ ] Once approach is validated: modify the `chore/test-hermetic-build` branch with arbitrary values in `Version.java` files and confirm they remain untouched via integration test --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent b974740 commit 3d65c78

File tree

5 files changed

+70
-2
lines changed

5 files changed

+70
-2
lines changed

sdk-platform-java/hermetic_build/library_generation/postprocess_library.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,20 @@ preprocessed_libraries_binding="${owlbot_cli_source_folder}"
8585

8686
pushd "${postprocessing_target}"
8787

88+
# Backs up all files matching `stub/Version.java`
89+
# This is a workaround to prevent owl-bot-copy from omitting
90+
# Version.java files when transferring the generated code
91+
backup_dir=$(mktemp -d)
92+
backup_version_java "${PWD}" "${backup_dir}"
93+
8894
owl-bot copy-code \
8995
--source-repo-commit-hash=none \
9096
--source-repo="${owlbot_cli_source_folder}" \
9197
--config-file="${owlbot_yaml_relative_path}"
9298

99+
restore_version_java "${PWD}" "${backup_dir}"
100+
rm -rf "${backup_dir}"
101+
93102

94103
# clean the custom owlbot yaml
95104
if [[ "${is_monorepo}" == "true" ]]; then

sdk-platform-java/hermetic_build/library_generation/templates/owlbot.yaml.monorepo.j2

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ deep-remove-regex:
2121

2222
deep-preserve-regex:
2323
- "/{{ module_name }}/google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
24-
- "/.*google-.*/src/main/java/.*/stub/Version.java"
2524

2625
deep-copy-regex:
2726
- source: "/{{ proto_path }}/(v.*)/.*-java/proto-google-.*/src"

sdk-platform-java/hermetic_build/library_generation/tests/generate_library_unit_tests.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,27 @@ get_proto_path_from_preprocessed_sources_multiple_proto_dirs_fails() {
213213
assertEquals 1 ${res}
214214
}
215215

216+
backup_and_restore_version_java_succeeds() {
217+
local target_dir=$(mktemp -d)
218+
local backup_dir=$(mktemp -d)
219+
220+
mkdir -p "${target_dir}/google-cloud-test/src/main/java/com/google/cloud/test/v1/stub"
221+
echo "version1" > "${target_dir}/google-cloud-test/src/main/java/com/google/cloud/test/v1/stub/Version.java"
222+
223+
backup_version_java "${target_dir}" "${backup_dir}"
224+
225+
# Simulate owl-bot overwriting the file
226+
echo "version2" > "${target_dir}/google-cloud-test/src/main/java/com/google/cloud/test/v1/stub/Version.java"
227+
228+
restore_version_java "${target_dir}" "${backup_dir}"
229+
230+
# The original "version1" should have been restored
231+
local restored_content=$(cat "${target_dir}/google-cloud-test/src/main/java/com/google/cloud/test/v1/stub/Version.java")
232+
assertEquals "version1" "${restored_content}"
233+
234+
rm -rf "${target_dir}" "${backup_dir}"
235+
}
236+
216237
normalize_owlbot_yaml_test() {
217238
local temp_dir=$(mktemp -d)
218239
local input_file="${temp_dir}/input.yaml"
@@ -266,6 +287,7 @@ test_list=(
266287
get_proto_path_from_preprocessed_sources_valid_library_succeeds
267288
get_proto_path_from_preprocessed_sources_empty_library_fails
268289
get_proto_path_from_preprocessed_sources_multiple_proto_dirs_fails
290+
backup_and_restore_version_java_succeeds
269291
normalize_owlbot_yaml_test
270292
)
271293

sdk-platform-java/hermetic_build/library_generation/tests/resources/goldens/.OwlBot-hermetic-golden.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ deep-remove-regex:
2121

2222
deep-preserve-regex:
2323
- "/java-bare-metal-solution/google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
24-
- "/.*google-.*/src/main/java/.*/stub/Version.java"
2524

2625
deep-copy-regex:
2726
- source: "/google/cloud/baremetalsolution/(v.*)/.*-java/proto-google-.*/src"

sdk-platform-java/hermetic_build/library_generation/utils/utilities.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,45 @@ error_if_not_exists() {
334334
fi
335335
}
336336

337+
# Backups existing Version.java files in the specified target directory
338+
# Arguments:
339+
# 1 - target_directory: The directory where to search for Version.java
340+
# 2 - backup_directory: The directory where the backups will be stored
341+
backup_version_java() {
342+
local target_directory=$1
343+
local backup_directory=$2
344+
345+
pushd "${target_directory}" > /dev/null
346+
find . -type f -path "*/src/*/stub/Version.java" -print0 | while IFS= read -r -d '' file; do
347+
local backup_path="${backup_directory}/${file#./}"
348+
mkdir -p "$(dirname "${backup_path}")"
349+
cp "$file" "${backup_path}"
350+
done
351+
popd > /dev/null
352+
}
353+
354+
# Restores Version.java files from the backup directory to the target directory
355+
# Arguments:
356+
# 1 - target_directory: The directory where to restore Version.java
357+
# 2 - backup_directory: The directory where the backups are stored
358+
restore_version_java() {
359+
local target_directory=$1
360+
local backup_directory=$2
361+
362+
if [[ ! -d "${backup_directory}" ]]; then
363+
return 0
364+
fi
365+
366+
pushd "${backup_directory}" > /dev/null
367+
find . -type f -print0 | while IFS= read -r -d '' file; do
368+
local relative_path="${file#./}"
369+
local target_path="${target_directory}/${relative_path}"
370+
mkdir -p "$(dirname "${target_path}")"
371+
mv "$file" "${target_path}"
372+
done
373+
popd > /dev/null
374+
}
375+
337376
normalize_owlbot_yaml() {
338377
local input_file="$1"
339378
local output_file="$2"

0 commit comments

Comments
 (0)