|
| 1 | +# `eng/tools/suppressions` |
| 2 | + |
| 3 | +`@azure-tools/suppressions` is the tool that reads `suppressions.yaml` files and returns the |
| 4 | +suppressions applicable to a given tool and path. Validation tools across the |
| 5 | +`Azure/azure-rest-api-specs` repository use it to let spec authors suppress specific checks for |
| 6 | +specific files or directories. |
| 7 | + |
| 8 | +This document has two audiences: |
| 9 | + |
| 10 | +- **[Usage](#usage)** — for _users_ of the suppressions API, how to author `suppressions.yaml` |
| 11 | + files and query suppressions from the CLI or as a library. |
| 12 | +- **[Folder structure & contributing](#folder-structure--contributing)** — for _developers_ of the |
| 13 | + suppressions tool, how the folder is organized and how to make changes. |
| 14 | + |
| 15 | +## Usage |
| 16 | + |
| 17 | +### Authoring `suppressions.yaml` |
| 18 | + |
| 19 | +A `suppressions.yaml` file is a YAML array of suppression entries. When a tool checks a file or |
| 20 | +directory, `getSuppressions` walks up the directory tree from that path to the filesystem root, |
| 21 | +reads every `suppressions.yaml` it finds, and returns the entries matching the tool name and path. |
| 22 | +Suppressions are ordered by file (closest to the path first), then within each file (top first). |
| 23 | + |
| 24 | +Each entry supports the following properties: |
| 25 | + |
| 26 | +- `tool` (required) — name of the tool the suppression applies to (matched exactly). |
| 27 | +- `paths` — array of glob patterns, relative to the `suppressions.yaml` file, that the path under |
| 28 | + analysis must match. Patterns use [minimatch](https://github.com/isaacs/minimatch) syntax. |
| 29 | +- `path` — convenience for a single pattern; if present it is inserted at the start of `paths`. At |
| 30 | + least one of `path` or `paths` must be present. |
| 31 | +- `reason` (required) — human-readable explanation for the suppression. |
| 32 | +- `rules` — optional array of rule names the suppression applies to. |
| 33 | +- `sub-rules` — optional array of sub-rule names the suppression applies to. |
| 34 | +- `if` — optional string of CommonJS JavaScript, evaluated in a prepared context, that must return |
| 35 | + truthy for the suppression to apply. |
| 36 | + |
| 37 | +Example `suppressions.yaml`: |
| 38 | + |
| 39 | +```yaml |
| 40 | +- tool: TypeSpecRequirement |
| 41 | + paths: ["data-plane/Foo/stable/2023-01-01/*.json"] |
| 42 | + reason: Legacy API version predates the TypeSpec requirement. |
| 43 | + |
| 44 | +- tool: TypeSpecValidation |
| 45 | + reason: Specs added as folder structure v1, not yet converted to v2 |
| 46 | + rules: [FolderStructure] |
| 47 | + paths: [Automation.Management] |
| 48 | +``` |
| 49 | +
|
| 50 | +### Command line |
| 51 | +
|
| 52 | +Build the package (see [contributing](#folder-structure--contributing)), then query suppressions |
| 53 | +with the `get-suppressions` CLI: |
| 54 | + |
| 55 | +``` |
| 56 | +npx get-suppressions <tool-name> <path-to-file-or-directory> |
| 57 | +``` |
| 58 | +
|
| 59 | +It prints a JSON array of the suppressions (which may be empty) for the given tool that apply to the |
| 60 | +given file or directory: |
| 61 | +
|
| 62 | +``` |
| 63 | +npx get-suppressions TypeSpecRequirement specification/foo/data-plane/Foo/stable/2023-01-01/Foo.json |
| 64 | +[{"tool":"TypeSpecRequirement","paths":["data-plane/Foo/stable/2023-01-01/*.json"],"reason":"foo"}] |
| 65 | +``` |
| 66 | +
|
| 67 | +### Library |
| 68 | +
|
| 69 | +The package also exposes `getSuppressions` for programmatic use: |
| 70 | +
|
| 71 | +```ts |
| 72 | +import { getSuppressions, Suppression } from "@azure-tools/suppressions"; |
| 73 | +
|
| 74 | +const suppressions: Suppression[] = await getSuppressions( |
| 75 | + "TypeSpecRequirement", |
| 76 | + "specification/foo/data-plane/Foo/stable/2023-01-01/Foo.json", |
| 77 | +); |
| 78 | +``` |
| 79 | + |
| 80 | +`getSuppressions(tool, path)` resolves `path`, throws if it does not exist, walks up the directory |
| 81 | +tree collecting `suppressions.yaml` files, and returns the matching `Suppression[]`. |
| 82 | + |
| 83 | +## Folder structure & contributing |
| 84 | + |
| 85 | +``` |
| 86 | +eng/tools/suppressions |
| 87 | +├── cmd/ # Executable CLI entry point (exposed via package.json "bin") |
| 88 | +├── src/ # The tool source (TypeScript) |
| 89 | +├── test/ # Vitest unit + end-to-end tests and fixtures |
| 90 | +├── package.json # "bin", scripts, dependencies |
| 91 | +├── tsconfig.json # Type-checking / build config |
| 92 | +├── eslint.config.js # ESLint config |
| 93 | +└── vitest.config.ts # Test + coverage config |
| 94 | +``` |
| 95 | + |
| 96 | +### `src` |
| 97 | + |
| 98 | +- [`src/suppressions.ts`](./src/suppressions.ts) — the core implementation: `getSuppressions`, |
| 99 | + `getSuppressionsFromYaml`, the `Suppression` type, and the zod schema that validates |
| 100 | + `suppressions.yaml`. |
| 101 | +- [`src/index.ts`](./src/index.ts) — the package entry point. Exports `getSuppressions` and |
| 102 | + `Suppression`, and provides `main` for the CLI. |
| 103 | + |
| 104 | +### `cmd` |
| 105 | + |
| 106 | +CLI entry point exposed via `package.json` `"bin"`. |
| 107 | +[`cmd/get-suppressions.js`](./cmd/get-suppressions.js) backs `npx get-suppressions` by running the |
| 108 | +built `dist/src/index.js`. |
| 109 | + |
| 110 | +### `test` |
| 111 | + |
| 112 | +[Vitest](https://vitest.dev/) tests: |
| 113 | + |
| 114 | +- [`test/suppressions.test.ts`](./test/suppressions.test.ts) — unit tests for |
| 115 | + `getSuppressionsFromYaml`. |
| 116 | +- [`test/suppressions.e2e.test.ts`](./test/suppressions.e2e.test.ts) — end-to-end tests for |
| 117 | + `getSuppressions` against the fixtures under `test/e2e/`. |
| 118 | +- `test/e2e/` — sample folder trees with `suppressions.yaml` files used by the e2e tests. |
| 119 | + |
| 120 | +### Contributing |
| 121 | + |
| 122 | +When changing the tool, keep the source, tests, and this document in sync. Build first (the CLI runs |
| 123 | +from `dist/`), then add or update tests under `test/`. |
| 124 | + |
| 125 | +Useful scripts (run from `eng/tools/suppressions`): |
| 126 | + |
| 127 | +| Command | Description | |
| 128 | +| ---------------------- | --------------------------------------------------------- | |
| 129 | +| `npm run build` | Compile TypeScript to `dist/`. | |
| 130 | +| `npm test` | Run tests in watch mode (vitest). | |
| 131 | +| `npm run test:ci` | Run tests once with coverage. | |
| 132 | +| `npm run lint` | Run ESLint. | |
| 133 | +| `npm run format` | Auto-format with prettier. | |
| 134 | +| `npm run format:check` | Check formatting without writing. | |
| 135 | +| `npm run check` | Run build, lint, format check, and tests (the full gate). | |
0 commit comments