aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Demeulenaere <jdemeulenaere@google.com>2023-02-09 15:27:00 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-02-09 15:27:00 +0000
commitad7515c1cc7434597eed9b3f09a0f279afc72b03 (patch)
treeac75862b7d2bccb64dd92cbd8cf68795266b0785
parent1f24f1b696bf7bd38ba5c6f9e4518326b811a0a2 (diff)
parenta56945eb52ea48e7a58f036f10b732459941de9b (diff)
downloadktfmt-ad7515c1cc7434597eed9b3f09a0f279afc72b03.tar.gz
Replace prepare_upgrade.sh by a Python equivalent am: a56945eb52
Original change: https://googleplex-android-review.googlesource.com/c/platform/external/ktfmt/+/21147693 Change-Id: I4d8750b7675a1763ac1dc3dfd2c4e5708e16f7c2 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rwxr-xr-xprepare_upgrade.py257
-rwxr-xr-xprepare_upgrade.sh151
2 files changed, 257 insertions, 151 deletions
diff --git a/prepare_upgrade.py b/prepare_upgrade.py
new file mode 100755
index 0000000..cccd909
--- /dev/null
+++ b/prepare_upgrade.py
@@ -0,0 +1,257 @@
+#!/usr/bin/env python3
+
+#
+# Copyright 2023, 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.
+#
+"""Script to prepare an update to a new version of ktfmt."""
+
+import subprocess
+import os
+import sys
+import re
+import shutil
+import argparse
+import textwrap
+
+tmp_dir = "/tmp/ktfmt"
+zip_path = os.path.join(tmp_dir, "common.zip")
+jar_path = os.path.join(tmp_dir, "framework/ktfmt.jar")
+copy_path = os.path.join(tmp_dir, "copy.jar")
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="Prepare a repository for the upgrade of ktfmt to a new version."
+ )
+ parser.add_argument(
+ "--build_id",
+ required=True,
+ help="The build ID of aosp-build-tools-release with the new version of ktfmt"
+ )
+ parser.add_argument(
+ "--bug_id",
+ required=True,
+ help="The bug ID associated to each CL generated by this tool")
+ parser.add_argument(
+ "--repo",
+ required=True,
+ help="The relative path of the repository to upgrade, e.g. 'frameworks/base/'"
+ )
+ args = parser.parse_args()
+
+ build_id = args.build_id
+ bug_id = args.bug_id
+ repo_relative_path = args.repo
+
+ build_top = os.environ["ANDROID_BUILD_TOP"]
+ repo_absolute_path = os.path.join(build_top, repo_relative_path)
+
+ print("Preparing upgrade of ktfmt from build", build_id)
+ os.chdir(repo_absolute_path)
+ check_workspace_clean()
+ check_branches()
+
+ print("Downloading ktfmt.jar from aosp-build-tools-release")
+ download_jar(build_id)
+
+ print(f"Creating local branch ktfmt_update1")
+ run_cmd(["repo", "start", "ktfmt_update1"])
+
+ includes_file = find_includes_file(repo_relative_path)
+ if includes_file:
+ update_includes_file(build_top, includes_file, bug_id)
+ else:
+ print("No includes file found, skipping first CL")
+
+ print(f"Creating local branch ktfmt_update2")
+ run_cmd(["repo", "start", "--head", "ktfmt_update2"])
+ format_files(build_top, includes_file, repo_absolute_path, bug_id)
+
+ print("Done. You can now submit the generated CL(s), if any.")
+
+
+def run_cmd(cmd):
+ result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ if result.returncode != 0:
+ print("Error running command: {}".format(" ".join(cmd)))
+ print("Output: {}".format(result.stderr.decode()))
+ sys.exit(1)
+ return result.stdout.decode("utf-8")
+
+
+def is_workspace_clean():
+ return run_cmd(["git", "status", "--porcelain"]) == ""
+
+
+def check_workspace_clean():
+ if not is_workspace_clean():
+ print(
+ "The current repository contains uncommitted changes, please run this script in a clean workspace"
+ )
+ sys.exit(1)
+
+
+def check_branches():
+ result = run_cmd(["git", "branch"])
+ if "ktfmt_update1" in result or "ktfmt_update2" in result:
+ print(
+ "Branches ktfmt_update1 or ktfmt_update2 already exist, you should delete them before running this script"
+ )
+ sys.exit(1)
+
+
+def download_jar(build_id):
+ cmd = [
+ "/google/data/ro/projects/android/fetch_artifact", "--branch",
+ "aosp-build-tools-release", "--bid", build_id, "--target", "linux",
+ "build-common-prebuilts.zip", zip_path
+ ]
+ run_cmd(cmd)
+ cmd = ["unzip", "-q", "-o", "-d", tmp_dir, zip_path]
+ run_cmd(cmd)
+
+ if not os.path.isfile(jar_path):
+ print("Error: {} is not readable".format(jar_path))
+ sys.exit(1)
+
+
+def find_includes_file(repo_relative_path):
+ with open("PREUPLOAD.cfg") as f:
+ includes_line = [line for line in f if "ktfmt.py" in line][0].split(" ")
+ if "-i" not in includes_line:
+ return None
+
+ index = includes_line.index("-i") + 1
+ includes_file = includes_line[index][len("${REPO_ROOT}/") +
+ len(repo_relative_path):]
+ if not os.path.isfile(includes_file):
+ print("Error: {} does not exist or is not a file".format(includes_file))
+ sys.exit(1)
+ return includes_file
+
+
+def get_included_folders(includes_file):
+ with open(includes_file) as f:
+ return [line[1:] for line in f.read().splitlines() if line.startswith("+")]
+
+
+def update_includes_file(build_top, includes_file, bug_id):
+ included_folders = get_included_folders(includes_file)
+ cmd = [
+ f"{build_top}/external/ktfmt/generate_includes_file.py",
+ f"--output={includes_file}"
+ ] + included_folders
+ print(f"Updating {includes_file} with the command: {cmd}")
+ run_cmd(cmd)
+
+ if is_workspace_clean():
+ print(f"No change were made to {includes_file}, skipping first CL")
+ else:
+ print(f"Creating first CL with update of {includes_file}")
+ create_first_cl(bug_id)
+
+
+def create_first_cl(bug_id):
+ sha1sum = get_sha1sum(jar_path)
+ change_id = f"I{sha1sum}"
+ command = " ".join(sys.argv)
+ cl_message = textwrap.dedent(f"""
+ Regenerate include file for ktfmt upgrade
+
+ This CL was generated automatically from the following command:
+
+ $ {command}
+
+ This CL regenerates the inclusion file with the current version of ktfmt
+ so that it is up-to-date with files currently formatted or ignored by
+ ktfmt.
+
+ Bug: {bug_id}
+ Test: Presubmits
+ Change-Id: {change_id}
+ Merged-In: {change_id}
+ """)
+
+ run_cmd(["git", "add", "--all"])
+ run_cmd(["git", "commit", "-m", cl_message])
+
+
+def get_sha1sum(file):
+ output = run_cmd(["sha1sum", file])
+ regex = re.compile(r"[a-f0-9]{40}")
+ match = regex.search(output)
+ if not match:
+ print(f"sha1sum not found in output: {output}")
+ sys.exit(1)
+ return match.group()
+
+
+def format_files(build_top, includes_file, repo_absolute_path, bug_id):
+ if (includes_file):
+ included_folders = get_included_folders(includes_file)
+ cmd = [
+ f"{build_top}/external/ktfmt/ktfmt.py", "-i", includes_file, "--jar",
+ jar_path
+ ] + included_folders
+ else:
+ cmd = [
+ f"{build_top}/external/ktfmt/ktfmt.py", "--jar", jar_path,
+ repo_absolute_path
+ ]
+
+ print(
+ f"Formatting the files that are already formatted with the command: {cmd}"
+ )
+ run_cmd(cmd)
+
+ if is_workspace_clean():
+ print("All files were already properly formatted, skipping second CL")
+ else:
+ print("Creating second CL that formats all files")
+ create_second_cl(bug_id)
+
+
+def create_second_cl(bug_id):
+ # Append 'ktfmt_update' at the end of a copy of the jar file to get
+ # a different sha1sum.
+ shutil.copyfile(jar_path, copy_path)
+ with open(copy_path, "a") as file_object:
+ file_object.write("ktfmt_update")
+
+ sha1sum = get_sha1sum(copy_path)
+ change_id = f"I{sha1sum}"
+ command = " ".join(sys.argv)
+ cl_message = textwrap.dedent(f"""
+ Format files with the upcoming version of ktfmt
+
+ This CL was generated automatically from the following command:
+
+ $ {command}
+
+ This CL formats all files already correctly formatted with the upcoming
+ version of ktfmt.
+
+ Bug: {bug_id}
+ Test: Presubmits
+ Change-Id: {change_id}
+ Merged-In: {change_id}
+ """)
+
+ run_cmd(["git", "add", "--all"])
+ run_cmd(["git", "commit", "-m", cl_message])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/prepare_upgrade.sh b/prepare_upgrade.sh
deleted file mode 100755
index 5ee6f7f..0000000
--- a/prepare_upgrade.sh
+++ /dev/null
@@ -1,151 +0,0 @@
-# Copyright (C) 2023 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.
-
-# This script prepares the update to a new ktfmt version in a single git
-# repository. This will create max 2 CLs:
-# 1. One that regenerates the ktfmt_includes.txt with the current version
-# of ktfmt, so that all files already properly formatted are checked
-# and files that are not already formatted are ignored. If the file is
-# already up-to-date, then this CL won't be created.
-# 2. One that reformats all files with the new version of ktfmt. This CL
-# won't be created if all files are already formatted.
-
-# Stop the script at the first error.
-set -e
-
-# Stop the script if we try to access a variable that does not exist.
-set -u
-
-# Fail if we didn't pass the correct args.
-[ $# -ne 3 ] && {
- echo "Usage: $0 build_tools_id relative/repo/path/ bug_id"
- echo "Example: prepare_upgrade.sh 8932651 frameworks/base/ 266197805"
- exit 1
-}
-
-build_id=$1
-repo_relative_path=$2
-bug_id=$3
-repo_absolute_path="${ANDROID_BUILD_TOP}/$repo_relative_path"
-
-echo "Preparing upgrade of ktfmt from build $build_id"
-
-cd $repo_absolute_path
-
-# Check that the ktfmt_update1 and ktfmt_update2 local branches don't exist yet.
-existing_branches=$(git branch | grep 'ktfmt_update1\|ktfmt_update2' || echo "")
-[[ ! -z "$existing_branches" ]] && {
- echo "Branches ktfmt_update1 or ktfmt_update2 already exist, you should delete them before running this script"
- exit 1
-}
-
-# Fail if the workspace is not clean.
-git_status=$(git status --porcelain)
-[[ ! -z "$git_status" ]] && {
- echo "The current repository contains uncommitted changes, please run this script in a clean workspace"
- exit 1
-}
-
-echo "Downloading ktfmt.jar from aosp-build-tools-release"
-tmp=/tmp/ktfmt
-mkdir -p $tmp
-zip_path="$tmp/common.zip"
-/google/data/ro/projects/android/fetch_artifact --branch aosp-build-tools-release --bid $build_id --target linux build-common-prebuilts.zip $zip_path
-unzip -q -o -d $tmp $zip_path
-new_jar="$tmp/framework/ktfmt.jar"
-[ -r "$new_jar" ] || (echo "Error: $new_jar is not readable" && exit 1)
-echo "Extracted jar in $new_jar"
-
-# Find the ktfmt_includes.txt and the folders/files that were included file
-includes_file=$(cat PREUPLOAD.cfg | grep ktfmt.py | sed 's/.*-i \(.*\) .*/\1/' | cut -c 14-)
-includes_file=${includes_file#"$repo_relative_path"}
-[ -r "$includes_file" ] || (echo "Error: $includes_file is not readable" && exit 1)
-included_folders=$(cat ktfmt_includes.txt | grep + | cut -c 2- | tr '\n' ' ')
-
-echo "Creating local branch ktfmt_update1"
-repo start ktfmt_update1
-
-echo "Updating $includes_file with the command: \$ANDROID_BUILD_TOP/external/ktfmt/generate_includes_file.py --output=$includes_file $included_folders"
-$ANDROID_BUILD_TOP/external/ktfmt/generate_includes_file.py --output=$includes_file $included_folders
-
-git_status=$(git status --porcelain)
-if [[ ! -z "$git_status" ]]
-then
- echo "Creating first CL with update of $includes_file"
-
- # Use the sha1 of the jar file for change ID.
- change_id="I$(sha1sum $new_jar | sed 's/\([a-z0-9]\{40\}\) .*/\1/')"
- cl_message=$(cat << EOF
-Regenerate include file for ktfmt upgrade
-
-This CL was generated automatically from the following command:
-
-$ $0 $@
-
-This CL regenerates the inclusion file with the current version of ktfmt
-so that it is up-to-date with files currently formatted or ignored by
-ktfmt.
-
-Bug: $bug_id
-Test: Presubmits
-Change-Id: $change_id
-Merged-In: $change_id
-EOF
-)
- git add --all
- git commit -m "$cl_message"
-else
- echo "No change were made to $includes_file, skipping first CL"
-fi
-
-echo "Creating local branch ktfmt_update2"
-repo start --head ktfmt_update2
-
-echo "Formatting the files that are already formatted with the command: \${ANDROID_BUILD_TOP}/external/ktfmt/ktfmt.py -i $includes_file --jar $new_jar $included_folders"
-${ANDROID_BUILD_TOP}/external/ktfmt/ktfmt.py -i $includes_file --jar $new_jar $included_folders 2> /dev/null
-
-git_status=$(git status --porcelain)
-if [[ ! -z "$git_status" ]]
-then
- echo "Creating second CL that format all files"
-
- # Use the sha1 of the jar file + some random salt for change ID.
- jar_copy=/tmp/ktfmt/copy.jar
- cp $new_jar $jar_copy
- echo "ktfmt_update" >> $jar_copy
- change_id="I$(sha1sum $jar_copy | sed 's/\([a-z0-9]\{40\}\) .*/\1/')"
- cl_message=$(cat << EOF
-Format files with the upcoming version of ktfmt
-
-This CL was generated automatically from the following command:
-
-$ $0 $@
-
-This CL formats all files already correctly formatted with the upcoming
-version of ktfmt.
-
-Bug: $bug_id
-Test: Presubmits
-Change-Id: $change_id
-Merged-In: $change_id
-EOF
-)
- git add --all
- git commit -m "$cl_message"
-else
- echo "All files were already properly formatted, skipping second CL"
-fi
-
-echo
-echo "Done. You can now submit the generated CL(s), if any."