# sanctuary-scripts Shell scripts used in multiple Sanctuary projects. Many scripts are also compatible with non-Sanctuary projects. Each script is referenced in the `"bin"` field of __package.json__, and symlink names are `sanctuary-`-prefixed to avoid collisions. To use `generate-readme`, for example, one would use the path __node\_modules/.bin/sanctuary-generate-readme__ (or simply __sanctuary-generate-readme__ when using npm scripts). ## Installation 1. Add `sanctuary-scripts` to `"devDependencies"` in __package.json__. 2. Define the following `"scripts"` in __package.json__: ```json { "scripts": { "doctest": "sanctuary-doctest", "lint": "sanctuary-lint", "release": "sanctuary-release", "test": "npm run lint && sanctuary-test && npm run doctest" } } ``` 3. Add a file named __.config__ in the project's root directory, with suitable `repo-owner` and `repo-name` values. For example: ```text repo-owner = sanctuary-js repo-name = sanctuary-type-classes ``` 4. Add a file named __.eslintrc.json__ in the project's root directory, with the following JSON configuration: ```json { "root": true, "extends": ["./node_modules/sanctuary-style/eslint.json"] } ``` ## Usage ### `npm test` Runs [`lint`][], [`test`][], and [`doctest`][]. ### `npm run lint` Runs [`lint`][] only. ### `npm run doctest` Runs [`doctest`][] only. ### `npm run release <increment>` Runs [`release`][] with the specified increment (`major`, `minor`, `patch`, `premajor`, `preminor`, `prepatch`, or `prerelease`). ## Configuration There are two layers of configuration available: [variables][] and [custom scripts][]. ### Variables Certain variables may be specified in a file named __.config__ in the project's root directory. Each line in the file should be a `${name} = ${value}` pair. For example: repo-owner = sanctuary-js repo-name = sanctuary-type-classes Many variables have default values and are therefore optional. | Variable name | Default value | Description | | ----------------------------- | --------------------- | ----------------------------------------------------------------------------- | | `repo-owner` | | The name of the GitHub user or organization who owns the repository. | | `repo-name` | | The name of the GitHub repository. | | `default-branch` | `main` | The name of the repository's default branch. | | `min-branch-coverage` | `100` | The minimum acceptable branch coverage (as a percentage). | | `author-name` | `Sanctuary` | The name of the individual or group to whom copyright should be attributed. | | `contributing-file` | `CONTRIBUTING.md` | The name of the CONTRIBUTING file. | | `license-file` | `LICENSE` | The name of the licence file. | | `source-files` | `index.js` | Space-separated list of filenames. Globbing is supported (with `globstar`). | | `readme-source-files` | `index.js` | Space-separated list of filenames. Globbing is supported (with `globstar`). | | `test-files` | `test/**/*.js` | Space-separated list of filenames. Globbing is supported (with `globstar`). | | `heading-level` | `4` | The `<h[1-6]>` level of headings transcribed from `heading-prefix` comments. | | `heading-prefix` | `#` | The character which follows `//` to signify a heading to transcribe. | | `comment-prefix` | `.` | The character which follows `//` to signify documentation to transcribe. | | `opening-delimiter` | `` ```javascript `` | The opening delimiter of doctest blocks in the source files. | | `closing-delimiter` | `` ``` `` | The closing delimiter of doctest blocks in the source files. | | `module-type` | `esm` | The module system doctest should use (`amd`, `commonjs`, or `esm`). | | `version-tag-prefix` | `v` | The prefix of annotated version tags (`version-tag-prefix =` for no prefix). | ### Custom scripts Variables do not always provide sufficient control over a script's behaviour, so one can provide a custom script to be used in place of the default script. Custom scripts live in the __scripts__ subdirectory of the project's root directory, and their names correspond to those of the scripts they replace (without `sanctuary-` prefixes). To augment rather than override (or disable) the default behaviour, have the custom script run the default script. ## Scripts ### `check-required-files` Asserts that the project contains important files such as a licence file. Configurable via [variables][] (`contributing-file`, `license-file`). ### `doctest` Runs [`doctest`↗︎][] with suitable `--module`, `--prefix`, `--opening-delimiter`, and `--closing-delimiter` values. Configurable via [variables][] (`source-files`, `comment-prefix`, `opening-delimiter`, `closing-delimiter`, `module-type`). ### `generate-readme` Runs [`transcribe`↗︎][] then performs the following replacements to produce a Markdown readme: - `v:${owner}/${name}` → `https://github.com/${owner}/${name}/tree/v${version}` - `V:${owner}/${name}` → `https://github.com/${owner}/${name}/tree/${version}` - `v:${owner}/${name}#${ident}` → `https://github.com/${owner}/${name}/tree/v${version}#${ident}` - `V:${owner}/${name}#${ident}` → `https://github.com/${owner}/${name}/tree/${version}#${ident}` `${version}` comes from either the `"dependencies"` field or the `"devDependencies"` field in __package.json__. This necessitates that the dependency's version be specified exactly (`"1.2.3"` rather than `"1.2.x"`, for example). Configurable via [variables][] (`repo-owner`, `repo-name`, `readme-source-files`, `heading-level`, `heading-prefix`, `comment-prefix`, `version-tag-prefix`). ### `lint` Runs the following linters: - [`check-required-files`][] - [`eslint`↗︎][] - [`lint-package-json`][] - [`lint-commit-messages`][] Configurable via [variables][] (`source-files`, `test-files`, and those respected by the aforementioned linters). ### `lint-commit-messages` Asserts that none of the commits on the current branch but not on the default branch has a summary which exceeds 72 characters. Asserts that the current branch name is short enough to appear in a merge commit without the commit summary exceeding 72 characters. Configurable via [variables][] (`default-branch`). ### `lint-json` Asserts that the specified JSON files exist and are neatly formatted. ### `lint-package-json` Asserts that __package.json__ exists and contains important fields with suitable values. Configurable via [variables][] (`repo-owner`, `repo-name`). ### `prepublish` Runs [`update-copyright-year`][] and [`generate-readme`][], and marks (via `git add`) the licence file and readme for inclusion in the release commit. Configurable via [variables][] (`license-file`). :warning: _This script is intended to be run indirectly via [`release`][]._ ### `release` Runs [`xyz`↗︎][] to publish a new version of the package. `$1` must be a valid increment: `major`, `minor`, `patch`, `premajor`, `preminor`, `prepatch`, or `prerelease`. Configurable via [variables][] (`repo-owner`, `repo-name`, `default-branch`, `version-tag-prefix`, and those respected by [`prepublish`][]). ### `test` Runs [`oletus`↗︎][] via [`c8`↗︎][] to run the project's test suite and assert that it satisfies the project's coverage requirements. Configurable via [variables][] (`min-branch-coverage`, `test-files`). ### `update-copyright-year` Replaces the copyright year in the licence file with the year of the project's most recently authored commit on the current branch. Assumes that the licence file contains `Copyright (c) <year> <author-name>`. Configurable via [variables][] (`author-name`, `license-file`). [`check-required-files`]: #check-required-files [`doctest`]: #doctest [`generate-readme`]: #generate-readme [`lint`]: #lint [`lint-commit-messages`]: #lint-commit-messages [`lint-package-json`]: #lint-package-json [`prepublish`]: #prepublish [`release`]: #release [`test`]: #test [`update-copyright-year`]: #update-copyright-year [custom scripts]: #custom-scripts [variables]: #variables [`c8`↗︎]: https://github.com/bcoe/c8 [`doctest`↗︎]: https://github.com/davidchambers/doctest [`eslint`↗︎]: https://eslint.org/ [`oletus`↗︎]: https://github.com/bearror/oletus [`transcribe`↗︎]: https://github.com/plaid/transcribe [`xyz`↗︎]: https://github.com/davidchambers/xyz