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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ jobs:
with:
go-version-file: go.mod
- run: make build
- run: ./bin/decolint -format=github -deny-warnings -platform=vscode,codespaces .
- run: ./bin/decolint --format=github --deny-warnings --platform=vscode,codespaces .

docker:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sarif-upload-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
# non-zero status is a real failure. It runs from the repository root so that the reported
# paths are relative to it, which is how code scanning resolves them. Merging is off so the
# run needs no registry access and cannot fail for reasons unrelated to the upload.
run: ./bin/decolint -format=sarif -merge=false "$FIXTURE" > decolint.sarif || [ "$?" -eq 1 ]
run: ./bin/decolint --format=sarif --merge=false "$FIXTURE" > decolint.sarif || [ "$?" -eq 1 ]

- name: Upload the SARIF log
id: upload
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ needs `GOEXPERIMENT=jsonv2`. The [Makefile](Makefile) sets it for you:
make build # build ./bin/decolint
make test # go test ./...
make lint # golangci-lint
make run ARGS="-format=json path/to/dir"
make run ARGS="--format=json path/to/dir"
```

The documentation site in [`docs/`](docs/) is built with
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ privileges:
Nothing in it is wrong. The problems are in what it pulls in:

```console
$ decolint -merge .
$ decolint --merge .
Downloading image metadata(mcr.microsoft.com/devcontainers/go:1.24@sha256:8de3d5b3a3ce235671c7649f0b910414158a220d18cbd2714a4446cc0cc6acd3)
Config: .decolint.jsonc
Linted 1 file:
Expand All @@ -115,7 +115,7 @@ installs two unpinned VS Code extensions, and that configuration reaches the
container whether or not anyone reads it. decolint reports each finding at the
property that pulled it in.

