Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ on:

permissions: {} # No default permissions

env:
GO_VERSION: '1.23.4'

jobs:
test:
runs-on: ubuntu-latest
Expand All @@ -26,7 +23,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
with:
go-version: ${{ env.GO_VERSION }}
go-version: 'stable'
cache: false

- name: Test
Expand Down
26 changes: 14 additions & 12 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,10 @@ linters:

nakedret:
# Default: 30
max-func-lines: 4
max-func-lines: 7

nestif:
min-complexity: 12
min-complexity: 15

nolintlint:
# Exclude following linters from requiring an explanation.
Expand All @@ -171,17 +171,11 @@ linters:
rules:
- name: add-constant
severity: warning
disabled: false
exclude: [""]
arguments:
- max-lit-count: "5"
allow-strs: '"","\n"'
allow-ints: "0,1,2,3,24,30,60,100,365,0o600,0o700,0o750,0o755"
allow-floats: "0.0,0.,1.0,1.,2.0,2."
disabled: true
- name: cognitive-complexity
arguments: [55]
disabled: true # prefer maintidx
- name: cyclomatic
arguments: [60]
disabled: true # prefer maintidx
- name: function-length
arguments: [150, 225]
- name: line-length-limit
Expand All @@ -192,6 +186,8 @@ linters:
arguments: [10]
- name: flag-parameter # fixes are difficult
disabled: true
- name: bare-return
disabled: true

rowserrcheck:
# database/sql is always checked.
Expand All @@ -213,8 +209,14 @@ linters:
os-temp-dir: true

varnamelen:
max-distance: 40
max-distance: 75
min-name-length: 2
check-receivers: false
ignore-names:
- r
- w
- f
- err

exclusions:
# Default: []
Expand Down
2 changes: 1 addition & 1 deletion .yamllint
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ rules:
document-start: disable
line-length:
level: warning
max: 200
max: 160
allow-non-breakable-inline-mappings: true
truthy: disable
109 changes: 85 additions & 24 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -95,56 +95,117 @@ help:
@echo " make ko-build - Build server container with ko"
@echo " make ko-publish - Publish server container with ko"

# BEGIN: lint-install - POSIX-compliant version
# Works with both BSD make and GNU make
# BEGIN: lint-install .
# http://github.com/codeGROOVE-dev/lint-install

.PHONY: lint
lint: _lint

# Use simple assignment for maximum compatibility
LINT_ARCH != uname -m || echo x86_64
LINT_OS != uname || echo Darwin
LINT_ROOT = .
LINT_ARCH := $(shell uname -m)
LINT_OS := $(shell uname)
LINT_OS_LOWER := $(shell echo $(LINT_OS) | tr '[:upper:]' '[:lower:]')
LINT_ROOT := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))

LINTERS =
FIXERS =
# shellcheck and hadolint lack arm64 native binaries: rely on x86-64 emulation
ifeq ($(LINT_OS),Darwin)
ifeq ($(LINT_ARCH),arm64)
LINT_ARCH=x86_64
endif
endif

GOLANGCI_LINT_CONFIG = $(LINT_ROOT)/.golangci.yml
GOLANGCI_LINT_VERSION = v2.3.1
GOLANGCI_LINT_BIN = $(LINT_ROOT)/out/linters/golangci-lint-$(GOLANGCI_LINT_VERSION)-$(LINT_ARCH)
LINTERS :=
FIXERS :=

SHELLCHECK_VERSION ?= v0.11.0
SHELLCHECK_BIN := $(LINT_ROOT)/out/linters/shellcheck-$(SHELLCHECK_VERSION)-$(LINT_ARCH)
$(SHELLCHECK_BIN):
mkdir -p $(LINT_ROOT)/out/linters
curl -sSfL -o $@.tar.xz https://github.com/koalaman/shellcheck/releases/download/$(SHELLCHECK_VERSION)/shellcheck-$(SHELLCHECK_VERSION).$(LINT_OS_LOWER).$(LINT_ARCH).tar.xz \
|| echo "Unable to fetch shellcheck for $(LINT_OS)/$(LINT_ARCH): falling back to locally install"
test -f $@.tar.xz \
&& tar -C $(LINT_ROOT)/out/linters -xJf $@.tar.xz \
&& mv $(LINT_ROOT)/out/linters/shellcheck-$(SHELLCHECK_VERSION)/shellcheck $@ \
|| printf "#!/usr/bin/env shellcheck\n" > $@
chmod u+x $@

