Skip to content

diggsweden/devbase-check

Repository files navigation

devbase-check

Tag

License: MIT REUSE

OpenSSF Scorecard

Reusable linting for Just task runner. Install once, use across multiple projects.

What it does

  • Runs linters (shellcheck, yamlfmt, gitleaks, etc.) with one command
  • Skips what you don't need - no XML files? No XML linting
  • Add language-specific linters (Java, Node/TypeScript) on top
  • Centralized linting - update once, affects all projects
  • No copy-paste of linter scripts and configs between projects

Requirements

  • Just - task runner
  • mise - tool version manager
  • Git

Quick Start

  1. Copy an example justfile to your project:

  2. Run setup:

    just setup-devtools  # Downloads to ~/.local/share/devbase-check
    just lint-all        # Runs all linters

That's it.

Updates

Run just setup-devtools again to check for updates:

  • Interactive: Prompts "Update available: vX.Y.Z. Update? [y/N]"
  • CI/non-interactive: Auto-updates to latest tag

How it works

You get base linters for free. Add language-specific linters if needed. Disable base linters you dont want.

lint-base composition

  • lint-base - General inters that work on most project (YAML, shell, secrets, etc.)
  • lint-all - Uses lint-base, override to add Java/Node/Python linters
  • Individual recipes - Run them seperatly, example just lint-yaml or just lint-shell.

Base Linters

Run on every project. Skip automatically if no relevant files found:

Recipe Tool Checks Skips when
lint-commits conform Commit message format On default branch or no new commits
lint-secrets gitleaks Secrets/credentials Never (scans commits)
lint-yaml yamlfmt YAML formatting No .yml/.yaml files
lint-markdown rumdl Markdown style No .md files
lint-shell shellcheck Shell script bugs No .sh/.bash files
lint-shell-fmt shfmt Shell formatting No .sh/.bash files
lint-actions actionlint GitHub Actions syntax No .github/workflows/
lint-license reuse License compliance Never (scans all)
lint-container hadolint Dockerfile best practices No Containerfile/Dockerfile
lint-xml xmllint XML syntax/formatting No .xml files

Language-Specific Linters

Java

Recipe Tool Description
lint-java maven Run all (checkstyle + pmd + spotbugs)
lint-java-checkstyle checkstyle Style checks
lint-java-pmd pmd Static analysis
lint-java-spotbugs spotbugs Bug detection
lint-java-fmt formatter Check formatting
lint-java-fmt-fix formatter Fix formatting
test-java maven Run tests (mvn verify)

Node/TypeScript

Recipe Tool Description
lint-node npm Run all (eslint + prettier + types)
lint-node-eslint eslint Code quality checks (JS/TS)
lint-node-format prettier Code formatting check
lint-node-format-fix prettier Fix code formatting
lint-node-ts-types tsc TypeScript type checking

Add language-specific linters

Add language-specific recipes to your justfile. The verify.sh script (called by just verify) automatically detects recipes with these names and includes them in the summary:

  • Java: lint-java-checkstyle, lint-java-pmd, lint-java-spotbugs
  • Node: lint-node-eslint, lint-node-format, lint-node-ts-types

No need to override lint-all - just define the recipes and they're picked up automatically.

Java/Maven Project

java_lint := devtools_dir + "/linters/java"

# Run all Java linters together (convenience command)
[group('lint')]
lint-java:
    @{{java_lint}}/lint.sh

# Individual Java linters (auto-detected by verify.sh)
[group('lint')]
lint-java-checkstyle:
    @{{java_lint}}/checkstyle.sh

[group('lint')]
lint-java-pmd:
    @{{java_lint}}/pmd.sh

[group('lint')]
lint-java-spotbugs:
    @{{java_lint}}/spotbugs.sh

[group('lint')]
lint-java-fmt:
    @{{java_lint}}/format.sh check

[group('fix')]
lint-java-fmt-fix:
    @{{java_lint}}/format.sh fix

