# Gometalinter > gometalinter [flags] [packages] --- # gometalinter Command Reference ## Source: https://github.com/alecthomas/gometalinter ## Basic Syntax ```bash gometalinter [flags] [packages] ``` ## Common Commands and Examples ### Basic Linting ```bash # Lint current package gometalinter ./ # Lint all packages recursively gometalinter ./... # Lint specific package gometalinter ./mypackage # Lint multiple packages gometalinter ./pkg1 ./pkg2 ./pkg3 ``` ### Linter Control ```bash # List all available linters gometalinter --list-linters # Enable specific linters only gometalinter --disable-all --enable=vet --enable=golint ./... # Disable specific linters gometalinter --disable=misspell --disable=lll ./... # Enable all linters gometalinter --enable-all ./... ``` ### Output and Formatting ```bash # Checkstyle XML format (for CI/CD tools) gometalinter --checkstyle ./... # JSON output gometalinter --json ./... # Specify output format with template gometalinter --format='{{.Path}}:{{.Line}}:{{.Column}}: {{.Message}} ({{.Linter}})' ./... # Show only errors (not warnings) gometalinter --severity=error ./... # Show errors and warnings gometalinter --severity=warning ./... ``` ### Performance and Timeout ```bash # Set deadline (timeout) for all linters gometalinter --deadline=30s ./... # Set deadline for specific linter gometalinter --deadline=vet:5s ./... # Run linters with specific number of workers gometalinter --concurrency=4 ./... # Skip linters that take too long gometalinter --deadline=1m --errors ./... ``` ### File and Pattern Matching ```bash # Exclude files matching pattern gometalinter --exclude=vendor ./... # Exclude directories gometalinter --exclude-dir=build --exclude-dir=dist ./... # Only check Go test files gometalinter --include='.*_test\.go$' ./... # Include specific file patterns gometalinter --include='*.go' ./... ``` ### Configuration Files ```bash # Use specific config file gometalinter --config=.custom-gometalinter.json ./... # Generate config file gometalinter --write-config=.gometalinter.json ./... # Save configuration to file gometalinter --save-config ./... ``` ## Detailed Flag Reference ### Linter Selection | Flag | Type | Description | |------|------|-------------| | `--enable` | string | Enable specific linter | | `--disable` | string | Disable specific linter | | `--enable-all` | bool | Enable all linters | | `--disable-all` | bool | Disable all linters (use with `--enable`) | | `--list-linters` | bool | List all available linters and exit | ### Output Control | Flag | Type | Description | |------|------|-------------| | `--format` | string | Output format template (default: `::[]: ()`) | | `--json` | bool | Output results as JSON | | `--checkstyle` | bool | Output Checkstyle XML format | | `--severity` | string | Report only issues with this severity or higher (error, warning) | ### Performance | Flag | Type | Description | |------|------|-------------| | `--deadline` | duration | Maximum total time for all linters (e.g., "30s", "2m") | | `--concurrency` | int | Number of worker threads for parallel execution | ### File Matching | Flag | Type | Description | |------|------|-------------| | `--include` | string | Include file pattern (regex) | | `--exclude` | string | Exclude file pattern (regex) | | `--exclude-dir` | string | Exclude directory pattern (regex) | | `--vendor` | bool | Enable checking vendor directory | ### Configuration | Flag | Type | Description | |------|------|-------------| | `--config` | string | Path to config file | | `--write-config` | string | Write config to file and exit | | `--save-config` | bool | Save config file for this run | ### Other Options | Flag | Type | Description | |------|------|-------------| | `--fast` | bool | Only run fast linters | | `--skip-vendor` | bool | Skip vendor directory | | `--var-naming` | bool | Enable variable naming checks | | `--errors` | bool | Show errors only | | `--warnings` | bool | Show warnings only | ## Environment Variables ```bash # Override PATH for linter binaries export GOMETALINTER_LINTERS=/custom/path/to/linters # Set default deadline export GOMETALINTER_DEADLINE=30s # Enable specific linters by default export GOMETALINTER_ENABLE=vet,golint ``` ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success (no linting issues found) | | 1 | Linting issues found | | 2 | Error running gometalinter | ## Practical Examples ### CI/CD Pipeline ```bash # Run with strict settings for CI gometalinter \ --deadline=5m \ --severity=error \ --checkstyle \ --errors \ ./... > linting-results.xml ``` ### Pre-commit Hook ```bash #!/bin/bash # .git/hooks/pre-commit if ! gometalinter --deadline=10s ./...; then echo "Linting errors found. Commit aborted." exit 1 fi ``` ### Development Check ```bash # Fast check during development gometalinter --deadline=30s --enable=vet --enable=golint ./... ``` ### Custom Linter Integration ```bash # Add custom linter gometalinter \ --linter="custom:my-linter {file}:^(?P.*?):(?P\d+): (?P.*)$" \ ./... ``` ### Jenkins Integration ```groovy // Jenkinsfile stage('Lint') { steps { sh 'gometalinter --checkstyle ./... > checkstyle-report.xml' publishHTML target: [ reportDir: '.', reportFiles: 'checkstyle-report.xml', reportName: 'Linting Report' ] } } ``` ## Troubleshooting Commands ```bash # Check which linters are installed gometalinter --list-linters # Test specific linter gometalinter --enable=golint --disable-all ./... # Check for timeout issues gometalinter --deadline=60s --verbose ./... # View configuration being used gometalinter --config=.gometalinter.json --help # Test with minimal linters gometalinter --enable-all --exclude-dir=vendor ./mypackage ``` ## Notes - All durations use Go duration format: "300ms", "5s", "2m30s" - Patterns use Go regex syntax (RE2) - Multiple `--enable` and `--disable` flags can be combined - Configuration file options override command-line defaults --- # gometalinter Configuration Guide ## Source: https://github.com/alecthomas/gometalinter ## Configuration File Locations gometalinter looks for configuration files in this order: 1. `.gometalinter.json` (project root) 2. `.gometalinter.yaml` (project root) 3. Command-line specified config file (via `--config` flag) ## Configuration File Formats ### JSON Format (.gometalinter.json) ```json { "linters": { "vet": { "command": "go vet", "pattern": "^(?P.*?\\.go):(?P\\d+): (?P.*)" }, "golint": { "command": "golint -set_exit_status", "pattern": "^(?P.*?\\.go):(?P\\d+):(?P\\d+): (?P.*)" } }, "enable": [ "vet", "gotype", "golint", "errcheck", "staticcheck", "gosec", "misspell", "unconvert" ], "disable": [ "lll", "testify" ], "severity": "warning", "errors": false, "warnings": false, "skip-dirs": [ "vendor", "build" ], "skip-files": [ ".*\\.pb\\.go$" ], "deadline": "1m", "checkstyle": false, "json": false } ``` ### YAML Format (.gometalinter.yaml) ```yaml linters: vet: command: go vet pattern: '^(?P.*?\.go):(?P\d+): (?P.*)$' golint: command: golint -set_exit_status pattern: '^(?P.*?\.go):(?P\d+):(?P\d+): (?P.*)$' enable: - vet - gotype - golint - errcheck - staticcheck - gosec - misspell - unconvert disable: - lll - testify severity: warning errors: false warnings: false skip-dirs: - vendor - build - dist skip-files: - .*\.pb\.go$ - .*\.mock\.go$ deadline: 1m checkstyle: false json: false ``` ## Configuration Options ### Top-Level Options #### `linters` (object) Defines custom linters and overrides for built-in linters. ```json { "linters": { "my-custom-linter": { "command": "my-linter-command", "pattern": "^(?P.*?\\.go):(?P\\d+): (?P.*)$" } } } ``` **Linter Definition:** - **command** - Shell command to run - **pattern** - Regex pattern to parse output (must include named groups: `path`, `line`, `message`, optional: `column`, `severity`) #### `enable` (array) List of linters to enable by default. ```json { "enable": ["vet", "golint", "errcheck", "staticcheck"] } ``` **Default enabled linters:** ``` vet, gotype, deadcode, gocyclo, golint, errcheck, staticcheck, gosec, misspell, unconvert ``` #### `disable` (array) List of linters to disable. ```json { "disable": ["lll", "testify", "gofmt"] } ``` #### `severity` (string) Minimum severity level to report. - `error` - Report only errors (default) - `warning` - Report errors and warnings ```json { "severity": "warning" } ``` #### `errors` (boolean) Show only errors, filter out warnings. ```json { "errors": true } ``` #### `warnings` (boolean) Show only warnings, filter out errors. ```json { "warnings": true } ``` #### `skip-dirs` (array) Directories to skip during linting. ```json { "skip-dirs": [ "vendor", "build", "dist", "node_modules", ".git" ] } ``` #### `skip-files` (array) File patterns to skip (regex). ```json { "skip-files": [ ".*\\.pb\\.go$", ".*\\.mock\\.go$", ".*_test\\.go$" ] } ``` #### `deadline` (duration) Maximum time for all linters to complete. ```json { "deadline": "5m" } ``` Format: Go duration string - `"300ms"` - 300 milliseconds - `"5s"` - 5 seconds - `"2m30s"` - 2 minutes 30 seconds #### `checkstyle` (boolean) Output results in Checkstyle XML format. ```json { "checkstyle": true } ``` #### `json` (boolean) Output results as JSON. ```json { "json": true } ``` #### `format` (string) Custom output format using Go template syntax. ```json { "format": "{{.Path}}:{{.Line}}:{{.Column}}: {{.Message}} ({{.Linter}})" } ``` **Available template variables:** - `{{.Path}}` - File path - `{{.Line}}` - Line number - `{{.Column}}` - Column number - `{{.Message}}` - Message text - `{{.Linter}}` - Linter name - `{{.Severity}}` - Error/warning severity ## Real-World Configuration Examples ### Strict Development Setup ```json { "enable": [ "vet", "golint", "errcheck", "staticcheck", "gosec", "misspell" ], "disable": ["lll"], "skip-dirs": ["vendor", "build"], "deadline": "30s", "severity": "error" } ``` ### CI/CD Pipeline Configuration ```json { "enable": [ "vet", "golint", "errcheck", "staticcheck", "gosec", "unconvert", "misspell" ], "disable": ["lll", "testify"], "skip-dirs": ["vendor", "build", "dist"], "skip-files": [".*_test\\.go$"], "deadline": "5m", "checkstyle": true, "severity": "warning" } ``` ### Lenient Development Configuration ```json { "enable": ["vet", "golint"], "disable-all": true, "skip-dirs": ["vendor", "build"], "deadline": "1m", "severity": "error" } ``` ### Custom Linter Integration ```json { "linters": { "custom-security-check": { "command": "my-security-tool", "pattern": "^(?P.*?\\.go):(?P\\d+):(?P\\d+): (?P\\[(?P[^\\]]+)\\] .*)" } }, "enable": [ "vet", "custom-security-check" ], "deadline": "2m" } ``` ## Pattern Matching for Custom Linters Custom linter output must match regex patterns with named groups: ### Required Named Groups - `path` - File path (e.g., `main.go`) - `line` - Line number (e.g., `42`) - `message` - Error message text ### Optional Named Groups - `column` - Column number - `severity` - "error" or "warning" ### Pattern Examples ``` # Standard format: file:line: message ^(?P.*?\.go):(?P\d+): (?P.*)$ # With column: file:line:column: message ^(?P.*?\.go):(?P\d+):(?P\d+): (?P.*)$ # With severity: file:line: [severity] message ^(?P.*?\.go):(?P\d+): \[(?P[^\]]+)\] (?P.*)$ # Complex: Multiple captures ^(?P.*?\.go):(?P\d+):(?P\d+):\s+(?Perror|warning):\s+(?P.*)$ ``` ## Per-Linter Deadlines Override deadline for specific slow linters: ```json { "deadline": "1m", "linters": { "misspell": { "command": "misspell", "pattern": "^(?P.*?\\.go):(?P\\d+):(?P\\d+): (?P.*)", "deadline": "10s" } } } ``` ## Environment Variable Integration Reference environment variables in configuration: ```bash # Set environment variables export GOMETALINTER_DEADLINE="30s" export GOMETALINTER_ENABLE="vet,golint,errcheck" # These can be used in custom linter commands gometalinter --linter="custom:MY_TOOL $MY_VAR" ./... ``` ## Configuration Validation Validate configuration file syntax: ```bash # Check if config file is valid JSON cat .gometalinter.json | python3 -m json.tool # Test configuration with verbose output gometalinter --config=.gometalinter.json --verbose ./... ``` ## Gotchas and Best Practices ### 1. Skip Patterns Are Regex ```json { "skip-dirs": [ "vendor", // Matches "vendor" directory name "^\\..*", // Skip hidden directories "build|dist" // Match multiple directories ] } ``` ### 2. Deadline Applies to All Linters - Each linter timeout adds to total deadline - Set deadline high enough for all linters to complete - Use `--errors` flag to exit early on errors ### 3. Disable-All Requires Explicit Enable ```json { "disable": ["lll"], // This doesn't disable all others "enable": ["vet"] // Must explicitly enable what you want } ``` ### 4. JSON Escape Characters ```json { "skip-files": [ ".*\\.pb\\.go$" // Backslashes must be escaped ] } ``` ### 5. Order Matters - Command-line flags override config file - Later config entries override earlier ones ## Migrating to golangci-lint When migrating from gometalinter to golangci-lint, convert configuration: **gometalinter:** ```json { "enable": ["vet", "golint", "errcheck"], "deadline": "1m" } ``` **golangci-lint equivalent:** ```yaml linters: enable: - vet - golint - errcheck run: timeout: 1m ``` --- # gometalinter Practical Examples and Use Cases ## Source: https://github.com/alecthomas/gometalinter ## Project Setup Examples ### New Project Setup Initialize gometalinter for a new Go project: ```bash # 1. Install gometalinter brew install gometalinter # 2. Download and install all linters gometalinter --install # 3. Create initial config gometalinter --write-config=.gometalinter.json ./... # 4. Run initial lint gometalinter ./... # 5. Address issues or suppress false positives # Edit code to fix real issues # Use // nolint for false positives ``` ### Existing Project Integration Add gometalinter to an established project: ```bash # 1. Install with moderate settings cat > .gometalinter.json << 'EOF' { "enable": ["vet", "golint", "errcheck"], "skip-dirs": ["vendor", "build"], "deadline": "1m" } EOF # 2. Run and capture baseline gometalinter ./... 2>&1 | tee lint-baseline.txt # 3. Gradually enable more linters as team addresses issues # Uncomment additional linters weekly ``` ## Development Workflow Examples ### Daily Development Check Quick lint check during development: ```bash # Fast check - only vet and golint gometalinter --deadline=10s --enable=vet --enable=golint ./... ``` Save as a shell alias: ```bash # Add to ~/.bashrc or ~/.zshrc alias gmt-fast="gometalinter --deadline=10s --enable=vet --enable=golint" # Usage gmt-fast ./... ``` ### Pre-commit Hook Prevent commits with linting issues: ```bash #!/bin/bash # .git/hooks/pre-commit # Get modified Go files MODIFIED_GO_FILES=$(git diff --cached --name-only | grep '\.go$') if [ -z "$MODIFIED_GO_FILES" ]; then exit 0 fi # Run gometalinter on modified files echo "Running gometalinter on modified files..." for file in $MODIFIED_GO_FILES; do if ! gometalinter --deadline=5s "$file" 2>&1; then echo "Linting errors in $file. Commit aborted." exit 1 fi done exit 0 ``` ### Feature Branch Validation Lint changes in a feature branch: ```bash #!/bin/bash # Check only files changed in this branch BASE_BRANCH="main" CHANGED_FILES=$(git diff $BASE_BRANCH...HEAD --name-only | grep '\.go$') echo "Linting changed files in branch..." gometalinter --deadline=30s $(dirname $(echo $CHANGED_FILES | tr '\n' ' ' | awk '{print}')) ``` ## CI/CD Integration Examples ### GitHub Actions Workflow ```yaml # .github/workflows/lint.yml name: Lint on: [push, pull_request] jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Go uses: actions/setup-go@v4 with: go-version: '1.21' - name: Install gometalinter run: | go install gopkg.in/alecthomas/gometalinter.v1@latest gometalinter --install - name: Run gometalinter run: gometalinter --deadline=5m ./... - name: Checkstyle Report if: always() run: | gometalinter --checkstyle ./... > checkstyle-report.xml || true - name: Publish Checkstyle Report if: always() uses: actions/upload-artifact@v3 with: name: checkstyle-report path: checkstyle-report.xml ``` ### GitLab CI Configuration ```yaml # .gitlab-ci.yml stages: - lint lint: stage: lint image: golang:1.21 script: - go install gopkg.in/alecthomas/gometalinter.v1@latest - gometalinter --install - gometalinter --deadline=5m --checkstyle ./... > checkstyle.xml artifacts: reports: junit: checkstyle.xml paths: - checkstyle.xml allow_failure: false ``` ### Jenkins Pipeline ```groovy // Jenkinsfile pipeline { agent any stages { stage('Lint') { steps { script { sh ''' go install gopkg.in/alecthomas/gometalinter.v1@latest gometalinter --install gometalinter --deadline=5m --checkstyle ./... > checkstyle-report.xml || true ''' } } } stage('Report') { steps { publishHTML([ allowMissing: false, alwaysLinkToLastBuild: true, keepAll: true, reportDir: '.', reportFiles: 'checkstyle-report.xml', reportName: 'Checkstyle Report' ]) } } } post { always { step([$class: 'CheckStylePublisher', pattern: 'checkstyle-report.xml']) } } } ``` ### Makefile Integration ```makefile # Makefile .PHONY: lint lint-install lint-check # Install gometalinter lint-install: go install gopkg.in/alecthomas/gometalinter.v1@latest gometalinter --install # Quick lint check lint-check: gometalinter --deadline=10s --enable=vet --enable=golint ./... # Full lint with report lint: lint-install gometalinter --deadline=5m --checkstyle ./... > lint-report.xml || true @echo "Lint report generated: lint-report.xml" # Run all checks check: lint lint-check test @echo "All checks passed!" ``` ## Suppressing False Positives ### Using // nolint Comment Directive Suppress all linters for a line: ```go package main import "fmt" func main() { // nolint var unused string // nolint result := someExpensiveOperation() fmt.Println(result) } ``` Suppress specific linter: ```go // Only suppress misspell linter // nolint: misspell const commond = "misspell" // Intentional // Suppress multiple specific linters // nolint: errcheck,misspell err = someFunction() // Suppress errcheck ``` Suppress warnings on function: ```go // nolint func DisabledLinterCheck() { var unusedVar string return } ``` Suppress in struct tags: ```go type Config struct { // nolint OldField string `deprecated:"Use NewField"` } ``` ### Suppress Entire Files Create `.nolintignore` file: ``` # Ignore linting in generated files **/*_pb.go **/*_mock.go **/*_gen.go ``` ### Suppress Directory Use configuration file: ```json { "skip-dirs": ["vendor", "build"], "skip-files": [".*_test\\.go$", ".*_mock\\.go$"] } ``` ## Custom Linter Examples ### Adding a Custom Style Checker ```bash # Create custom linter script cat > /usr/local/bin/my-style-checker << 'EOF' #!/bin/bash grep -n "fmt.Print" "$1" | sed "s/:/ $(basename $1):/; s/$/: Use logging instead of fmt.Print/" EOF chmod +x /usr/local/bin/my-style-checker # Configure in gometalinter gometalinter \ --linter="mystyle:my-style-checker {file}:^.*?:(?P\\d+): (?P.*)$" \ ./... ``` ### Integrating with Project-Specific Linters ```json { "linters": { "custom-auth": { "command": "go run ./tools/lint-auth.go", "pattern": "^(?P.*?\\.go):(?P\\d+): (?P.*)" }, "custom-sql": { "command": "go run ./tools/lint-sql.go", "pattern": "^(?P.*?\\.go):(?P\\d+): (?P.*)" } }, "enable": [ "vet", "golint", "custom-auth", "custom-sql" ] } ``` ## Gradual Adoption Strategy ### Phase 1: Start Minimal Week 1 configuration: ```json { "enable": ["vet"], "skip-dirs": ["vendor"], "deadline": "30s", "severity": "error" } ``` ### Phase 2: Add Common Linters Week 2-3 configuration: ```json { "enable": [ "vet", "golint", "errcheck" ], "skip-dirs": ["vendor"], "deadline": "1m" } ``` ### Phase 3: Add Security and Performance Week 4-6 configuration: ```json { "enable": [ "vet", "golint", "errcheck", "staticcheck", "gosec", "misspell" ], "skip-dirs": ["vendor", "build"], "deadline": "2m" } ``` ### Phase 4: Full Coverage Final configuration: ```json { "enable": [ "vet", "golint", "errcheck", "staticcheck", "gosec", "misspell", "unconvert", "gocyclo", "deadcode" ], "disable": ["lll"], "skip-dirs": ["vendor", "build", "dist"], "deadline": "5m" } ``` ## Team Integration Examples ### Code Review Integration In pull request comments, run gometalinter on changed code: ```bash #!/bin/bash # comment-pr-lint.sh PR_FILES=$(gh pr diff $1 --name-only | grep '\.go$') if [ -z "$PR_FILES" ]; then echo "No Go files changed" exit 0 fi LINT_ISSUES=$(gometalinter --deadline=2m $PR_FILES 2>&1) if [ -z "$LINT_ISSUES" ]; then gh pr comment $1 -b "✅ No linting issues found" else gh pr comment $1 -b "⚠️ Linting issues found:\n\`\`\`\n$LINT_ISSUES\n\`\`\`" fi ``` ### Team Standards Documentation Create `LINTING.md` for your team: ```markdown # Linting Standards ## Running Linters ```bash # Daily development make lint-check # Before committing make lint # In CI/CD gometalinter --deadline=5m ./... ``` ## Suppressing False Positives Only use `// nolint` for legitimate false positives. Always explain why in a comment: ```go // nolint: errcheck // We intentionally ignore Close() errors for stdout fmt.Println(result) ``` ## Enabled Linters - **vet**: Official Go static analyzer - **golint**: Style issues - **errcheck**: Unchecked errors - **staticcheck**: Advanced static analysis - **gosec**: Security issues - **misspell**: Spelling errors Contact the team before suppressing warnings. ``` ## Monitoring and Reporting ### Generate Weekly Report ```bash #!/bin/bash # weekly-lint-report.sh TIMESTAMP=$(date +%Y-%m-%d) REPORT_FILE="lint-reports/${TIMESTAMP}-lint-report.txt" mkdir -p lint-reports gometalinter \ --deadline=10m \ --json ./... > "lint-reports/${TIMESTAMP}-lint.json" || true # Generate summary echo "=== Lint Report for $TIMESTAMP ===" > "$REPORT_FILE" echo "" >> "$REPORT_FILE" echo "Total Issues: $(cat "lint-reports/${TIMESTAMP}-lint.json" | jq length)" >> "$REPORT_FILE" echo "By Linter:" >> "$REPORT_FILE" cat "lint-reports/${TIMESTAMP}-lint.json" | jq -r '.[].Linter' | sort | uniq -c >> "$REPORT_FILE" echo "Report saved to $REPORT_FILE" ``` ### Track Lint Quality Over Time ```bash #!/bin/bash # track-lint-history.sh for week in {1..12}; do DATE=$(date -d "$week weeks ago" +%Y-%m-%d) COUNT=$(cat "lint-reports/${DATE}-lint.json" 2>/dev/null | jq length || echo 0) echo "$DATE: $COUNT issues" done | sort | tee lint-history.txt ``` ## Troubleshooting Examples ### Linter Not Found Problem: `"go vet not found"` Solution: ```bash # Check if linter is installed which go which golint # Install missing linter go install honnef.co/go/tools/cmd/staticcheck@latest # Update PATH if needed export PATH="$PATH:$(go env GOPATH)/bin" ``` ### Timeout Issues Problem: `"deadline exceeded"` Solution: ```bash # Increase deadline gometalinter --deadline=5m ./... # Or disable slow linters gometalinter --disable=gocyclo --deadline=2m ./... ``` ### False Positives in Generated Code Problem: Linting errors in `_pb.go` files Solution: ```json { "skip-files": [ ".*_pb\\.go$", ".*_gen\\.go$" ] } ``` --- # Go Meta Linter (gometalinter) - Official Documentation # Source: https://github.com/alecthomas/gometalinter ## Status: DEPRECATED **gometalinter is deprecated and was archived on April 7, 2019.** The project maintainers recommend migrating to [golangci-lint](https://github.com/golangci/golangci-lint) as the successor tool. This documentation is provided for legacy projects still using gometalinter. ## Overview gometalinter is a tool that **aggregates multiple Go linters into a single command-line interface**. It concurrently runs a collection of community and standard Go linting tools and normalizes their output to a consistent format, making it easier to manage code quality across projects. The tool standardizes output from different linters to a consistent format: ``` ::[]: () ``` ## Core Features ### 1. Concurrent Execution - Runs multiple linters in parallel for improved performance - Significantly faster than invoking each linter individually - Efficient resource utilization for large codebases ### 2. Standardized Output Format - Normalizes output from different linters to a consistent, parseable format - Makes it easier to integrate with CI/CD pipelines - Supports multiple output formats including Checkstyle XML ### 3. Comment-Based Suppression - Use `// nolint` directives to suppress specific linter messages - Fine-grained control over which linters to ignore per file or line - Helps manage false positives without disabling entire linters ### 4. Flexible Configuration - Command-line options for quick customization - `.gometalinter.json` configuration files for persistent settings - Support for custom linters via `--linter=NAME:COMMAND:PATTERN` syntax ### 5. Editor Integration - Sublime Text - Atom - Visual Studio Code - GoLand/IntelliJ IDEA - Vim/Neovim ## Installation ### Using Installation Script ```bash curl -L https://git.io/vp6lP | sh ``` ### Using Homebrew ```bash brew tap alecthomas/homebrew-tap brew install gometalinter ``` ### From Source ```bash go get -u gopkg.in/alecthomas/gometalinter.v1 cd $GOPATH/src/gopkg.in/alecthomas/gometalinter.v1 go install ``` ## Supported Linters ### Enabled by Default (20+) - **go vet** - The official Go static analysis tool - **gotype** - Syntactic and semantic analysis for Go - **deadcode** - Finds unused code - **gocyclo** - Computes cyclomatic complexity - **golint** - Finds style mistakes - **errcheck** - Checks for unchecked errors - **staticcheck** - Advanced static analysis - **gosec** - Security issue scanner - **misspell** - Finds commonly misspelled words - **unconvert** - Detects unnecessary type conversions ### Available but Disabled by Default - testify - gofmt - goimports - lll (line length linter) ## Quick Start ### Basic Usage ```bash # Lint current package gometalinter ./... # Lint specific package gometalinter ./mypackage ``` ### Enable Specific Linters ```bash # Only run go vet and golint gometalinter --disable-all --enable=vet --enable=golint ./... ``` ### Suppress Specific Warnings ```go // nolint var unusedVariable string // nolint: misspell // This is a commond example (intentional misspelling) ``` ### Configure Output ```bash # Show Checkstyle XML output (for Jenkins/CI) gometalinter --checkstyle ./... # Show warnings and errors gometalinter --severity=warning ./... ``` ## Configuration File Create `.gometalinter.json` in your project root: ```json { "linters": { "vet": { "command": "go vet" } }, "enable": ["vet", "gotype", "golint"], "disable": ["lll", "testify"], "severity": "warning", "checkstyle": false, "deadline": "1m" } ``` ### Configuration Options - **linters** - Define custom linters with command and error pattern - **enable** - List of enabled linters - **disable** - List of disabled linters - **severity** - Minimum severity level: "error" (default), "warning" - **checkstyle** - Output Checkstyle XML format - **deadline** - Maximum time to run all linters (e.g., "5s", "1m") - **errors** - Pattern to match error messages - **warnings** - Pattern to match warning messages ## Custom Linters Add custom linters using the command-line or configuration file: ```bash # Command-line syntax gometalinter --linter="my-linter:COMMAND:PATTERN" ./... ``` Example pattern for matching `file:line: message` format: ``` ^(?P.*?\.go):(?P\d+):\s*(?P.*)$ ``` ## CI/CD Integration ### Jenkins / Checkstyle Plugin ```bash gometalinter --checkstyle ./... > checkstyle-report.xml ``` ### GitLab CI ```yaml lint: script: - gometalinter ./... ``` ### GitHub Actions ```yaml - name: Run gometalinter run: gometalinter ./... ``` ## Editor Plugins ### VS Code Install the "Go" extension by Google, which includes gometalinter support. ### Vim/Neovim Use vim-go plugin with gometalinter support: ```vim let g:go_metalinter_enabled = ['vet', 'golint', 'errcheck'] ``` ### Sublime Text Install GoSublime or GoTools packages with gometalinter integration. ## Common Issues and Solutions ### Linter Not Found **Issue**: "linter X not found" **Solution**: Install the missing linter or ensure it's in your `$PATH` ### Timeout Errors **Issue**: "deadline exceeded" **Solution**: Increase deadline with `--deadline=2m` or disable slow linters ### False Positives **Issue**: Warnings that aren't real problems **Solution**: Use `// nolint` comment directive to suppress specific warnings ## Migration Guide (to golangci-lint) Since gometalinter is deprecated, projects should migrate to **golangci-lint**: ### Key Differences - golangci-lint is actively maintained and faster - Better performance and lower memory usage - More linters and better integration with modern Go tools - Configuration format: `.golangci.yml` instead of `.gometalinter.json` ### Migration Steps 1. Install golangci-lint: `brew install golangci-lint` 2. Convert configuration from `.gometalinter.json` to `.golangci.yml` 3. Update CI/CD pipelines to use `golangci-lint run ./...` 4. Test to ensure similar linter coverage ### Basic golangci-lint Equivalent ```yaml # .golangci.yml linters: enable: - vet - golint - errcheck - staticcheck - gosec - misspell - unconvert ``` ## API and Programmatic Usage gometalinter can be used as a library in Go programs: ```go import "gopkg.in/alecthomas/gometalinter.v1" // Configure and run linters config := gometalinter.NewConfig() config.Linters = []string{"vet", "golint"} results, _ := gometalinter.Run([]string{"./..."}, config) for _, result := range results { fmt.Printf("%s:%d: %s\n", result.Path, result.Line, result.Message) } ``` ## Performance Characteristics - **Startup time**: ~100-500ms depending on linters enabled - **Runtime**: Highly variable based on codebase size and linters enabled - **Memory usage**: Moderate, scales with codebase size - **Parallelization**: Good scalability across CPU cores ## Related Tools - **golangci-lint** - Modern replacement, actively maintained - **go vet** - Official static analysis tool - **gopls** - Go Language Server with integrated linting - **golint** - Individual style linter (now part of revive) ## References - GitHub Repository: https://github.com/alecthomas/gometalinter - pkg.go.dev: https://pkg.go.dev/gopkg.in/alecthomas/gometalinter.v1 - Go Linters Guide: https://blog.gopheracademy.com/advent-2016/some-tools-for-go-that-you-might-not-know-yet/ --- # gometalinter Quick Reference ## Source: https://github.com/alecthomas/gometalinter ## Installation ```bash brew install gometalinter # macOS go get gopkg.in/alecthomas/gometalinter.v1 # From source curl -L https://git.io/vp6lP | sh # Automatic installer ``` ## One-Line Commands ```bash # Basic lint gometalinter ./... # Lint with strict settings gometalinter --deadline=2m --severity=error ./... # Generate Checkstyle XML for CI gometalinter --checkstyle ./... > report.xml # Only specific linters gometalinter --disable-all --enable=vet --enable=golint ./... # Exclude patterns gometalinter --exclude=vendor ./... # List available linters gometalinter --list-linters ``` ## Common Configuration Save as `.gometalinter.json`: ```json { "enable": ["vet", "golint", "errcheck", "staticcheck"], "skip-dirs": ["vendor"], "deadline": "1m" } ``` Then run: ```bash gometalinter ./... ``` ## Default Enabled Linters | Linter | Purpose | |--------|---------| | vet | Official static analyzer | | gotype | Syntactic/semantic analysis | | deadcode | Finds unused code | | gocyclo | Cyclomatic complexity | | golint | Style issues | | errcheck | Unchecked errors | | staticcheck | Advanced static analysis | | gosec | Security issues | | misspell | Spelling errors | | unconvert | Unnecessary type conversions | ## Common Flags | Flag | Purpose | |------|---------| | `--deadline=5m` | Set timeout | | `--enable=NAME` | Enable specific linter | | `--disable=NAME` | Disable specific linter | | `--checkstyle` | XML output for CI | | `--json` | JSON output | | `--exclude=PATTERN` | Skip files matching pattern | | `--severity=warning` | Report warnings (default: errors only) | ## Suppress Warnings Inline suppression: ```go // nolint var unused string // nolint: misspell const commond = "typo" ``` Per-directory in config: ```json { "skip-dirs": ["vendor", "build"] } ``` ## CI/CD Quick Setup GitHub Actions: ```yaml - run: go install gopkg.in/alecthomas/gometalinter.v1@latest - run: gometalinter --install - run: gometalinter --deadline=5m ./... ``` ## Alias for Development Add to `.bashrc` or `.zshrc`: ```bash alias gmt="gometalinter --deadline=30s" alias gmt-check="gometalinter --deadline=10s --enable=vet --enable=golint" alias gmt-strict="gometalinter --deadline=5m ./..." ``` ## Useful Patterns ### Check Only Modified Files (Git) ```bash gometalinter $(git diff master --name-only | grep '\.go$' | xargs dirname | sort -u) ``` ### Check Package Recursively ```bash gometalinter ./... ``` ### Check Single Package ```bash gometalinter ./mypkg ``` ## Exit Codes | Code | Meaning | |------|---------| | 0 | No issues | | 1 | Issues found | | 2 | Error | ## Resources - **GitHub**: https://github.com/alecthomas/gometalinter - **pkg.go.dev**: https://pkg.go.dev/gopkg.in/alecthomas/gometalinter.v1 - **Status**: DEPRECATED (use golangci-lint instead) ## Migration to golangci-lint Since gometalinter is deprecated, migrate to: ```bash brew install golangci-lint golangci-lint run ./... ``` See main documentation for migration details.