LINTERS += shellcheck-lint
shellcheck-lint: $(SHELLCHECK_BIN)
$(SHELLCHECK_BIN) $(shell find . -name "*.sh")

FIXERS += shellcheck-fix
shellcheck-fix: $(SHELLCHECK_BIN)
$(SHELLCHECK_BIN) $(shell find . -name "*.sh") -f diff | { read -t 1 line || exit 0; { echo "$$line" && cat; } | git apply -p2; }

GOLANGCI_LINT_CONFIG := $(LINT_ROOT)/.golangci.yml
GOLANGCI_LINT_VERSION ?= v2.7.2
GOLANGCI_LINT_BIN := $(LINT_ROOT)/out/linters/golangci-lint-$(GOLANGCI_LINT_VERSION)-$(LINT_ARCH)
$(GOLANGCI_LINT_BIN):
mkdir -p $(LINT_ROOT)/out/linters
rm -rf $(LINT_ROOT)/out/linters/golangci-lint-*
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(LINT_ROOT)/out/linters $(GOLANGCI_LINT_VERSION)
mv $(LINT_ROOT)/out/linters/golangci-lint $(GOLANGCI_LINT_BIN)
mv $(LINT_ROOT)/out/linters/golangci-lint $@

LINTERS += golangci-lint-lint
golangci-lint-lint: $(GOLANGCI_LINT_BIN)
find . -name go.mod -execdir $(GOLANGCI_LINT_BIN) run -c $(GOLANGCI_LINT_CONFIG) \;
find . -name go.mod -execdir "$(GOLANGCI_LINT_BIN)" run -c "$(GOLANGCI_LINT_CONFIG)" \;

FIXERS += golangci-lint-fix
golangci-lint-fix: $(GOLANGCI_LINT_BIN)
find . -name go.mod -execdir $(GOLANGCI_LINT_BIN) run -c $(GOLANGCI_LINT_CONFIG) --fix \;

YAMLLINT_VERSION = 1.37.1
YAMLLINT_ROOT = $(LINT_ROOT)/out/linters/yamllint-$(YAMLLINT_VERSION)
YAMLLINT_BIN = $(YAMLLINT_ROOT)/dist/bin/yamllint
find . -name go.mod -execdir "$(GOLANGCI_LINT_BIN)" run -c "$(GOLANGCI_LINT_CONFIG)" --fix \;

YAMLLINT_VERSION ?= 1.37.1
YAMLLINT_ROOT := $(LINT_ROOT)/out/linters/yamllint-$(YAMLLINT_VERSION)
YAMLLINT_BIN := $(YAMLLINT_ROOT)/dist/bin/yamllint
$(YAMLLINT_BIN):
mkdir -p $(LINT_ROOT)/out/linters
rm -rf $(LINT_ROOT)/out/linters/yamllint-*
curl -sSfL https://github.com/adrienverge/yamllint/archive/refs/tags/v$(YAMLLINT_VERSION).tar.gz | tar -C $(LINT_ROOT)/out/linters -zxf -
cd $(YAMLLINT_ROOT) && (pip3 install --target dist . || pip install --target dist .)
cd $(YAMLLINT_ROOT) && pip3 install --target dist . || pip install --target dist .

LINTERS += yamllint-lint
yamllint-lint: $(YAMLLINT_BIN)
PYTHONPATH=$(YAMLLINT_ROOT)/dist $(YAMLLINT_BIN) .
PYTHONPATH=$(YAMLLINT_ROOT)/dist $(YAMLLINT_ROOT)/dist/bin/yamllint .

BIOME_VERSION ?= 2.3.8
BIOME_BIN := $(LINT_ROOT)/out/linters/biome-$(BIOME_VERSION)-$(LINT_ARCH)
BIOME_CONFIG := $(LINT_ROOT)/biome.json

# Map architecture names for Biome downloads
BIOME_ARCH := $(LINT_ARCH)
ifeq ($(LINT_ARCH),x86_64)
BIOME_ARCH := x64
endif

