diff --git a/common.sh b/common.sh index c580b954..917367f1 100644 --- a/common.sh +++ b/common.sh @@ -2,11 +2,21 @@ readonly branch=15-qpr2 readonly aosp_tag_old=android-15.0.0_r36 readonly aosp_tag=android-15.0.0_r36 +# The reference (branch/tag) containing the Graphene code of interest. Typically this will be the same as branch, but +# might not be when handling a device released on old code. For tags, just specifying the tag is fine. For branches, +# specifying the remote is needed (e.g. remotes/grapheneos/15-qpr2). +readonly graphene_ref=remotes/grapheneos/15-qpr2 +readonly developer_port_branch=port-to-15-qpr2 + user_error() { echo $1 >&2 exit 1 } +echo_red() { + echo "$(tput setaf 1)$1$(tput setaf 0)" +} + readonly aosp_forks=( device_common device_generic_goldfish diff --git a/developer-scripts/manage.sh b/developer-scripts/manage.sh new file mode 100755 index 00000000..052d1b29 --- /dev/null +++ b/developer-scripts/manage.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +set -o errexit -o nounset -o pipefail +source "$(dirname ${BASH_SOURCE[0]})/../common.sh" + +readonly script_dir=$(dirname "$(realpath ${BASH_SOURCE[0]})") + +[[ ! $# -eq 1 ]] && user_error "expected 1 argument, add-aosp-remotes|fetch-aosp-tags|fork-all-graphene|rebase-all-graphene|get-all-graphene-paths" +readonly action=$1 + +if [[ $action == "add-aosp-remotes" ]]; then + repo forall -v -e -p -c "${script_dir}/repo-add-aosp-remotes.sh" +elif [[ $action == "fetch-aosp-tags" ]]; then + repo forall -v -e -p -c "${script_dir}/repo-fetch-aosp-tags.sh" +elif [[ $action == "fork-all-graphene" ]]; then + repo forall -v -e -p -c "${script_dir}/repo-fork-all-graphene.sh" +elif [[ $action == "rebase-all-graphene" ]]; then + repo forall -v -e -p -c "${script_dir}/repo-rebase-all-graphene.sh" +elif [[ $action == "get-all-graphene-paths" ]]; then + repo forall -v -e -c "${script_dir}/repo-get-all-graphene-paths.sh" +else + user_error "unrecognized action, expected add-aosp-remotes|fetch-aosp-tags|fork-all-graphene|rebase-all-graphene|get-all-graphene-paths" +fi + diff --git a/developer-scripts/repo-add-aosp-remotes.sh b/developer-scripts/repo-add-aosp-remotes.sh new file mode 100755 index 00000000..93969a72 --- /dev/null +++ b/developer-scripts/repo-add-aosp-remotes.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +# TODO: Write better bash. + +set -o errexit -o nounset -o pipefail +source "$(dirname ${BASH_SOURCE[0]})/../common.sh" + +readonly aosp_repo_base="https://android.googlesource.com/" + +add_remote() { + aosp_repo="${1//_/\/}" + aosp_remote="${aosp_repo_base}${aosp_repo}" + + git_exit=0 + git remote add upstream $aosp_remote &>/dev/null || git_exit=$? + if [[ "${git_exit}" == 3 ]]; then + echo "success, already exists" + elif [[ "${git_exit}" != 0 ]]; then + echo_red "fail" + exit 1 + else + echo "success" + fi +} + +# We can't just check if $REPO_REMOTE == "grapheneos" because not all of our repos are AOSP forks. `repo` project groups +# would allow us to simplify this so that we could just run `repo forall -g aosp-forks`. +for graphene_repo in "${aosp_forks[@]}"; do + if [[ "${graphene_repo}" == "${REPO_PROJECT}" ]] ; then + add_remote "${graphene_repo}" + exit 0 + fi +done + diff --git a/developer-scripts/repo-fetch-aosp-tags.sh b/developer-scripts/repo-fetch-aosp-tags.sh new file mode 100755 index 00000000..14dbfdcd --- /dev/null +++ b/developer-scripts/repo-fetch-aosp-tags.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# TODO: Write better bash. + +set -o errexit -o nounset -o pipefail +source "$(dirname ${BASH_SOURCE[0]})/../common.sh" + +fetch_aosp_tags() { + # If clone-depth="1" is set in manifest then the commit will be grafted. Don't fetch tags. These are typically + # prebuilts where our additions need to be handled manually. Even if they aren't prebuilt, we don' want to rebase + # without full history. + if git log -1 --oneline --decorate | grep grafted + then + echo "success, but skipping as repository has clone-depth set" + exit 0 + fi + + git_exit=0 + if ! git fetch upstream --tags &>/dev/null + then + echo_red "fail" + exit 1 + else + echo "success" + fi +} + +# We can't just check if $REPO_REMOTE == "grapheneos" because not all of our repos are AOSP forks. `repo` project groups +# would allow us to simplify this so that we could just run `repo forall -g aosp-forks`. +for graphene_repo in "${aosp_forks[@]}"; do + if [[ "${graphene_repo}" == "${REPO_PROJECT}" ]] ; then + fetch_aosp_tags "${graphene_repo}" + exit 0 + fi +done + diff --git a/developer-scripts/repo-fork-all-graphene.sh b/developer-scripts/repo-fork-all-graphene.sh new file mode 100755 index 00000000..f3677125 --- /dev/null +++ b/developer-scripts/repo-fork-all-graphene.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# TODO: Write better bash. +# TODO: `gh repo fork` will silently ignore `--remote-name` if an existing remote exists. We should handle this, +# otherwise it shows up as an error when repo-rebase-all-graphene.sh looks for my-fork remote. + +set -o errexit -o nounset -o pipefail +source "$(dirname ${BASH_SOURCE[0]})/../common.sh" + +if [[ "${REPO_REMOTE}" == "grapheneos" ]]; then + if [[ -z "${GH_TOKEN:-}" ]]; then + echo_red "fail, expected GH_TOKEN environment variable to be set" + exit 1 + fi + + # Without this, `repo fork` will complain about GrapheneOS repos that are GitHub forks themselves. + # Example: platform_development. + if ! gh repo set-default GrapheneOS/"${REPO_PROJECT}" &>/dev/null + then + # This will happen if repository doesn't exist in GrapheneOS GitHub. Unlikely to occur unless using an old tag, in + # which case temporarily update this branch to exit 0. The reason `repo sync` still works is because Graphene + # redirects the URL to an archive. + echo_red "fail, probably because the remote repository does not exist" + exit 2 + fi + + # This will add my-fork remote and exit with 0 even if the fork already exists. + if ! gh repo fork --remote --remote-name my-fork &>/dev/null + then + echo_red "fail" + exit 3 + fi + + echo "success" + exit 0 +fi \ No newline at end of file diff --git a/developer-scripts/repo-get-all-graphene-paths.sh b/developer-scripts/repo-get-all-graphene-paths.sh new file mode 100755 index 00000000..f1495537 --- /dev/null +++ b/developer-scripts/repo-get-all-graphene-paths.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# TODO: Write better bash. + +set -o errexit -o nounset -o pipefail + +if [[ "${REPO_REMOTE}" == "grapheneos" || "${REPO_REMOTE}" == "grapheneos-gitlab" ]]; then + echo "\"${REPO_PATH}\"," +fi \ No newline at end of file diff --git a/developer-scripts/repo-rebase-all-graphene.sh b/developer-scripts/repo-rebase-all-graphene.sh new file mode 100755 index 00000000..94050905 --- /dev/null +++ b/developer-scripts/repo-rebase-all-graphene.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +# TODO: Write better bash. +# TODO: Rename this to rebase-all-aosp-forks + +set -o errexit -o nounset -o pipefail +source "$(dirname ${BASH_SOURCE[0]})/../common.sh" + +rebase() { + # See repo-fetch-aosp-tags. + if git log -1 --oneline --decorate | grep grafted + then + echo "success, but requires manual handling as clone-depth is set" + # Create a file so that repo status alerts on this repository. + touch "temporary-repo-status-marker" + exit 0 + fi + + # Allows us to run this script multiple times if something went wrong. + git rebase --abort &>/dev/null || true + + git checkout -q -B "${developer_port_branch}" "${graphene_ref}" + git_exit=0 + git rebase -q --onto $aosp_tag $aosp_tag_old &>/dev/null || git_exit=$? + if [[ "${git_exit}" == 1 ]]; then + echo "success, but requires manual conflict resolution" + return 0 + elif [[ "${git_exit}" != 0 ]]; then + # If the rebase never begins due to bad tags then git exits with 128. + echo_red "fail, unexpected error during rebase" + exit 1 + fi + + if [[ "${REPO_REMOTE}" == "grapheneos" ]]; then + if ! git push -q -f my-fork $developer_port_branch &>/dev/null + then + echo_red "fail, unexpected error during push" + exit 2 + fi + echo "success" + else + echo "success, but can't push due to hosted on GitLab" + fi +} + +create_developer_port_branch() { + if ! git checkout -q -B "${developer_port_branch}" "${graphene_ref}" + then + # Most likely a repo was introduced during the manifest port and it did not exist for the previous release. A new + # kernel, for example. + echo_red "fail, developer port branch target does not exist" + exit 3 + fi + if ! git push -q -f my-fork $developer_port_branch &>/dev/null + then + echo_red "fail, unexpected error during push" + exit 2 + fi + echo "success" +} + +# We can't just check if $REPO_REMOTE == "grapheneos" because not all of our repos are AOSP forks. `repo` project groups +# would allow us to simplify this so that we could just run `repo forall -g aosp-forks`. +for graphene_repo in "${aosp_forks[@]}"; do + if [[ "${graphene_repo}" == "${REPO_PROJECT}" ]] ; then + rebase "${graphene_repo}" + exit 0 + fi +done + +# If it's not an aosp_fork but its remote is grapheneos then create a branch such that we can update the grapheneos +# remote in the platform manifest to point to a branch in our own repository. +if [[ "${REPO_REMOTE}" == "grapheneos" ]]; then + create_developer_port_branch + exit 0 +fi