123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- #!/bin/bash -eu
- #
- # Copyright 2017 Google Inc. All rights reserved.
- #
- # 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.
- set -e
- # This file makes it easy to confirm that a set of changes in source code don't result in any
- # changes to the generated ninja files. This is to reduce the effort required to be confident
- # in the correctness of refactorings
- function die() {
- echo "$@" >&2
- exit 1
- }
- function usage() {
- violation="$1"
- die "$violation
- Usage: diff_build_graphs.sh [--products=product1,product2...] <OLD_VERSIONS> <NEW_VERSIONS>
- This file builds and parses the build files (Android.mk, Android.bp, etc) for each requested
- product and for both sets of versions, and checks whether the ninja files (which implement
- the build graph) changed between the two versions.
- Example: diff_build_graphs.sh 'build/soong:work^ build/blueprint:work^' 'build/soong:work build/blueprint:work'
- Options:
- --products=PRODUCTS comma-separated list of products to check"
- }
- PRODUCTS_ARG=""
- OLD_VERSIONS=""
- NEW_VERSIONS=""
- function parse_args() {
- # parse optional arguments
- while true; do
- arg="${1-}"
- case "$arg" in
- --products=*) PRODUCTS_ARG="$arg";;
- *) break;;
- esac
- shift
- done
- # parse required arguments
- if [ "$#" != "2" ]; then
- usage ""
- fi
- #argument validation
- OLD_VERSIONS="$1"
- NEW_VERSIONS="$2"
- }
- parse_args "$@"
- # find some file paths
- cd "$(dirname $0)"
- SCRIPT_DIR="$PWD"
- cd ../../..
- CHECKOUT_ROOT="$PWD"
- OUT_DIR="${OUT_DIR-}"
- if [ -z "$OUT_DIR" ]; then
- OUT_DIR=out
- fi
- WORK_DIR="$OUT_DIR/diff"
- OUT_DIR_OLD="$WORK_DIR/out_old"
- OUT_DIR_NEW="$WORK_DIR/out_new"
- OUT_DIR_TEMP="$WORK_DIR/out_temp"
- function checkout() {
- versionSpecs="$1"
- for versionSpec in $versionSpecs; do
- project="$(echo $versionSpec | sed 's|\([^:]*\):\([^:]*\)|\1|')"
- ref="$(echo $versionSpec | sed 's|\([^:]*\):\([^:]*\)|\2|')"
- echo "checking out ref $ref in project $project"
- git -C "$project" checkout "$ref"
- done
- }
- function run_build() {
- echo
- echo "Starting build"
- # rebuild multiproduct_kati, in case it was missing before,
- # or in case it is affected by some of the changes we're testing
- make blueprint_tools
- # find multiproduct_kati and have it build the ninja files for each product
- builder="$(echo $OUT_DIR/host/*/bin/multiproduct_kati)"
- BUILD_NUMBER=sample "$builder" $PRODUCTS_ARG --keep --out "$OUT_DIR_TEMP" || true
- echo
- }
- function diffProduct() {
- product="$1"
- zip1="$OUT_DIR_OLD/${product}.zip"
- unzipped1="$OUT_DIR_OLD/$product"
- zip2="$OUT_DIR_NEW/${product}.zip"
- unzipped2="$OUT_DIR_NEW/$product"
- unzip -qq "$zip1" -d "$unzipped1"
- unzip -qq "$zip2" -d "$unzipped2"
- #do a diff of the ninja files
- diffFile="$WORK_DIR/diff.txt"
- diff -r "$unzipped1" "$unzipped2" -x build_date.txt -x build_number.txt -x '\.*' -x '*.log' -x build_fingerprint.txt -x build.ninja.d -x '*.zip' > $diffFile || true
- if [[ -s "$diffFile" ]]; then
- # outputs are different, so remove the unzipped versions but keep the zipped versions
- echo "First few differences (total diff linecount=$(wc -l $diffFile)) for product $product:"
- cat "$diffFile" | head -n 10
- echo "End of differences for product $product"
- rm -rf "$unzipped1" "$unzipped2"
- else
- # outputs are the same, so remove all of the outputs
- rm -rf "$zip1" "$unzipped1" "$zip2" "$unzipped2"
- fi
- }
- function do_builds() {
- #reset work dir
- rm -rf "$WORK_DIR"
- mkdir "$WORK_DIR"
- #build new code
- checkout "$NEW_VERSIONS"
- run_build
- mv "$OUT_DIR_TEMP" "$OUT_DIR_NEW"
- #build old code
- #TODO do we want to cache old results? Maybe by the time we care to cache old results this will
- #be running on a remote server somewhere and be completely different
- checkout "$OLD_VERSIONS"
- run_build
- mv "$OUT_DIR_TEMP" "$OUT_DIR_OLD"
- #cleanup
- echo created "$OUT_DIR_OLD" and "$OUT_DIR_NEW"
- }
- function main() {
- do_builds
- checkout "$NEW_VERSIONS"
- #find all products
- productsFile="$WORK_DIR/all_products.txt"
- find $OUT_DIR_OLD $OUT_DIR_NEW -mindepth 1 -maxdepth 1 -name "*.zip" | sed "s|^$OUT_DIR_OLD/||" | sed "s|^$OUT_DIR_NEW/||" | sed "s|\.zip$||" | sort | uniq > "$productsFile"
- echo Diffing products
- for product in $(cat $productsFile); do
- diffProduct "$product"
- done
- echo Done diffing products
- echo "Any differing outputs can be seen at $OUT_DIR_OLD/*.zip and $OUT_DIR_NEW/*.zip"
- echo "See $WORK_DIR/diff.txt for the full list of differences for the latest product checked"
- }
- main
|