$(BIOME_BIN):
mkdir -p $(LINT_ROOT)/out/linters
rm -rf $(LINT_ROOT)/out/linters/biome-*
curl -sSfL -o $@ https://github.com/biomejs/biome/releases/download/%40biomejs%2Fbiome%40$(BIOME_VERSION)/biome-$(LINT_OS_LOWER)-$(BIOME_ARCH) \
|| echo "Unable to fetch biome for $(LINT_OS_LOWER)/$(BIOME_ARCH), falling back to local install"
test -f $@ || printf "#!/usr/bin/env biome\n" > $@
chmod u+x $@

LINTERS += biome-lint
biome-lint: $(BIOME_BIN)
$(BIOME_BIN) check --config-path=$(BIOME_CONFIG) .

FIXERS += biome-fix
biome-fix: $(BIOME_BIN)
$(BIOME_BIN) check --write --config-path=$(BIOME_CONFIG) .

.PHONY: _lint $(LINTERS)
_lint: $(LINTERS)
_lint:
@exit_code=0; \
for target in $(LINTERS); do \
$(MAKE) $$target || exit_code=1; \
done; \
exit $$exit_code

.PHONY: fix $(FIXERS)
fix: $(FIXERS)

# END: lint-install
fix:
@exit_code=0; \
for target in $(FIXERS); do \
$(MAKE) $$target || exit_code=1; \
done; \
exit $$exit_code

# END: lint-install .
129 changes: 129 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
{
"$schema": "https://biomejs.dev/schemas/2.3.8/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"ignoreUnknown": false,
"includes": [
"**",
"!**/node_modules",
"!**/dist",
"!**/build",
"!**/out",
"!**/coverage",
"!**/.next",
"!**/.nuxt",
"!**/*.html"
]
},
"formatter": {
"enabled": true,
"formatWithErrors": false,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100
},
"assist": { "actions": { "source": { "organizeImports": "on" } } },
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"complexity": {
"noExtraBooleanCast": "error",
"noUselessCatch": "error",
"noUselessTypeConstraint": "error",
"noAdjacentSpacesInRegex": "error",
"noArguments": "error"
},
"correctness": {
"noConstAssign": "error",
"noConstantCondition": "error",
"noEmptyCharacterClassInRegex": "error",
"noEmptyPattern": "error",
"noGlobalObjectCalls": "error",
"noInnerDeclarations": "error",
"noInvalidConstructorSuper": "error",
"noNonoctalDecimalEscape": "error",
"noPrecisionLoss": "error",
"noSelfAssign": "error",
"noSetterReturn": "error",
"noSwitchDeclarations": "error",
"noUndeclaredVariables": "error",
"noUnreachable": "error",
"noUnreachableSuper": "error",
"noUnsafeFinally": "error",
"noUnsafeOptionalChaining": "error",
"noUnusedLabels": "error",
"noUnusedVariables": "error",
"useIsNan": "error",
"useValidForDirection": "error",
"useYield": "error",
"noInvalidBuiltinInstantiation": "error",
"useValidTypeof": "error"
},
"security": {
"noDangerouslySetInnerHtml": "warn",
"noDangerouslySetInnerHtmlWithChildren": "error"
},
"style": {
"useConst": "error"
},
"suspicious": {
"noAssignInExpressions": "error",
"noAsyncPromiseExecutor": "error",
"noCatchAssign": "error",
"noClassAssign": "error",
"noCompareNegZero": "error",
"noControlCharactersInRegex": "error",
"noDebugger": "error",
"noDoubleEquals": "warn",
"noDuplicateCase": "error",
"noDuplicateClassMembers": "error",
"noDuplicateObjectKeys": "error",
"noDuplicateParameters": "error",
"noEmptyBlockStatements": "warn",
"noExplicitAny": "warn",
"noExtraNonNullAssertion": "error",
"noFallthroughSwitchClause": "error",
"noFunctionAssign": "error",
"noGlobalAssign": "error",
"noImportAssign": "error",
"noMisleadingCharacterClass": "error",
"noPrototypeBuiltins": "error",
"noRedeclare": "error",
"noShadowRestrictedNames": "error",
"noUnsafeDeclarationMerging": "error",
"noUnsafeNegation": "error",
"useGetterReturn": "error",
"noWith": "error",
"noVar": "error"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"jsxQuoteStyle": "double",
"quoteProperties": "asNeeded",
"trailingCommas": "es5",
"semicolons": "always",
"arrowParentheses": "always",
"bracketSpacing": true,
"bracketSameLine": false
}
},
"json": {
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2
},
"parser": {
"allowComments": true,
"allowTrailingCommas": false
}
}
}
Loading