When you run just verify, the verify script automatically detects lint-java-checkstyle, lint-java-pmd, and lint-java-spotbugs recipes and includes them in the summary table. You can also run just lint-java to execute all Java linters together.

See examples/java-justfile for a complete example.

Node/TypeScript Project

node_lint := devtools_dir + "/linters/node"

# Run all Node linters together (convenience command)
[group('lint')]
lint-node:
    @{{node_lint}}/lint.sh

# Individual Node linters (auto-detected by verify.sh)
[group('lint')]
lint-node-eslint:
    @{{node_lint}}/eslint.sh

[group('lint')]
lint-node-format:
    @{{node_lint}}/format.sh check

[group('lint')]
lint-node-ts-types:
    @{{node_lint}}/types.sh

[group('fix')]
lint-node-format-fix:
    @{{node_lint}}/format.sh fix

When you run just verify, the verify script automatically detects lint-node-* recipes and includes them in the summary table. You can also run just lint-node to execute all Node linters together.

See examples/node-justfile for a complete example.

Go Project

# Go linter (add to verify.sh detection if needed)
[group('lint')]
lint-go:
    go vet ./...
    golangci-lint run

Rust Project

# Rust linters (add to verify.sh detection if needed)
[group('lint')]
lint-rust:
    cargo fmt --check
    cargo clippy -- -D warnings

Note: Go and Rust linters are not auto-detected by verify.sh yet. You can add detection in scripts/verify.sh following the Java/Node pattern, or run them separately with just lint-go / just lint-rust.

Minimal Project (base linters only)

# Run all linters with summary (base linters only)
lint-all: _ensure-devtools
    @{{devtools_dir}}/scripts/verify.sh

Multiple Languages

# Define linters from multiple languages - verify.sh auto-detects them all
lint-all: _ensure-devtools
    @{{devtools_dir}}/scripts/verify.sh

# Java linters
lint-java-checkstyle:
    @{{java_lint}}/checkstyle.sh

# Node linters
lint-node-eslint:
    @{{node_lint}}/eslint.sh

All defined lint-* recipes are automatically detected and included in the summary.

Customizing and Skipping Linters

You can override any linter recipe in your project's justfile to customize behavior or skip checks.

Disable or Skip a Linter

Two options to disable a linter:

Option 1: Hide completely - empty recipe (no output), linter won't appear in summary:

[group('lint')]
lint-license:

Option 2: Show as skipped - output message containing "Skip", shown as skipped in summary:

[group('lint')]
lint-license:
    @echo "Skipping license check - not required for this project"

Result in summary:

# Option 1: not shown at all
# Option 2:
License                reuse         -  skipped

Customize a Linter

Override a recipe to use custom configurations or different tools:

# Use custom shellcheck config
lint-shell:
    @shellcheck --severity=warning --exclude=SC2034 **/*.sh

# Run checkstyle with custom rules
lint-java-checkstyle:
    @mvn checkstyle:check -Dcheckstyle.config.location=custom-checks.xml

Conditional Linting

Skip linters conditionally based on environment or files:

# Skip license check in development, run in CI
lint-license:
    #!/usr/bin/env bash
    if [[ "${CI:-}" == "true" ]]; then
        {{lint}}/license.sh
    else
        echo "Skipping license check in development"
    fi

# Skip spotbugs if no Java code changed
lint-java-spotbugs:
    #!/usr/bin/env bash
    if git diff --name-only main | grep -q "\.java$"; then
        {{java_lint}}/spotbugs.sh
    else
        echo "Skipping SpotBugs - no Java files changed"
    fi

Note: The justfile is the interface - verify.sh respects all recipe overrides. Changes take effect immediately without updating devbase-check.

Utilities

Use colors.sh for consistent output in custom recipes:

my-recipe:
    #!/usr/bin/env bash
    source "{{colors}}"
    just_header "My Task" "some command"
    just_run "Task description" some command arg1 arg2
    just_success "Task completed"

Available functions:

Function Description
just_header "Title" "cmd" Cyan header with dim command
just_run "desc" cmd args... Run command, show output only on failure
just_success "msg" Green ✓ message
just_error "msg" Red ✗ message
just_warn "msg" Yellow ! message

Configuration

Override Default Linter Configs

Linters use sensible defaults (e.g., excluding target/, node_modules/, generated-sources/). Override by adding config files to your project:

Linter Project config file Default exclusions
yamlfmt .yamlfmt target/, node_modules/, generated-sources/, dist/, build/
spotbugs development/spotbugs-exclude.xml or .spotbugs-exclude.xml *generated-sources*
gitleaks .gitleaks.toml none
rumdl .rumdl.toml CHANGELOG.md

Example .yamlfmt:

exclude:
  - target/
  - my-custom-dir/
formatter:
  type: basic
  retain_line_breaks_single: true

Example development/spotbugs-exclude.xml:

<FindBugsFilter>
    <Match><Package name="~com\.example\.generated.*"/></Match>
</FindBugsFilter>

Custom Repository Location

Override the default repository URL via environment variable:

# Bash/Zsh - add to .bashrc or .zshrc
export DEVBASE_CHECK_REPO="https://internal.git/org/devbase-check"
# Fish - add to config.fish
set -gx DEVBASE_CHECK_REPO "https://internal.git/org/devbase-check"

The justfile picks this up automatically:

devtools_repo := env("DEVBASE_CHECK_REPO", "https://github.com/diggsweden/devbase-check")

CI Integration

The verify.sh script automatically detects the CI environment and adjusts output accordingly:

Environment Detection Output
Local/Console No CI env vars Colored table in terminal
GitHub Actions GITHUB_STEP_SUMMARY set Markdown summary in Actions UI
GitLab CI CI_JOB_URL set Console output (fallback)
Codeberg/Gitea GITEA_ACTIONS set Console output (fallback)

GitHub Actions

When running in GitHub Actions, results appear in the job summary with:

  • Markdown table showing each linter's status
  • Expandable error details for failed linters
  • Pass/fail/skip counts

No configuration needed - detection is automatic.

Using with reusable-ci

If using reusable-ci, enable devbase-check in your workflow:

jobs:
  lint:
    uses: diggsweden/reusable-ci/.github/workflows/pullrequest-orchestrator.yml@main
    with:
      project-type: maven
      linters.devbasecheck: true

Directory Structure

devbase-check/
├── linters/
│   ├── config/
│   │   └── .yamlfmt           # Default yamlfmt config
│   ├── java/
│   │   ├── config/
│   │   │   └── spotbugs-exclude.xml  # Default spotbugs exclusions
│   │   ├── checkstyle.sh
│   │   ├── format.sh
│   │   ├── lint.sh
│   │   ├── pmd.sh
│   │   ├── spotbugs.sh
│   │   └── test.sh
│   ├── node/
│   │   ├── eslint.sh
│   │   ├── format.sh
│   │   ├── lint.sh
│   │   └── types.sh
│   ├── commits.sh
│   ├── container.sh
│   ├── github-actions.sh
│   ├── license.sh
│   ├── markdown.sh
│   ├── secrets.sh
│   ├── shell-fmt.sh
│   ├── shell.sh
│   ├── xml.sh
│   └── yaml.sh
├── scripts/
│   ├── check-tools.sh
│   ├── setup.sh
│   └── verify.sh
├── summary/
│   ├── common.sh              # CI environment detection
│   ├── console.sh             # Terminal output (colored table)
│   └── github.sh              # GitHub Actions markdown summary
├── utils/
│   └── colors.sh
├── examples/
│   ├── base-justfile
│   ├── java-justfile
│   └── node-justfile
├── .mise.toml
├── justfile
└── README.md

License

This project is licensed under the MIT License. Documentation and configuration files are licensed under CC0-1.0.

See the SPDX headers in each file for details. This project is REUSE compliant.

About

A collection of lint and recipes to reuse in just/mise based projects.

Topics

Resources

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published