[CI] Add shellcheck and fix up warnings (#2809)

# Motivation

We have quite a lot of shell scripts in our repo and want to make sure that they all pass `shellcheck`.

# Modification

This PR adds a GH action workflow to the soundness script for `shellcheck` and fixes up all errors and warnings.

# Result

No more shell/bash discussions
This commit is contained in:
Franz Busch
2024-07-25 16:55:44 +02:00
committed by GitHub
parent 55d4c49334
commit f17f7e5909
53 changed files with 191 additions and 319 deletions
+14
View File
@@ -130,3 +130,17 @@ jobs:
run: |
apt-get -qq update && apt-get -qq -y install curl
curl -s https://raw.githubusercontent.com/apple/swift-nio/main/scripts/check-swift-format.sh | bash
shell-check:
name: Shell check
if: ${{ inputs.format_check_enabled }}
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Mark the workspace as safe
# https://github.com/actions/checkout/issues/766
run: git config --global --add safe.directory ${GITHUB_WORKSPACE}
- name: Run shellcheck
run: git ls-files -z '*.sh' | xargs -0 shellcheck
@@ -226,7 +226,7 @@ while getopts "ns:p:m:d:t:" opt; do
do_hooking=false
;;
s)
shared_files+=( $(abs_path "$OPTARG") )
shared_files+=( "$(abs_path "$OPTARG")" )
;;
p)
pkg_root=$(abs_path "$OPTARG")
+3 -3
View File
@@ -44,9 +44,9 @@ function junit_output_replace() {
function plugin_junit_xml_test_suite_begin() {
junit_testsuite_time=0
junit_output_write "<testsuite name='$1' hostname='$(hostname)' "\
"timestamp='$(date -u +"%Y-%m-%dT%H:%M:%S")' tests='XXX-TESTS-XXX' "\
"failures='XXX-FAILURES-XXX' time='XXX-TIME-XXX' errors='0' id='$(date +%s)'"\
junit_output_write "<testsuite name='$1' hostname='$(hostname)' " \
"timestamp='$(date -u +"%Y-%m-%dT%H:%M:%S")' tests='XXX-TESTS-XXX' " \
"failures='XXX-FAILURES-XXX' time='XXX-TIME-XXX' errors='0' id='$(date +%s)'" \
" package='NIOIntegrationTests.$1'>"
}
+5
View File
@@ -20,12 +20,17 @@ set -x
set -o pipefail
test="$1"
# shellcheck disable=SC2034 # Used by whatever we source transpile in
tmp="$2"
# shellcheck disable=SC2034 # Used by whatever we source transpile in
root="$3"
# shellcheck disable=SC2034 # Used by whatever we source transpile in
g_show_info="$4"
here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# shellcheck source=IntegrationTests/test_functions.sh
source "$here/test_functions.sh"
# shellcheck source=/dev/null
source "$test"
wait
)
+8 -6
View File
@@ -36,7 +36,9 @@ function plugins_do() {
done
}
# shellcheck source=IntegrationTests/plugin_echo.sh
source "$here/plugin_echo.sh"
# shellcheck source=/dev/null
source "$here/plugin_junit_xml.sh"
plugins="echo"
@@ -88,7 +90,7 @@ function run_test() {
if $verbose; then
"$@" 2>&1 | tee -a "$out"
# we need to return the return value of the first command
return ${PIPESTATUS[0]}
return "${PIPESTATUS[0]}"
else
"$@" >> "$out" 2>&1
fi
@@ -113,13 +115,13 @@ for f in tests_*; do
plugins_do test_begin "$t" "$f"
start=$(date +%s)
if run_test "$here/run-single-test.sh" "$here/$f/$t" "$test_tmp" "$here/.." "$show_info"; then
plugins_do test_ok "$(time_diff_to_now $start)"
plugins_do test_ok "$(time_diff_to_now "$start")"
suite_ok=$((suite_ok+1))
if $verbose; then
cat "$out"
fi
else
plugins_do test_fail "$(time_diff_to_now $start)" "$out"
plugins_do test_fail "$(time_diff_to_now "$start")" "$out"
suite_fail=$((suite_fail+1))
fi
if ! $debug; then
@@ -131,7 +133,7 @@ for f in tests_*; do
cnt_ok=$((cnt_ok + suite_ok))
cnt_fail=$((cnt_fail + suite_fail))
cd ..
plugins_do test_suite_end "$(time_diff_to_now $start_suite)" "$suite_ok" "$suite_fail"
plugins_do test_suite_end "$(time_diff_to_now "$start_suite")" "$suite_ok" "$suite_fail"
done
if ! $debug; then
@@ -142,7 +144,7 @@ fi
# report
if [[ $cnt_fail > 0 ]]; then
if [[ $cnt_fail -gt 0 ]]; then
# terminate leftovers (the whole process group)
trap '' TERM
kill 0 # ignore-unacceptable-language
@@ -152,7 +154,7 @@ else
plugins_do summary_ok "$cnt_ok" "$cnt_fail"
fi
if [[ $cnt_fail > 0 ]]; then
if [[ $cnt_fail -gt 0 ]]; then
exit 1
else
exit 0
+1
View File
@@ -64,6 +64,7 @@ function assert_greater_than_or_equal() {
g_has_previously_infoed=false
function info() {
# shellcheck disable=SC2154 # Defined by an include our by being source transpiled in
if $g_show_info; then
if ! $g_has_previously_infoed; then
echo >&3 || true # echo an extra newline so it looks better
+21 -8
View File
@@ -58,7 +58,7 @@ function do_netstat() {
}
function create_token() {
mktemp "$tmp/server_token_XXXXXX"
mktemp "${tmp:?}/server_token_XXXXXX"
}
function start_server() {
@@ -84,6 +84,7 @@ function start_server() {
mkdir "$tmp/htdocs"
swift build
# shellcheck disable=SC2086 # Disabled to properly pass the args
"$(swift build --show-bin-path)/NIOHTTP1Server" $extra_args $maybe_nio_host "$port" "$tmp/htdocs" &
tmp_server_pid=$!
case "$type" in
@@ -114,9 +115,11 @@ function start_server() {
esac
echo "port: $port"
echo "curl port: $curl_port"
echo "local token_port; local token_htdocs; local token_pid;" >> "$token"
echo " token_port='$port'; token_htdocs='$tmp/htdocs'; token_pid='$!';" >> "$token"
echo " token_type='$type'; token_server_ip='$maybe_nio_host'" >> "$token"
{
echo "local token_port; local token_htdocs; local token_pid;"
echo " token_port='$port'; token_htdocs='$tmp/htdocs'; token_pid='$!';"
echo " token_type='$type'; token_server_ip='$maybe_nio_host'"
} >> "$token"
tmp_server_pid=$(get_server_pid "$token")
echo "local token_open_fds" >> "$token"
echo "token_open_fds='$(get_number_of_open_fds_for_pid "$tmp_server_pid")'" >> "$token"
@@ -125,21 +128,25 @@ function start_server() {
}
function get_htdocs() {
# shellcheck source=/dev/null
source "$1"
echo "$token_htdocs"
# shellcheck disable=SC2154
echo "${token_htdocs:?}"
}
function get_socket() {
# shellcheck source=/dev/null
source "$1"
echo "$token_port"
echo "${token_port:?}"
}
function stop_server() {
# shellcheck source=/dev/null
source "$1"
sleep 0.5 # just to make sure all the fds could be closed
if command -v lsof > /dev/null 2> /dev/null; then
do_netstat "$token_type"
assert_number_of_open_fds_for_pid_equals "$token_pid" "$token_open_fds"
do_netstat "${token_type:?}"
assert_number_of_open_fds_for_pid_equals "${token_pid:?}" "${token_open_fds:?}"
fi
# assert server is still running
kill -0 "$token_pid" # ignore-unacceptable-language
@@ -149,6 +156,7 @@ function stop_server() {
if ! kill -0 "$token_pid" 2> /dev/null; then # ignore-unacceptable-language
break # good, dead
fi
# shellcheck disable=SC2009
ps auxw | grep "$token_pid" || true
sleep 0.1
done
@@ -158,21 +166,26 @@ function stop_server() {
}
function get_server_pid() {
# shellcheck source=/dev/null
source "$1"
echo "$token_pid"
}
function get_server_port() {
# shellcheck source=/dev/null
source "$1"
echo "$token_port"
}
function get_server_ip() {
# shellcheck source=/dev/null
source "$1"
# shellcheck disable=SC2154
echo "$token_server_ip"
}
function do_curl() {
# shellcheck source=/dev/null
source "$1"
shift
case "$token_type" in
@@ -13,6 +13,7 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
@@ -22,7 +23,7 @@ echo FOO BAR > "$htdocs/some_file.txt"
touch "$htdocs/empty"
for file in some_file.txt empty; do
for method in sendfile fileio; do
do_curl "$token" "http://foobar.com/$method/$file" > "$tmp/out.txt"
do_curl "$token" "http://foobar.com/$method/$file" > "${tmp:?"tmp variable not set"}/out.txt"
assert_equal_files "$htdocs/$file" "$tmp/out.txt"
done
done
@@ -13,6 +13,7 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
@@ -22,7 +23,7 @@ base="s/o/m/e/r/a/n/d/o/m/f/o/l/d/e/r"
mkdir -p "$htdocs/$base"
dd if=/dev/urandom of="$htdocs/$base/random.bytes" bs=$((1024 * 1024)) count=2
for method in sendfile fileio; do
do_curl "$token" "http://foobar.com/$method/$base/random.bytes" > "$tmp/random.bytes"
do_curl "$token" "http://foobar.com/$method/$base/random.bytes" > "${tmp:?"tmp variable not set"}/random.bytes"
assert_equal_files "$htdocs/$base/random.bytes" "$tmp/random.bytes"
done
stop_server "$token"
@@ -13,11 +13,12 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
start_server "$token"
dd if=/dev/urandom of="$tmp/random.bytes" bs=$((64*1024)) count=1
dd if=/dev/urandom of="${tmp:?"tmp variable not set"}/random.bytes" bs=$((64*1024)) count=1
do_curl "$token" --data-binary "@$tmp/random.bytes" \
"http://foobar.com/dynamic/echo" > "$tmp/random.bytes.out"
cmp "$tmp/random.bytes" "$tmp/random.bytes.out"
@@ -13,6 +13,7 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
@@ -20,7 +21,7 @@ start_server "$token"
server_pid=$(get_server_pid "$token")
echo -n \
"$server_pid$server_pid$server_pid$server_pid$server_pid$server_pid$server_pid$server_pid$server_pid$server_pid" \
> "$tmp/out_expected"
> "${tmp:?"tmp variable not set"}/out_expected"
do_curl "$token" \
"http://foobar.com/dynamic/pid" \
"http://foobar.com/dynamic/pid" \
@@ -13,12 +13,13 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
start_server "$token"
do_curl "$token" "http://foobar.com/dynamic/pid" > "$tmp/out"
for f in $(seq 100); do
do_curl "$token" "http://foobar.com/dynamic/pid" > "${tmp:?"tmp variable not set"}/out"
for _ in $(seq 100); do
do_curl "$token" "http://foobar.com/dynamic/pid" > "$tmp/out2"
assert_equal_files "$tmp/out" "$tmp/out2"
done
@@ -13,11 +13,12 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
start_server "$token"
echo foo > "$tmp/out_expected"
echo foo > "${tmp:?"tmp variable not set"}/out_expected"
do_curl "$token" --data-binary "@$tmp/out_expected" --http1.0 \
"http://foobar.com/dynamic/echo_balloon" > "$tmp/out_actual"
assert_equal_files "$tmp/out_expected" "$tmp/out_actual"
@@ -13,12 +13,13 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
start_server "$token"
do_curl "$token" -H "foo: bar" --http1.0 \
"http://foobar.com/dynamic/info" > "$tmp/out"
"http://foobar.com/dynamic/info" > "${tmp:?"tmp variable not set"}/out"
if ! grep -q '("foo", "bar")' "$tmp/out"; then
fail "couldn't find header in response"
fi
@@ -13,6 +13,7 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
@@ -21,16 +22,16 @@ htdocs=$(get_htdocs "$token")
server_pid=$(get_server_pid "$token")
echo FOO BAR > "$htdocs/some_file.txt"
for f in $(seq 20); do
for _ in $(seq 20); do
# send some signals that are usually discarded
kill -CHLD "$server_pid" # ignore-unacceptable-language
kill -URG "$server_pid" # ignore-unacceptable-language
kill -CONT "$server_pid" # ignore-unacceptable-language
kill -WINCH "$server_pid" # ignore-unacceptable-language
do_curl "$token" "http://foobar.com/fileio/some_file.txt" > "$tmp/out.txt" &
do_curl "$token" "http://foobar.com/fileio/some_file.txt" > "${tmp:?"tmp variable not set"}/out.txt" &
curl_pid=$!
for g in $(seq 20); do
for _ in $(seq 20); do
kill -URG "$server_pid" # ignore-unacceptable-language
done
wait $curl_pid
@@ -13,6 +13,7 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
@@ -31,6 +32,6 @@ do_curl "$token" \
"http://foobar.com/dynamic/trailers" \
"http://foobar.com/dynamic/trailers" \
"http://foobar.com/dynamic/trailers" \
> "$tmp/out.txt"
assert_equal_files "$htdocs/some_file.txt" "$tmp/out.txt"
> "${tmp:?"tmp variable not set"}/out.txt"
assert_equal_files "$htdocs/some_file.txt" "${tmp}/out.txt"
stop_server "$token"
@@ -13,22 +13,22 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
start_server "$token"
htdocs=$(get_htdocs "$token")
server_pid=$(get_server_pid "$token")
socket=$(get_socket "$token")
kill -0 $server_pid # ignore-unacceptable-language
kill -0 "$server_pid" # ignore-unacceptable-language
(
echo -e 'POST /dynamic/echo HTTP/1.1\r\nContent-Length: 400000\r\n\r\nsome_bytes'
for f in $(seq 5); do
echo $f
echo "$f"
sleep 0.1
done
) | do_nc -U "$socket"
sleep 0.1
kill -0 $server_pid # ignore-unacceptable-language
kill -0 "$server_pid" # ignore-unacceptable-language
stop_server "$token"
@@ -13,15 +13,19 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
start_server "$token"
# shellcheck disable=SC2034
htdocs=$(get_htdocs "$token")
# shellcheck disable=SC2034
server_pid=$(get_server_pid "$token")
# shellcheck disable=SC2034
socket=$(get_socket "$token")
cat > "$tmp/expected" <<EOF
cat > "${tmp:?"tmp variable not set"}/expected" <<EOF
line 1
line 2
line 3
@@ -13,12 +13,13 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
start_server "$token"
htdocs=$(get_htdocs "$token")
touch "$tmp/empty"
touch "${tmp:?"tmp variable not set"}/empty"
cr=$(echo -e '\r')
cat > "$tmp/headers_expected" <<EOF
HTTP/1.1 400 Bad Request$cr
@@ -49,7 +50,7 @@ if ! grep -q 'Connection: close' "$tmp/headers_actual"; then
fi
linecount=$(wc "$tmp/headers_actual")
if [ $linecount -ne 4 ]; then
if [ "$linecount" -ne 4 ]; then
fail "overlong response"
fi
stop_server "$token"
@@ -13,18 +13,20 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
start_server "$token"
# shellcheck disable=SC2034
htdocs=$(get_htdocs "$token")
server_pid=$(get_server_pid "$token")
socket=$(get_socket "$token")
kill -0 $server_pid # ignore-unacceptable-language
kill -0 "$server_pid" # ignore-unacceptable-language
echo -e 'GET /dynamic/count-to-ten HTTP/1.1\r\n\r\nGET /dynamic/count-to-ten HTTP/1.1\r\n\r\n' | \
do_nc -U "$socket" > "$tmp/actual"
do_nc -U "$socket" > "${tmp:?"tmp variable not set"}/actual"
backslash_r=$(echo -ne '\r')
cat > "$tmp/expected" <<EOF
HTTP/1.1 200 OK$backslash_r
@@ -78,5 +80,5 @@ $backslash_r
0$backslash_r
$backslash_r
EOF
assert_equal_files "$tmp/expected" "$tmp/actual"
assert_equal_files "${tmp}/expected" "${tmp}/actual"
stop_server "$token"
@@ -13,13 +13,15 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
start_server "$token"
# shellcheck disable=SC2034
htdocs=$(get_htdocs "$token")
socket=$(get_socket "$token")
echo -e 'GET / HTT\r\n\r\n' | do_nc -U "$socket" > "$tmp/actual"
echo -e 'GET / HTT\r\n\r\n' | do_nc -U "$socket" > "${tmp:?"tmp variable not set"}/actual"
if ! grep -q 'HTTP/1.1 400 Bad Request' "$tmp/actual"; then
fail "couldn't find status line in response"
@@ -13,11 +13,12 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
start_server "$token"
dd if=/dev/urandom of="$tmp/random.bytes" bs=$((64*1024)) count=1
dd if=/dev/urandom of="${tmp:?"tmp variable not set"}/random.bytes" bs=$((64*1024)) count=1
do_curl "$token" -X POST --header "Transfer-Encoding: chunked" \
--data-binary "@$tmp/random.bytes" \
"http://foobar.com/dynamic/echo" > "$tmp/random.bytes.out"
@@ -13,12 +13,14 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
start_server "$token" tcp
# shellcheck disable=SC2034
htdocs=$(get_htdocs "$token")
echo -n '[IPv4]127.0.0.1' > "$tmp/expected_ipv4"
echo -n '[IPv4]127.0.0.1' > "${tmp:?"tmp variable not set"}/expected_ipv4"
echo -n '[IPv6]::1' > "$tmp/expected_ipv6"
do_curl "$token" "http://localhost:$(get_server_port "$token")/dynamic/client-ip" > "$tmp/actual"
if grep -q '\[IPv4\]127.0.0.1' "$tmp/actual"; then
@@ -13,6 +13,7 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
@@ -21,10 +22,8 @@ htdocs=$(get_htdocs "$token")
# create a 3GB sparse file, this is above the 2,147,479,552 mentioned in the
# BUGS section of Linux's sendfile(2) man page.
dd if=/dev/zero of="$htdocs/lots_of_zeroes" seek=$((3 * 1024)) bs=$((1024 * 1024)) count=1
for method in fileio; do
do_curl "$token" "http://foobar.com/$method/lots_of_zeroes" | shasum > "$tmp/actual_sha"
echo "bf184d91c8f82092198e4d8e1d029e576dbec3bc -" > "$tmp/expected_sha"
assert_equal_files "$tmp/expected_sha" "$tmp/actual_sha"
done
do_curl "$token" "http://foobar.com/fileio/lots_of_zeroes" | shasum > "${tmp:?"tmp variable not set"}/actual_sha"
echo "bf184d91c8f82092198e4d8e1d029e576dbec3bc -" > "$tmp/expected_sha"
assert_equal_files "$tmp/expected_sha" "$tmp/actual_sha"
sleep 3 # wait for all the fds to be closed
stop_server "$token"
@@ -13,18 +13,20 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
start_server "$token"
# shellcheck disable=SC2034
htdocs=$(get_htdocs "$token")
server_pid=$(get_server_pid "$token")
socket=$(get_socket "$token")
kill -0 $server_pid # ignore-unacceptable-language
kill -0 "$server_pid" # ignore-unacceptable-language
echo -e 'GET /dynamic/count-to-ten HTTP/1.1\r\nConnection: close\r\n\r\n' | \
do_nc -U "$socket" > "$tmp/actual"
do_nc -U "$socket" > "${tmp:?"tmp variable not set"}/actual"
backslash_r=$(echo -ne '\r')
cat > "$tmp/expected" <<EOF
HTTP/1.1 200 OK$backslash_r
@@ -13,6 +13,7 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
@@ -13,16 +13,18 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
start_server --disable-half-closure "$token" tcp
# shellcheck disable=SC2034
htdocs=$(get_htdocs "$token")
server_pid=$(get_server_pid "$token")
ip=$(get_server_ip "$token")
port=$(get_server_port "$token")
kill -0 $server_pid # ignore-unacceptable-language
kill -0 "$server_pid" # ignore-unacceptable-language
echo -e 'GET /dynamic/write-delay/10000 HTTP/1.1\r\n\r\n' | do_nc -w1 "$ip" "$port"
sleep 0.2
stop_server "$token"
@@ -13,16 +13,18 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
start_server --disable-half-closure "$token" tcp
# shellcheck disable=SC2034
htdocs=$(get_htdocs "$token")
server_pid=$(get_server_pid "$token")
ip=$(get_server_ip "$token")
port=$(get_server_port "$token")
kill -0 $server_pid # ignore-unacceptable-language
kill -0 "$server_pid" # ignore-unacceptable-language
# try to simulate a TCP connection reset, works really well on Darwin but not on
# Linux over loopback. On Linux however
# `test_19_connection_drop_while_waiting_for_response_uds.sh` tests a very
@@ -13,12 +13,13 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
start_server "$token"
do_curl "$token" -H 'connection: keep-alive' -v --http1.0 \
"http://foobar.com/dynamic/info" > "$tmp/out_actual" 2>&1
"http://foobar.com/dynamic/info" > "${tmp:?"tmp variable not set"}/out_actual" 2>&1
grep -qi '< Connection: keep-alive' "$tmp/out_actual"
grep -qi '< HTTP/1.0 200 OK' "$tmp/out_actual"
stop_server "$token"
@@ -13,13 +13,14 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
token=$(create_token)
start_server "$token"
socket=$(get_socket "$token")
echo -ne 'HTTP/1.1 200 OK\r\ncontent-length: 13\r\n\r\nHello World\r\n' > "$tmp/expected"
for f in $(seq 2000); do
echo -ne 'HTTP/1.1 200 OK\r\ncontent-length: 13\r\n\r\nHello World\r\n' > "${tmp:?"tmp variable not set"}/expected"
for _ in $(seq 2000); do
echo -e 'GET / HTTP/1.1\r\n\r\n' | do_nc -w10 -U "$socket" > "$tmp/actual"
assert_equal_files "$tmp/expected" "$tmp/actual"
done
@@ -13,11 +13,12 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
swift build
echo -ne "::: HELLO\n::: WORLD\n:::\n" > "$tmp/file"
lines_in_file="$(cat "$tmp/file" | wc -l | tr -d '\t ')"
echo -ne "::: HELLO\n::: WORLD\n:::\n" > "${tmp:?"tmp variable not set"}/file"
lines_in_file="$(wc -l < "$tmp/file" | tr -d '\t ')"
function echo_request_close() {
echo -e 'GET /fileio/file HTTP/1.1\r\nconnection: close\r\nhost: stdio\r\n\r\n'
}
@@ -33,7 +34,7 @@ assert_equal_files "$tmp/file" "$tmp/output-just-file"
how_many=100
{
for f in $(seq "$(( how_many - 1 ))" ); do
for _ in $(seq "$(( how_many - 1 ))" ); do
echo_request_keep_alive
done
echo_request_close
@@ -16,7 +16,7 @@
set -eu
function make_package() {
if [[ ! -d "$tmpdir/syscallwrapper/Sources/syscallwrapper/" ]]; then
if [[ ! -d "${tmpdir:?"tmpdir variable not set"}/syscallwrapper/Sources/syscallwrapper/" ]]; then
mkdir "$tmpdir/syscallwrapper/Sources/syscallwrapper/"
mv "$tmpdir"/syscallwrapper/Sources/*.swift "$tmpdir/syscallwrapper/Sources/syscallwrapper/"
fi
@@ -50,7 +50,7 @@ let package = Package(
]
)
EOF
cp "$here/../../Tests/NIOPosixTests/SystemCallWrapperHelpers.swift" \
cp "${here:?"here variable not set"}/../../Tests/NIOPosixTests/SystemCallWrapperHelpers.swift" \
"$here/../../Sources/NIOCore/BSDSocketAPI.swift" \
"$here/../../Sources/NIOPosix/BSDSocketAPICommon.swift" \
"$here/../../Sources/NIOPosix/BSDSocketAPIPosix.swift" \
@@ -15,12 +15,14 @@
set -eu
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
swift_binary=swift
# shellcheck disable=SC2034 # Used in defines.sh
here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [[ ! -z "${SWIFT_EXEC-}" ]]; then
if [[ -n "${SWIFT_EXEC-}" ]]; then
swift_binary="$(dirname "$SWIFT_EXEC")/swift"
elif [[ "$(uname -s)" == "Linux" ]]; then
swift_binary=$(which swift)
@@ -15,12 +15,14 @@
set -eu
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
swift_binary=swift
# shellcheck disable=SC2034 # Used in defines.sh
here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [[ ! -z "${SWIFT_EXEC-}" ]]; then
if [[ -n "${SWIFT_EXEC-}" ]]; then
swift_binary="$(dirname "$SWIFT_EXEC")/swift"
elif [[ "$(uname -s)" == "Linux" ]]; then
swift_binary=$(which swift)
@@ -68,7 +70,7 @@ make_package
for mode in debug release; do
for error in EFAULT EBADF; do
temp_file="$tmp/stderr"
temp_file="${tmp:?"tmp variable not set"}/stderr"
if "$swift_binary" run -c "$mode" -Xswiftc -DRUNNING_INTEGRATION_TESTS \
syscallwrapper "$error" 2> "$temp_file"; then
@@ -15,12 +15,14 @@
set -eu
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
swift_binary=swift
# shellcheck disable=SC2034 # Used in defines.sh
here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [[ ! -z "${SWIFT_EXEC-}" ]]; then
if [[ -n "${SWIFT_EXEC-}" ]]; then
swift_binary="$(dirname "$SWIFT_EXEC")/swift"
elif [[ "$(uname -s)" == "Linux" ]]; then
swift_binary=$(which swift)
@@ -86,7 +88,7 @@ make_package
for mode in debug release; do
for error in EFAULT EBADF EINVAL; do
temp_file="$tmp/stderr"
temp_file="${tmp:?"tmp variable not set"}/stderr"
if "$swift_binary" run -c "$mode" -Xswiftc -DRUNNING_INTEGRATION_TESTS \
syscallwrapper "$error" 2> "$temp_file"; then
@@ -14,7 +14,8 @@
##===----------------------------------------------------------------------===##
here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
pushd "$here/../.."
pushd "$here/../.." || exit
swift build
# shellcheck disable=SC2034 # Used by imports
bin_path=$(swift build --show-bin-path)
popd
popd || exit
@@ -13,6 +13,7 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
function check_does_not_link() {
@@ -21,7 +22,7 @@ function check_does_not_link() {
case "$(uname -s)" in
Darwin)
otool -L "$binary" > "$tmp/linked_libs"
otool -L "$binary" > "${tmp:?"tmp variable not set"}/linked_libs"
;;
Linux)
ldd "$binary" > "$tmp/linked_libs"
@@ -37,7 +38,7 @@ function check_does_not_link() {
}
for binary in NIOEchoServer NIOEchoClient NIOChatServer NIOChatClient NIOHTTP1Server; do
check_does_not_link /Foundation "$bin_path/$binary" # Darwin (old)
check_does_not_link /Foundation "${bin_path:?"tmp variable not set"}/$binary" # Darwin (old)
check_does_not_link libFoundation "$bin_path/$binary" # Linux
check_does_not_link swiftFoundation "$bin_path/$binary" # Darwin (new)
done
@@ -13,6 +13,7 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
"$bin_path/NIOCrashTester" run-all
"${bin_path:?"bin_path variable not set"}/NIOCrashTester" run-all
@@ -13,6 +13,7 @@
##
##===----------------------------------------------------------------------===##
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
set -eu
@@ -39,7 +40,7 @@ for test in "${all_tests[@]}"; do
not_freed_allocations=$(grep "^test_$test_case.remaining_allocations:" "$tmp/output" | cut -d: -f2 | sed 's/ //g')
leaked_fds=$(grep "^test_$test_case.leaked_fds:" "$tmp/output" | cut -d: -f2 | sed 's/ //g')
max_allowed_env_name="MAX_ALLOCS_ALLOWED_$test_case"
max_allowed=$(jq '.'\"$test_case\" "$here/Thresholds/$SWIFT_VERSION.json")
max_allowed=$(jq '.'\""$test_case"\" "$here/Thresholds/$SWIFT_VERSION.json")
info "$test_case: allocations not freed: $not_freed_allocations"
info "$test_case: total number of mallocs: $total_allocations"
@@ -62,5 +63,5 @@ for test in "${all_tests[@]}"; do
assert_less_than_or_equal "$total_allocations" "$max_allowed"
assert_greater_than "$total_allocations" "$(( max_allowed - 1000))"
fi
done < <(grep "^test_$test[^\W]*.total_allocations:" "$tmp/output" | cut -d: -f1 | cut -d. -f1 | sort | uniq)
done < <(grep "^test_${test[^\W]}*.total_allocations:" "$tmp/output" | cut -d: -f1 | cut -d. -f1 | sort | uniq)
done
@@ -16,7 +16,7 @@
set -eu
function make_package() {
cat > "$tmpdir/syscallwrapper/Package.swift" <<"EOF"
cat > "${tmpdir:?"tmpdir variable not set"}/syscallwrapper/Package.swift" <<"EOF"
// swift-tools-version:5.7
// The swift-tools-version declares the minimum version of Swift required to build this package.
@@ -45,7 +45,7 @@ let package = Package(
]
)
EOF
cp "$here/../../Tests/NIOTests/SystemCallWrapperHelpers.swift" \
cp "${here:?"here variable not set"}/../../Tests/NIOTests/SystemCallWrapperHelpers.swift" \
"$here/../../Sources/NIOPosix/System.swift" \
"$here/../../Sources/NIOPosix/IO.swift" \
"$tmpdir/syscallwrapper/Sources/syscallwrapper"
@@ -15,18 +15,19 @@
set -eu
# shellcheck source=IntegrationTests/tests_01_http/defines.sh
source defines.sh
swift_binary=swiftc
here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [[ ! -z "${SWIFT_EXEC-}" ]]; then
if [[ -n "${SWIFT_EXEC-}" ]]; then
swift_binary="$(dirname "$SWIFT_EXEC")/swiftc"
elif [[ "$(uname -s)" == "Linux" ]]; then
swift_binary=$(which swiftc)
fi
cp "$here/../../Sources/NIOConcurrencyHelpers/"{lock,NIOLock}.swift "$tmp"
cp "$here/../../Sources/NIOConcurrencyHelpers/"{lock,NIOLock}.swift "${tmp:?"tmp variable not set"}"
cat > "$tmp/main.swift" <<"EOF"
let l = NIOLock()
l.lock()
@@ -19,10 +19,10 @@ here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
case "$(uname -s)" in
Darwin)
sed=gsed
sed="gsed"
;;
*)
sed=sed
sed="sed"
;;
esac
@@ -104,9 +104,9 @@ compiletmp=$(mktemp -d /tmp/.test_compile_XXXXXX)
for f in *.c; do
clang -o "$compiletmp/$f.o" -c "$here/$f"
num_non_nio=$(nm "$compiletmp/$f.o" | grep ' T ' | grep -v c_nio | wc -l)
num_non_nio=$(nm "$compiletmp/$f.o" | grep ' T ' | grep -cv c_nio)
test 0 -eq $num_non_nio || {
test 0 -eq "$num_non_nio" || {
echo "ERROR: $num_non_nio exported non-prefixed symbols found"
nm "$compiletmp/$f.o" | grep ' T ' | grep -v c_nio
exit 1
+4 -4
View File
@@ -19,10 +19,10 @@ here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
case "$(uname -s)" in
Darwin)
sed=gsed
sed="gsed"
;;
*)
sed=sed
sed="sed"
;;
esac
@@ -63,9 +63,9 @@ mv "$here/c_nio_sha1.h" "$here/include/CNIOSHA1.h"
tmp=$(mktemp -d /tmp/.test_compile_XXXXXX)
clang -o "$tmp/test.o" -c "$here/c_nio_sha1.c"
num_non_nio=$(nm "$tmp/test.o" | grep ' T ' | grep -v c_nio | wc -l)
num_non_nio=$(nm "$tmp/test.o" | grep ' T ' | grep -vc c_nio)
test 0 -eq $num_non_nio || {
test 0 -eq "$num_non_nio" || {
echo "ERROR: $num_non_nio exported non-prefixed symbols found"
exit 1
}
+1 -1
View File
@@ -37,5 +37,5 @@ for f in 58 59 510 nightly-6.0 main; do
docker_file=$(ls "$target_repo/docker/docker-compose."*"$f"*".yaml")
docker-compose -f docker/docker-compose.yaml -f $docker_file run update-benchmark-baseline
docker-compose -f docker/docker-compose.yaml -f "$docker_file" run update-benchmark-baseline
done
+1 -1
View File
@@ -20,7 +20,7 @@ error() { printf -- "** ERROR: %s\n" "$*" >&2; }
fatal() { error "$@"; exit 1; }
raw_targets=$(sed -E -n -e 's/^.* - documentation_targets: \[(.*)\].*$/\1/p' .spi.yml)
targets=(${raw_targets//,/ })
targets=("${raw_targets//,/ }")
for target in "${targets[@]}"; do
swift package plugin generate-documentation --target "$target" --warnings-as-errors --analyze --level detailed
+2 -1
View File
@@ -36,12 +36,13 @@ expected_file_header_template="@@===--------------------------------------------
paths_with_missing_license=( )
file_paths=$(git ls-files $(cat .licenseignore | xargs -I% printf ":(exclude)% "))
file_paths=$(tr '\n' '\0' < .licenseignore | xargs -0 -I% printf '":(exclude)%" '| xargs git ls-files)
while IFS= read -r file_path; do
file_basename=$(basename -- "${file_path}")
file_extension="${file_basename##*.}"
# shellcheck disable=SC2001 # We prefer to use sed here instead of bash search/replace
case "${file_extension}" in
swift) expected_file_header=$(sed -e 's|@@|//|g' <<<"${expected_file_header_template}") ;;
h) expected_file_header=$(sed -e 's|@@|//|g' <<<"${expected_file_header_template}") ;;
+5 -5
View File
@@ -28,19 +28,19 @@ command_5_10="$COMMAND_OVERRIDE_5_10"
command_nightly_6_0="$COMMAND_OVERRIDE_NIGHTLY_6_0"
command_nightly_main="$COMMAND_OVERRIDE_NIGHTLY_MAIN"
if [ "$swift_version" == "5.8" ] && [ -n "$command_5_8" ]; then
if [[ "$swift_version" == "5.8" ]] && [[ -n "$command_5_8" ]]; then
log "Running 5.8 command override"
eval "$command_5_8"
elif [ "$swift_version" == "5.9" ] && [ -n "$command_5_9" ]; then
elif [[ "$swift_version" == "5.9" ]] && [[ -n "$command_5_9" ]]; then
log "Running 5.9 command override"
eval "$command_5_9"
elif [ "$swift_version" == "5.10" ] && [ -n "$command_5_10" ]; then
elif [[ "$swift_version" == "5.10" ]] && [[ -n "$command_5_10" ]]; then
log "Running 5.10 command override"
eval "$command_5_10"
elif [ "$swift_version" == "nightly-6.0" ] && [ -n "$command_nightly_6_0" ]; then
elif [[ "$swift_version" == "nightly-6.0" ]] && [[ -n "$command_nightly_6_0" ]]; then
log "Running nightly 6.0 command override"
eval "$command_nightly_6_0"
elif [ "$swift_version" == "nightly-main" ] && [ -n "$command_nightly_main" ]; then
elif [[ "$swift_version" == "nightly-main" ]] && [[ -n "$command_nightly_main" ]]; then
log "Running nightly main command override"
eval "$command_nightly_main"
else
+16 -9
View File
@@ -18,22 +18,29 @@ log() { printf -- "** %s\n" "$*" >&2; }
error() { printf -- "** ERROR: %s\n" "$*" >&2; }
fatal() { error "$@"; exit 1; }
excluded_files=""
if [ -f .swiftformatignore ]; then
if [[ -f .swiftformatignore ]]; then
log "Found swiftformatignore file..."
excluded_files=$(cat .swiftformatignore | xargs -I% printf ":(exclude)% ")
log "Running swift format format..."
tr '\n' '\0' < .swiftformatignore| xargs -0 -I% printf '":(exclude)%" '| xargs git ls-files -z '*.swift' | xargs -0 swift format format --parallel --in-place
log "Running swift format lint..."
tr '\n' '\0' < .swiftformatignore | xargs -0 -I% printf '":(exclude)%" '| xargs git ls-files -z '*.swift' | xargs -0 swift format lint --strict --parallel
else
log "Running swift format format..."
git ls-files -z '*.swift' | xargs -0 swift format format --parallel --in-place
log "Running swift format lint..."
git ls-files -z '*.swift' | xargs -0 swift format lint --strict --parallel
fi
log "Running swift format format..."
git ls-files -z '*.swift' $excluded_files | xargs -0 swift format format --parallel --in-place
log "Running swift format lint..."
git ls-files -z '*.swift' $excluded_files | xargs -0 swift format lint --strict --parallel
log "Checking for modified files..."
GIT_PAGER= git diff --exit-code '*.swift'
GIT_PAGER='' git diff --exit-code '*.swift'
log "✅ Found no formatting issues."
+1 -1
View File
@@ -51,4 +51,4 @@ for old_tag in "$@"; do
swift package diagnose-api-breaking-changes "$old_tag"
done
echo done
echo "done"
+3 -3
View File
@@ -17,9 +17,9 @@ set -eu
sourcedir=$(pwd)
workingdir=$(mktemp -d)
projectname=$(basename $workingdir)
projectname=$(basename "$workingdir")
cd $workingdir
cd "$workingdir"
swift package init
cat << EOF > Package.swift
@@ -62,7 +62,7 @@ let package = Package(
)
EOF
cat << EOF > Sources/$projectname/$(echo $projectname | tr . _).swift
cat << EOF > Sources/"$projectname"/"$(echo "$projectname" | tr . _)".swift
import NIO
import NIOCore
import NIOConcurrencyHelpers
-51
View File
@@ -1,51 +0,0 @@
#!/bin/bash
##===----------------------------------------------------------------------===##
##
## This source file is part of the SwiftNIO open source project
##
## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors
## Licensed under Apache License v2.0
##
## See LICENSE.txt for license information
## See CONTRIBUTORS.txt for the list of SwiftNIO project authors
##
## SPDX-License-Identifier: Apache-2.0
##
##===----------------------------------------------------------------------===##
set -eu
here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
contributor_list=$( cd "$here"/.. && git shortlog -es | cut -f2 )
filtered_hashes=$( cat "$here/../.mailfilter" | grep -E '^[a-z0-9]+$' | sort )
NL=$'\n'
contributors=''
while IFS= read -r line; do
hashed="$(echo -n "$line" | shasum | head -c 40)"
found_hash=$(comm -12 <(echo "$hashed") <(echo "$filtered_hashes"))
if [ ! -z "$found_hash" ]; then
continue
fi
contributors="${contributors}- $line$NL"
done <<< "$contributor_list"
cat > "$here/../CONTRIBUTORS.txt" <<- EOF
For the purpose of tracking copyright, this is the list of individuals and
organizations who have contributed source code to SwiftNIO.
For employees of an organization/company where the copyright of work done
by employees of that company is held by the company itself, only the company
needs to be listed here.
## COPYRIGHT HOLDERS
- Apple Inc. (all contributors with '@apple.com')
### Contributors
$contributors
**Updating this list**
Please do not edit this file manually. It is generated using \`./scripts/generate_contributors_list.sh\`. If a name is misspelled or appearing multiple times: add an entry in \`./.mailmap\`
EOF
+1 -1
View File
@@ -16,4 +16,4 @@
set +ex
mkdir -p .build # for the junit.xml file
./IntegrationTests/run-tests.sh --junit-xml .build/junit-sh-tests.xml -i $@
./IntegrationTests/run-tests.sh --junit-xml .build/junit-sh-tests.xml -i "$@"
-161
View File
@@ -1,161 +0,0 @@
#!/bin/bash
##===----------------------------------------------------------------------===##
##
## This source file is part of the SwiftNIO open source project
##
## Copyright (c) 2017-2022 Apple Inc. and the SwiftNIO project authors
## Licensed under Apache License v2.0
##
## See LICENSE.txt for license information
## See CONTRIBUTORS.txt for the list of SwiftNIO project authors
##
## SPDX-License-Identifier: Apache-2.0
##
##===----------------------------------------------------------------------===##
set -eu
here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
function replace_acceptable_years() {
# this needs to replace all acceptable forms with 'YEARS'
sed -e 's/20[12][7890123]-20[12][8901234]/YEARS/' -e 's/20[12][8901234]/YEARS/'
}
printf "=> Checking for unacceptable language... "
# This greps for unacceptable terminology. The square bracket[s] are so that
# "git grep" doesn't find the lines that greps :).
unacceptable_terms=(
-e blacklis[t]
-e whitelis[t]
-e slav[e]
-e sanit[y]
)
# We have to exclude the code of conduct as it gives examples of unacceptable
# language.
if git grep --color=never -i "${unacceptable_terms[@]}" -- . ":(exclude).github/workflows/pull_request_soundness.yml" > /dev/null; then
printf "\033[0;31mUnacceptable language found.\033[0m\n"
git grep -i "${unacceptable_terms[@]}" -- . ":(exclude).github/workflows/pull_request_soundness.yml"
exit 1
fi
printf "\033[0;32mokay.\033[0m\n"
printf "=> Checking license headers\n"
tmp=$(mktemp /tmp/.swift-nio-soundness_XXXXXX)
for language in swift-or-c bash dtrace python; do
printf " * $language... "
declare -a matching_files
declare -a exceptions
expections=( )
matching_files=( -name '*' )
case "$language" in
swift-or-c)
exceptions=( -name c_nio_llhttp.c -o -name c_nio_api.c -o -name c_nio_http.c -o -name c_nio_llhttp.h -o -name cpp_magic.h -o -name Package.swift -o -name 'Package@*.swift' -o -path './Snippets/*' -o -name CNIOSHA1.h -o -name c_nio_sha1.c -o -name ifaddrs-android.c -o -name ifaddrs-android.h)
matching_files=( -name '*.swift' -o -name '*.c' -o -name '*.h' )
cat > "$tmp" <<"EOF"
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) YEARS Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
EOF
;;
bash)
matching_files=( -name '*.sh' )
cat > "$tmp" <<"EOF"
#!/bin/bash
##===----------------------------------------------------------------------===##
##
## This source file is part of the SwiftNIO open source project
##
## Copyright (c) YEARS Apple Inc. and the SwiftNIO project authors
## Licensed under Apache License v2.0
##
## See LICENSE.txt for license information
## See CONTRIBUTORS.txt for the list of SwiftNIO project authors
##
## SPDX-License-Identifier: Apache-2.0
##
##===----------------------------------------------------------------------===##
EOF
;;
python)
matching_files=( -name '*.py' )
cat > "$tmp" <<"EOF"
#!/usr/bin/env python3
##===----------------------------------------------------------------------===##
##
## This source file is part of the SwiftNIO open source project
##
## Copyright (c) YEARS Apple Inc. and the SwiftNIO project authors
## Licensed under Apache License v2.0
##
## See LICENSE.txt for license information
## See CONTRIBUTORS.txt for the list of SwiftNIO project authors
##
## SPDX-License-Identifier: Apache-2.0
##
##===----------------------------------------------------------------------===##
EOF
;;
dtrace)
matching_files=( -name '*.d' )
cat > "$tmp" <<"EOF"
#!/usr/sbin/dtrace -q -s
/*===----------------------------------------------------------------------===*
*
* This source file is part of the SwiftNIO open source project
*
* Copyright (c) YEARS Apple Inc. and the SwiftNIO project authors
* Licensed under Apache License v2.0
*
* See LICENSE.txt for license information
* See CONTRIBUTORS.txt for the list of SwiftNIO project authors
*
* SPDX-License-Identifier: Apache-2.0
*
*===----------------------------------------------------------------------===*/
EOF
;;
*)
echo >&2 "ERROR: unknown language '$language'"
;;
esac
expected_lines=$(cat "$tmp" | wc -l)
expected_sha=$(cat "$tmp" | shasum)
(
cd "$here/.."
{
find . \
\( \! -path './.build/*' -a \
\( "${matching_files[@]}" \) -a \
\( \! \( "${exceptions[@]}" \) \) \)
if [[ "$language" = bash ]]; then
# add everything with a shell shebang too
git grep --full-name -l '#!/bin/bash'
git grep --full-name -l '#!/bin/sh'
fi
} | while read line; do
if [[ "$(cat "$line" | replace_acceptable_years | head -n $expected_lines | shasum)" != "$expected_sha" ]]; then
printf "\033[0;31mmissing headers in file '$line'!\033[0m\n"
diff -u <(cat "$line" | replace_acceptable_years | head -n $expected_lines) "$tmp"
exit 1
fi
done
printf "\033[0;32mokay.\033[0m\n"
)
done
rm "$tmp"