@nitra/cursor 12.3.3 → 12.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/package.json +1 -1
- package/rules/bun/bun.mdc +2 -2
- package/rules/lint/js/docs/orchestrate.md +3 -3
- package/rules/lint/js/orchestrate.mjs +22 -4
- package/rules/php/js/docs/index.md +1 -0
- package/rules/php/js/docs/lint.md +20 -0
- package/rules/php/js/lint.mjs +13 -0
- package/rules/php/php.mdc +1 -3
- package/rules/php/policy/lint_php_yml/template/lint-php.yml.snippet.yml +1 -1
- package/rules/python/policy/lint_python_yml/template/lint-python.yml.snippet.yml +1 -1
- package/rules/python/python.mdc +1 -3
- package/rules/rust/js/docs/index.md +1 -0
- package/rules/rust/js/docs/lint.md +21 -0
- package/rules/rust/js/lint.mjs +67 -0
- package/rules/rust/rust.mdc +2 -4
- package/rules/php/policy/package_json/package_json.rego +0 -16
- package/rules/php/policy/package_json/target.json +0 -4
- package/rules/php/policy/package_json/template/package.json.contains.json +0 -5
- package/rules/python/policy/package_json/package_json.rego +0 -16
- package/rules/python/policy/package_json/target.json +0 -4
- package/rules/python/policy/package_json/template/package.json.contains.json +0 -5
- package/rules/rust/policy/package_json/package_json.rego +0 -18
- package/rules/rust/policy/package_json/target.json +0 -5
- package/rules/rust/policy/package_json/template/package.json.contains.json +0 -9
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
package/rules/bun/bun.mdc
CHANGED
|
@@ -68,8 +68,8 @@ FROM oven/bun:alpine AS build-env
|
|
|
68
68
|
|
|
69
69
|
Лінт запускається через CLI **`n-cursor`**, **не** через `package.json`-скрипти:
|
|
70
70
|
|
|
71
|
-
- **`n-cursor lint --full`** — весь репо:
|
|
72
|
-
- **`n-cursor lint`** — дельта vs origin (per-file лінтери лише змінених файлів);
|
|
71
|
+
- **`n-cursor lint --full`** — весь репо: активні у `.n-cursor.json` правила (per-file + full лінтери за `meta.json#lint` scope, конформність) + `oxfmt` у кінці (fix-режим);
|
|
72
|
+
- **`n-cursor lint`** — дельта vs origin (активні у `.n-cursor.json` per-file лінтери лише змінених файлів);
|
|
73
73
|
- **`n-cursor lint <rule…>`** — конкретні правила (лінтер + конформність), напр. **`n-cursor lint ga`**.
|
|
74
74
|
|
|
75
75
|
У кореневому `package.json` **не повинно бути** `lint`/`lint-*` скриптів — єдина точка лінту — CLI `n-cursor`. У CI кожен workflow викликає **`n-cursor lint <rule> --read-only`** напряму (без обгорток).
|
|
@@ -11,12 +11,12 @@ docgen:
|
|
|
11
11
|
|
|
12
12
|
## Огляд
|
|
13
13
|
|
|
14
|
-
Модуль відповідає за визначення та виконання процесу лінтування коду.
|
|
14
|
+
Модуль відповідає за визначення та виконання процесу лінтування коду. Unscoped linter-фаза бере активні правила з `.n-cursor.json`, а `meta.json#lint` використовує лише як класифікацію scope (`per-file` або `full`). Функція `runLint` запускає перевірку обраних правил для змінених або всіх файлів репозиторію.
|
|
15
15
|
|
|
16
16
|
## Поведінка
|
|
17
17
|
|
|
18
|
-
selectLintRules вибирає і сортує ідентифікатори правил для лінтування
|
|
19
|
-
runLint запускає процес лінтування, виконуючи перевірку правил для змінених файлів або для всього репозиторію, залежно від наданих опцій, і може виконувати форматування.
|
|
18
|
+
selectLintRules вибирає і сортує ідентифікатори правил для лінтування з уже активованого списку `.n-cursor.json`, включаючи можливість включення правил, що застосовуються до всього репозиторію.
|
|
19
|
+
runLint запускає процес лінтування, виконуючи перевірку активних правил для змінених файлів або для всього репозиторію, залежно від наданих опцій, і може виконувати форматування. Scoped режим `lint <rule…>` запускає названі правила напряму та не потребує `.n-cursor.json` для linter-фази.
|
|
20
20
|
|
|
21
21
|
## Публічний API
|
|
22
22
|
|
|
@@ -8,6 +8,7 @@ import { spawnSync } from 'node:child_process'
|
|
|
8
8
|
import { parseRuleLintSpec, readRuleMetaRaw } from '../../../scripts/lib/rule-meta.mjs'
|
|
9
9
|
import { collectChangedFilesSince, resolveChangedBase } from '../../../scripts/lib/changed-files.mjs'
|
|
10
10
|
import { resolveCmd } from '../../../scripts/utils/resolve-cmd.mjs'
|
|
11
|
+
import { isRuleEnabled, readNCursorConfigLite } from '../../../scripts/lib/read-n-cursor-config-lite.mjs'
|
|
11
12
|
|
|
12
13
|
// Цей файл: npm/rules/lint/js/orchestrate.mjs → PACKAGE_ROOT = npm (чотири dirname угору).
|
|
13
14
|
const PACKAGE_ROOT = dirname(dirname(dirname(dirname(fileURLToPath(import.meta.url)))))
|
|
@@ -42,17 +43,33 @@ async function runConformance(cwd, readOnly, log, filter = []) {
|
|
|
42
43
|
* Вибирає id правил для контексту, алфавітно.
|
|
43
44
|
* @param {Record<string, {lint?: unknown}>} metaById мапа id → meta-обʼєкт
|
|
44
45
|
* @param {boolean} full `false` → лише `per-file` правила; `true` → усі (`per-file` ∪ `full`)
|
|
46
|
+
* @param {string[]} enabledRuleIds активні rule-id з `.n-cursor.json`
|
|
45
47
|
* @returns {string[]} відсортовані id
|
|
46
48
|
*/
|
|
47
|
-
export function selectLintRules(metaById, full) {
|
|
49
|
+
export function selectLintRules(metaById, full, enabledRuleIds) {
|
|
50
|
+
const enabled = new Set(enabledRuleIds)
|
|
48
51
|
const out = []
|
|
49
52
|
for (const [id, raw] of Object.entries(metaById)) {
|
|
53
|
+
if (!enabled.has(id)) continue
|
|
50
54
|
const scope = parseRuleLintSpec(raw?.lint)
|
|
51
55
|
if (scope === 'per-file' || (full && scope === 'full')) out.push(id)
|
|
52
56
|
}
|
|
53
57
|
return out.toSorted((a, b) => a.localeCompare(b))
|
|
54
58
|
}
|
|
55
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Активні правила для unscoped linter-фази. `.n-cursor.json` — єдине джерело
|
|
62
|
+
* whitelist/disable, `meta.json#lint` нижче використовується лише як scope (`per-file`/`full`).
|
|
63
|
+
* @param {Record<string, unknown>} metaById доступні bundled правила
|
|
64
|
+
* @param {string} cwd корінь
|
|
65
|
+
* @returns {Promise<string[]>} активні rule-id з конфіга, що існують у пакеті
|
|
66
|
+
*/
|
|
67
|
+
async function readEnabledLintRuleIds(metaById, cwd) {
|
|
68
|
+
const config = await readNCursorConfigLite(cwd)
|
|
69
|
+
if (!config.exists) return []
|
|
70
|
+
return Object.keys(metaById).filter(id => isRuleEnabled(config, id))
|
|
71
|
+
}
|
|
72
|
+
|
|
56
73
|
/**
|
|
57
74
|
* Зчитує meta всіх правил пакета.
|
|
58
75
|
* @param {string} rulesDir каталог rules
|
|
@@ -130,7 +147,7 @@ async function runFullConformancePhase(cwd, readOnly, log) {
|
|
|
130
147
|
* @param {(s: string) => void} log логер
|
|
131
148
|
* @returns {Promise<number>} код виходу oxfmt (0 — OK або пропущено)
|
|
132
149
|
*/
|
|
133
|
-
|
|
150
|
+
function runFormat(cwd, log) {
|
|
134
151
|
const oxfmt = resolveCmd('oxfmt')
|
|
135
152
|
if (!oxfmt) {
|
|
136
153
|
log('ℹ️ lint: oxfmt недоступний у PATH — формат-крок пропущено.\n')
|
|
@@ -201,7 +218,8 @@ export async function runLint(opts = {}) {
|
|
|
201
218
|
}
|
|
202
219
|
|
|
203
220
|
const metaById = readAllMeta(rulesDir)
|
|
204
|
-
const
|
|
221
|
+
const enabledRuleIds = await readEnabledLintRuleIds(metaById, cwd)
|
|
222
|
+
const ids = selectLintRules(metaById, full, enabledRuleIds)
|
|
205
223
|
const perFile = await runPerFileRules(ids, { rulesDir, changed, cwd, readOnly, metaById, log })
|
|
206
224
|
if (perFile.stop) return perFile.code
|
|
207
225
|
let worst = perFile.code
|
|
@@ -219,7 +237,7 @@ export async function runLint(opts = {}) {
|
|
|
219
237
|
// Формат-крок (oxfmt): fix-режим — завжди (будь-який scope); read-only пропускаємо (нуль
|
|
220
238
|
// мутацій). Кастомний rulesDir (юніт-тести) — реальний пакет недоступний, тож пропускаємо.
|
|
221
239
|
if (!readOnly && opts.rulesDir === undefined) {
|
|
222
|
-
const fmtCode =
|
|
240
|
+
const fmtCode = runFormat(cwd, log)
|
|
223
241
|
if (fmtCode !== 0) worst = fmtCode
|
|
224
242
|
}
|
|
225
243
|
return worst
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: JS Module
|
|
3
|
+
title: lint.mjs
|
|
4
|
+
resource: npm/rules/php/js/lint.mjs
|
|
5
|
+
docgen:
|
|
6
|
+
crc: 7de6b473
|
|
7
|
+
score: 100
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
Оркестраторний адаптер правила `php` для `n-cursor lint`. Делегує лінтер-фазу наявній функції `run` із `../lint/lint.mjs` (composer audit, php-cs-fixer у `--dry-run`, phpstan/psalm). Режиму на рівні окремих файлів немає — composer-інструменти працюють по всьому проєкту, тож параметр `files` ігнорується. Інструменти read-only (`--dry-run`/`analyse`), тож мутацій робочого дерева немає.
|
|
11
|
+
|
|
12
|
+
## Поведінка
|
|
13
|
+
|
|
14
|
+
1. Викликає `run` — лінтер-фаза php по всьому проєкту.
|
|
15
|
+
2. Повертає код виходу інструменту.
|
|
16
|
+
|
|
17
|
+
## Гарантії поведінки
|
|
18
|
+
|
|
19
|
+
- Read-only: інструменти не мутують робоче дерево.
|
|
20
|
+
- Не звертається до мережі напряму (composer-кроки можуть, але це поведінка делегата, не цього модуля).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** @see ./docs/lint.md */
|
|
2
|
+
import { run } from '../lint/lint.mjs'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Оркестраторний адаптер `n-cursor lint php` (лінтер-фаза): composer audit + php-cs-fixer
|
|
6
|
+
* (`--dry-run`) + phpstan/psalm через `run` (read-only — мутацій немає, тож `opts` ігнорується).
|
|
7
|
+
* Структурні php.mdc-перевірки — у конформність-фазі. Без composer-інструментів крок — no-op.
|
|
8
|
+
* @param {string[] | undefined} _files ігнорується (whole-repo обхід)
|
|
9
|
+
* @returns {number} exit code
|
|
10
|
+
*/
|
|
11
|
+
export function lint(_files) {
|
|
12
|
+
return run()
|
|
13
|
+
}
|
package/rules/php/php.mdc
CHANGED
|
@@ -63,9 +63,7 @@ composer audit
|
|
|
63
63
|
|
|
64
64
|
## lint-php
|
|
65
65
|
|
|
66
|
-
`composer`-інструмененти не мають єдиного CLI, який сам обходить репозиторій, тому
|
|
67
|
-
|
|
68
|
-
- Канон `package.json#scripts.lint-php` (substring requirement): [package.json.contains.json](./policy/package_json/template/package.json.contains.json)
|
|
66
|
+
`composer`-інструмененти не мають єдиного CLI, який сам обходить репозиторій, тому php-лінт делегується у JS-скрипт-обгортку. Запуск — через **`n-cursor lint php`** (CI — `--read-only`); окремого `package.json`-скрипта немає.
|
|
69
67
|
|
|
70
68
|
Скрипт `run-php.mjs`:
|
|
71
69
|
|
package/rules/python/python.mdc
CHANGED
|
@@ -27,9 +27,7 @@ Python-проєкти ведуться **виключно** на [uv](https://do
|
|
|
27
27
|
|
|
28
28
|
## lint-python
|
|
29
29
|
|
|
30
|
-
Інструменти uv-екосистеми не мають єдиного CLI, що сам обходить репозиторій, тому
|
|
31
|
-
|
|
32
|
-
- Канон `package.json#scripts.lint-python` (substring requirement): [package.json.contains.json](./policy/package_json/template/package.json.contains.json)
|
|
30
|
+
Інструменти uv-екосистеми не мають єдиного CLI, що сам обходить репозиторій, тому python-лінт делегується у JS-скрипт-обгортку. Запуск — через **`n-cursor lint python`** (CI — `--read-only`); окремого `package.json`-скрипта немає.
|
|
33
31
|
|
|
34
32
|
Скрипт `rules/python/lint/lint.mjs`:
|
|
35
33
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: JS Module
|
|
3
|
+
title: lint.mjs
|
|
4
|
+
resource: npm/rules/rust/js/lint.mjs
|
|
5
|
+
docgen:
|
|
6
|
+
crc: 5d7c4123
|
|
7
|
+
score: 100
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
Оркестраторний адаптер правила `rust` для `n-cursor lint`: rustfmt + clippy через `cargo`. Запускається на `n-cursor lint rust`. За відсутності `Cargo.toml` у корені — no-op (вихід 0). `cargo`/`rustfmt`/`clippy` резолвляться з PATH (Rust toolchain через rustup), не з npm-залежностей; якщо `cargo` відсутній за наявного `Cargo.toml` — помилка.
|
|
11
|
+
|
|
12
|
+
## Поведінка
|
|
13
|
+
|
|
14
|
+
1. `readOnly` (CI): `cargo fmt --all -- --check` + `cargo clippy --all-targets --all-features -- -D warnings` — детект без мутацій.
|
|
15
|
+
2. fix-режим: `cargo fmt --all` + `cargo clippy --fix` + фінальний `cargo clippy … -D warnings`.
|
|
16
|
+
3. Перший ненульовий cargo-крок спиняє ланцюг і повертає його код.
|
|
17
|
+
|
|
18
|
+
## Гарантії поведінки
|
|
19
|
+
|
|
20
|
+
- Read-only за наявності `readOnly`: cargo не мутує робоче дерево (`--check`, без `--fix`).
|
|
21
|
+
- Не звертається до мережі напряму (cargo-кроки можуть тягнути crates, але це поведінка тулчейну).
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/** @see ./docs/lint.md */
|
|
2
|
+
import { spawnSync } from 'node:child_process'
|
|
3
|
+
import { existsSync } from 'node:fs'
|
|
4
|
+
import { join } from 'node:path'
|
|
5
|
+
|
|
6
|
+
import { createCheckReporter } from '../../../scripts/lib/check-reporter.mjs'
|
|
7
|
+
import { resolveCmd } from '../../../scripts/utils/resolve-cmd.mjs'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Запускає cargo-крок і репортить результат.
|
|
11
|
+
* @param {string} label назва кроку
|
|
12
|
+
* @param {string} cargo абсолютний шлях до `cargo`
|
|
13
|
+
* @param {string[]} args аргументи
|
|
14
|
+
* @param {(m: string) => void} pass callback pass
|
|
15
|
+
* @param {(m: string) => void} fail callback fail
|
|
16
|
+
* @returns {boolean} true якщо крок успішний
|
|
17
|
+
*/
|
|
18
|
+
function runCargo(label, cargo, args, pass, fail) {
|
|
19
|
+
const r = spawnSync(cargo, args, { stdio: 'inherit', shell: false })
|
|
20
|
+
if (r.status === 0) {
|
|
21
|
+
pass(`lint-rust: ${label} — OK`)
|
|
22
|
+
return true
|
|
23
|
+
}
|
|
24
|
+
const code = typeof r.status === 'number' ? r.status : 1
|
|
25
|
+
fail(`lint-rust: ${label} — помилка (код ${code}, rust.mdc)`)
|
|
26
|
+
return false
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Оркестраторний адаптер `n-cursor lint rust`: rustfmt + clippy через cargo. Без `Cargo.toml` —
|
|
31
|
+
* no-op (0). `cargo`/`rustfmt`/`clippy` — Rust toolchain (rustup), не npm-залежності.
|
|
32
|
+
* readOnly (CI): `cargo fmt --all -- --check` + `cargo clippy … -D warnings` (нуль мутацій).
|
|
33
|
+
* fix: `cargo fmt --all` + `cargo clippy --fix` + фінальний `cargo clippy … -D warnings`.
|
|
34
|
+
* @param {string[] | undefined} _files ігнорується (cargo обходить crate сам)
|
|
35
|
+
* @param {string} [cwd] корінь
|
|
36
|
+
* @param {{ readOnly?: boolean }} [opts] readOnly → без мутацій
|
|
37
|
+
* @returns {number} exit code
|
|
38
|
+
*/
|
|
39
|
+
export function lint(_files, cwd = process.cwd(), opts = {}) {
|
|
40
|
+
const readOnly = opts.readOnly === true
|
|
41
|
+
const reporter = createCheckReporter()
|
|
42
|
+
const { pass, fail } = reporter
|
|
43
|
+
|
|
44
|
+
if (!existsSync(join(cwd, 'Cargo.toml'))) {
|
|
45
|
+
pass('lint-rust: немає Cargo.toml — кроки Rust пропущено')
|
|
46
|
+
return reporter.getExitCode()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const cargo = resolveCmd('cargo')
|
|
50
|
+
if (!cargo) {
|
|
51
|
+
fail('lint-rust: `cargo` не знайдено в PATH (Rust toolchain через rustup, rust.mdc)')
|
|
52
|
+
return reporter.getExitCode()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const fmtArgs = readOnly ? ['fmt', '--all', '--', '--check'] : ['fmt', '--all']
|
|
56
|
+
if (!runCargo(readOnly ? 'cargo fmt --check' : 'cargo fmt', cargo, fmtArgs, pass, fail)) {
|
|
57
|
+
return reporter.getExitCode()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!readOnly) {
|
|
61
|
+
const fixArgs = ['clippy', '--fix', '--allow-staged', '--allow-dirty', '--all-targets', '--all-features']
|
|
62
|
+
if (!runCargo('cargo clippy --fix', cargo, fixArgs, pass, fail)) return reporter.getExitCode()
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
runCargo('cargo clippy -D warnings', cargo, ['clippy', '--all-targets', '--all-features', '--', '-D', 'warnings'], pass, fail)
|
|
66
|
+
return reporter.getExitCode()
|
|
67
|
+
}
|
package/rules/rust/rust.mdc
CHANGED
|
@@ -5,12 +5,10 @@ alwaysApply: false
|
|
|
5
5
|
version: '1.4'
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
**rustfmt** ([rust-lang/rustfmt](https://github.com/rust-lang/rustfmt)) — форматер; **clippy** ([rust-lang/rust-clippy](https://github.com/rust-lang/rust-clippy)) — лінтер.
|
|
8
|
+
**rustfmt** ([rust-lang/rustfmt](https://github.com/rust-lang/rustfmt)) — форматер; **clippy** ([rust-lang/rust-clippy](https://github.com/rust-lang/rust-clippy)) — лінтер. Запуск — через **`n-cursor lint rust`** (адаптер `js/lint.mjs`): локально (fix) `cargo fmt --all` → `cargo clippy --fix --allow-staged --allow-dirty --all-targets --all-features` → фінальний `cargo clippy --all-targets --all-features -- -D warnings`; у `--read-only` (детект) — `cargo fmt --all -- --check` + `cargo clippy ... -- -D warnings`. Окремого `package.json`-скрипта немає. У CI cargo викликається напряму (див. `lint-rust.yml`).
|
|
9
9
|
|
|
10
10
|
`cargo`, `rustfmt`, `clippy` не додавай у `devDependencies` — це Rust toolchain, ставиться через `rustup` локально або через `dtolnay/rust-toolchain@stable` у CI.
|
|
11
11
|
|
|
12
|
-
Канон `scripts.lint-rust` (substring requirement): [package.json.contains.json](./policy/package_json/template/package.json.contains.json)
|
|
13
|
-
|
|
14
12
|
У `.vscode/extensions.json` `recommendations` мають містити `rust-lang.rust-analyzer` і `tamasfe.even-better-toml`: [extensions.json.snippet.json](./policy/vscode_extensions/template/extensions.json.snippet.json)
|
|
15
13
|
|
|
16
14
|
Канон workflow `.github/workflows/lint-rust.yml`: [lint-rust.yml.snippet.yml](./policy/lint_rust_yml/template/lint-rust.yml.snippet.yml)
|
|
@@ -21,7 +19,7 @@ version: '1.4'
|
|
|
21
19
|
|
|
22
20
|
Tauri-проєкт завжди має `src-tauri/Cargo.toml`, тому правило `rust` активується автоматично разом з `tauri`. Поділ обов'язків:
|
|
23
21
|
|
|
24
|
-
- `rust` — `lint
|
|
22
|
+
- `rust` — лінт через `n-cursor lint rust`, `rust-analyzer`, `even-better-toml`, CI workflow.
|
|
25
23
|
- `tauri` — `tauri-apps.tauri-vscode` (див. **tauri.mdc**).
|
|
26
24
|
|
|
27
25
|
Обидва правила перевіряють `.vscode/extensions.json` за `contains`-семантикою; конкурентного запису немає.
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# Перевірка `package.json` (php.mdc).
|
|
2
|
-
#
|
|
3
|
-
# Канон надходить через --data: { "template": { "contains": ... } }
|
|
4
|
-
# Структура --data сформована з template/package.json.contains.json.
|
|
5
|
-
# FS-перевірки (`composer.json`, наявність `package.json` як такого) — у JS.
|
|
6
|
-
package php.package_json
|
|
7
|
-
|
|
8
|
-
import rego.v1
|
|
9
|
-
|
|
10
|
-
deny contains msg if {
|
|
11
|
-
some script_name, needles in data.template.contains.scripts
|
|
12
|
-
actual := object.get(object.get(input, "scripts", {}), script_name, "")
|
|
13
|
-
some needle in needles
|
|
14
|
-
not contains(actual, needle)
|
|
15
|
-
msg := sprintf("package.json: scripts.%s має містити %q (php.mdc)", [script_name, needle])
|
|
16
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# Перевірка `package.json` (python.mdc).
|
|
2
|
-
#
|
|
3
|
-
# Канон надходить через --data: { "template": { "contains": ... } }
|
|
4
|
-
# Структура --data сформована з template/package.json.contains.json.
|
|
5
|
-
# FS-перевірки (наявність `package.json` як такого) — у JS.
|
|
6
|
-
package python.package_json
|
|
7
|
-
|
|
8
|
-
import rego.v1
|
|
9
|
-
|
|
10
|
-
deny contains msg if {
|
|
11
|
-
some script_name, needles in data.template.contains.scripts
|
|
12
|
-
actual := object.get(object.get(input, "scripts", {}), script_name, "")
|
|
13
|
-
some needle in needles
|
|
14
|
-
not contains(actual, needle)
|
|
15
|
-
msg := sprintf("package.json: scripts.%s має містити %q (python.mdc)", [script_name, needle])
|
|
16
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# Перевірка `package.json` для правила rust (rust.mdc).
|
|
2
|
-
#
|
|
3
|
-
# Канон надходить через --data: { "template": { "contains": ... } }
|
|
4
|
-
# Структура --data сформована з template/package.json.contains.json.
|
|
5
|
-
# Перевіряємо substring-вимоги до scripts.lint-rust: усі три кроки
|
|
6
|
-
# (`cargo fmt`, `cargo clippy --fix`, фінальний `cargo clippy ... -D warnings`)
|
|
7
|
-
# мають бути присутніми у значенні скрипта.
|
|
8
|
-
package rust.package_json
|
|
9
|
-
|
|
10
|
-
import rego.v1
|
|
11
|
-
|
|
12
|
-
deny contains msg if {
|
|
13
|
-
some script_name, needles in data.template.contains.scripts
|
|
14
|
-
actual := object.get(object.get(input, "scripts", {}), script_name, "")
|
|
15
|
-
some needle in needles
|
|
16
|
-
not contains(actual, needle)
|
|
17
|
-
msg := sprintf("package.json: scripts.%s має містити %q (rust.mdc)", [script_name, needle])
|
|
18
|
-
}
|