UNPKG

standardlint

Version:
292 lines (171 loc) • 10.7 kB
# StandardLint šŸ“ ![Build Status](https://github.com/mikaelvesavuori/standardlint/workflows/main/badge.svg) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=mikaelvesavuori_standardlint&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=mikaelvesavuori_standardlint) [![CodeScene Code Health](https://codescene.io/projects/34030/status-badges/code-health)](https://codescene.io/projects/34030) [![CodeScene System Mastery](https://codescene.io/projects/34030/status-badges/system-mastery)](https://codescene.io/projects/34030) [![codecov](https://codecov.io/gh/mikaelvesavuori/standardlint/branch/main/graph/badge.svg?token=LDZV8XOA4X)](https://codecov.io/gh/mikaelvesavuori/standardlint) [![Maintainability](https://api.codeclimate.com/v1/badges/2688b07db3c43d9b18b8/maintainability)](https://codeclimate.com/github/mikaelvesavuori/standardlint/maintainability) ## Extensible standards auditing and linting tool. Nags like your mother but is probably a lot more technical. --- With StandardLint, you use _Checks_ to inform what standards you want to inspect, in effect being your standards _yardstick_: > A fact or standard by which you can judge the success or value of something. > — [Cambridge Dictionary](https://dictionary.cambridge.org/dictionary/english/standardlint) StandardLint makes it convenient and easy to set up guardrails and guidelines for development teams and making sure they follow your house conventions. The result of a run could look like this: ```text āœ… PASS: Diagrams āœ… PASS: Changelog šŸ›Žļø No custom path assigned to check "Diagrams" - Using default path "diagrams"... āš ļø WARN: Diagrams āœ… PASS: Lock files āœ… PASS: License āŒ FAIL: Code owners āŒ FAIL: Contribution information šŸ›Žļø No custom path assigned to check "IAC configuration" - Using default path "serverless.yml"... āœ… PASS: IAC configuration šŸ›Žļø No custom path assigned to check "SLOs" - Using default path "manifest.json"... āš ļø WARN: SLOs šŸ›Žļø No custom path assigned to check "Tags" - Using default path "manifest.json"... āœ… PASS: Tags šŸ›Žļø No custom path assigned to check "CI configuration" - Using default path ".github/workflows/main.yml"... āœ… PASS: CI configuration āœ… PASS: Security information šŸ›Žļø No custom path assigned to check "Service metadata" - Using default path "manifest.json"... āœ… PASS: Service metadata ``` ### Relation to projects like ESLint The majority of StandardLint checks are meant to assess the overall architecture, for example presence of certain files or documentation. While StandardLint has a few checks that inspect code (throwing errors and using `console`), the majority of such use cases are better handled with something like [ESLint](https://eslint.org). ## StandardLint GitHub Action There's a ready-to-use [StandardLint GitHub Action](https://github.com/marketplace/actions/standardlint-action) in the Marketplace if you really want the minimum hassle. Plus, you get a great visual overview of your checks! ## Usage ### Installation Install StandardLint with `npm install standardlint`. ### Configuration Before running StandardLint you need a configuration. This is a basic JSON file with the name `standardlint.json`. Place it in the root of your project. The format is: ```json { "basePath": "", "checks": [], "defaultSeverity": "" } ``` | Key | Required | Default | Example | Description | | ----------------- | -------- | --------------- | ----------------------------------------- | ----------------------------------------------------------------------- | | `basePath` | No | `.` | `./project_dir/` | Sets the base path for any file lookups. | | `ignorePaths` | No | `[]` | `["/tests/", "/src/problematic-file.ts"]` | Paths that will be ignored for some checks. Does not support globbing. | | `checks` | Yes | - | `["checkForPresenceLicense"]` | A list of checks to run, either using string or object form. | | `defaultSeverity` | No | `error` | `warn` | Sets the default severity level for any issues. | | `path` | No | Multiple values | `api/schema.yml` | Sets the exact path to a resource. Only used optionally by some checks. | #### Base path If you for some reason keep your project files "lower" than in the root where you want to do file lookups, you can add this optional argument. _It's recommended you do not change this unless you know what you are doing._ #### Ignore paths This provides the possibility to ignore certain paths. These paths will be respected and discarded by the following checks: - `checkForConsoleUsage` - `checkForPresenceTests` - `checkForThrowingPlainErrors` #### Checks Checks can be provided in string form or object form: - String format: `["checkForDefinedTags"]` - Object format: `[{ "name": "checkForPresenceContributing", "severity": "warn" }]` You need to use the object form if you want to override the overall severity level, and use the check's `severity` level. You can also combine the formats for different checks. - `["checkForDefinedTags", { "name": "checkForPresenceContributing", "severity": "warn" }]` Some checks also provide the optional `path` key. Use this when you want to override default values, for example to the location of an API schema. - `[{ "name": "checkForPresenceApiSchema", "path": "api/schema.yml" }]` #### Default severity This can be either `warn` or `error` (the default value). Using it in `error` mode means that any failure will produce an error, while the `warn` mode simply warns for any non-compliance. ### Usage #### From the command line It's super easy to use StandardLint from the CLI! Just run `npx standardlint` and it will use the configuration in your project. ##### Outputting results into a JSON file To output the results into `standardlint.results.json`, run `npx standardlint --output`. #### Importing StandardLint as a Node package You can also import and use StandardLint like a conventional Node package. It exposes a factory function to vend a new `StandardLint` instance with a `check()` method. If using it as an imported package, you will need to provide either a configuration file (for example loaded with `fs`) or the actual configuration as an object. ```ts import { createNewStandardLint } from 'standardlint'; const config = { checks: [ { name: 'checkForPresenceContributing', severity: 'warn' }, { name: 'checkForPresenceLicense', severity: 'error' } ] }; const standardLint = createNewStandardLint(config); const results = standardLint.check(); console.log(results); ``` #### Using static file trees instead of reading from disk If you want to use a static representation of paths rather than actually checking on disk, then this is possible using the `filetree` parameter. ```ts const standardlint = createNewStandardLint(config, ['path/to/file.js']); ``` ##### Outputting results into a JSON file To output the results into `standardlint.results.json`, run: ```ts const standardLint = createNewStandardLint(config); const results = standardLint.check(true); // <--- Adding true here will output the results to disk ``` ## Available checks _Service metadata definition checks assume you are using [Catalogist](https://github.com/mikaelvesavuori/catalogist) or something with the same manifest file structure._ Any check with a `default` value can be overridden using the `path` argument. ### `all` Runs all checks. ### `checkForConflictingLockfiles` Checks if there are conflicting Node package lock files (i.e. both a Yarn lock file and an NPM lock file). ### `checkForConsoleUsage` Checks if `console` is used, e.g. `console.log()` and similar. This is useful when you want to ensure a more comprehensive logging approach is used. Note that this uses a naive solution so even just a mention of console.log() (or similar) will fail this check. **Will respect `ignorePaths` options.** **Default**: `src` ### `checkForDefinedRelations` Checks if the service metadata defines system relations. **Default**: `manifest.json` ### `checkForDefinedServiceLevelObjectives` Checks if the service metadata defines Service Level Objectives. **Default**: `manifest.json` ### `checkForDefinedTags` Checks if the service metadata defines tags. **Default**: `manifest.json` ### `checkForPresenceApiSchema` Checks if there is an API schema. **Default**: `api/schema.json` ### `checkForPresenceChangelog` Checks if there is a `CHANGELOG.md` file. ### `checkForPresenceCiConfig` Checks if there is a CI/CD configuration file. **Default**: `.github/workflows/main.yml` ### `checkForPresenceCodeowners` Checks if there is a `CODEOWNERS` file. ### `checkForPresenceContributing` Checks if there is a `CONTRIBUTING.md` file. ### `checkForPresenceDiagramsFolder` Checks if there is a diagrams folder with diagram files in it. The check assumes `.drawio` files. **Default**: `diagrams` ### `checkForPresenceIacConfig` Checks if there is Infrastructure-as-Code configuration present. **Default**: `serverless.yml` ### `checkForPresenceLicense` Checks if there is a `LICENSE.md` file. ### `checkForPresenceReadme` Checks if there is a `README.md` file. ### `checkForPresenceSecurity` Checks if there is a `SECURITY.md` file. ### `checkForPresenceServiceMetadata` Checks if there a service metadata file present. **Default**: `manifest.json` ### `checkForPresenceTemplateIssues` Checks if there is a template for GitHub issues. **Default**: `.github/ISSUE_TEMPLATE/issue.md` ### `checkForPresenceTemplatePullRequests` Checks if there is a template for GitHub Pull Requests. **Default**: `.github/ISSUE_TEMPLATE/pull_request.md` ### `checkForPresenceTests` Checks if there are any tests in the provided location. This will match anything ending in `(test|spec).(ts|js)`. **Default**: `tests` **Will respect `ignorePaths` options.** ### `checkForThrowingPlainErrors` Checks if any file uses `throw Error` or `throw new Error`. This is meant to push toward the use of actual loggers, rather than plain console output. **Will respect `ignorePaths` options.** --- ## Ideas for improvements - Service metadata: Do you link to observability resources (logs/metrics/traces/dashboards etc.)? - Support for external config