github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/soong/scripts/diff_build_graphs.sh (about)

     1  #!/bin/bash -eu
     2  #
     3  # Copyright 2017 Google Inc. All rights reserved.
     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  set -e
    18  
    19  # This file makes it easy to confirm that a set of changes in source code don't result in any
    20  # changes to the generated ninja files. This is to reduce the effort required to be confident
    21  # in the correctness of refactorings
    22  
    23  function die() {
    24    echo "$@" >&2
    25    exit 1
    26  }
    27  
    28  function usage() {
    29    violation="$1"
    30    die "$violation
    31  
    32    Usage: diff_build_graphs.sh [--products=product1,product2...] <OLD_VERSIONS> <NEW_VERSIONS>
    33  
    34    This file builds and parses the build files (Android.mk, Android.bp, etc) for each requested
    35    product and for both sets of versions, and checks whether the ninja files (which implement
    36    the build graph) changed between the two versions.
    37  
    38    Example: diff_build_graphs.sh 'build/soong:work^ build/blueprint:work^' 'build/soong:work build/blueprint:work'
    39  
    40    Options:
    41      --products=PRODUCTS  comma-separated list of products to check"
    42  }
    43  
    44  PRODUCTS_ARG=""
    45  OLD_VERSIONS=""
    46  NEW_VERSIONS=""
    47  function parse_args() {
    48    # parse optional arguments
    49    while true; do
    50      arg="${1-}"
    51      case "$arg" in
    52        --products=*) PRODUCTS_ARG="$arg";;
    53        *) break;;
    54      esac
    55      shift
    56    done
    57    # parse required arguments
    58    if [ "$#" != "2" ]; then
    59      usage ""
    60    fi
    61    #argument validation
    62    OLD_VERSIONS="$1"
    63    NEW_VERSIONS="$2"
    64  
    65  }
    66  parse_args "$@"
    67  
    68  
    69  # find some file paths
    70  cd "$(dirname $0)"
    71  SCRIPT_DIR="$PWD"
    72  cd ../../..
    73  CHECKOUT_ROOT="$PWD"
    74  OUT_DIR="${OUT_DIR-}"
    75  if [ -z "$OUT_DIR" ]; then
    76    OUT_DIR=out
    77  fi
    78  WORK_DIR="$OUT_DIR/diff"
    79  OUT_DIR_OLD="$WORK_DIR/out_old"
    80  OUT_DIR_NEW="$WORK_DIR/out_new"
    81  OUT_DIR_TEMP="$WORK_DIR/out_temp"
    82  
    83  
    84  function checkout() {
    85    versionSpecs="$1"
    86    for versionSpec in $versionSpecs; do
    87      project="$(echo $versionSpec | sed 's|\([^:]*\):\([^:]*\)|\1|')"
    88      ref="$(echo     $versionSpec | sed 's|\([^:]*\):\([^:]*\)|\2|')"
    89      echo "checking out ref $ref in project $project"
    90      git -C "$project" checkout "$ref"
    91    done
    92  }
    93  
    94  function run_build() {
    95    echo
    96    echo "Starting build"
    97    # rebuild multiproduct_kati, in case it was missing before,
    98    # or in case it is affected by some of the changes we're testing
    99    make blueprint_tools
   100    # find multiproduct_kati and have it build the ninja files for each product
   101    builder="$(echo $OUT_DIR/soong/host/*/bin/multiproduct_kati)"
   102    BUILD_NUMBER=sample "$builder" $PRODUCTS_ARG --keep --out "$OUT_DIR_TEMP" || true
   103    echo
   104  }
   105  
   106  function diffProduct() {
   107    product="$1"
   108  
   109    zip1="$OUT_DIR_OLD/${product}.zip"
   110    unzipped1="$OUT_DIR_OLD/$product"
   111  
   112    zip2="$OUT_DIR_NEW/${product}.zip"
   113    unzipped2="$OUT_DIR_NEW/$product"
   114  
   115    unzip -qq "$zip1" -d "$unzipped1"
   116    unzip -qq "$zip2" -d "$unzipped2"
   117  
   118    #do a diff of the ninja files
   119    diffFile="$WORK_DIR/diff.txt"
   120    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
   121    if [[ -s "$diffFile" ]]; then
   122      # outputs are different, so remove the unzipped versions but keep the zipped versions
   123      echo "First few differences (total diff linecount=$(wc -l $diffFile)) for product $product:"
   124      cat "$diffFile" | head -n 10
   125      echo "End of differences for product $product"
   126      rm -rf "$unzipped1" "$unzipped2"
   127    else
   128      # outputs are the same, so remove all of the outputs
   129      rm -rf "$zip1" "$unzipped1" "$zip2" "$unzipped2"
   130    fi
   131  }
   132  
   133  function do_builds() {
   134    #reset work dir
   135    rm -rf "$WORK_DIR"
   136    mkdir "$WORK_DIR"
   137  
   138    #build new code
   139    checkout "$NEW_VERSIONS"
   140    run_build
   141    mv "$OUT_DIR_TEMP" "$OUT_DIR_NEW"
   142  
   143    #build old code
   144    #TODO do we want to cache old results? Maybe by the time we care to cache old results this will
   145    #be running on a remote server somewhere and be completely different
   146    checkout "$OLD_VERSIONS"
   147    run_build
   148    mv "$OUT_DIR_TEMP" "$OUT_DIR_OLD"
   149  
   150    #cleanup
   151    echo created "$OUT_DIR_OLD" and "$OUT_DIR_NEW"
   152  }
   153  
   154  function main() {
   155    do_builds
   156    checkout "$NEW_VERSIONS"
   157  
   158    #find all products
   159    productsFile="$WORK_DIR/all_products.txt"
   160    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"
   161    echo Diffing products
   162    for product in $(cat $productsFile); do
   163      diffProduct "$product"
   164    done
   165    echo Done diffing products
   166    echo "Any differing outputs can be seen at $OUT_DIR_OLD/*.zip and $OUT_DIR_NEW/*.zip"
   167    echo "See $WORK_DIR/diff.txt for the full list of differences for the latest product checked"
   168  }
   169  
   170  main