Skip to content

Commit ad5717d

Browse files
committed
Lint: Add lint-includes.sh
linter to test for duplicate includes, including of `.cpp` files, and introductions/removals of Boost modules.
1 parent faba3f6 commit ad5717d

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

test/lint/lint-includes.sh

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Copyright (c) 2018-2020 The Bitcoin Core developers
4+
# Distributed under the MIT software license, see the accompanying
5+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
6+
#
7+
# Check for duplicate includes.
8+
# Guard against accidental introduction of new Boost dependencies.
9+
# Check includes: Check for duplicate includes. Enforce bracket syntax includes.
10+
11+
export LC_ALL=C
12+
IGNORE_REGEXP="/(chiabls|leveldb|secp256k1|univalue|crc32c)/"
13+
14+
# cd to root folder of git repo for git ls-files to work properly
15+
cd "$(dirname "$0")/../.." || exit 1
16+
17+
filter_suffix() {
18+
git ls-files | grep -E "^src/.*\.${1}"'$' | grep -Ev "${IGNORE_REGEXP}"
19+
}
20+
21+
EXIT_CODE=0
22+
23+
for HEADER_FILE in $(filter_suffix h); do
24+
DUPLICATE_INCLUDES_IN_HEADER_FILE=$(grep -E "^#include " < "${HEADER_FILE}" | sort | uniq -d)
25+
if [[ ${DUPLICATE_INCLUDES_IN_HEADER_FILE} != "" ]]; then
26+
echo "Duplicate include(s) in ${HEADER_FILE}:"
27+
echo "${DUPLICATE_INCLUDES_IN_HEADER_FILE}"
28+
echo
29+
EXIT_CODE=1
30+
fi
31+
done
32+
33+
for CPP_FILE in $(filter_suffix cpp); do
34+
DUPLICATE_INCLUDES_IN_CPP_FILE=$(grep -E "^#include " < "${CPP_FILE}" | sort | uniq -d)
35+
if [[ ${DUPLICATE_INCLUDES_IN_CPP_FILE} != "" ]]; then
36+
echo "Duplicate include(s) in ${CPP_FILE}:"
37+
echo "${DUPLICATE_INCLUDES_IN_CPP_FILE}"
38+
echo
39+
EXIT_CODE=1
40+
fi
41+
done
42+
43+
INCLUDED_CPP_FILES=$(git grep -E "^#include [<\"][^>\"]+\.cpp[>\"]" -- "*.cpp" "*.h")
44+
if [[ ${INCLUDED_CPP_FILES} != "" ]]; then
45+
echo "The following files #include .cpp files:"
46+
echo "${INCLUDED_CPP_FILES}"
47+
echo
48+
EXIT_CODE=1
49+
fi
50+
51+
EXPECTED_BOOST_INCLUDES=(
52+
boost/algorithm/string.hpp
53+
boost/algorithm/string/classification.hpp
54+
boost/algorithm/string/replace.hpp
55+
boost/algorithm/string/split.hpp
56+
boost/date_time/posix_time/posix_time.hpp
57+
boost/filesystem.hpp
58+
boost/filesystem/fstream.hpp
59+
boost/multi_index/sequenced_index.hpp
60+
boost/optional.hpp
61+
boost/pool/pool_alloc.hpp
62+
boost/preprocessor/cat.hpp
63+
boost/preprocessor/stringize.hpp
64+
boost/signals2/connection.hpp
65+
boost/signals2/last_value.hpp
66+
boost/signals2/signal.hpp
67+
boost/test/unit_test.hpp
68+
boost/thread.hpp
69+
boost/thread/condition_variable.hpp
70+
boost/thread/mutex.hpp
71+
boost/thread/thread.hpp
72+
boost/tokenizer.hpp
73+
boost/variant.hpp
74+
boost/variant/apply_visitor.hpp
75+
boost/variant/static_visitor.hpp
76+
)
77+
78+
for BOOST_INCLUDE in $(git grep '^#include <boost/' -- "*.cpp" "*.h" | cut -f2 -d: | cut -f2 -d'<' | cut -f1 -d'>' | sort -u); do
79+
IS_EXPECTED_INCLUDE=0
80+
for EXPECTED_BOOST_INCLUDE in "${EXPECTED_BOOST_INCLUDES[@]}"; do
81+
if [[ "${BOOST_INCLUDE}" == "${EXPECTED_BOOST_INCLUDE}" ]]; then
82+
IS_EXPECTED_INCLUDE=1
83+
break
84+
fi
85+
done
86+
if [[ ${IS_EXPECTED_INCLUDE} == 0 ]]; then
87+
EXIT_CODE=1
88+
echo "A new Boost dependency in the form of \"${BOOST_INCLUDE}\" appears to have been introduced:"
89+
git grep "${BOOST_INCLUDE}" -- "*.cpp" "*.h"
90+
echo
91+
fi
92+
done
93+
94+
for EXPECTED_BOOST_INCLUDE in "${EXPECTED_BOOST_INCLUDES[@]}"; do
95+
if ! git grep -q "^#include <${EXPECTED_BOOST_INCLUDE}>" -- "*.cpp" "*.h"; then
96+
echo "Good job! The Boost dependency \"${EXPECTED_BOOST_INCLUDE}\" is no longer used."
97+
echo "Please remove it from EXPECTED_BOOST_INCLUDES in $0"
98+
echo "to make sure this dependency is not accidentally reintroduced."
99+
echo
100+
EXIT_CODE=1
101+
fi
102+
done
103+
104+
# TODO: Uncomment this check once we move to bracket includes
105+
#QUOTE_SYNTAX_INCLUDES=$(git grep '^#include "' -- "*.cpp" "*.h" | grep -Ev "${IGNORE_REGEXP}")
106+
#if [[ ${QUOTE_SYNTAX_INCLUDES} != "" ]]; then
107+
# echo "Please use bracket syntax includes (\"#include <foo.h>\") instead of quote syntax includes:"
108+
# echo "${QUOTE_SYNTAX_INCLUDES}"
109+
# echo
110+
# EXIT_CODE=1
111+
#fi
112+
113+
exit ${EXIT_CODE}

0 commit comments

Comments
 (0)