1#!/bin/bash 2#set -x 3 4# used for projects where some files are mainline, some are not 5# we get a list of the files/directories out of the project's root. 6# 7# invocation $0 ${repo_root} ${preupload_files} 8# 9# Example PREUPLOAD.cfg: 10# 11# [Hook Scripts] 12# mainline_hook = ${REPO_ROOT}/frameworks/av/tools/mainline_hook_partial.sh ${REPO_ROOT} ${PREUPLOAD_FILES} 13# 14# MainlineFiles.cfg syntax: 15# 16# ignore comment (#) lines and blank lines 17# rest are path prefixes starting at root of the project 18# (so OWNERS, not frameworks/av/OWNERS) 19# 20# path 21# INCLUDE path 22# EXCLUDE path 23# 24# 'path' and 'INCLUDE path' are identical -- they both indicate that this path 25# is part of mainline 26# EXCLUDE indicates that this is not part of mainline, 27# so 'foo/' and 'EXCLUDE foo/nope' 28# means everything under foo/ is part of mainline EXCEPT foo/nope. 29# INCLUDE/EXCLUDE/INCLUDE nested structuring is not supported 30# 31# matching is purely prefix 32# so 'foo' will match 'foo', 'foo.c', 'foo/bar/baz' 33# if you want to exclude a directory, best to use a pattern like "foo/" 34# 35 36## tunables: 37## 38## as of 2024/5, things are all on the same branch. 39DEV_BRANCH=main 40MAINLINE_BRANCH=main 41filelist_file=MainlineFiles.cfg 42 43### 44 45REPO_ROOT=$1; shift 46# the rest of the command line is the file list 47PREUPLOAD_FILES="$*" 48 49RED=$(tput setaf 1) 50NORMAL=$(tput sgr0) 51 52## get the active branch: 53## * <localbranch> <shainfo> [goog/master] Fix to handle missing checks on error returned 54## strip this down to "master" 55## * b157501573_advisory 25521834a6 [goog/sc-dev] Merge "PlayerBase: add audio session ID" into sc-dev 56## 57current=`git branch -vv | grep -P "^\*[^\[]+\[goog/"|sed -e 's/^.*\[//' | sed -e 's/\].*$//'|sed -e 's/:.*$//'| sed -e 's/^goog\///'` 58if [ "${current}" = "" ] ; then 59 current=unknown 60fi 61 62## figure out whether which files are for mainline and which are not 63if [ "${PREUPLOAD_FILES}" = "" ] ; then 64 # empty files? what's up there, i suppose we'll let that go 65 exit 0 66fi 67 68## get the list of files out of the project's root 69## figure out which way I'm going .. 70## use list of files to scan PREUPLOAD_FILES 71## use PREUPLOAD_FILES to scan the list of good/bad from the project root 72## 73## remember to do an exclude, so I can say 74## include/these/files/ 75## EXCLUDE include/these/files/nested/ 76## 77## and it should all be prefix based stuff... 78 79if [ ! -f ${REPO_ROOT}/${REPO_PATH}/${filelist_file} ] ; then 80 echo "Poorly Configured project, missing ${filelist_file} in root of project" 81 exit 1 82fi 83 84# is 1st arg a prefix of 2nd arg 85beginswith() { case $2 in "$1"*) true;; *) false;; esac; } 86 87exclusions="" 88inclusions="" 89while read p1 p2 90do 91 # ignore comment lines in the file 92 # ignore empty lines in the file 93 if beginswith "#" "${p1}" ; then 94 # ignore this line 95 true 96 elif [ -z "${p1}" ] ; then 97 # ignore blanks 98 true 99 elif [ ${p1} = "EXCLUDE" ] ; then 100 # add to the exclusion list 101 if [ ! -z ${p2} ] ; then 102 exlusions="${exclusions} ${p2}" 103 fi 104 elif [ ${p1} = "INCLUDE" ] ; then 105 # add to the inclusion list 106 if [ ! -z ${p2} ] ; then 107 inclusions="${inclusions} ${p2}" 108 fi 109 elif [ ! -z ${p1} ] ; then 110 inclusions="${inclusions} ${p1}" 111 fi 112done < ${REPO_ROOT}/${REPO_PATH}/${filelist_file} 113 114# so we can play with array syntax 115#INCLUSIONS=( ${inclusions} ) 116#EXCLUSIONS=( ${exclusions} ) 117 118mainline_yes="" 119mainline_no="" 120 121# is it part of the list of mainline files/directories? 122for path in ${PREUPLOAD_FILES} ; do 123 #echo is ${path} a mainline file... 124 for aprefix in ${inclusions} .. ; do 125 #echo compare against ${aprefix} ... 126 if [ "${aprefix}" = ".." ] ; then 127 mainline_no="${mainline_no} ${path}" 128 elif beginswith ${aprefix} ${path} ; then 129 mainline_yes="${mainline_yes} ${path}" 130 break # on to next uploaded file 131 fi 132 done 133done 134 135# TODO: audit the yes list to see if some should be moved to the no list 136 137# 3 situations 138# -- everything is on mainline (mainline_yes non-empty, other empty) 139# -- some is mainline, some is not (files_* both non-empty) 140# -- none is mainline (mainline_yes empty, other non_empty 141# -- both empty only happens if PREUPLOAD_FILES is empty, covered above 142 143if [ -z "${mainline_yes}" ] ; then 144 # no mainline files, everything else is non-mainline, let it go 145 exit 0 146fi 147 148# 149# exit 0 is "all good, no output passed along to user" 150# exit 77 is "a warning, pass along the output to the user" 151# exit 1 will be a failure. 152# 153result=0 154 155# simple reminder that it should also land in mainline branch 156# 157if [ "${current}" != "${MAINLINE_BRANCH}" ] ; then 158 # simple reminder to ensure it hits mainline 159 result=77 160 cat - <<EOF 161You are uploading repo ${RED}${REPO_PATH}${NORMAL} to branch ${RED}${current}${NORMAL}. 162The mainline branch for ${RED}${REPO_PATH}${NORMAL} is branch ${RED}${MAINLINE_BRANCH}${NORMAL}. 163 164Ensure an appropriate cherry pick or equivalent lands in branch ${RED}${MAINLINE_BRANCH}${NORMAL}. 165Security bulletin timing or unreleased functionality may drive when this can be landed. 166EOF 167fi 168 169# watch for the mixed some mainline / some not CL 170# we usually want to reject such mixed CLs 171# 172 173if [ ! -z "${mainline_no}" ] ; then 174 # mixed bag, suggest (not insist) that developer split them. 175 result=1 176 cat - <<EOF 177This change contains both mainline and non-mainline files. Please separate 178them into separate CLs. It may also be appropriate to update the list of mainline 179files in ${RED}${REPO_ROOT}/${filelist_file}${NORMAL}. 180 181EOF 182 echo "===== Mainline files =====" 183 echo -e ${RED} 184 echo ${mainline_yes} | sed -e 's/ / 185/g' 186 echo -e ${NORMAL} 187 188 echo "===== Non-Mainline files =====" 189 echo -e ${RED} 190 echo ${mainline_no} | sed -e 's/ / 191/g' 192 echo -e ${NORMAL} 193 194 cat - <<EOF 195 196If you are sure you want to proceed uploading to branch ${RED}${current}${NORMAL}, 197re-run your repo upload command with the '--no-verify' option 198 199EOF 200fi 201 202# result will be: 203# 0: all good, no output passed to user 204# 77: warnings (but we pass), output passed along to user 205# else: failure, output passed along to the user 206 207exit ${result} 208 209