| #!/bin/bash |
| |
| # Copyright 2023 The LUCI 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 |
| # |
| # 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. |
| |
| # sample usage and meaning |
| # |
| # ./test-fft -i ~/cr -p 9 |
| # infra-dir patchset-# |
| |
| # Defensively set the CDPATH to something safe before doing anything. |
| export CDPATH= |
| |
| # This script owns the branch below in every git repo ever. This should be safe |
| # since it contains a UUID. |
| readonly MY_INFRA_BRANCH='ftt-test-branch-149cb550-9322-46a2-a27d-06c05781102d' |
| export MY_INFRA_BRANCH |
| # We use the devel branch in the LUCI repo to make it easier to patch the |
| # commit series and upload a new chain. |
| readonly MY_DEVEL_BRANCH='ftt-devel-branch-91e1de00-c43a-4d07-b6fe-ed05322a465b' |
| export MY_DEVEL_BRANCH |
| |
| # die writes a message to stderr and then exits abnormally. |
| die() { |
| printf '%s\n' "$@" 1>&2 |
| exit 1 |
| } |
| |
| # checkdep checks for a dependency and dies if it isn't available. |
| checkdep() { |
| which -- "$1" 1>/dev/null 2>/dev/null || die 'missing dependency: '"$1" |
| } |
| |
| # backup_self backs up the currently-executing script to ~/test-ftt. |
| # We do this for convenience. |
| # |
| # The script test-ftt is itself checked into the LUCI git repo. |
| # It also manipulates the git state, which can cause changes to the script |
| # to be removed from the working directory. We copy ourselves to the home |
| # directory in order to make it easier to tweak something and then immediately |
| # run the script again. |
| backup_self() { |
| cp -- "${HOME}/test-ftt" "${HOME}/test-ftt.BAK" 1>/dev/null 2>/dev/null |
| if cmp --silent -- "${selfpath}" "${HOME}"/test-ftt; then |
| return |
| fi |
| cp -- "${selfpath}" "${HOME}"/test-ftt || die 'failed to back up self' |
| } |
| |
| # must_check_git_clean checks that the git repo pointed to by $1 is clean. |
| # We die informatively if it is not clean. |
| # |
| # Submodules being dirty or pointing to the wrong commit is okay here. We are only |
| # concerend about preventing the user from losing work. |
| must_check_git_clean() { |
| [[ -z "$(git -C "$1" status --porcelain --ignore-submodules=all)" ]] || die "directory '$1' is not clean" |
| } |
| |
| # must_checkout_patchset_in_luci_dir checks out the patchset specified by the user in the luci directory. |
| # This function is only safe to call if we have already checked that the directory is clear. |
| must_checkout_patchset_in_luci_dir() { |
| # (1/5) Clear the local version of the dev branch so we have somewhere to work. We don't care whether the branch exists or not. |
| git -C "$luci_dir" branch -D "$MY_DEVEL_BRANCH" 1>/dev/null 2>/dev/null |
| # (2/5) Fetch the user-specified patchset. Don't check whether it's the latest or not because I don't know how to do that. |
| git -C "$luci_dir" fetch https://chromium.googlesource.com/infra/luci/luci-go refs/changes/51/4917851/"$patchset" || die 'failed to fetch patchset' |
| # (3/5) Move the working directory to point at the thing that we just fetched. |
| git -C "$luci_dir" checkout FETCH_HEAD || die 'failed to check out fetch head after fetching patch. Wowzers.' |
| # (4/5) Drop a branch to save our current location. Use the branch name that we freed in step 1. |
| git -C "$luci_dir" checkout -b "$MY_DEVEL_BRANCH" || die 'failed to drop development branch for later devleopment' |
| # (5/5) Set the tracking branch of the branch that we just dropped to the upstream so that we can run 'git cl upload' later. |
| git -C "$luci_dir" branch -u "origin/main" || die 'failed to set the upstream branch of the development branch correctly' |
| } |
| |
| # main takes the input args and runs the tests. |
| main() { |
| local -r usage='test-ftt [-h] [-i infra-dir] [-p patchset-number] |
| |
| This script produces the branch "ftt-test-branch-149cb550-9322-46a2-a27d-06c05781102d" |
| in the infra tree. This branch is temporary. |
| |
| This script produces the branch "ftt-devel-branch-149cb550-9322-46a2-a27d-06c05781102d" |
| in the LUCI tree. This branch can be modified and then re-uploaded. |
| ' |
| |
| while getopts ':hi:p:' opt; do |
| case "${opt}" in |
| h) printf '%s' "${usage}"; exit 0;; |
| i) local infra_dir="${OPTARG}";; |
| p) local patchset="${OPTARG}";; |
| :) |
| 1>&2 printf '%s' "${usage}"; exit 1;; |
| *) |
| 1>&2 printf '%s' "${usage}"; exit 1;; |
| esac |
| done |
| |
| checkdep 'realpath' |
| checkdep 'git' |
| checkdep 'mktemp' |
| checkdep 'cp' |
| checkdep 'unlink' |
| |
| [[ -n ${infra_dir} ]] || die "no directory given" |
| [[ -e ${infra_dir} ]] || die "path \`${infra_dir}' does not exist" |
| [[ -d ${infra_dir} ]] || die "path \`${infra_dir}' is not directory" |
| |
| [[ -n "${patchset}" ]] || die 'no patchset given' |
| |
| local -r selfpath="$(realpath -- "$0")" |
| |
| local -r infra_dir="$(realpath -- "${infra_dir}")" || die "failed to get realpath to \`$1'" |
| |
| # cd to a defensive dir so we catch inadvertent uses of relative paths rather |
| # than computed absolute paths. |
| local -r defensive_dir="$(mktemp -d)" || die 'failed to make defensive dir' |
| cd -- "${defensive_dir}" || die 'failed to cd to defensive dir' |
| |
| [[ -f ${infra_dir}/.gclient ]] || die 'failed heuristic: no gclient file: is the file path correct?' |
| |
| local -r luci_dir="${infra_dir}"/infra/go/src/go.chromium.org/luci |
| |
| [[ -d $luci_dir ]] || die "luci directory \`${luci_dir}' does not exist or is not directory" |
| [[ -f $luci_dir/AUTHORS ]] || die "failed heuristic: derived directory \`${luci_dir}' has no AUTHORS file" |
| |
| local -r infra_go_root="${infra_dir}/infra/go/src/infra" |
| [[ -d "${infra_dir}" ]] || die "infra go root directory ${infra_go_root} does not exist" |
| [[ -d "${infra_go_root}/unifiedfleet" ]] || die "failed heuristic: derived directory '${infra_go_root}/unifiedfleet' does not exist." |
| |
| must_check_git_clean "${infra_go_root}" |
| must_check_git_clean "${luci_dir}" |
| |
| # Back ourselves up, after this point all subsequent commands can change the git state. |
| backup_self |
| |
| must_checkout_patchset_in_luci_dir |
| |
| die 'not yet implemented' |
| } |
| |
| main "$@" |