Files

175 lines
3.6 KiB
Bash
Executable File

#!/usr/bin/env bash
set -Eeuo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "${repo_root}"
required_tools=(
bash
find
git
grep
kubectl
make
sed
)
optional_tools=(
age
argocd
conftest
flux
gitleaks
helm
kubeconform
shellcheck
sops
terraform
tofu
trivy
yamllint
)
activated_tools=()
missing=0
collect_source_files() {
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
git ls-files --cached --others --exclude-standard -z
else
find . \
\( \
-type d \
\( \
-name .build -o \
-name .cache -o \
-name .git -o \
-name .terraform -o \
-name .terragrunt-cache -o \
-name dist -o \
-name rendered -o \
-name tmp \
\) -prune \
\) -o \
-type f -print0
fi
}
source_files=()
while IFS= read -r -d '' file; do
file="${file#./}"
if [[ -f "${file}" ]]; then
source_files+=("${file}")
fi
done < <(collect_source_files)
has_chart=0
iac_file=""
for file in "${source_files[@]}"; do
if [[ "${file##*/}" == "Chart.yaml" ]]; then
has_chart=1
fi
case "${file}" in
bootstrap/*.tf | bootstrap/*.tf.json | bootstrap/*.tofu | bootstrap/*.tofu.json | \
infrastructure/*.tf | infrastructure/*.tf.json | infrastructure/*.tofu | \
infrastructure/*.tofu.json)
iac_file="${file}"
;;
esac
done
if ((has_chart == 1)); then
activated_tools+=("helm")
fi
if [[ -n "${iac_file}" ]]; then
iac_engine=""
if [[ -f infrastructure/.iac-engine && ! -L infrastructure/.iac-engine ]]; then
iac_engine_values=()
while IFS= read -r line; do
case "${line}" in
"" | \#*)
continue
;;
esac
iac_engine_values+=("${line}")
done < infrastructure/.iac-engine
if ((${#iac_engine_values[@]} == 1)); then
iac_engine="${iac_engine_values[0]}"
fi
fi
case "${iac_engine}" in
terraform | tofu)
activated_tools+=("${iac_engine}")
;;
*)
printf '[missing] infrastructure/.iac-engine must select terraform or tofu because IaC files exist.\n' >&2
missing=1
;;
esac
fi
is_activated() {
local candidate="$1"
local tool
for tool in "${activated_tools[@]}"; do
if [[ "${candidate}" == "${tool}" ]]; then
return 0
fi
done
return 1
}
printf 'Required tools\n'
for tool in "${required_tools[@]}"; do
if command -v "${tool}" >/dev/null 2>&1; then
printf ' [ok] %-14s %s\n' "${tool}" "$(command -v "${tool}")"
else
printf ' [missing] %s\n' "${tool}"
missing=1
fi
done
if ((${#activated_tools[@]} > 0)); then
printf '\nTools required by activated source files\n'
for tool in "${activated_tools[@]}"; do
if command -v "${tool}" >/dev/null 2>&1; then
printf ' [ok] %-14s %s\n' "${tool}" "$(command -v "${tool}")"
else
printf ' [missing] %s\n' "${tool}"
missing=1
fi
done
fi
printf '\nOptional tools (required only after the related feature is enabled)\n'
for tool in "${optional_tools[@]}"; do
if is_activated "${tool}"; then
continue
fi
if command -v "${tool}" >/dev/null 2>&1; then
printf ' [found] %-14s %s\n' "${tool}" "$(command -v "${tool}")"
else
printf ' [not set] %s\n' "${tool}"
fi
done
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
printf '\nRepository: Git work tree detected.\n'
else
printf '\nRepository: Git is not initialized yet; run git init when this skeleton becomes a repository.\n'
fi
if ((missing != 0)); then
printf '\nInstall/configure the missing required items before validation.\n' >&2
exit 1
fi
printf '\nDoctor check passed.\n'