1*a67afe4dSAndroid Build Coastguard Worker#!/usr/bin/env bash 2*a67afe4dSAndroid Build Coastguard Workerset -o errexit -o pipefail -o posix 3*a67afe4dSAndroid Build Coastguard Worker 4*a67afe4dSAndroid Build Coastguard Worker# Copyright (c) 2019-2024 Cosmin Truta. 5*a67afe4dSAndroid Build Coastguard Worker# 6*a67afe4dSAndroid Build Coastguard Worker# Use, modification and distribution are subject to the MIT License. 7*a67afe4dSAndroid Build Coastguard Worker# Please see the accompanying file LICENSE_MIT.txt 8*a67afe4dSAndroid Build Coastguard Worker# 9*a67afe4dSAndroid Build Coastguard Worker# SPDX-License-Identifier: MIT 10*a67afe4dSAndroid Build Coastguard Worker 11*a67afe4dSAndroid Build Coastguard Worker# shellcheck source=ci/lib/ci.lib.sh 12*a67afe4dSAndroid Build Coastguard Workersource "$(dirname "$0")/lib/ci.lib.sh" 13*a67afe4dSAndroid Build Coastguard Workercd "$CI_TOPLEVEL_DIR" 14*a67afe4dSAndroid Build Coastguard Worker 15*a67afe4dSAndroid Build Coastguard Worker# Initialize the global constants CI_{...}{CHECK,CHECKER,LINT}. 16*a67afe4dSAndroid Build Coastguard WorkerCI_SHELLCHECK="${CI_SHELLCHECK:-shellcheck}" 17*a67afe4dSAndroid Build Coastguard WorkerCI_EDITORCONFIG_CHECKER="${CI_EDITORCONFIG_CHECKER:-editorconfig-checker}" 18*a67afe4dSAndroid Build Coastguard WorkerCI_YAMLLINT="${CI_YAMLLINT:-yamllint}" 19*a67afe4dSAndroid Build Coastguard Worker 20*a67afe4dSAndroid Build Coastguard Worker# Initialize the global lint status. 21*a67afe4dSAndroid Build Coastguard WorkerCI_LINT_STATUS=0 22*a67afe4dSAndroid Build Coastguard Worker 23*a67afe4dSAndroid Build Coastguard Workerfunction ci_init_lint { 24*a67afe4dSAndroid Build Coastguard Worker ci_info "## START OF LINTING ##" 25*a67afe4dSAndroid Build Coastguard Worker local my_program 26*a67afe4dSAndroid Build Coastguard Worker # Complete the initialization of CI_SHELLCHECK. 27*a67afe4dSAndroid Build Coastguard Worker # Set it to the empty string if the shellcheck program is unavailable. 28*a67afe4dSAndroid Build Coastguard Worker my_program="$(command -v "$CI_SHELLCHECK")" || { 29*a67afe4dSAndroid Build Coastguard Worker ci_warn "program not found: '$CI_SHELLCHECK'" 30*a67afe4dSAndroid Build Coastguard Worker } 31*a67afe4dSAndroid Build Coastguard Worker CI_SHELLCHECK="$my_program" 32*a67afe4dSAndroid Build Coastguard Worker # Complete the initialization of CI_EDITORCONFIG_CHECKER. 33*a67afe4dSAndroid Build Coastguard Worker # Set it to the empty string if the editorconfig-checker program is unavailable. 34*a67afe4dSAndroid Build Coastguard Worker my_program="$(command -v "$CI_EDITORCONFIG_CHECKER")" || { 35*a67afe4dSAndroid Build Coastguard Worker ci_warn "program not found: '$CI_EDITORCONFIG_CHECKER'" 36*a67afe4dSAndroid Build Coastguard Worker } 37*a67afe4dSAndroid Build Coastguard Worker CI_EDITORCONFIG_CHECKER="$my_program" 38*a67afe4dSAndroid Build Coastguard Worker # Complete the initialization of CI_YAMLLINT. 39*a67afe4dSAndroid Build Coastguard Worker # Set it to the empty string if the yamllint program is unavailable. 40*a67afe4dSAndroid Build Coastguard Worker my_program="$(command -v "$CI_YAMLLINT")" || { 41*a67afe4dSAndroid Build Coastguard Worker ci_warn "program not found: '$CI_YAMLLINT'" 42*a67afe4dSAndroid Build Coastguard Worker } 43*a67afe4dSAndroid Build Coastguard Worker CI_YAMLLINT="$my_program" 44*a67afe4dSAndroid Build Coastguard Worker} 45*a67afe4dSAndroid Build Coastguard Worker 46*a67afe4dSAndroid Build Coastguard Workerfunction ci_finish_lint { 47*a67afe4dSAndroid Build Coastguard Worker ci_info "## END OF LINTING ##" 48*a67afe4dSAndroid Build Coastguard Worker if [[ $CI_LINT_STATUS -eq 0 ]] 49*a67afe4dSAndroid Build Coastguard Worker then 50*a67afe4dSAndroid Build Coastguard Worker ci_info "## SUCCESS ##" 51*a67afe4dSAndroid Build Coastguard Worker else 52*a67afe4dSAndroid Build Coastguard Worker ci_info "linting failed" 53*a67afe4dSAndroid Build Coastguard Worker fi 54*a67afe4dSAndroid Build Coastguard Worker return "$CI_LINT_STATUS" 55*a67afe4dSAndroid Build Coastguard Worker} 56*a67afe4dSAndroid Build Coastguard Worker 57*a67afe4dSAndroid Build Coastguard Workerfunction ci_lint_ci_scripts { 58*a67afe4dSAndroid Build Coastguard Worker [[ -x $CI_SHELLCHECK ]] || { 59*a67afe4dSAndroid Build Coastguard Worker ci_warn "## NOT LINTING: CI scripts ##" 60*a67afe4dSAndroid Build Coastguard Worker return 0 61*a67afe4dSAndroid Build Coastguard Worker } 62*a67afe4dSAndroid Build Coastguard Worker ci_info "## LINTING: CI scripts ##" 63*a67afe4dSAndroid Build Coastguard Worker ci_spawn "$CI_SHELLCHECK" --version 64*a67afe4dSAndroid Build Coastguard Worker find ./ci -maxdepth 1 -name "*.sh" | { 65*a67afe4dSAndroid Build Coastguard Worker local my_file 66*a67afe4dSAndroid Build Coastguard Worker while IFS="" read -r my_file 67*a67afe4dSAndroid Build Coastguard Worker do 68*a67afe4dSAndroid Build Coastguard Worker ci_spawn "$CI_SHELLCHECK" -x "$my_file" || { 69*a67afe4dSAndroid Build Coastguard Worker # Linting failed. 70*a67afe4dSAndroid Build Coastguard Worker return 1 71*a67afe4dSAndroid Build Coastguard Worker } 72*a67afe4dSAndroid Build Coastguard Worker done 73*a67afe4dSAndroid Build Coastguard Worker } 74*a67afe4dSAndroid Build Coastguard Worker} 75*a67afe4dSAndroid Build Coastguard Worker 76*a67afe4dSAndroid Build Coastguard Workerfunction ci_lint_text_files { 77*a67afe4dSAndroid Build Coastguard Worker [[ -x $CI_EDITORCONFIG_CHECKER ]] || { 78*a67afe4dSAndroid Build Coastguard Worker ci_warn "## NOT LINTING: text files ##" 79*a67afe4dSAndroid Build Coastguard Worker return 0 80*a67afe4dSAndroid Build Coastguard Worker } 81*a67afe4dSAndroid Build Coastguard Worker ci_info "## LINTING: text files ##" 82*a67afe4dSAndroid Build Coastguard Worker ci_spawn "$CI_EDITORCONFIG_CHECKER" --version 83*a67afe4dSAndroid Build Coastguard Worker ci_spawn "$CI_EDITORCONFIG_CHECKER" || { 84*a67afe4dSAndroid Build Coastguard Worker # Linting failed. 85*a67afe4dSAndroid Build Coastguard Worker return 1 86*a67afe4dSAndroid Build Coastguard Worker } 87*a67afe4dSAndroid Build Coastguard Worker} 88*a67afe4dSAndroid Build Coastguard Worker 89*a67afe4dSAndroid Build Coastguard Workerfunction ci_lint_yaml_files { 90*a67afe4dSAndroid Build Coastguard Worker [[ -x $CI_YAMLLINT ]] || { 91*a67afe4dSAndroid Build Coastguard Worker ci_warn "## NOT LINTING: YAML files ##" 92*a67afe4dSAndroid Build Coastguard Worker return 0 93*a67afe4dSAndroid Build Coastguard Worker } 94*a67afe4dSAndroid Build Coastguard Worker ci_info "## LINTING: YAML files ##" 95*a67afe4dSAndroid Build Coastguard Worker ci_spawn "$CI_YAMLLINT" --version 96*a67afe4dSAndroid Build Coastguard Worker find . \( -iname "*.yml" -o -iname "*.yaml" \) -not -path "./out/*" | { 97*a67afe4dSAndroid Build Coastguard Worker local my_file 98*a67afe4dSAndroid Build Coastguard Worker while IFS="" read -r my_file 99*a67afe4dSAndroid Build Coastguard Worker do 100*a67afe4dSAndroid Build Coastguard Worker ci_spawn "$CI_YAMLLINT" --strict "$my_file" || { 101*a67afe4dSAndroid Build Coastguard Worker # Linting failed. 102*a67afe4dSAndroid Build Coastguard Worker return 1 103*a67afe4dSAndroid Build Coastguard Worker } 104*a67afe4dSAndroid Build Coastguard Worker done 105*a67afe4dSAndroid Build Coastguard Worker } 106*a67afe4dSAndroid Build Coastguard Worker} 107*a67afe4dSAndroid Build Coastguard Worker 108*a67afe4dSAndroid Build Coastguard Workerfunction ci_lint { 109*a67afe4dSAndroid Build Coastguard Worker ci_init_lint 110*a67afe4dSAndroid Build Coastguard Worker ci_lint_ci_scripts || CI_LINT_STATUS=1 111*a67afe4dSAndroid Build Coastguard Worker ci_lint_text_files || CI_LINT_STATUS=1 112*a67afe4dSAndroid Build Coastguard Worker ci_lint_yaml_files || CI_LINT_STATUS=1 113*a67afe4dSAndroid Build Coastguard Worker # TODO: ci_lint_png_files, etc. 114*a67afe4dSAndroid Build Coastguard Worker ci_finish_lint 115*a67afe4dSAndroid Build Coastguard Worker} 116*a67afe4dSAndroid Build Coastguard Worker 117*a67afe4dSAndroid Build Coastguard Workerfunction usage { 118*a67afe4dSAndroid Build Coastguard Worker echo "usage: $CI_SCRIPT_NAME [<options>]" 119*a67afe4dSAndroid Build Coastguard Worker echo "options: -?|-h|--help" 120*a67afe4dSAndroid Build Coastguard Worker exit "${@:-0}" 121*a67afe4dSAndroid Build Coastguard Worker} 122*a67afe4dSAndroid Build Coastguard Worker 123*a67afe4dSAndroid Build Coastguard Workerfunction main { 124*a67afe4dSAndroid Build Coastguard Worker local opt 125*a67afe4dSAndroid Build Coastguard Worker while getopts ":" opt 126*a67afe4dSAndroid Build Coastguard Worker do 127*a67afe4dSAndroid Build Coastguard Worker # This ain't a while-loop. It only pretends to be. 128*a67afe4dSAndroid Build Coastguard Worker [[ $1 == -[?h]* || $1 == --help || $1 == --help=* ]] && usage 0 129*a67afe4dSAndroid Build Coastguard Worker ci_err "unknown option: '$1'" 130*a67afe4dSAndroid Build Coastguard Worker done 131*a67afe4dSAndroid Build Coastguard Worker shift $((OPTIND - 1)) 132*a67afe4dSAndroid Build Coastguard Worker [[ $# -eq 0 ]] || { 133*a67afe4dSAndroid Build Coastguard Worker echo >&2 "error: unexpected argument: '$1'" 134*a67afe4dSAndroid Build Coastguard Worker usage 2 135*a67afe4dSAndroid Build Coastguard Worker } 136*a67afe4dSAndroid Build Coastguard Worker # And... go! 137*a67afe4dSAndroid Build Coastguard Worker ci_lint 138*a67afe4dSAndroid Build Coastguard Worker} 139*a67afe4dSAndroid Build Coastguard Worker 140*a67afe4dSAndroid Build Coastguard Workermain "$@" 141