go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/scripts/test-ftt (about) 1 #!/bin/bash 2 3 # Copyright 2023 The LUCI Authors. 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 # sample usage and meaning 18 # 19 # ./test-fft -i ~/cr -p 9 20 # infra-dir patchset-# 21 22 # Defensively set the CDPATH to something safe before doing anything. 23 export CDPATH= 24 25 # This script owns the branch below in every git repo ever. This should be safe 26 # since it contains a UUID. 27 readonly MY_INFRA_BRANCH='ftt-test-branch-149cb550-9322-46a2-a27d-06c05781102d' 28 export MY_INFRA_BRANCH 29 # We use the devel branch in the LUCI repo to make it easier to patch the 30 # commit series and upload a new chain. 31 readonly MY_DEVEL_BRANCH='ftt-devel-branch-91e1de00-c43a-4d07-b6fe-ed05322a465b' 32 export MY_DEVEL_BRANCH 33 34 # die writes a message to stderr and then exits abnormally. 35 die() { 36 printf '%s\n' "$@" 1>&2 37 exit 1 38 } 39 40 # checkdep checks for a dependency and dies if it isn't available. 41 checkdep() { 42 which -- "$1" 1>/dev/null 2>/dev/null || die 'missing dependency: '"$1" 43 } 44 45 # backup_self backs up the currently-executing script to ~/test-ftt. 46 # We do this for convenience. 47 # 48 # The script test-ftt is itself checked into the LUCI git repo. 49 # It also manipulates the git state, which can cause changes to the script 50 # to be removed from the working directory. We copy ourselves to the home 51 # directory in order to make it easier to tweak something and then immediately 52 # run the script again. 53 backup_self() { 54 cp -- "${HOME}/test-ftt" "${HOME}/test-ftt.BAK" 1>/dev/null 2>/dev/null 55 if cmp --silent -- "${selfpath}" "${HOME}"/test-ftt; then 56 return 57 fi 58 cp -- "${selfpath}" "${HOME}"/test-ftt || die 'failed to back up self' 59 } 60 61 # must_check_git_clean checks that the git repo pointed to by $1 is clean. 62 # We die informatively if it is not clean. 63 # 64 # Submodules being dirty or pointing to the wrong commit is okay here. We are only 65 # concerend about preventing the user from losing work. 66 must_check_git_clean() { 67 [[ -z "$(git -C "$1" status --porcelain --ignore-submodules=all)" ]] || die "directory '$1' is not clean" 68 } 69 70 # must_checkout_patchset_in_luci_dir checks out the patchset specified by the user in the luci directory. 71 # This function is only safe to call if we have already checked that the directory is clear. 72 must_checkout_patchset_in_luci_dir() { 73 # (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. 74 git -C "$luci_dir" branch -D "$MY_DEVEL_BRANCH" 1>/dev/null 2>/dev/null 75 # (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. 76 git -C "$luci_dir" fetch https://chromium.googlesource.com/infra/luci/luci-go refs/changes/51/4917851/"$patchset" || die 'failed to fetch patchset' 77 # (3/5) Move the working directory to point at the thing that we just fetched. 78 git -C "$luci_dir" checkout FETCH_HEAD || die 'failed to check out fetch head after fetching patch. Wowzers.' 79 # (4/5) Drop a branch to save our current location. Use the branch name that we freed in step 1. 80 git -C "$luci_dir" checkout -b "$MY_DEVEL_BRANCH" || die 'failed to drop development branch for later devleopment' 81 # (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. 82 git -C "$luci_dir" branch -u "origin/main" || die 'failed to set the upstream branch of the development branch correctly' 83 } 84 85 # main takes the input args and runs the tests. 86 main() { 87 local -r usage='test-ftt [-h] [-i infra-dir] [-p patchset-number] 88 89 This script produces the branch "ftt-test-branch-149cb550-9322-46a2-a27d-06c05781102d" 90 in the infra tree. This branch is temporary. 91 92 This script produces the branch "ftt-devel-branch-149cb550-9322-46a2-a27d-06c05781102d" 93 in the LUCI tree. This branch can be modified and then re-uploaded. 94 ' 95 96 while getopts ':hi:p:' opt; do 97 case "${opt}" in 98 h) printf '%s' "${usage}"; exit 0;; 99 i) local infra_dir="${OPTARG}";; 100 p) local patchset="${OPTARG}";; 101 :) 102 1>&2 printf '%s' "${usage}"; exit 1;; 103 *) 104 1>&2 printf '%s' "${usage}"; exit 1;; 105 esac 106 done 107 108 checkdep 'realpath' 109 checkdep 'git' 110 checkdep 'mktemp' 111 checkdep 'cp' 112 checkdep 'unlink' 113 114 [[ -n ${infra_dir} ]] || die "no directory given" 115 [[ -e ${infra_dir} ]] || die "path \`${infra_dir}' does not exist" 116 [[ -d ${infra_dir} ]] || die "path \`${infra_dir}' is not directory" 117 118 [[ -n "${patchset}" ]] || die 'no patchset given' 119 120 local -r selfpath="$(realpath -- "$0")" 121 122 local -r infra_dir="$(realpath -- "${infra_dir}")" || die "failed to get realpath to \`$1'" 123 124 # cd to a defensive dir so we catch inadvertent uses of relative paths rather 125 # than computed absolute paths. 126 local -r defensive_dir="$(mktemp -d)" || die 'failed to make defensive dir' 127 cd -- "${defensive_dir}" || die 'failed to cd to defensive dir' 128 129 [[ -f ${infra_dir}/.gclient ]] || die 'failed heuristic: no gclient file: is the file path correct?' 130 131 local -r luci_dir="${infra_dir}"/infra/go/src/go.chromium.org/luci 132 133 [[ -d $luci_dir ]] || die "luci directory \`${luci_dir}' does not exist or is not directory" 134 [[ -f $luci_dir/AUTHORS ]] || die "failed heuristic: derived directory \`${luci_dir}' has no AUTHORS file" 135 136 local -r infra_go_root="${infra_dir}/infra/go/src/infra" 137 [[ -d "${infra_dir}" ]] || die "infra go root directory ${infra_go_root} does not exist" 138 [[ -d "${infra_go_root}/unifiedfleet" ]] || die "failed heuristic: derived directory '${infra_go_root}/unifiedfleet' does not exist." 139 140 must_check_git_clean "${infra_go_root}" 141 must_check_git_clean "${luci_dir}" 142 143 # Back ourselves up, after this point all subsequent commands can change the git state. 144 backup_self 145 146 must_checkout_patchset_in_luci_dir 147 148 die 'not yet implemented' 149 } 150 151 main "$@"