https://github.com/replicatedhq/replicated-lint
YAML linting tools for Replicated applications
https://github.com/replicatedhq/replicated-lint
Last synced: 10 months ago
JSON representation
YAML linting tools for Replicated applications
- Host: GitHub
- URL: https://github.com/replicatedhq/replicated-lint
- Owner: replicatedhq
- License: mit
- Created: 2017-06-09T21:41:23.000Z (almost 9 years ago)
- Default Branch: main
- Last Pushed: 2023-07-11T00:21:40.000Z (almost 3 years ago)
- Last Synced: 2024-11-16T14:36:12.337Z (over 1 year ago)
- Language: TypeScript
- Homepage:
- Size: 1.52 MB
- Stars: 8
- Watchers: 24
- Forks: 13
- Open Issues: 27
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG
- License: LICENSE
Awesome Lists containing this project
README
# replicated-lint
[](https://circleci.com/gh/replicatedhq/replicated-lint/tree/main)
[](https://codeclimate.com/github/replicatedhq/replicated-lint)
[](https://codeclimate.com/github/replicatedhq/replicated-lint)
YAML linting tools for Replicated applications.
## Usage
Install the CLI executable with
```sh
npm install -g replicated-lint
```
Lint with `replicated-lint validate`
```sh
replicated-lint validate -f my-app.yml
```
or pipe from stdin:
```sh
cat my-app.yml | replicated-lint validate -f -
```
Results that have issues will look something like:
```typescript
{ type: 'info',
rule: 'prop-configitem-testproc-run-on-save',
message: 'If a config item\'s test_proc.run_on_save is not set to \'true\', test_proc\'s will not be checked automatically. Consider setting your test_proc\'s run_on_save to automatically validate inputs',
positions:
[ { path: 'config.1.items.2.test_proc',
start: { position: 8130, line: 325, column: 4 },
end: { position: 8322, line: 331, column: 0 } },
{ path: 'config.3.test_proc',
start: { position: 8692, line: 346, column: 2 },
end: { position: 9141, line: 365, column: 2 } } ],
links: [ 'https://www.replicated.com/docs/packaging-an-application/test-procs/' ] }
# prop-configitem-testproc-run-on-save continued from line 321
322
323 - name: phone_number
324 type: text
325 test_proc:
326 display_name: Is this a Phone Number?
327 command: regex_match
328 args:
329 - "([0-9]{3})[-]([0-9]{3})[-]([0-9]{4})$"
330 - "That doesn't seem to be a phone number!"
331 - name: auth
332 title: Authentication
333 description: Where will user accounts be provisioned
334 items:
```
### Extending the CLI with custom rules
`replicated-lint` rules can be expressed as JSON, so it is easy to add your own custom rules.
If you have a custom rule set in `no-latest.json`, you can pass it to `replicated-lint` using
```sh
cat my-app.yml | replicated-lint validate -f - --extraRules no-latest.yaml
```
`--extraRules` can be specified multiple times. An example YAML rule set might look something like
```yaml
---
- name: custom-no-latest
type: error
message: "Don't use `latest` for container versions."
test:
AnyOf:
path: components
pred:
AnyOf: containers
pred:
Eq:
path: version
value: latest
```
`replicated-lint validate` supports the following options:
```
Options:
--version Show version number [boolean]
--help Show help [boolean]
--infile, -f Input file to validate. Use "-" for stdin
[string] [default: "-"]
--threshold, -t Threshold of of issues to report
[string] [choices: "info", "warn", "error"] [default: "error"]
--extraRules, -e Path to file containing JSON definitions for additional yaml
rules. Can be specified multiple times.[array] [default: []]
--reporter, -r Output Format to use
[string] [choices: "console", "junit"] [default: "console"]
--outputDir, -o junit reporter only -- path to directory to output junit xml
reports [string] [default: "test-results"]
```
## Developing
### Installing Dependencies
We compile to ES5 and test on nodejs 7.8.0, but earlier versions of node should work as well.
```sh
npm install -g yarn
yarn
```
### Running the tests
To run the tests once
```sh
yarn test
```
To watch files and re-run tests on changes, use the `tdd` script
```sh
./tdd
```
### Before committing
Run
```sh
make project-import PROJECT=
```
Where `` is the project being updated and should be one of
- replicated-supportbundle
- replicated-entitlements
- replicated-rbac
- replicated-ship
For more up to date list check the project directory listing.
### Regenerating the documentation
`replicated-lint docs gen` will print reference documentation stdout as markdown. `yarn docs` will write it to `docs/gen.md`.
To update the docs in help center, grab everything in `replicated-lint/docs/gen.md` and paste it into `help-center/.../yaml.md`, replacing everything below ``.
## Library Usage
`replicated-lint` is designed with extensibility in mind, making it suitable for general purpose
YAML and JSON linting and policy definition
- Flexible, modular rule sets
- CLI
- Autogenerate unit tests and documentation from rule definitions
```sh
npm install --save replicated-lint
```
```typescript
import * as linter from "replicated-lint";
const yaml = `
---
replicated_api_version: 2.8.0
components:
- name: ELK
containers:
- image: getelk/search`;
const ruleViolations = linter.defaultLint(yaml);
console.log(ruleViolations); // []
```
### Custom Rule Sets
`linter.rules.all` can be substituted or extended with custom rule
definitions. A rule's `test` field should return `{ matched: true }`
when the rule is triggered by invalid JSON.
```typescript
import * as linter from "replicated-lint";
const yaml = `
---
foo:
bar: baz`;
const testSpec: any = {
Or: {
preds: [
{Eq: { path: "foo.bar", value: "baz"}},
{Eq: { path: "foo.bar", value: "boz"}},
],
}
}
const rules: linter.YAMLRule[] = [
{
name: "foo-bar-neq-baz",
message: "foo.bar can't be baz!",
test: testSpec,
type: "error",
}
];
const ruleViolations = linter.lint(yaml, { rules });
console.log(ruleViolations); /*
[{
type: "error",
positions: [{
path: "foo.bar",
start: {
position: 12,
line: 3,
column: 2,
},
end: {
position: 20,
line: 3,
column: 10,
},
}],
message: "foo.bar can't be baz!",
}]
*/
```
Register new rules with `linter.enginer.register`. Rules should implement `JSONReadable>`, usually as a static method
```typescript
import * as linter from "replicated-lint";
// rule MyRule checks if root object has property "spam" equal to "eggs"
class MyRule implements linter.Predicate {
test(obj: any) {
const matched = obj.spam !== "eggs"; // fail when spam != eggs
const paths = ["spam"]; // if matched == true, optionally include a path where a rule was violated
return { matched, paths };
}
public static fromJson(obj: any, registry: linter.engine.Registry) {
return new MyRule();
}
}
linter.engine.register(MyRule);
const testSpec: linter.Test = { MyRule: {}};
const rules: linter.YAMLRule[] = [
{
name: "spam-eq-eggs",
message: "spam must be equal to eggs!",
test: testSpec,
type: "error",
}
];
const yaml = `
---
spam: eggs`;
const ruleViolations = linter.lint(yaml, { rules });
console.log(ruleViolations); // []
```
Custom implementations of `engine.Registry` can also be passed as a third argument to `linter.lint`, otherwise a default
registry will be used.