7 Commits

Author SHA1 Message Date
k3nny 8c3605ed52 feat(cli): colorized, columnized text output with line:col locations
Replace the per-line fmt.Println loop with writeTextFindings() in
cmd/glint/output.go. The new renderer:

- Aligns all findings into four space-separated columns: location,
  rule ID, severity, message — widths computed from the full finding
  set so all lines are flush
- Colors severity words when stdout is a TTY and NO_COLOR is not set:
  red+bold for "error", orange+bold for "warning"; location dimmed;
  rule ID bold
- Formats location as file:line:col when column is known, file:line
  otherwise, falling back to just file

To populate column numbers, add Column int to model.Job (set from
keyNode.Column in the YAML parser) and Finding.Column (set during
the checkJob source-location attachment pass and in the ten cross-job
check sites that explicitly set Line: job.Line).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 22:13:52 +02:00
k3nny 522c637b75 fix(model): reject null/empty YAML mapping keys in ParseBytes
ci / vet, staticcheck, test, build (push) Failing after 2m43s
A bare '?' in YAML is an explicit-key indicator for a null key, which
produced a job with an empty name (p.Jobs[""]) — a parser invariant
violation caught by FuzzParseBytes.

ParseBytes now returns an error when keyNode.Value is empty.
Failing corpus entry retained as a seed so CI exercises this path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 23:43:40 +02:00
k3nny 02d8e63a98 feat(cli): .glint.yml config and inline suppression comments
ci / vet, staticcheck, test, build (push) Successful in 2m25s
release / Build and publish release (push) Successful in 1m24s
Adds project-level configuration and per-job suppression directives:

.glint.yml (searched from pipeline dir up to the git root):
- ignore: [GL007, GL032] — suppress rules globally for the project
- severity: {GL004: warning} — override rule severity (error/warning/ignore)
- stages: [quality] — extra stages beyond the pipeline's stages: block
- token: / url: / cache_dir: — defaults for flags; lower priority than
  CLI flags and environment variables

Inline suppression (# glint: ignore):
- Place "# glint: ignore GL007" immediately before a job definition to
  suppress that rule for the specific job only
- Multiple rules: "# glint: ignore GL007, GL032" (comma or space separated)
- Wildcard: "# glint: ignore all" suppresses every finding for the job
- Suppressions are scoped to the annotated job; pipeline-level findings
  are unaffected
- Parsed from yaml.Node head/line comments in the first parse pass;
  stored in Pipeline.Suppressions (root file only, not includes)

New packages: internal/config (Load, walk-up search, .git boundary stop)
New files: cmd/glint/filter.go (applyConfig, isSuppressed helpers)
Tests: config_test.go, parser_suppress_test.go, filter_test.go
Validate fixtures: testdata/config_ignored/, config_severity/, config_suppress/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 10:23:33 +02:00
k3nny 1339ab4149 fix(linter): 🐛 yaml parser with escape in regex
ci / vet, staticcheck, test, build (push) Successful in 1m54s
release / Build and publish release (push) Successful in 1m10s
2026-06-12 01:04:35 +02:00
k3nny a303f63a5e feat(linter): add file/line to findings; downgrade extends missing-script to warning
Every finding now carries the source file and exact line number of the job
key in its YAML file. Format: [ERROR] job "name" (file.yml:12): message.

Pipeline-level findings (workflow rules, no stages) reference p.SourceFile.
Cross-file include jobs (local, project, component) carry the include source
as their File, set via Pipeline.SetJobOrigin after each ParseBytes call in
the resolver.

Line numbers come from the yaml.Node key node (exact job-name line) in a
new document-level first pass in ParseBytes, replacing the previous
map[string]yaml.Node approach which only gave value-node lines.

Also: jobs that declare extends: but have no script after resolution now
emit WARNING instead of ERROR. The script may come from a base in a remote
include that was not fetched (no token, offline), making the error a false
positive in common project setups.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 21:24:18 +02:00
k3nny ff0d9b51f3 feat(gitlab-sim): 🚀 ajout graph 2026-06-07 20:13:03 +02:00
k3nny e2334ec12d feat(gitlab-sim): first commit 2026-06-05 01:29:07 +02:00