1#!/bin/sh
2# Copyright 2017 gRPC authors.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16set -x
17
18cd ${IWYU_ROOT}
19
20export PATH=${PATH}:${IWYU_ROOT}/iwyu_build/bin
21
22# number of CPUs available
23CPU_COUNT=`nproc`
24
25rm -rf iwyu || true
26git clone https://github.com/include-what-you-use/include-what-you-use.git iwyu
27
28###############################################################################
29#
30#   BEWARE!  BEWARE!  BEWARE!  BEWARE!  BEWARE!  BEWARE!  BEWARE!  BEWARE!
31#
32#   Changing the version of iwyu can bring along subtle changes.
33#   You *must* test the new version of iwyu:
34#   1. run it on the entire codebase before submitting
35#   2. UPLOAD A CHANGE THAT SHOULD BE BROKEN AFTER SUBMISSION OF THIS CHANGE
36#   ensure that the broken change is caught by the new version of iwyu
37#
38#   BEWARE!  BEWARE!  BEWARE!  BEWARE!  BEWARE!  BEWARE!  BEWARE!  BEWARE!
39#
40###############################################################################
41
42# latest commit on the clang 15 branch
43cd ${IWYU_ROOT}/iwyu
44git checkout 7f0b6c304acf69c42bb7f6e03c63f836924cb7e0
45if [ $? -ne 0 ]; then
46  echo "Failed to checkout iwyu commit"
47  exit 1
48fi
49mkdir -p ${IWYU_ROOT}/iwyu_build
50cd ${IWYU_ROOT}/iwyu_build
51cmake -G "Unix Makefiles" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DLLVM_ROOT_DIR=/usr/lib/llvm-15 ${IWYU_ROOT}/iwyu
52if [ $? -ne 0 ]; then
53  echo "Failed to cmake iwyu"
54  exit 1
55fi
56make -j $CPU_COUNT
57if [ $? -ne 0 ]; then
58  echo "Failed to make iwyu"
59  exit 1
60fi
61cd ${IWYU_ROOT}
62
63# patch python shebang for our environment (we need python3, not python)
64sed -i 's,^#!/usr/bin/env python,#!/usr/bin/env python3,g' ${IWYU_ROOT}/iwyu/iwyu_tool.py
65sed -i 's,^#!/usr/bin/env python,#!/usr/bin/env python3,g' ${IWYU_ROOT}/iwyu/fix_includes.py
66
67cat compile_commands.json                            \
68  | sed "s/ -DNDEBUG//g"                             \
69  | sed "s/ -std=c\\+\\+14/ -std=c++17/g"            \
70  | sed "s,\"file\": \",\"file\": \"${IWYU_ROOT}/,g" \
71  > compile_commands_for_iwyu.json
72
73export ENABLED_MODULES='
74  src/core/ext
75  src/core/lib
76  src/cpp
77  test/core
78  fuzztest
79'
80
81export DISABLED_MODULES='
82  src/core/lib/gpr
83  src/core/lib/iomgr
84  src/core/ext/transport/binder
85  test/core/alts
86  test/core/iomgr
87  test/core/security
88  test/core/tsi
89  test/core/transport/binder
90'
91
92export INCLUSION_REGEX=`echo $ENABLED_MODULES | sed 's/ /|/g' | sed 's,\\(.*\\),^(\\1)/,g'`
93export EXCLUSION_REGEX=`echo $DISABLED_MODULES | sed 's/ /|/g' | sed 's,\\(.*\\),^(\\1)/,g'`
94
95# figure out which files to include
96cat compile_commands.json | jq -r '.[].file'                                     \
97  | grep -E $INCLUSION_REGEX                                                     \
98  | grep -v -E "/upb-generated/|/upbdefs-generated/"                             \
99  | grep -v -E $EXCLUSION_REGEX                                                  \
100  | grep -v src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h \
101  | grep -v test/core/end2end/end2end_tests.cc                                   \
102  | sort                                                                         \
103  > iwyu_files0.txt
104
105cat iwyu_files0.txt                    \
106  | xargs -d '\n' ls -1df 2> /dev/null \
107  > iwyu_files.txt                     \
108  || true
109
110echo '#!/bin/sh
111${IWYU_ROOT}/iwyu/iwyu_tool.py -p compile_commands_for_iwyu.json $1       \
112    -- -Xiwyu --no_fwd_decls                                              \
113       -Xiwyu --update_comments                                           \
114       -Xiwyu --mapping_file=${IWYU_ROOT}/tools/distrib/iwyu_mappings.imp \
115  | grep -v -E "port_platform.h"                                          \
116  | grep -v -E "repeated_ptr_field.h"                                     \
117  | grep -v -E "repeated_field.h"                                         \
118  | grep -v -E "^(- )?namespace "                                         \
119  > iwyu/iwyu.`echo $1 | sha1sum`.out
120' > iwyu/run_iwyu_on.sh
121chmod +x iwyu/run_iwyu_on.sh
122
123# run iwyu, filtering out changes to port_platform.h
124xargs -n 1 -P $CPU_COUNT -a iwyu_files.txt ${IWYU_ROOT}/iwyu/run_iwyu_on.sh
125
126cat iwyu/iwyu.*.out > iwyu.out
127
128# apply the suggested changes
129${IWYU_ROOT}/iwyu/fix_includes.py \
130  --nocomments                    \
131  --nosafe_headers                \
132  --ignore_re='^(include/.*|src/core/lib/security/credentials/tls/grpc_tls_credentials_options\.h)' \
133  < iwyu.out                      \
134  | grep 'IWYU edited 0 files on your behalf'
135
136if [ $? -ne 0 ]
137then
138    echo "Iwyu edited some files. Here is the diff of files edited by iwyu:"
139    git --no-pager diff
140    # Exit with a non zero error code to ensure sanity checks fail accordingly.
141    exit 1
142fi
143