Skip to content

Commit

Permalink
Added pre-commit hooks for Go tests and linting.
Browse files Browse the repository at this point in the history
**Added:**

- `.hooks/run-go-tests.sh` for running Go tests.
- Pre-commit hook for running Go unit tests in `.pre-commit-config.yaml`.
- Pre-commit hook for running `go vet` in `.pre-commit-config.yaml`.
- Pre-commit hook for checking Go licenses in `.pre-commit-config.yaml`.
  • Loading branch information
l50 authored and actions-user committed Jun 24, 2024
1 parent af1c207 commit 814cf98
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .hooks/go-copyright.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
set -ex

copyright_header='/*
Copyright © 2023-present, Meta Platforms, Inc. and affiliates
Copyright © 2024-present, Meta Platforms, Inc. and affiliates
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
Expand Down
43 changes: 43 additions & 0 deletions .hooks/go-licenses.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/bin/bash

# Function to check if go mod vendor should run or not
run_vendor() {
echo "Running go mod vendor..."
go mod vendor
}

# Function to check licenses
check_licenses() {
action=$1

go install github.com/google/go-licenses@latest

# Decide action based on input
if [[ $action == "check_forbidden" ]]; then
echo "Checking for forbidden licenses..."
output=$(go-licenses check ./... 2> /dev/null)
if [[ "${output}" == *"ERROR: forbidden license found"* ]]; then
echo "Forbidden licenses found. Please remove them."
exit 1
else
echo "No forbidden licenses found."
fi
elif [[ $action == "output_csv" ]]; then
echo "Outputting licenses to csv..."
status=go-licenses csv ./... 2> /dev/null
elif [[ $action == "vendor" ]]; then
echo "Vendoring dependencies..."
run_vendor
fi
}

