{"id":18266283,"url":"https://github.com/ssube/salty-dog","last_synced_at":"2025-04-04T21:32:38.203Z","repository":{"id":37335003,"uuid":"192132274","full_name":"ssube/salty-dog","owner":"ssube","description":"Rule-based JSON/YAML validator using JSON schemas","archived":false,"fork":false,"pushed_at":"2024-04-27T19:00:05.000Z","size":2892,"stargazers_count":12,"open_issues_count":13,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-10-03T01:18:36.829Z","etag":null,"topics":["json","json-lint","json-schema","json-validator","jsonpath","lint","validation","yaml","yaml-lint","yaml-validator"],"latest_commit_sha":null,"homepage":"https://ssube.github.io/salty-dog/","language":"TypeScript","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/ssube.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"docs/roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-15T23:28:20.000Z","updated_at":"2024-03-07T14:44:46.000Z","dependencies_parsed_at":"2023-02-04T11:16:01.620Z","dependency_job_id":"d28be450-7ce1-4f68-94af-5c8143ef0eba","html_url":"https://github.com/ssube/salty-dog","commit_stats":{"total_commits":1550,"total_committers":6,"mean_commits":258.3333333333333,"dds":0.552258064516129,"last_synced_commit":"584a7062c1b3445575a5d077b004d8356ebe9a46"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssube%2Fsalty-dog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssube%2Fsalty-dog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssube%2Fsalty-dog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssube%2Fsalty-dog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ssube","download_url":"https://codeload.github.com/ssube/salty-dog/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223159812,"owners_count":17097534,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["json","json-lint","json-schema","json-validator","jsonpath","lint","validation","yaml","yaml-lint","yaml-validator"],"created_at":"2024-11-05T11:22:44.758Z","updated_at":"2024-11-05T11:22:46.070Z","avatar_url":"https://github.com/ssube.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# Salty Dog\n\n`salty-dog` is a tool to validate JSON and YAML data using JSON schema rules. It can filter elements and validate\nselect parts of the document, supports multiple documents in the same stream or file, and can insert defaults during\nvalidation.\n\n[Check out the getting started guide](./docs/getting-started.md).\n\n## Contents\n\n- [Salty Dog](#salty-dog)\n  - [Contents](#contents)\n  - [Status](#status)\n  - [Releases](#releases)\n  - [Build](#build)\n  - [Usage](#usage)\n    - [Using The Container](#using-the-container)\n    - [Using The Package](#using-the-package)\n      - [Project Package](#project-package)\n      - [Global Package](#global-package)\n    - [Usage Modes](#usage-modes)\n      - [Check Mode](#check-mode)\n      - [Fix Mode](#fix-mode)\n        - [Default Values](#default-values)\n        - [Coercing Values](#coercing-values)\n      - [List Mode](#list-mode)\n    - [Formatting Logs](#formatting-logs)\n  - [Rules](#rules)\n    - [Loading Rule Sources](#loading-rule-sources)\n    - [Using Rule Tags](#using-rule-tags)\n    - [Validating Rules](#validating-rules)\n  - [License](#license)\n\n## Status\n\n[![Pipeline status](https://img.shields.io/gitlab/pipeline/ssube/salty-dog.svg?gitlab_url=https%3A%2F%2Fgit.apextoaster.com\u0026logo=gitlab)](https://git.apextoaster.com/ssube/salty-dog/commits/master)\n[![MIT license](https://img.shields.io/github/license/ssube/salty-dog.svg)](https://github.com/ssube/salty-dog/blob/master/LICENSE.md)\n[![Renovate badge](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com)\n[![Known vulnerabilities](https://snyk.io/test/github/ssube/salty-dog/badge.svg)](https://snyk.io/test/github/ssube/salty-dog)\n\n[![Open bug count](https://img.shields.io/github/issues-raw/ssube/salty-dog/type-bug.svg)](https://github.com/ssube/salty-dog/issues?q=is%3Aopen+is%3Aissue+label%3Atype%2Fbug)\n[![Open issue count](https://img.shields.io/github/issues-raw/ssube/salty-dog.svg)](https://github.com/ssube/salty-dog/issues?q=is%3Aopen+is%3Aissue)\n[![Closed issue count](https://img.shields.io/github/issues-closed-raw/ssube/salty-dog.svg)](https://github.com/ssube/salty-dog/issues?q=is%3Aissue+is%3Aclosed)\n\n[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=ssube_salty-dog\u0026metric=ncloc)](https://sonarcloud.io/dashboard?id=ssube_salty-dog)\n[![Test coverage](https://codecov.io/gh/ssube/salty-dog/branch/master/graph/badge.svg)](https://codecov.io/gh/ssube/salty-dog)\n[![Technical debt ratio](https://img.shields.io/codeclimate/tech-debt/ssube/salty-dog.svg)](https://codeclimate.com/github/ssube/salty-dog/trends/technical_debt)\n\n[![Maintainability score](https://api.codeclimate.com/v1/badges/5d4326d6f68a2fa137cd/maintainability)](https://codeclimate.com/github/ssube/salty-dog/maintainability)\n[![Quality issues](https://img.shields.io/codeclimate/issues/ssube/salty-dog.svg)](https://codeclimate.com/github/ssube/salty-dog/issues)\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fssube%2Fsalty-dog.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fssube%2Fsalty-dog?ref=badge_shield)\n\n## Releases\n\n[![github release link](https://img.shields.io/badge/github-release-blue?logo=github)](https://github.com/ssube/salty-dog/releases)\n[![github release version](https://img.shields.io/github/tag/ssube/salty-dog.svg)](https://github.com/ssube/salty-dog/releases)\n[![github commits since release](https://img.shields.io/github/commits-since/ssube/salty-dog/v0.9.2.svg)](https://github.com/ssube/salty-dog/compare/v0.9.2...master)\n\n[![npm package link](https://img.shields.io/badge/npm-package-blue?logo=npm)](https://www.npmjs.com/package/salty-dog)\n[![npm release version](https://img.shields.io/npm/v/salty-dog.svg)](https://www.npmjs.com/package/salty-dog)\n[![Typescript definitions](https://img.shields.io/npm/types/salty-dog.svg)](https://www.npmjs.com/package/salty-dog)\n\n[![docker image link](https://img.shields.io/badge/docker-image-blue?logo=docker)](https://hub.docker.com/r/ssube/salty-dog)\n[![docker image size](https://img.shields.io/docker/image-size/ssube/salty-dog?sort=semver)](https://microbadger.com/images/ssube/salty-dog:master)\n\n## Build\n\n`salty-dog` is written in Typescript and requires `make`, `node`, and `yarn` to build. It can be built locally or in\na container.\n\n[Please see the build docs](./docs/index.md#build) for more details.\n\n## Usage\n\n`salty-dog` is distributed as a docker container and an npm package.\n\nWhile the container is the preferred way of running `salty-dog`, it has one limitation: `docker run` combines\n`stdout` and `stderr`, making it impossible to separate logs and the output document. Writing either the logs or dest\nto a file works around this.\n\n### Using The Container\n\nTo run the Docker container: `docker run --rm ssube/salty-dog:master`\n\nThe latest semi-stable image is published to `ssube/salty-dog:master`. Containers are published based on both Alpine\nLinux and Debian (currently Stretch). All of the [available tags are listed here](https://hub.docker.com/r/ssube/salty-dog/tags).\n\nRules are provided in the image at `/salty-dog/rules`. To use custom rules in the container, mount them with\n`-v $(pwd)/rules:/salty-dog/rules:ro` and load them with `--rules /rules/foo.yml`.\n\nThe `ssube/salty-dog` container image can be run normally or interactively.\n\nTo validate a file or input normally:\n\n```shell\n\u003e docker run --rm ssube/salty-dog:master --help\n```\n\nYou can also launch a shell within the container, using local rules:\n\n```shell\n\u003e docker run \\\n    --rm \\\n    -it \\\n    --entrypoint bash \\\n    ssube/salty-dog:master\n```\n\n### Using The Package\n\n`salty-dog` is also published as [an npm package](https://www.npmjs.com/package/salty-dog) with a binary, so it can\nbe used as a CLI command or programmatically.\n\n#### Project Package\n\nTo install `salty-dog` for the current project:\n\n```shell\n\u003e yarn add -D salty-dog\n\u003e $(yarn bin)/salty-dog --help\n```\n\n#### Global Package\n\nIt is also possible to install `salty-dog` globally, rather than within a project. However, this is\nnot recommended.\n\n```shell\n\u003e yarn global add salty-dog\n\u003e export PATH=\"${PATH}:$(yarn global bin)\"\n\u003e salty-dog --help\n```\n\n### Usage Modes\n\n`salty-dog` can run in a few different modes: `check` mode will report errors, `fix` mode will attempt to modify the\ninput document, and `list` mode will print the active set of rules.\n\n#### Check Mode\n\nBy default, `salty-dog` will validate the structure and contents of the `--source` document. If all rules pass, the\ndocument will be printed to `--dest`.\n\n```shell\n\u003e cat examples/kubernetes-resources-pass.yml | salty-dog \\\n    --rules rules/kubernetes.yml \\\n    --tag kubernetes\n\n...\n[2019-06-15T23:53:34.223Z]  INFO: salty-dog/19839 on cerberus: all rules passed\n\n\u003e cat examples/kubernetes-resources-fail.yml | salty-dog \\\n    --rules rules/kubernetes.yml \\\n    --tag kubernetes\n\n...\n[2019-06-15T23:56:04.764Z] ERROR: salty-dog/22211 on cerberus: some rules failed (errors=1)\n\n```\n\nThe `--source` and `--dest` default to stdin and stdout, respectively, but a path may be provided:\n\n```shell\n\u003e salty-dog \\\n    --rules rules/kubernetes.yml \\\n    --tag kubernetes \\\n    --source examples/kubernetes-resources-pass.yml \\\n    --dest /tmp/kubernetes-resource.yml\n\n...\n[2019-06-15T23:53:34.223Z]  INFO: salty-dog/19839 on cerberus: all rules passed\n```\n\n#### Fix Mode\n\n`salty-dog` can also add default values to missing properties in `fix` mode. If a rule does not immediately pass\nwith the `--source` document, but defaults are provided in the schema, the defaults will be inserted before printing to\n`--dest`.\n\n```shell\n\u003e salty-dog fix \\\n    --source examples/kubernetes-resources-some.yml \\\n    --rules rules/kubernetes.yml \\\n    --tag kubernetes\n```\n\n##### Default Values\n\nProperties that appear in the schema with a `default` provided will be added to each element as it is checked. Rules\napply in order, as do their defaults.\n\n##### Coercing Values\n\nProperties that appear in the document with a different `type` than they have in the schema may be coerced, if the\nvalue is compatible with the schema type. [The full matrix of valid type coercions](https://ajv.js.org/coercion.html)\nis documented by Ajv.\n\n#### List Mode\n\n`salty-dog` can list the active set of rules, to help debug tags and inclusion. Both `--source` and `--dest` are\nignored in `list` mode.\n\n```shell\n\u003e salty-dog list \\\n    --rules rules/kubernetes.yml \\\n    --tag kubernetes\n\n...\n[2019-06-30T18:39:11.930Z]  INFO: salty-dog/26330 on cerberus: listing active rules\n    rules: [\n      {\n        \"desc\": \"resource limits are too low\",\n        \"level\": \"debug\",\n        \"name\": \"kubernetes-resources-minimum-cpu\",\n\n...\n    ]\n```\n\n### Formatting Logs\n\n`salty-dog` uses [node-bunyan](https://github.com/trentm/node-bunyan) for logging and prints structured JSON output.\nLogs can be pretty-printed by redirecting `stderr` through `bunyan` itself or `jq`, both of which are installed in\nthe `salty-dog` container:\n\n```shell\n\u003e cat resource.yml | salty-dog --rules rules/kubernetes.yml --tag kubernetes 2\u003e \u003e(bunyan)\n\n...\n[2019-06-15T23:53:34.223Z]  INFO: salty-dog/19839 on cerberus: all rules passed\n\n\u003e cat resource.yml | salty-dog --rules rules/kubernetes.yml --tag kubernetes 2\u003e \u003e(jq)\n\n...\n{\n  \"name\": \"salty-dog\",\n  \"hostname\": \"cerberus\",\n  \"pid\": 19839,\n  \"level\": 30,\n  \"msg\": \"all rules passed\",\n  \"time\": \"2019-06-15T23:53:34.223Z\",\n  \"v\": 0\n}\n```\n\nUsing `jq` allows for additional filtering and formatting. For example, `jq 'select(.level \u003e 30)'` will only print\nwarnings and errors (the minimum log level to print can be set in the configuration file).\n\nTo print the last line's message and error messages: `tail -1 | jq '[.msg, try (.errors[] | .msg)]'`\n\n```shell\n\u003e cat test/examples/kubernetes-resources-high.yml | salty-dog \\\n    --rules rules/kubernetes.yml \\\n    --tag kubernetes 2\u003e \u003e(tail -1 | jq '[.msg, try (.errors[] | .msg)]')\n\n[\n  \"all rules passed\"\n]\n\n\u003e cat test/examples/kubernetes-resources-some.yml | salty-dog \\\n    --rules rules/kubernetes.yml \\\n    --tag kubernetes 2\u003e \u003e(tail -1 | jq '[.msg, try (.errors[] | .msg)]')\n\n[\n  \"some rules failed\",\n  \".resources.limits should have required property 'memory' at $.spec.template.spec.containers[*] for kubernetes-resources\",\n  \".metadata should have required property 'labels' at $ for kubernetes-labels\"\n]\n```\n\n## Rules\n\nRules combine a jsonpath expression and JSON schema to select and validate the document.\n\nThe rule's `select` expression is used to select nodes that should be validated, which are `filter`ed, then `check`ed.\n\nThe structure of rule files and the rules within them [are documented here](docs/rules.md).\n\n### Loading Rule Sources\n\nRules can be loaded from a file, module, or path.\n\nTo load a file by name, `--rule-file foo.yml`. This will accept any extension.\n\nTo load a module, `--rule-module foo`. The required module exports [are documented here](./docs/rules.md#from-module).\n\nTo load a path, `--rule-path foo/`. This will recursively load any files matching `*.+(json|yaml|yml)`.\n\n### Using Rule Tags\n\nAll rules are disabled by default and must be enabled by name, level, or tag.\n\nTo enable a single rule by name, `--include-name foo-rule`.\n\nTo enable a group of rules by level, `--include-level warn`.\n\nTo enable a group of rules by tag, `--include-tag foo`.\n\n### Validating Rules\n\nTo validate the rules in the `rules/` directory using the meta-rules:\n\n```shell\n\u003e make test-rules\n\n...\n{\"name\":\"salty-dog\",\"hostname\":\"cerberus\",\"pid\":29403,\"level\":30,\"msg\":\"all rules passed\",\"time\":\"2019-06-16T00:56:55.132Z\",\"v\":0}\n```\n\n## License\n\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fssube%2Fsalty-dog.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fssube%2Fsalty-dog?ref=badge_large)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fssube%2Fsalty-dog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fssube%2Fsalty-dog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fssube%2Fsalty-dog/lists"}