1#!/bin/bash 2 3SELF=$(basename "${0}") 4DEFAULT_TAG="jdk17u/jdk-17.0.6-ga" 5SUPPORTED_TAGS="jdk7u/jdk7u40-b60" 6SUPPORTED_TAGS="${SUPPORTED_TAGS} jdk8u/jdk8u121-b13" 7SUPPORTED_TAGS="${SUPPORTED_TAGS} jdk8u/jdk8u60-b31" 8SUPPORTED_TAGS="${SUPPORTED_TAGS} jdk9/jdk-9+181" 9SUPPORTED_TAGS="${SUPPORTED_TAGS} jdk11u/jdk-11+28" 10SUPPORTED_TAGS="${SUPPORTED_TAGS} jdk11u/jdk-11.0.13-ga" 11SUPPORTED_TAGS="${SUPPORTED_TAGS} jdk17u/jdk-17.0.2-ga" 12SUPPORTED_TAGS="${SUPPORTED_TAGS} jdk17u/jdk-17.0.5-ga" 13SUPPORTED_TAGS="${SUPPORTED_TAGS} jdk17u/jdk-17.0.6-ga" 14 15 16USAGE=$(cat << EndOfUsage 17Usage: 18 ${SELF} [-b <bug_number>] [-t <upstream_tag>] <package_name> <package_name> ... 19 For example: 20 ${SELF} -b 123456 -t jdk17u/jdk-17.0.6-ga java.util.concurrent java.util.concurrent.atomic 21 ${SELF} java.util.concurrent.atomic -c AtomicInteger,AtomicBoolean,AtomicLong 22 ${SELF} java.util.concurrent.atomic -c AtomicInteger -c AtomicBoolean -c AtomicLong 23 24Possible arguments: 25 -h|--help - print help and exit 26 -t|--tag - the upstream tag to merge to; default: ${DEFAULT_TAG} or 27 OJLUNI_MERGE_TARGET (if defined) 28 -c|--classes - list of classes from the package to be processed; this is useful if only 29 some classes from a package are to be merged; only a single 30 package must be specified; can be provided as a comma-separated 31 list, or repeated -c arguments 32 -b|--bug - the bug number to use in the commit message; if not defined it will 33 be picked up from the libcore branch name (for example 34 "b-12345-oj-merge" -> "-b 12345") 35 36The supported upstream tags are: 37 $(echo ${SUPPORTED_TAGS} | sed 's/ /\n /g') 38EndOfUsage 39) 40 41HELP=$(cat << EndOfHelp 42Merges one or more packages from an upstream branch. 43 44This will use the correct form of add/modify based on what is already stored in 45libcore/EXPECTED_UPSTREAM. Also it will find new files in the new version of 46the upstream package and add those as well. 47 48${USAGE} 49EndOfHelp 50) 51 52BUG="" 53PACKAGES=() 54TAG="${OJLUNI_MERGE_TARGET:-"$DEFAULT_TAG"}" 55CLASSES=() 56 57function die() 58{ 59 echo -e ${1} 60 if [[ -n "${2}" ]] 61 then 62 echo -e "" 63 echo -e "${USAGE}" 64 fi 65 exit 1 66} 67 68function validate_tag 69{ 70 for expected in ${SUPPORTED_TAGS} 71 do 72 if [[ "${TAG}" == "${expected}" ]] 73 then 74 return 75 fi 76 done 77 die "Unknown tag: ${TAG}" "y" 78} 79 80function setup_env 81{ 82 if [[ -z "${ANDROID_BUILD_TOP}" ]] 83 then 84 die "ANDROID_BUILD_TOP not found. You need to run lunch first." 85 fi 86 87 shopt -s expand_aliases 88 source "${ANDROID_BUILD_TOP}/libcore/tools/expected_upstream/install_tools.sh" 89} 90 91while [[ $# -gt 0 ]]; do 92 case ${1} in 93 -h|--help) 94 echo "${HELP}" 95 exit 0 96 ;; 97 -b|--bug) 98 BUG="${2}" 99 shift 100 ;; 101 -t|--tag) 102 TAG="${2}" 103 shift 104 ;; 105 -c|--classes) 106 classes=$(echo "${2}" | sed 's/,/ /g') 107 for class in $(echo "${2}" | sed 's/,/ /g') 108 do 109 CLASSES+=(${class}) 110 done 111 shift 112 ;; 113 *) 114 PACKAGES+=(${1}) 115 ;; 116 esac 117 shift 118done 119 120if [[ ${#PACKAGES[@]} -eq 0 ]] 121then 122 die "You need to specify at least one package to merge." "y" 123elif [[ ${#CLASSES[@]} -gt 0 && ${#PACKAGES[@]} -gt 1 ]] 124then 125 die "The -c|--classes argument can only be provided with a single package" "y" 126fi 127 128setup_env 129validate_tag 130 131if [[ -z "${BUG}" ]] 132then 133 pushd "${ANDROID_BUILD_TOP}/libcore" 134 BUG=$(git branch --show-current | grep -E -o "\<b\>[-/][0-9]+-" | grep -E -o "[0-9]+") 135 popd 136fi 137 138function merge-class 139{ 140 local method="${1}" 141 local name="${2}" 142 local version="${3}" 143 144 local first_arg="${name}" 145 local second_arg="${version}" 146 147 if [[ "${method}" == "add" ]] 148 then 149 first_arg="${version}" 150 second_arg="${name}" 151 fi 152 echo ojluni_modify_expectation "${method}" "${first_arg}" "${second_arg}" 153 ojluni_modify_expectation "${method}" "${first_arg}" "${second_arg}" || \ 154 die "Failed to modify expectation file for ${name}" 155} 156 157function do-merge 158{ 159 local package="${1}" 160 local bug="${2}" 161 162 if [[ -n "${bug}" ]] 163 then 164 echo ojluni_merge_to_main -b "${bug}" 165 ojluni_merge_to_main -b "${bug}" || die "Failed to merge ${package} to master" 166 else 167 echo ojluni_merge_to_main 168 ojluni_merge_to_main || die "Failed to merge ${package} to master" 169 fi 170} 171 172function is-class-in-expected-upstream 173{ 174 local package_path="${1}" 175 local class_name="${2}" 176 local class_path="ojluni/src/main/java/${package_path}/${class_name}\.java" 177 grep "${class_path}" "${ANDROID_BUILD_TOP}/libcore/EXPECTED_UPSTREAM" 178} 179 180function get-package-path 181{ 182 local package="${1}" 183 echo "${package}" | sed --sandbox 's/\./\//'g 184} 185 186function ojluni-merge-package 187{ 188 local package="${1}" 189 local version="${2}" 190 local bug="${3}" 191 local package_path=$(get-package-path "${package}") 192 local package_full_path="${ANDROID_BUILD_TOP}/libcore/ojluni/src/main/java/${package_path}" 193 194 pushd "${ANDROID_BUILD_TOP}/libcore" 195 196 for f in $(ls "${package_full_path}"/*.java) 197 do 198 local class_name=$(basename -s .java ${f}) 199 local in_expected_upstream=$(is-class-in-expected-upstream "${package_path}" "${class_name}") 200 if [[ -n "${in_expected_upstream}" ]] 201 then 202 merge-class modify "${package}.${class_name}" "${version}" 203 else 204 merge-class add "${package}.${class_name}" "${version}" 205 fi 206 done 207 208 local version_id=$(echo "${version}" | grep -oE "^[^/]+") 209 local branch="aosp/upstream-open${version_id}" 210 local new_classes=$(git diff --name-only --diff-filter=D "${branch}" -- \ 211 "src/java.base/share/classes/${package_path}" \ 212 "ojluni/src/main/java/${package_path}") 213 214 for f in ${new_classes} 215 do 216 local class_name=$(basename -s .java ${f}) 217 local class_path="ojluni/src/main/java/${package_path}/${class_name}\.java" 218 merge-class add "${package}.${class_name}" "${version}" 219 done 220 221 do-merge "${package}" "${bug}" 222 223 popd 224} 225 226function ojluni-merge-class 227{ 228 local package="${1}" 229 local class="${2}" 230 local version="${3}" 231 local package_path=$(get-package-path "${package}") 232 local in_expected_upstream=$(is-class-in-expected-upstream "${package_path}" "${class}") 233 if [[ -n "${in_expected_upstream}" ]] 234 then 235 merge-class modify "${package}.${class}" "${version}" 236 else 237 merge-class add "${package}.${class}" "${version}" 238 fi 239} 240 241if [[ ${#CLASSES[@]} -eq 0 ]] 242then 243 for package in ${PACKAGES[@]} 244 do 245 echo "Merging '${package}' from ${TAG}" 246 ojluni-merge-package "${package}" "${TAG}" "${BUG}" 247 done 248elif [[ ${#PACKAGES[@]} -eq 1 ]] 249then 250 package=${PACKAGES[0]} 251 for class in ${CLASSES[@]} 252 do 253 echo "Merging ${package}.${class}" 254 ojluni-merge-class "${package}" "${class}" "${TAG}" 255 done 256 do-merge "${package}" "${BUG}" 257fi 258