blob: 5b2dfd29a22aa5af94d5d71c73b0a11878a80c6a [file] [log] [blame]
#!/bin/bash
#
# Copyright 2025 The Android Open Source Project
#
# 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
#
# http://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.
###############################################################################
# What this script does and why we need it?
# This script synchronizes common configuration files from `example/` (the
# source of truth) to all project templates in `templates/*/`. This ensures all
# templates are up-to-date with shared configurations.
#
# When to run this script?
# - After updating files/dirs listed below in the `example/` project.
# This can happen when updating the autorepro plugin version (see
# go/autorepro#releasing-to-gmaven) or making other manual changes.
# - After adding a new project template under `templates/` to ensure it receives
# the common files followed by validating the newly synced template.
#
# Files/dirs synced between `example/` and `templates/*/`:
# - .gitignore
# - .run/
# - gradle/
# - gradle.properties
# - gradlew
# - gradlew.bat
# - settings.gradle.kts
#
# Updating the above files/dirs in example and syncing:
# 1. Make and validate changes in the `example/` project. This may include:
# - Updating `settings.gradle.kts` (e.g., plugin versions).
# - Running a Gradle sync in Android Studio which may update wrapper files.
# - Modifying shared `.run/` configurations or `.gitignore`.
# 2. Run this script to propagate the changes to all templates:
# ./sync-common.sh
###############################################################################
set -euo pipefail
readonly SCRIPT_DIR=$(realpath "$(dirname "$0")")
readonly SOURCE_DIR="${SCRIPT_DIR}/example"
_ERROR_MESSAGE=""
die() {
_ERROR_MESSAGE="${@:2}"
exit "$1"
}
on_exit() {
local exit_code=$?
if [[ ${exit_code} -eq 0 ]]; then
printf "\nSYNC COMPLETED SUCCESSFULLY.\n"
return
fi
# If an error message was set by die(), print it to stderr.
if [[ -n "${_ERROR_MESSAGE}" ]]; then
printf "\nERROR: %s\n" "${_ERROR_MESSAGE}" >&2
fi
# Instructions on a failed sync
cat <<EOF
SYNC FAILED WITH EXIT CODE: ${exit_code}.
The target directories may be in an inconsistent state.
Please do not commit any of the resulting changes.
EOF
}
trap on_exit EXIT
main() {
declare -a target_dirs=()
# Add all templates/* folders in target_dirs
for d in "${SCRIPT_DIR}"/templates/*; do
if [[ -d "$d" ]]; then
target_dirs+=("$d")
fi
done
if [[ ${#target_dirs[@]} -eq 0 ]]; then
die 1 "No template directories found. Nothing to sync."
fi
# List all directories from target_dirs
printf "\n- Identified target directory: [%s]\n" "${target_dirs[@]}"
# Create array of files/dirs to sync
declare -a files_to_sync=(
"${SOURCE_DIR}/./.gitignore"
"${SOURCE_DIR}/./.run/"
"${SOURCE_DIR}/./gradle/"
"${SOURCE_DIR}/./gradle.properties"
"${SOURCE_DIR}/./gradlew"
"${SOURCE_DIR}/./gradlew.bat"
"${SOURCE_DIR}/./settings.gradle.kts"
)
# Start syncing
for target in "${target_dirs[@]}"; do
printf "\n- Syncing from [%s] to [%s]\n" "$SOURCE_DIR" "$target"
rsync -avR "${files_to_sync[@]}" "$target" \
|| die "$?" "Failed to sync [${target}] (see previous errors)"
done
}
main "$@"