Skip to content
Draft
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
134 changes: 134 additions & 0 deletions .github/alias.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#!/bin/bash
set -euo pipefail

# Check unnecessary aliased imports where no conflict exists
# Flags: 1) alias != basename when basename is not imported, 2) redundant alias == basename
# Exception: when the actual package name equals the current package name, alias is NOT flagged
# (since using the same name would conflict with the current package)

# Pre-build a cache of import path -> actual package name for common stdlib packages
# This speeds up the check significantly

find . -type f -name '*.go' \
-not -name '*.qtpl.go' \
-not -path '*/vendor/*' \
-not -path '*/.claude/*' \
-not -path '*/prototype/*' \
| while read -r file; do
gawk '
BEGIN {
inblock = 0
line_count = 0
current_package = ""
}

# Store all lines of the file and detect current package
{
lines[line_count++] = $0
# Detect package declaration
if (match($0, /^package\s+([a-zA-Z_][a-zA-Z0-9_]*)/, pkg)) {
current_package = pkg[1]
}
}

# First pass: collect all imports with aliases and their paths
/^\s*import\s*\(/ { inblock = 1; next }
inblock && /^\s*\)/ { inblock = 0; next }

inblock && match($0, /^\s*"([^"]+)"\s*$/, m) {
split(m[1], parts, "/")
base = parts[length(parts)]
used[base] = 1
next
}

inblock && match($0, /^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s+"([^"]+)"/, m) {
alias = m[1]
path = m[2]
imports[path] = alias
used[alias] = 1
next
}

match($0, /^\s*import\s+"([^"]+)"\s*$/, m) {
split(m[1], parts, "/")
base = parts[length(parts)]
used[base] = 1
next
}

match($0, /^\s*import\s+([a-zA-Z_][a-zA-Z0-9_]*)\s+"([^"]+)"\s*$/, m) {
alias = m[1]
path = m[2]
imports[path] = alias
used[alias] = 1
next
}

END {
inblock = 0
for (i = 0; i < line_count; i++) {
line = lines[i]

if (line ~ /^\s*import\s*\(/) { inblock = 1; continue }
if (inblock && line ~ /^\s*\)/) { inblock = 0; continue }

if (inblock && match(line, /^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s+"([^"]+)"/, m)) {
alias = m[1]
path = m[2]
split(path, parts, "/")
base = parts[length(parts)]

# Determine actual package name
pkg_name = base
# Only check external packages, not stdlib or local paths
if (path !~ /^\./ && index(path, ".") > 0) {
cmd = "go list -f \"{{.Name}}\" \"" path "\" 2>/dev/null"
if ((cmd | getline pname) > 0) {
pkg_name = pname
}
close(cmd)
}

# Skip if alias is underscore, dot, equals base, or base is already used
# Also skip if the actual package name equals current package (alias is necessary to avoid conflict)
# Also skip if alias equals actual package name (necessary for versioned modules like /v2)
if (alias != "_" && alias != "." && alias != base && alias != pkg_name && !(base in used) && pkg_name != current_package && base != current_package) {
print FILENAME ":" i+1 ":" line
}
# Flag redundant alias (alias == base) - the alias provides no benefit
if (alias != "_" && alias != "." && alias == base) {
print FILENAME ":" i+1 ": redundant alias (remove \"" alias "\"): " line
}
continue
}

if (!inblock && match(line, /^\s*import\s+([a-zA-Z_][a-zA-Z0-9_]*)\s+"([^"]+)"\s*$/, m)) {
alias = m[1]
path = m[2]
split(path, parts, "/")
base = parts[length(parts)]

# Determine actual package name
pkg_name = base
if (path !~ /^\./ && index(path, ".") > 0) {
cmd = "go list -f \"{{.Name}}\" \"" path "\" 2>/dev/null"
if ((cmd | getline pname) > 0) {
pkg_name = pname
}
close(cmd)
}

# Same check for single-line import (including alias != pkg_name for versioned modules)
if (alias != "_" && alias != "." && alias != base && alias != pkg_name && !(base in used) && pkg_name != current_package && base != current_package) {
print FILENAME ":" i+1 ":" line
}
# Flag redundant alias (alias == base) - the alias provides no benefit
if (alias != "_" && alias != "." && alias == base) {
print FILENAME ":" i+1 ": redundant alias (remove \"" alias "\"): " line
}
}
}
}
' "$file"
done
7 changes: 5 additions & 2 deletions .github/workflows/go-cross.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
name: Go Matrix
on: [push, pull_request]

permissions:
contents: read

jobs:

cross:
Expand All @@ -11,7 +14,7 @@ jobs:

strategy:
matrix:
go-version: [ 1.24, 1.25, 1.x ]
go-version: [ 1.26, 1.x ]
os: [ubuntu-slim, macos-26, windows-latest]

steps:
Expand All @@ -23,7 +26,7 @@ jobs:

# https://github.com/marketplace/actions/checkout
- name: Checkout code
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: Test
run: make test
25 changes: 20 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,21 @@ on:
- master
pull_request:

permissions:
contents: read
pull-requests: read

jobs:

main:
name: Main Process
runs-on: ubuntu-slim
env:
GO_VERSION: 1.24
GOLANGCI_LINT_VERSION: v2.7.1
GO_VERSION: "1.26"
GOLANGCI_LINT_VERSION: v2.12.2
YAEGI_VERSION: v0.16.1
CGO_ENABLED: 1

steps:

# https://github.com/marketplace/actions/setup-go-environment
Expand All @@ -27,7 +31,7 @@ jobs:

# https://github.com/marketplace/actions/checkout
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@v7
with:
fetch-depth: 0

Expand All @@ -38,6 +42,13 @@ jobs:
- name: Install Yaegi ${{ env.YAEGI_VERSION }}
run: curl -sfL https://raw.githubusercontent.com/traefik/yaegi/master/install.sh | bash -s -- -b $(go env GOPATH)/bin ${YAEGI_VERSION}

- name: Install quality tooling
run: |
command -v bash >/dev/null || { echo "bash is required for the import-alias check"; exit 1; }
sudo apt-get update && sudo apt-get install -y gawk
go install golang.org/x/tools/cmd/goimports@v0.47.0
go install mvdan.cc/gofumpt@v0.10.0

- name: Check and get dependencies
run: |
go mod tidy
Expand All @@ -50,8 +61,12 @@ jobs:
- name: Lint and Tests
run: make

# Fail if `make` (gofumpt/goimports/golangci-lint --fix) rewrote any committed source.
- name: Ensure quality made no changes
run: git diff --exit-code

- name: Install goveralls
run: go install github.com/mattn/goveralls@latest
run: go install github.com/mattn/goveralls@v0.0.12
- name: Send coverage
env:
COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
Loading
Loading