Skip to content

Commit

Permalink
Makefile: add lint check for Go version in Dockerfile and YAML
Browse files Browse the repository at this point in the history
Implemented linter scripts to ensure consistency of the Go version
specified in Dockerfiles and YAML files. These scripts verify that the
Go version used across these files is uniform, enhancing maintainability
and reducing configuration errors.

This commit also introduces a `GO_VERSION` Makefile variable to control
the Go version used throughout the project.
  • Loading branch information
ffranr committed Jul 30, 2024
1 parent e4fb45c commit ca74929
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 2 deletions.
20 changes: 18 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ ifeq ($(shell expr $(ACTIVE_GO_VERSION_MINOR) \>= 21), 1)
LOOPVARFIX := GOEXPERIMENT=loopvar
endif

# GO_VERSION is the Go version used for the release build, docker files, and
# GitHub Actions.
GO_VERSION = 1.22.5

GOBUILD := $(LOOPVARFIX) go build -v
GOINSTALL := $(LOOPVARFIX) go install -v
GOTEST := $(LOOPVARFIX) go test
Expand Down Expand Up @@ -298,11 +302,23 @@ fmt-check: fmt
@$(call print, "Checking fmt results.")
if test -n "$$(git status --porcelain)"; then echo "code not formatted correctly, please run `make fmt` again!"; git status; git diff; exit 1; fi

#? lint: Run static code analysis
lint: docker-tools
check-go-version-yaml:
@$(call print, "Checking for target Go version (v$(GO_VERSION)) in YAML files (*.yaml, *.yml)")
./tools/check-go-version-yaml.sh $(GO_VERSION)

check-go-version-dockerfile:
@$(call print, "Checking for target Go version (v$(GO_VERSION)) in Dockerfile files (*Dockerfile)")
./tools/check-go-version-dockerfile.sh $(GO_VERSION)

check-go-version: check-go-version-dockerfile check-go-version-yaml

lint-source: docker-tools
@$(call print, "Linting source.")
$(DOCKER_TOOLS) golangci-lint run -v $(LINT_WORKERS)

#? lint: Run static code analysis
lint: lint-source check-go-version

#? protolint: Lint proto files using protolint
protolint:
@$(call print, "Linting proto files.")
Expand Down
40 changes: 40 additions & 0 deletions tools/check-go-version-dockerfile.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/bin/bash

# Function to check if the Dockerfile contains only the specified Go version.
check_go_version() {
local dockerfile="$1"
local required_go_version="$2"

# Use grep to find lines with 'FROM golang:'
local go_lines=$(grep -i '^FROM golang:' "$dockerfile")

# Check if all lines have the required Go version.
if [ -z "$go_lines" ]; then
# No Go version found in the file. Skip the check.
return
elif echo "$go_lines" | grep -q -v "$required_go_version"; then
echo "$go_lines"
echo "Error: $dockerfile does not use Go version $required_go_version exclusively."
exit 1
else
echo "$dockerfile is using Go version $required_go_version."
fi
}

# Check if the target Go version argument is provided.
if [ $# -eq 0 ]; then
echo "Usage: $0 <target_go_version>"
exit 1
fi

target_go_version="$1"

# Search for Dockerfiles in the current directory and its subdirectories.
dockerfiles=$(find . -type f -name "*.Dockerfile" -o -name "Dockerfile")

# Check each Dockerfile
for file in $dockerfiles; do
check_go_version "$file" "$target_go_version"
done

echo "All Dockerfiles pass the Go version check for Go version $target_go_version."
75 changes: 75 additions & 0 deletions tools/check-go-version-yaml.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/bin/bash

# Function to check if the YAML file contains the specified Go version after
# field 'go:'.
check_go_version_yaml() {
local yamlfile="$1"
local required_go_version="$2"

# Use grep to find lines with 'go:'. The grep exist status is ignored.
local go_lines=$(grep -i '^\s*go:\s*"[0-9]\+\.[0-9]\+\.[0-9]\+"' "$yamlfile" || true)

# Check if any lines specify the Go version.
if [ -n "$go_lines" ]; then
# Extract the Go version from the file's lines. Example matching strings:
# go: "1.21.0"
local extracted_go_version=$(echo "$go_lines" | grep -oP '^\s*go:\s*"\K[^"]+')

# Check if the extracted Go version matches the required version.
if [ "$extracted_go_version" != "$required_go_version" ]; then
echo "Error: $yamlfile specifies Go version '$extracted_go_version', but not version '$required_go_version'."
exit 1
else
echo "$yamlfile specifies Go version $required_go_version."
fi
fi
}

# Function to check if the YAML file contains the specified Go version after
# environment variable 'GO_VERSION:'.
check_go_version_env_variable() {
local yamlfile="$1"
local required_go_version="$2"

# Use grep to find lines with 'GO_VERSION:'. The grep exist status is
# ignored.
local go_lines=$(grep -i 'GO_VERSION:' "$yamlfile" || true)

# Check if any lines specify the Go version.
if [ -n "$go_lines" ]; then
# Extract the Go version from the file's lines. Example matching strings:
# GO_VERSION: "1.21.0"
# GO_VERSION: '1.21.0'
# GO_VERSION: 1.21.0
# GO_VERSION:1.21.0
# GO_VERSION:1.21.0
local extracted_go_version=$(echo "$go_lines" | sed -n 's/^[[:space:]]*GO_VERSION:[[:space:]]*\(['\''"]\?\)\?\([0-9]\+\.[0-9]\+\.[0-9]\+\)\(['\''"]\?\)\?/\2/p')

# Check if the extracted Go version matches the required version.
if [ "$extracted_go_version" != "$required_go_version" ]; then
echo "Error: $yamlfile specifies Go version '$extracted_go_version', but not version '$required_go_version'."
exit 1
else
echo "$yamlfile specifies Go version $required_go_version."
fi
fi
}

# Check if the target Go version argument is provided.
if [ $# -eq 0 ]; then
echo "Usage: $0 <target_go_version>"
exit 1
fi

target_go_version="$1"

# Search for YAML files in the current directory and its subdirectories.
yaml_files=$(find . -type f -name "*.yaml" -o -name "*.yml")

# Check each YAML file.
for file in $yaml_files; do
check_go_version_yaml "$file" "$target_go_version"
check_go_version_env_variable "$file" "$target_go_version"
done

echo "All YAML files pass the Go version check for Go version $target_go_version."

0 comments on commit ca74929

Please sign in to comment.