Turn it on with `-merge`, or `"merge": true` in your config; see [Lint what
Turn it on with `--merge`, or `"merge": true` in your config; see [Lint what
actually
runs](https://bare-devcontainer.github.io/decolint/getting-started/#4-lint-what-actually-runs)
for what gets resolved and what does not.
Expand Down
4 changes: 2 additions & 2 deletions cmd/decolint/color.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"golang.org/x/term"
)

// colorMode is when the text output should be colored, as given by the -color flag.
// colorMode is when the text output should be colored, as given by the --color flag.
type colorMode int

const (
Expand Down Expand Up @@ -41,7 +41,7 @@ func parseColorMode(name string) (colorMode, error) {
// colorAuto, in which case the environment does, in this order:
//
// - NO_COLOR set to a non-empty value turns color off. It wins over FORCE_COLOR, so decolint never
// emits escape sequences where they were declared unwanted; -color=always still forces them.
// emits escape sequences where they were declared unwanted; --color=always still forces them.
// - FORCE_COLOR decides on its own: "0" turns color off, any other non-empty value turns it on,
// for a destination that renders escape sequences without being a terminal, e.g. a CI log.
// - A "dumb" terminal, or a destination that is not a terminal at all, turns color off.
Expand Down
16 changes: 8 additions & 8 deletions cmd/decolint/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ import (
// Config is the on-disk shape of a decolint config file.
type Config struct {
// Platforms lists target platforms whose rules are linted in addition to platform-agnostic
// ones. The -platform flag, when given, takes precedence.
// ones. The --platform flag, when given, takes precedence.
Platforms []linter.Platform `json:"platforms"`
// Merge, when true, fetches the Features referenced in each devcontainer.json and
// lints the merged (effective) configuration. The -merge flag can enable it as well.
// lints the merged (effective) configuration. The --merge flag can enable it as well.
Merge bool `json:"merge"`
// DenyWarnings, when true, lowers the fail threshold to linter.SeverityWarn so that warnings
// also cause exit code 1. The -deny-warnings flag can enable it as well.
// also cause exit code 1. The --deny-warnings flag can enable it as well.
DenyWarnings bool `json:"denyWarnings"`
// Format selects how lint issues are written to stdout: "text" (the default when empty), "json",
// "github", or "sarif". The -format flag takes precedence.
// "github", or "sarif". The --format flag takes precedence.
Format string `json:"format"`
// LocalEnv maps names to the values "${localEnv:NAME}" (and "${env:NAME}") resolve to during
// variable substitution, which runs with Merge; see [substitute.Context.LocalEnv]. It is also
Expand Down Expand Up @@ -126,10 +126,10 @@ func writeSortedMap[V any](enc *jsontext.Encoder, m map[string]V) error {
}

// mergeConfig returns cfg with any CLI-provided opts fields applied as overrides. A non-empty
// -platform replaces the config file's Platforms (an empty -platform defers to the config file
// rather than clearing it). -merge and -deny-warnings, when explicitly given, override Merge and
// DenyWarnings in either direction (e.g. "-merge=false" disables merging even if the config file
// sets "merge": true). A non-empty -format replaces the config file's Format. LocalEnv, Categories,
// --platform replaces the config file's Platforms (an empty --platform defers to the config file
// rather than clearing it). --merge and --deny-warnings, when explicitly given, override Merge and
// DenyWarnings in either direction (e.g. "--merge=false" disables merging even if the config file
// sets "merge": true). A non-empty --format replaces the config file's Format. LocalEnv, Categories,
// and Rules are config-file only.
func mergeConfig(opts Options, cfg Config) Config {
if len(opts.Platforms) > 0 {
Expand Down
8 changes: 4 additions & 4 deletions cmd/decolint/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (

// initConfigFile writes a fresh .decolint.jsonc file to the current directory, listing every
// built-in rule at its default severity. It writes a confirmation message to output. It is an
// error if the file already exists, so -init never silently overwrites a user's customized config.
// error if the file already exists, so --init never silently overwrites a user's customized config.
func initConfigFile(output io.Writer) error {
name := defaultConfigNames[0] // ".decolint.jsonc"

Expand All @@ -35,16 +35,16 @@ func initConfigFile(output io.Writer) error {
// under "categories"; per-rule entries take precedence, e.g.:
// "categories": { "security": "error" }
// "platforms" lists target platforms whose rules run in addition to
// platform-agnostic ones (the -platform flag takes precedence), e.g.:
// platform-agnostic ones (the --platform flag takes precedence), e.g.:
// "platforms": ["vscode", "codespaces"]
// "merge", when true, fetches the Features referenced in each
// devcontainer.json and lints the merged (effective) configuration, e.g.:
// "merge": true
// "denyWarnings", when true, treats warnings as failures (exit code 1);
// the -deny-warnings flag takes precedence, e.g.:
// the --deny-warnings flag takes precedence, e.g.:
// "denyWarnings": true
// "format" selects the output format ("text", "json", "github", or
// "sarif"); the -format flag takes precedence, e.g.:
// "sarif"); the --format flag takes precedence, e.g.:
// "format": "github"
// "localEnv" supplies the values ${localEnv:NAME} resolves to when merging,
// and the environment Compose-file interpolation reads; environment
Expand Down
14 changes: 7 additions & 7 deletions cmd/decolint/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package main
import (
"context"
"errors"
"flag"
"fmt"
"io"
"io/fs"
Expand All @@ -21,6 +20,7 @@ import (
"github.com/bare-devcontainer/decolint/linter"
"github.com/bare-devcontainer/decolint/rules"
"github.com/bare-devcontainer/decolint/substitute"
"github.com/spf13/pflag"
)

// progName is the program name, used in the flag set, usage text, and error messages.
Expand Down Expand Up @@ -61,7 +61,7 @@ func main() {
func run(ctx context.Context, args []string, stdout, stderr io.Writer, getenv func(string) string) int {
opts, err := parseOptions(args, stderr)
if err != nil {
if errors.Is(err, flag.ErrHelp) {
if errors.Is(err, pflag.ErrHelp) {
return exitCodeSuccess
}
_, _ = fmt.Fprintln(stderr, progName+":", err)
Expand Down Expand Up @@ -113,14 +113,14 @@ func versionString() string {
return fmt.Sprintf("%s %s (revision %s)", progName, version, revision)
}

// severityEmoji renders a severity for the -rules table.
// severityEmoji renders a severity for the --rules table.
var severityEmoji = map[linter.Severity]string{
linter.SeverityOff: "",
linter.SeverityWarn: "🟡 WARN",
linter.SeverityError: "🔴 ERROR",
}

// rulesTableHeader is the header row of the -rules Markdown table.
// rulesTableHeader is the header row of the --rules Markdown table.
var rulesTableHeader = []string{"Rule ID", "Category", "Platform", "Current"}

// listRules writes a Markdown table of the built-in rules to output: each rule's ID, category,
Expand Down Expand Up @@ -200,7 +200,7 @@ func writeTableRow(output io.Writer, cells []string, widths []int) error {
}

// displayWidth estimates s's width in terminal columns. Plain ASCII/Latin text is single-width;
// symbols and emoji (used for severities in the -rules table) render double-width in virtually
// symbols and emoji (used for severities in the --rules table) render double-width in virtually
// every terminal, even though they're each a single rune, so utf8.RuneCountInString undercounts
// them and throws off column padding. Variation selectors (e.g. U+FE0F, which requests the emoji
// presentation of the preceding rune) contribute no width of their own.
Expand All @@ -219,7 +219,7 @@ func displayWidth(s string) int {
return w
}

func usage(fs *flag.FlagSet) error {
func usage(fs *pflag.FlagSet) error {
if _, err := io.WriteString(fs.Output(), fmt.Sprintf(`%s

usage: %s [directory ...]
Expand Down Expand Up @@ -259,7 +259,7 @@ func runLint(ctx context.Context, stdout, stderr io.Writer, opts Options, cfg Co
return false, fmt.Errorf("register rules: %w", err)
}
// Variable substitution and Feature merging together compute the effective configuration, so
// both are enabled by -merge: without it, decolint lints the file as written.
// both are enabled by --merge: without it, decolint lints the file as written.
var merge mergeFn
var subst substituteFn
if cfg.Merge {
Expand Down
Loading
Loading