# Ensure input is provided
if [[ $# -lt 1 ]]; then
echo "Incorrect number of arguments."
echo "Usage: $0 <licenses action>"
echo "Example: $0 check_forbidden"
exit 1
fi

# Run checks
check_licenses "${1}"
11 changes: 11 additions & 0 deletions .hooks/go-vet.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash
set -e

pkgs=$(go list ./...)

for pkg in $pkgs; do
dir="$(basename "$pkg")/"
if [[ "${dir}" != .*/ ]]; then
go vet "${pkg}"
fi
done
91 changes: 91 additions & 0 deletions .hooks/run-go-tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#!/bin/bash

set -e

TESTS_TO_RUN=$1
PROJECT=TTPFORGE
RETURN_CODE=0

TIMESTAMP=$(date +"%Y%m%d%H%M%S")
LOGFILE="/tmp/$PROJECT-unit-test-results-$TIMESTAMP.log"
MODULE_ROOT=$(go list -m -f "{{.Dir}}")

if [[ -z "${TESTS_TO_RUN}" ]]; then
echo "No tests input" | tee -a "$LOGFILE"
echo "Example - Run all shorter collection of tests: bash run-go-tests.sh short" | tee -a "$LOGFILE"
echo "Example - Run all tests: bash run-go-tests.sh all" | tee -a "$LOGFILE"
echo "Example - Run coverage for a specific version: bash run-go-tests.sh coverage" | tee -a "$LOGFILE"
echo "Example - Run tests for modified files: bash run-go-tests.sh modified" | tee -a "$LOGFILE"
exit 1
fi

run_tests() {
local coverage_file=$1
repo_root=$(git rev-parse --show-toplevel 2> /dev/null) || exit
pushd "${repo_root}" || exit
echo "Logging output to ${LOGFILE}" | tee -a "$LOGFILE"
echo "Run the following command to see the output in real time:" | tee -a "$LOGFILE"
echo "tail -f ${LOGFILE}" | tee -a "$LOGFILE"
echo "Running tests..." | tee -a "$LOGFILE"

# Check if go.mod and go.sum exist
if [[ -f "go.mod" && -f "go.sum" ]]; then
# Check if `go mod tidy` is necessary
MOD_TMP=$(mktemp)
SUM_TMP=$(mktemp)
cp go.mod "$MOD_TMP"
cp go.sum "$SUM_TMP"
go mod tidy
if ! cmp -s go.mod "$MOD_TMP" || ! cmp -s go.sum "$SUM_TMP"; then
echo "Running 'go mod tidy' to clean up module dependencies..." | tee -a "$LOGFILE"
go mod tidy 2>&1 | tee -a "$LOGFILE"
fi
rm "$MOD_TMP" "$SUM_TMP"
fi

if [[ "${TESTS_TO_RUN}" == 'coverage' ]]; then
go test -v -race -failfast -tags=integration -coverprofile="${coverage_file}" ./... 2>&1 | tee -a "$LOGFILE"
elif [[ "${TESTS_TO_RUN}" == 'all' ]]; then
go test -v -race -failfast ./... 2>&1 | tee -a "$LOGFILE"
elif [[ "${TESTS_TO_RUN}" == 'short' ]] && [[ "${GITHUB_ACTIONS}" != "true" ]]; then
go test -v -short -failfast -race ./... 2>&1 | tee -a "$LOGFILE"
elif [[ "${TESTS_TO_RUN}" == 'modified' ]]; then
# Run tests for modified files
local modified_files
IFS=$'\n' read -r -a modified_files <<< "$(git diff --name-only --cached | grep '\.go$')"

local pkg_dirs=()

for file in "${modified_files[@]}"; do
local pkg_dir
pkg_dir=$(dirname "$file")
pkg_dir=${pkg_dir#"$MODULE_ROOT/"}
pkg_dirs+=("$pkg_dir")
done

# Remove duplicate package directories
IFS=$'\n' read -r -a pkg_dirs <<< "$(sort -u <<< "${pkg_dirs[*]}")"
unset IFS

for dir in "${pkg_dirs[@]}"; do
go test -v -race -failfast "./$dir/..." 2>&1 | tee -a "$LOGFILE"
done
else
if [[ "${GITHUB_ACTIONS}" != 'true' ]]; then
go test -v -failfast -race "./.../${TESTS_TO_RUN}" 2>&1 | tee -a "$LOGFILE"
fi
fi

RETURN_CODE=$?
}

if [[ "${TESTS_TO_RUN}" == 'coverage' ]]; then
run_tests 'coverage-all.out'
else
run_tests
fi

if [[ "${RETURN_CODE}" -ne 0 ]]; then
echo "unit tests failed" | tee -a "$LOGFILE"
exit 1
fi
32 changes: 32 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,38 @@ repos:
language: script
files: go.mod

- id: go-unit-tests
name: Go unit tests
language: script
entry: .hooks/run-go-tests.sh modified
files: '\.go$'
pass_filenames: true

- id: go-vet
name: Run go vet
language: script
entry: .hooks/go-vet.sh
files: '\.go$'
always_run: true
pass_filenames: true
require_serial: true
log_file: /tmp/go-vet.log

- id: go-licenses
name: Run go-licenses
language: script
entry: .hooks/go-licenses.sh check_forbidden

- id: go-vet
name: Run go vet
language: script
entry: .hooks/go-vet.sh
files: '\.go$'
always_run: true
pass_filenames: true
require_serial: true
log_file: /tmp/go-vet.log

- id: go-copyright
name: Ensure all go files have the copyright header
language: script
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.21
require (
github.com/Masterminds/sprig/v3 v3.2.3
github.com/google/go-cmp v0.6.0
github.com/google/uuid v1.6.0
github.com/otiai10/copy v1.14.0
github.com/spf13/afero v1.11.0
github.com/spf13/cobra v1.8.0
Expand All @@ -18,7 +19,6 @@ require (
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
Expand Down

0 comments on commit 814cf98

Please sign in to comment.