github.com/MetalBlockchain/metalgo@v1.11.9/scripts/lint.sh (about)

     1  #!/usr/bin/env bash
     2  
     3  set -euo pipefail
     4  
     5  if ! [[ "$0" =~ scripts/lint.sh ]]; then
     6    echo "must be run from repository root"
     7    exit 255
     8  fi
     9  
    10  # The -P option is not supported by the grep version installed by
    11  # default on macos. Since `-o errexit` is ignored in an if
    12  # conditional, triggering the problem here ensures script failure when
    13  # using an unsupported version of grep.
    14  grep -P 'lint.sh' scripts/lint.sh &> /dev/null || (\
    15    >&2 echo "error: This script requires a recent version of gnu grep.";\
    16    >&2 echo "       On macos, gnu grep can be installed with 'brew install grep'.";\
    17    >&2 echo "       It will also be necessary to ensure that gnu grep is available in the path.";\
    18    exit 255 )
    19  
    20  if [ "$#" -eq 0 ]; then
    21    # by default, check all source code
    22    # to test only "snow" package
    23    # ./scripts/lint.sh ./snow/...
    24    TARGET="./..."
    25  else
    26    TARGET="${1}"
    27  fi
    28  
    29  # by default, "./scripts/lint.sh" runs all lint tests
    30  # to run only "license_header" test
    31  # TESTS='license_header' ./scripts/lint.sh
    32  TESTS=${TESTS:-"golangci_lint license_header require_error_is_no_funcs_as_params single_import interface_compliance_nil require_no_error_inline_func"}
    33  
    34  function test_golangci_lint {
    35    go install -v github.com/golangci/golangci-lint/cmd/golangci-lint@v1.58.1
    36    golangci-lint run --config .golangci.yml
    37  }
    38  
    39  # automatically checks license headers
    40  # to modify the file headers (if missing), remove "--verify" flag
    41  # TESTS='license_header' ADDLICENSE_FLAGS="--debug" ./scripts/lint.sh
    42  _addlicense_flags=${ADDLICENSE_FLAGS:-"--verify --debug"}
    43  function test_license_header {
    44    go install -v github.com/palantir/go-license@v1.25.0
    45    local files=()
    46    while IFS= read -r line; do files+=("$line"); done < <(find . -type f -name '*.go' ! -name '*.pb.go' ! -name 'mock_*.go')
    47  
    48    # shellcheck disable=SC2086
    49    go-license \
    50    --config=./header.yml \
    51    ${_addlicense_flags} \
    52    "${files[@]}"
    53  }
    54  
    55  function test_single_import {
    56    if grep -R -zo -P 'import \(\n\t".*"\n\)' .; then
    57      echo ""
    58      return 1
    59    fi
    60  }
    61  
    62  function test_require_error_is_no_funcs_as_params {
    63    if grep -R -zo -P 'require.ErrorIs\(.+?\)[^\n]*\)\n' .; then
    64      echo ""
    65      return 1
    66    fi
    67  }
    68  
    69  function test_require_no_error_inline_func {
    70    if grep -R -zo -P '\t+err :?= ((?!require|if).|\n)*require\.NoError\((t, )?err\)' .; then
    71      echo ""
    72      echo "Checking that a function with a single error return doesn't error should be done in-line."
    73      echo ""
    74      return 1
    75    fi
    76  }
    77  
    78  # Ref: https://go.dev/doc/effective_go#blank_implements
    79  function test_interface_compliance_nil {
    80    if grep -R -o -P '_ .+? = &.+?\{\}' .; then
    81      echo ""
    82      echo "Interface compliance checks need to be of the form:"
    83      echo "  var _ json.Marshaler = (*RawMessage)(nil)"
    84      echo ""
    85      return 1
    86    fi
    87  }
    88  
    89  function run {
    90    local test="${1}"
    91    shift 1
    92    echo "START: '${test}' at $(date)"
    93    if "test_${test}" "$@" ; then
    94      echo "SUCCESS: '${test}' completed at $(date)"
    95    else
    96      echo "FAIL: '${test}' failed at $(date)"
    97      exit 255
    98    fi
    99  }
   100  
   101  echo "Running '$TESTS' at: $(date)"
   102  for test in $TESTS; do
   103    run "${test}" "${TARGET}"
   104  done
   105  
   106  echo "ALL SUCCESS!"