{"id":49723541,"url":"https://github.com/dollarlint/dollarlint","last_synced_at":"2026-05-12T06:00:47.225Z","repository":{"id":356639666,"uuid":"1231499217","full_name":"dollarlint/dollarlint","owner":"dollarlint","description":"$schema validation for every JSON, YAML, \u0026 TOML file you've got","archived":false,"fork":false,"pushed_at":"2026-05-12T05:20:42.000Z","size":8100,"stargazers_count":0,"open_issues_count":12,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-12T06:00:21.023Z","etag":null,"topics":["cli","go","json-schema","jsonc","toml","validation","yaml"],"latest_commit_sha":null,"homepage":"https://dollarlint.dev","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dollarlint.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-07T02:45:04.000Z","updated_at":"2026-05-12T04:16:01.000Z","dependencies_parsed_at":null,"dependency_job_id":"0aa0ba9b-3b4c-48ad-b86b-92229a93cd97","html_url":"https://github.com/dollarlint/dollarlint","commit_stats":null,"previous_names":["dollarlint/dollarlint"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/dollarlint/dollarlint","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dollarlint%2Fdollarlint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dollarlint%2Fdollarlint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dollarlint%2Fdollarlint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dollarlint%2Fdollarlint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dollarlint","download_url":"https://codeload.github.com/dollarlint/dollarlint/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dollarlint%2Fdollarlint/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32926039,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-11T17:09:15.040Z","status":"online","status_checked_at":"2026-05-12T02:00:06.338Z","response_time":102,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","go","json-schema","jsonc","toml","validation","yaml"],"created_at":"2026-05-09T03:05:26.918Z","updated_at":"2026-05-12T06:00:47.216Z","avatar_url":"https://github.com/dollarlint.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"docs/public/logo.svg\" alt=\"DollarLint logo\" height=\"58\"\u003e\n\n# DollarLint\n\nDollarLint validates JSON (including JSONC, JSON5, JSON Lines), YAML, and TOML files against JSON Schemas.\n\n## Install\n\nWith Homebrew:\n\n```sh\nbrew install --cask dollarlint/tap/dollarlint\n```\n\nWith npm:\n\n```sh\nnpm install -g dollarlint\n```\n\nWith Go:\n\n```sh\ngo install github.com/dollarlint/dollarlint/cmd/dollarlint@latest\n```\n\nTo build from a local checkout:\n\n```sh\ngo build -o bin/dollarlint ./cmd/dollarlint\n./bin/dollarlint validate .\n```\n\n## GitHub Action\n\nRun DollarLint in GitHub Actions by pinning the action to the release tag you\nwant:\n\n```yaml\nname: DollarLint\n\non:\n  pull_request:\n  push:\n    branches: [main]\n\npermissions:\n  contents: read\n\njobs:\n  dollarlint:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dollarlint/dollarlint@vX.Y.Z\n        with:\n          path: .\n```\n\nThe action installs the matching DollarLint release archive for the runner,\nverifies it against `checksums.txt`, and runs `dollarlint validate`.\n\nTo upload SARIF results to GitHub code scanning:\n\n```yaml\npermissions:\n  contents: read\n  security-events: write\n\nsteps:\n  - uses: actions/checkout@v6\n  - uses: dollarlint/dollarlint@vX.Y.Z\n    with:\n      upload-sarif: true\n```\n\nUse `args` for additional validation flags, one argument per line:\n\n```yaml\n- uses: dollarlint/dollarlint@vX.Y.Z\n  with:\n    path: .\n    args: |\n      --catalogs\n      --catalog-failure=error\n```\n\n## Quick start\n\n```sh\ndollarlint init\ndollarlint validate .\n```\n\n`dollarlint init` creates a starter `.dollarlint.toml` in the current directory. It is safe by default and will not overwrite an existing file unless you confirm or pass `--force`.\n\n## Common commands\n\n### Initialize configuration\n\n```sh\ndollarlint init\ndollarlint init ./packages/api --catalogs\ndollarlint init --output ./packages/api/.dollarlint.toml\ndollarlint init --defaults --catalogs\n```\n\n### Validate files\n\n```sh\ndollarlint validate .\ndollarlint validate ./config --locations\ndollarlint validate ./config --verbose\ndollarlint validate ./config --format json\ndollarlint validate ./config --format sarif --output dollarlint.sarif\ndollarlint validate . --include '**/*.yaml' --schema 'settings/*.toml=./schemas/settings.schema.json'\ndollarlint validate . --catalogs\ndollarlint validate . --catalogs --catalog-failure error\n```\n\nUse `dollarlint validate \u003cpath\u003e` for all validation runs. Bare paths are not accepted.\n\n### Inspect schema associations\n\n```sh\ndollarlint inspect .\ndollarlint inspect . --catalogs\ndollarlint inspect . --format json\n```\n\n`dollarlint inspect` lists every discovered file, the schema DollarLint would associate with it, and the reason for that association. Files without a schema are shown as `schema: none`; catalog decisions include the same explainable `schemaMatch` metadata and suggested config snippets as validation output.\n\nExit codes:\n\n- `0`: no non-ignored issues\n- `1`: validation, schema loading, coverage, or parsing issues were found\n- `2`: CLI/configuration error\n\n## Schema declarations\n\nSupported in-file conventions:\n\n- JSON: root `$schema`, for example `{\"$schema\":\"./schema.json\"}`\n- JSONC/JSON5: root `$schema`, using the same convention after comments and JSON5 syntax are normalized\n- YAML: `# yaml-language-server: $schema=./schema.json`\n- YAML: root `$schema`\n- TOML: Taplo/Even Better TOML directive `#:schema ./schema.json`\n- TOML: root `\"$schema\" = \"./schema.json\"`\n\nJSON Lines files (`.jsonl` and `.ndjson`) are validated one non-empty line at a time. Because the file has no single root object, associate a schema through config, the `--schema` flag, or a catalog match.\n\nConfig-level schema associations can validate files that do not declare a schema themselves.\n\n## Configuration\n\nDollarLint configuration is TOML only. For each run, the CLI looks for one `.dollarlint.toml` in the target root, or beside an explicitly passed file. By default, that one config applies to the whole run. Set `configs.mode = \"nearest\"` in the root config to let nested `.dollarlint.toml` files apply to their own subtrees. A nested config inherits only when it declares `extends`.\n\nExample:\n\n```toml\nversion = 1\n\n[configs]\nmode = \"single\"\n\n[discovery]\nexclude = [\"generated/**\"]\nuseDefaultExcludes = true\nrespectGitIgnore = true\nforceExclude = false\nfollowSymlinks = false\n\n[parsing.json]\nmode = \"auto\"\n\n[schemas]\nmaxDepth = 8\nconcurrency = 8\nrequireCoverage = false\n\n[schemas.optimizations]\nenabled = true\n\n[schemas.optimizations.azure]\npruneResources = true\n\n[schemas.fetch]\nenabled = true\ncache = true\ntimeout = \"10s\"\nretries = 2\nretryMinWait = \"250ms\"\nretryMaxWait = \"2s\"\nallowedDomains = [\"*.schemastore.org\", \"www.rubyschema.org\", \"raw.githubusercontent.com\"]\nblockedDomains = [\"untrusted.example.com\"]\n\n[schemas.compile]\ntimeout = \"30s\"\n\n[schemas.catalogs]\nenabled = false\nfailure = \"warn\"\nmatch = \"auto\"\n\n[[schemas.catalogs.sources]]\nname = \"schemastore\"\nformat = \"schemastore\"\nurl = \"https://www.schemastore.org/api/json/catalog.json\"\nenabled = true\n\n[[schemas.catalogs.sources]]\nname = \"rubyschema\"\nformat = \"rubyschema\"\nenabled = true\n\n[[schemas.catalogs.ignore]]\nfile = \"data/tasks.json\"\nreason = \"application data, not a tool config\"\n\n[[schemas.associations]]\nfile = \"settings/*.toml\"\nschema = \"./schemas/settings.schema.json\"\n\n[[ignore]]\nfile = \"fixtures/*.json\"\nkeyword = \"required\"\nproperty = \"legacyName\"\nreason = \"legacy fixture kept for compatibility\"\n\n[output]\nshowSkipped = false\nverbose = false\nquiet = false\nlocations = false\nbranchErrors = \"best\"\nissueHints = \"auto\"\n```\n\nOutput format and artifact location are run-time options, not persistent config. Use `--format text|json|sarif` and `--output \u003cpath\u003e` on `dollarlint validate` when you need machine-readable output.\n\n### Discovery defaults\n\nIf `discovery.include` is unset, DollarLint discovers JSON, JSONC, JSON5, JSON Lines (`.jsonl` and `.ndjson`), YAML, YML, and TOML files at any depth.\n\n- Set `discovery.include` only when you want to replace the default file set.\n- Set `discovery.include = []` only when you intentionally want to discover no files from config.\n- A glob without a slash matches basenames at any depth (`*.json` matches `package.json` and `config/settings.json`).\n- `useDefaultExcludes = true` skips common dependency, generated, cache, build, temp, and VCS directories (`node_modules`, `vendor`, `dist`, `build`, `.build`, `DerivedData`, `SourcePackages/checkouts`, `.git`, `.venv`, `.cache`).\n- `discovery.exclude` adds project-specific excludes on top of defaults.\n- `respectGitIgnore = true` applies `.gitignore` patterns during directory discovery, including nested `.gitignore` files as the walk descends.\n- `forceExclude = true` also applies excludes to explicitly passed files.\n\nConfig-authored discovery, association, and ignore globs are relative to the directory containing `.dollarlint.toml`. CLI globs such as `--include`, `--exclude`, and `--schema` are relative to the validation root. Relative schema and local catalog paths in config are also resolved from the config file's directory.\n\n### Nested configs and extends\n\nUse `extends` when a config should inherit another config:\n\n```toml\nextends = \"../../.dollarlint.toml\"\n```\n\nUse nearest mode in the root config when a parent-directory run should apply nested configs:\n\n```toml\n[configs]\nmode = \"nearest\"\n```\n\nIn nearest mode, each file uses the closest `.dollarlint.toml` at or above its directory. A nested config does not implicitly inherit parent settings; add `extends` when you want shared defaults. Passing `--config` uses that explicit config for the whole run and suppresses nested config discovery.\n\n### JSON parsing\n\n`parsing.json.mode = \"auto\"` is the default. `.json` files are parsed as strict JSON first, then retried as JSONC when strict parsing fails, so comments and trailing commas work in projects whose existing tools accept them.\n\n- Use `\"strict\"` to parse every `.json` file as standard JSON.\n- Use `\"jsonc\"` to allow JSONC syntax in every `.json` file.\n- Files ending in `.jsonc` always use JSONC parsing.\n\n### Remote schema fetching\n\nRemote `http(s)` schema fetching is enabled by default, and successful schemas/catalogs are cached on disk.\n\n- Set `schemas.fetch.cache = false` or pass `--no-schema-cache` to disable caching.\n- Transient network failures (`408`, `425`, `429`, retryable `5xx`) are retried with bounded backoff.\n- `schemas.fetch.allowedDomains` restricts allowed hosts.\n- `schemas.fetch.blockedDomains` denies hosts even if they otherwise match the allowlist.\n- Leave `allowedDomains` empty to allow any remote schema host.\n- For SchemaStore, prefer `*.schemastore.org` or include both `www.schemastore.org` and `json.schemastore.org`.\n- For RubySchema, include `www.rubyschema.org`.\n\n### Catalog matching and coverage\n\nWhen `schemas.catalogs.enabled = true`, files without explicit schemas can match by filename using the built-in SchemaStore and RubySchema catalog sources, a local SchemaStore-shaped catalog, or additional sources. The default `schemas.catalogs.match = \"auto\"` skips low-confidence generic bare filename matches such as `tasks.json`; use `\"all\"` when you want every catalog filename match applied.\n\nWhen the built-in SchemaStore source is enabled, DollarLint layers on a small set of curated filename associations for known catalog gaps and drift. Today that includes Rust's `rustfmt.toml` / `.rustfmt.toml`, `release-plz.toml` / `.release-plz.toml`, and .NET's `launchSettings.json` / `Properties/launchSettings.json`.\n\nThe built-in RubySchema source covers common Ruby and Rails project configs such as RuboCop, Standard, Rails `config/database.yml`, Sidekiq, Shoryuken, Packwerk, i18n, Mongoid, Kamal, and related monitoring configs. Ambiguous Ruby/Rails filenames require nearby project evidence, such as `config/application.rb`, `bin/rails`, `Gemfile`, `Gemfile.lock`, `.ruby-version`, or Packwerk markers.\n\nFor important config files that DollarLint recognizes but cannot currently validate from a built-in or catalog schema, JSON output includes `schemaGap` context and skipped-file text explains the known gap. Examples include `netlify.toml`, `.cargo/config.toml`, `.terraform-docs.yml`, and `.asf.yaml`.\n\nCatalog matches are explainable in JSON output as `schemaMatch` and in text hints for catalog-sourced issues. DollarLint reports the catalog `fileMatch` pattern, confidence, why it matched or skipped, and a suggested config rule. If a catalog match is correct, add the suggested `[[schemas.associations]]` entry to make it explicit. If a file should never be inferred from catalogs, add:\n\n```toml\n[[schemas.catalogs.ignore]]\nfile = \"data/tasks.json\"\nreason = \"application data, not a tool config\"\n```\n\nPrecedence is:\n1. in-file schema declaration\n2. config association\n3. DollarLint's built-in `.dollarlint.toml` association\n4. catalog match\n5. skipped\n\nSet `schemas.requireCoverage = true` to fail the run when any discovered included file is not covered by one of those sources.\n\nDollarLint also validates discovered `.dollarlint.toml` files against its embedded config schema. You can override that with an in-file schema declaration or a config association for `.dollarlint.toml`.\n\nCatalog failures are separate from validation issues. With `schemas.catalogs.failure = \"warn\"` (default), DollarLint records a warning, skips catalog inference or catalog-inferred validation, still validates explicit/configured schemas, and exits `0` unless validation issues exist. Use `\"error\"` to fail with exit `2`, or `\"skip\"` for a silent fallback. Files with explicit in-file schemas still report schema load or compile failures as issues.\n\nKnown JSON Schema metaschemas are handled by the validator and are not pre-fetched as ordinary schema dependencies.\n\n### Azure optimization\n\nAzure Resource Manager deployment schemas from `schema.management.azure.com` are pruned to the resource provider schemas used by the template before compilation. This avoids compiling the full Azure provider catalog for typical ARM templates.\n\n- Set `schemas.optimizations.azure.pruneResources = false` to disable Azure pruning.\n- Set `schemas.optimizations.enabled = false` to disable all schema optimizations.\n\n## Examples\n\nThe `examples/` directory includes a small local schema demo, a nested-config demo, a `examples/schemastore/` suite that validates common config files against remote schemas from `https://www.schemastore.org`, and Azure ARM deployment templates that exercise remote schema fetching plus ARM resource pruning.\n\n```sh\ndollarlint validate ./examples/nested-configs --locations\ndollarlint validate ./examples/schemastore --locations\ndollarlint validate ./examples/azure --locations\n```\n\n## Text output\n\nDefault text output is grouped by file:\n\n```text\ndollarlint found 2 validation issues in 1 file after 47ms\n\nsettings.json\n  /name   type      expected string, received number\n  /count  minimum   must be \u003e= 1\n\nSummary: 4 discovered, 3 validated, 1 skipped, 2 validation issues in 47ms\n```\n\nUse `--locations` to opt into line/column source mapping for text output. JSON and SARIF request source mapping automatically.\n\n```text\nsettings.json\n  3:11  type      expected string, received number  /name\n  4:12  minimum   must be \u003e= 1   /count\n```\n\nUse `--verbose` to show schema URI and keyword metadata under each issue. Use `--quiet` for terse success output.\nUse `--show-skipped` to show skipped files grouped by reason, class, and coverage signal. Large low-signal groups such as fixtures, lockfiles, and data files are summarized in text output with a count; `--format json` keeps every skipped file.\nSet `output.branchErrors = \"all\"` when you need every failed `oneOf`/`anyOf` branch leaf for schema debugging; the default `\"best\"` reports the closest matching branch.\nIssue hints are enabled by default with `output.issueHints = \"auto\"`. Set `\"off\"` to show raw issues without curated hints, or `\"verbose\"` to include hint rule IDs, confidence, and source links in text output.\n\nJSON output (`--format json`) includes a top-level `$schema` declaration, `formatVersion`, relative `path` fields, root-relative local schemas, active findings in `issues`, ignored findings in `ignoredIssues`, always-present arrays, per-issue `category`, structured `issueHint` metadata when a hint applies, structured warnings, skip classification fields on skipped files, and numeric `summary.durationNanos`. External catalog and remote schema compile failures are reported as grouped schema-source warnings with affected files marked skipped. The output schema is published in `schemas/dollarlint-result.schema.json`.\n\nUse `--format bundle` when you need one artifact that captures every renderer from the same validation run. Bundle output is JSON with `json`, `sarif`, and `styled` keys; `styled` includes the normal terminal text as both ANSI and plain strings, plus the text-output options used to render it. If skipped-file text was summarized, `styled.truncated` is `true` while the `json` payload still contains full detail.\n\nText output uses subtle terminal styling when color is available and stays plain for machine-readable formats such as `--format json`, `--format sarif`, and `--format bundle`.\n\n## SARIF\n\nUse `--format sarif` to emit SARIF 2.1.0 for GitHub code scanning and similar tools. Use `--output` to write the SARIF artifact directly:\n\n```sh\ndollarlint validate . --format sarif --output dollarlint.sarif\n```\n\nDollarLint builds source-location maps for JSON and SARIF runs, and for text output when `--locations` is requested. Source locations are best-effort:\n\n- JSON-family positions are derived from a token walk over the source.\n- YAML positions come from `yaml.Node` line/column metadata.\n- TOML positions come from a conservative line scanner for common keys, tables, arrays, and inline tables.\n\nWhen a validation issue points to something missing, such as a `required` property, SARIF falls back to the nearest parent object location. If source mapping fails for any reason, validation still succeeds and SARIF falls back to file-level results.\n\n## Development\n\n```sh\ngo test ./...\ngo test -coverprofile=coverage.out ./internal/engine\ngo tool cover -func=coverage.out\n```\n\nMost implementation lives in `internal/engine`, with CLI wiring in `internal/cli`, so future integrations such as `serve`, LSP, and MCP can share the same validation engine without expanding the public Go API accidentally.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdollarlint%2Fdollarlint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdollarlint%2Fdollarlint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdollarlint%2Fdollarlint/lists"}