@gspothq/cli 0.0.0-stage → 0.1.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/README.md +18 -2
- package/configurations/database/postgres/manifest.toml +114 -0
- package/configurations/database/postgres/rules/POSTGRES.md +78 -0
- package/configurations/framework/astro/eslint-presets.json +138 -0
- package/configurations/framework/astro/manifest.toml +95 -0
- package/configurations/framework/astro/rules/ASTRO.md +39 -0
- package/configurations/framework/expo/manifest.toml +43 -0
- package/configurations/framework/express/manifest.toml +17 -0
- package/configurations/framework/express/rules/EXPRESS.md +73 -0
- package/configurations/framework/express/semgrep/express.yml +71 -0
- package/configurations/framework/fastapi/manifest.toml +11 -0
- package/configurations/framework/fastapi/rules/FASTAPI.md +100 -0
- package/configurations/framework/fastapi/semgrep/fastapi.yml +44 -0
- package/configurations/framework/nestjs/eslint-presets.json +62 -0
- package/configurations/framework/nestjs/manifest.toml +52 -0
- package/configurations/framework/nestjs/rules/NESTJS.md +44 -0
- package/configurations/framework/nextjs/eslint-presets.json +73 -0
- package/configurations/framework/nextjs/manifest.toml +119 -0
- package/configurations/framework/nextjs/rules/NEXTJS.md +43 -0
- package/configurations/framework/react/eslint-presets.json +77 -0
- package/configurations/framework/react/manifest.toml +93 -0
- package/configurations/framework/react/rules/REACT.md +108 -0
- package/configurations/framework/react-dom/eslint-presets.json +110 -0
- package/configurations/framework/react-dom/manifest.toml +24 -0
- package/configurations/framework/react-native/manifest.toml +46 -0
- package/configurations/framework/react-native/rules/REACT-NATIVE.md +51 -0
- package/configurations/framework/site/manifest.toml +170 -0
- package/configurations/framework/site/rules/SITE.md +20 -0
- package/configurations/framework/svelte/eslint-presets.json +67 -0
- package/configurations/framework/svelte/manifest.toml +83 -0
- package/configurations/framework/svelte/rules/SVELTE.md +48 -0
- package/configurations/framework/vue/eslint-presets.json +180 -0
- package/configurations/framework/vue/manifest.toml +83 -0
- package/configurations/framework/vue/rules/VUE.md +41 -0
- package/configurations/general/commits/manifest.toml +111 -0
- package/configurations/general/commits/rules/GIT.md +31 -0
- package/configurations/general/coverage/manifest.toml +3 -0
- package/configurations/general/dependencies/manifest.toml +159 -0
- package/configurations/general/dependencies/rules/DEPENDENCIES.md +30 -0
- package/configurations/general/dependencies/syncpack.json +15 -0
- package/configurations/general/docs/manifest.toml +79 -0
- package/configurations/general/docs/rules/DOCS.md +86 -0
- package/configurations/general/duplication/manifest.toml +32 -0
- package/configurations/general/engineering/manifest.toml +8 -0
- package/configurations/general/engineering/rules/agent/PLANNING.md +42 -0
- package/configurations/general/engineering/rules/agent/SUPPRESSIONS.md +16 -0
- package/configurations/general/engineering/rules/agent/TALKING.md +3 -0
- package/configurations/general/engineering/rules/agent/TASKS.md +19 -0
- package/configurations/general/engineering/rules/agent/WORKING.md +83 -0
- package/configurations/general/engineering/rules/code/ACCESSIBILITY.md +32 -0
- package/configurations/general/engineering/rules/code/CLI.md +37 -0
- package/configurations/general/engineering/rules/code/COMMENTS.md +38 -0
- package/configurations/general/engineering/rules/code/CONFIGURATION.md +25 -0
- package/configurations/general/engineering/rules/code/ERRORS.md +49 -0
- package/configurations/general/engineering/rules/code/HTTP.md +46 -0
- package/configurations/general/engineering/rules/code/LOGGING.md +55 -0
- package/configurations/general/engineering/rules/code/TESTING.md +58 -0
- package/configurations/general/files/manifest.toml +141 -0
- package/configurations/general/files/rules/YAML.md +19 -0
- package/configurations/general/format/manifest.toml +152 -0
- package/configurations/general/gspot/manifest.toml +65 -0
- package/configurations/general/gspot/rules/GENERATED.md +10 -0
- package/configurations/general/licenses/manifest.toml +33 -0
- package/configurations/general/naming/defaults.json +423 -0
- package/configurations/general/naming/manifest.toml +35 -0
- package/configurations/general/naming/rules/NAMING.md +179 -0
- package/configurations/general/prose/manifest.toml +86 -0
- package/configurations/general/prose/rules/WRITING.md +31 -0
- package/configurations/general/prose/vale/styles/LICENSES.md +55 -0
- package/configurations/general/prose/vale/styles/gspot/ampm.yml +8 -0
- package/configurations/general/prose/vale/styles/gspot/conscious-language.yml +16 -0
- package/configurations/general/prose/vale/styles/gspot/contractions.yml +43 -0
- package/configurations/general/prose/vale/styles/gspot/currency.yml +8 -0
- package/configurations/general/prose/vale/styles/gspot/dashes.yml +8 -0
- package/configurations/general/prose/vale/styles/gspot/date-ordinals.yml +41 -0
- package/configurations/general/prose/vale/styles/gspot/dates.yml +7 -0
- package/configurations/general/prose/vale/styles/gspot/file-paths.yml +7 -0
- package/configurations/general/prose/vale/styles/gspot/future.yml +17 -0
- package/configurations/general/prose/vale/styles/gspot/hedging.yml +22 -0
- package/configurations/general/prose/vale/styles/gspot/history.yml +16 -0
- package/configurations/general/prose/vale/styles/gspot/idioms.yml +21 -0
- package/configurations/general/prose/vale/styles/gspot/interface-verbs.yml +11 -0
- package/configurations/general/prose/vale/styles/gspot/jargon.yml +11 -0
- package/configurations/general/prose/vale/styles/gspot/leading-conjunctions.yml +12 -0
- package/configurations/general/prose/vale/styles/gspot/link-text.yml +8 -0
- package/configurations/general/prose/vale/styles/gspot/locations.yml +14 -0
- package/configurations/general/prose/vale/styles/gspot/marketing.yml +26 -0
- package/configurations/general/prose/vale/styles/gspot/merge-conflict-markers.yml +13 -0
- package/configurations/general/prose/vale/styles/gspot/militaristic-language.yml +22 -0
- package/configurations/general/prose/vale/styles/gspot/modals.yml +9 -0
- package/configurations/general/prose/vale/styles/gspot/numbered-units.yml +18 -0
- package/configurations/general/prose/vale/styles/gspot/obvious-fields.yml +14 -0
- package/configurations/general/prose/vale/styles/gspot/ordinal-adverbs.yml +15 -0
- package/configurations/general/prose/vale/styles/gspot/percentage-numbers.yml +8 -0
- package/configurations/general/prose/vale/styles/gspot/placeholders.yml +7 -0
- package/configurations/general/prose/vale/styles/gspot/product-centric-writing.yml +8 -0
- package/configurations/general/prose/vale/styles/gspot/punctuated-headings.yml +11 -0
- package/configurations/general/prose/vale/styles/gspot/self-reference.yml +15 -0
- package/configurations/general/prose/vale/styles/gspot/session-identifiers.yml +11 -0
- package/configurations/general/prose/vale/styles/gspot/since.yml +6 -0
- package/configurations/general/prose/vale/styles/gspot/straight-quotes.yml +11 -0
- package/configurations/general/prose/vale/styles/gspot/suspended-hyphens.yml +8 -0
- package/configurations/general/prose/vale/styles/gspot/symbols.yml +8 -0
- package/configurations/general/prose/vale/styles/gspot/time-ranges.yml +14 -0
- package/configurations/general/prose/vale/styles/gspot/url-prepositions.yml +10 -0
- package/configurations/general/prose/vale/styles/gspot/version-range.yml +8 -0
- package/configurations/general/repository/manifest.toml +24 -0
- package/configurations/general/secrets/gitleaks.toml +2 -0
- package/configurations/general/secrets/manifest.toml +125 -0
- package/configurations/general/secrets/rules/SECRETS.md +13 -0
- package/configurations/general/security/manifest.toml +77 -0
- package/configurations/general/security/rules/SECURITY.md +55 -0
- package/configurations/general/spelling/manifest.toml +46 -0
- package/configurations/general/structure/manifest.toml +70 -0
- package/configurations/infrastructure/ansible/manifest.toml +33 -0
- package/configurations/infrastructure/docker/manifest.toml +127 -0
- package/configurations/infrastructure/docker/rules/DOCKER.md +135 -0
- package/configurations/infrastructure/docker/trivyignore +2 -0
- package/configurations/infrastructure/github-actions/manifest.toml +76 -0
- package/configurations/infrastructure/github-actions/rules/GITHUB-ACTIONS.md +43 -0
- package/configurations/infrastructure/github-actions/zizmor.yml +3 -0
- package/configurations/infrastructure/nginx/manifest.toml +51 -0
- package/configurations/infrastructure/nginx/rules/NGINX.md +38 -0
- package/configurations/infrastructure/openapi/manifest.toml +50 -0
- package/configurations/infrastructure/openapi/rules/OPENAPI.md +39 -0
- package/configurations/infrastructure/xcode/manifest.toml +131 -0
- package/configurations/infrastructure/xcode/rules/XCODE.md +34 -0
- package/configurations/language/bash/manifest.toml +261 -0
- package/configurations/language/bash/rules/BASH.md +106 -0
- package/configurations/language/bash/rules/LANGUAGE.md +213 -0
- package/configurations/language/bash/rules/NAMING.md +62 -0
- package/configurations/language/bash/rules/OPERATIONS.md +77 -0
- package/configurations/language/bash/rules/SAFETY.md +222 -0
- package/configurations/language/bash/semgrep/bash.yml +30 -0
- package/configurations/language/css/manifest.toml +98 -0
- package/configurations/language/css/rules/CSS.md +28 -0
- package/configurations/language/css/rules/NAMING.md +17 -0
- package/configurations/language/css/rules/TAILWIND.md +26 -0
- package/configurations/language/css/stylelint-rule-names.json +89 -0
- package/configurations/language/html/manifest.toml +59 -0
- package/configurations/language/html/rules/HTML.md +27 -0
- package/configurations/language/html/rules/NAMING.md +16 -0
- package/configurations/language/javascript/eslint-presets.json +997 -0
- package/configurations/language/javascript/eslint-rule-names.json +299 -0
- package/configurations/language/javascript/eslint-runtime-names.json +61 -0
- package/configurations/language/javascript/manifest.toml +393 -0
- package/configurations/language/javascript/rules/BUN.md +13 -0
- package/configurations/language/javascript/rules/COMPONENTS.md +18 -0
- package/configurations/language/javascript/rules/DENO.md +15 -0
- package/configurations/language/javascript/rules/JAVASCRIPT.md +60 -0
- package/configurations/language/javascript/rules/NAMING.md +31 -0
- package/configurations/language/javascript/rules/NODE.md +21 -0
- package/configurations/language/javascript/rules/PLAYWRIGHT.md +34 -0
- package/configurations/language/javascript/semgrep/javascript.yml +84 -0
- package/configurations/language/markdown/manifest.toml +85 -0
- package/configurations/language/markdown/markdownlint-cli2.mjs +19 -0
- package/configurations/language/python/manifest.toml +621 -0
- package/configurations/language/python/rules/DESIGN.md +136 -0
- package/configurations/language/python/rules/FLOW.md +124 -0
- package/configurations/language/python/rules/NAMING.md +53 -0
- package/configurations/language/python/rules/PACKAGING.md +49 -0
- package/configurations/language/python/rules/PYTHON.md +136 -0
- package/configurations/language/python/rules/TYPING.md +132 -0
- package/configurations/language/sql/manifest.toml +68 -0
- package/configurations/language/sql/rules/NAMING.md +90 -0
- package/configurations/language/sql/rules/SQL.md +9 -0
- package/configurations/language/swift/manifest.toml +164 -0
- package/configurations/language/swift/rules/NAMING.md +88 -0
- package/configurations/language/swift/rules/SWIFT.md +134 -0
- package/configurations/language/swift/rules/SWIFTUI.md +61 -0
- package/configurations/language/swift/rules/UIKIT.md +99 -0
- package/configurations/language/swift/semgrep/swift.yml +126 -0
- package/configurations/language/typescript/eslint-presets.json +215 -0
- package/configurations/language/typescript/manifest.toml +72 -0
- package/configurations/language/typescript/rules/NAMING.md +73 -0
- package/configurations/language/typescript/rules/TYPESCRIPT.md +79 -0
- package/configurations/library/drizzle/manifest.toml +68 -0
- package/configurations/library/drizzle/rules/DRIZZLE.md +44 -0
- package/configurations/library/react-hook-form/manifest.toml +15 -0
- package/configurations/library/react-hook-form/rules/REACT-HOOK-FORM.md +48 -0
- package/configurations/library/swift-snapshot-testing/manifest.toml +32 -0
- package/configurations/library/tanstack-query/eslint-presets.json +21 -0
- package/configurations/library/tanstack-query/manifest.toml +26 -0
- package/configurations/library/tanstack-query/rules/TANSTACK-QUERY.md +41 -0
- package/configurations/library/testing-library/eslint-presets.json +191 -0
- package/configurations/library/testing-library/manifest.toml +47 -0
- package/configurations/library/translations/manifest.toml +40 -0
- package/configurations/library/translations/rules/NEXT-INTL.md +33 -0
- package/configurations/library/translations/rules/TRANSLATIONS.md +102 -0
- package/configurations/library/trpc/manifest.toml +14 -0
- package/configurations/library/trpc/rules/TRPC.md +43 -0
- package/configurations/library/zod/manifest.toml +25 -0
- package/configurations/library/zod/rules/ZOD.md +44 -0
- package/configurations/library/zustand/manifest.toml +18 -0
- package/configurations/library/zustand/rules/ZUSTAND.md +106 -0
- package/configurations/platform/cloudflare/manifest.toml +94 -0
- package/configurations/platform/cloudflare/rules/CLOUDFLARE.md +23 -0
- package/configurations/platform/cloudflare/semgrep/cloudflare.yml +12 -0
- package/configurations/platform/supabase/manifest.toml +112 -0
- package/configurations/platform/supabase/rules/SUPABASE.md +129 -0
- package/configurations/platform/supabase/semgrep/supabase.yml +60 -0
- package/configurations/testing/jest/manifest.toml +54 -0
- package/configurations/testing/pytest/manifest.toml +53 -0
- package/configurations/testing/swift-tests/manifest.toml +52 -0
- package/configurations/testing/swift-tests/rules/SWIFT-TESTS.md +79 -0
- package/configurations/testing/vitest/eslint-presets.json +22 -0
- package/configurations/testing/vitest/manifest.toml +69 -0
- package/configurations/testing/vitest/rules/VITEST.md +18 -0
- package/dist/LICENSE.md +201 -0
- package/dist/THIRD-PARTY-NOTICES.md +25 -0
- package/dist/eslint-rule-levels.json +10 -0
- package/dist/gspot.js +30740 -0
- package/dist/linkinator-program.js +65 -0
- package/dist/purgecss-program.js +51 -0
- package/dist/tool-versions.json +3 -0
- package/grammars/bash.wasm +0 -0
- package/grammars/css.wasm +0 -0
- package/grammars/html.wasm +0 -0
- package/grammars/javascript.wasm +0 -0
- package/grammars/licenses/tree-sitter-bash.txt +21 -0
- package/grammars/licenses/tree-sitter-css.txt +21 -0
- package/grammars/licenses/tree-sitter-html.txt +21 -0
- package/grammars/licenses/tree-sitter-javascript.txt +21 -0
- package/grammars/licenses/tree-sitter-python.txt +21 -0
- package/grammars/licenses/tree-sitter-swift.txt +21 -0
- package/grammars/licenses/tree-sitter-typescript.txt +21 -0
- package/grammars/python.wasm +0 -0
- package/grammars/swift.wasm +0 -0
- package/grammars/tsx.wasm +0 -0
- package/grammars/typescript.wasm +0 -0
- package/gspot.schema.json +45991 -0
- package/package.json +93 -5
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Task Runner
|
|
2
|
+
|
|
3
|
+
Rules for `mise` tasks, `package.json` scripts, `Makefile` targets, or the project's runner.
|
|
4
|
+
|
|
5
|
+
## Task behavior
|
|
6
|
+
|
|
7
|
+
- Reuse the task names the project has. Add a task only when asked.
|
|
8
|
+
- Do not add empty section markers or scripts that only echo a placeholder.
|
|
9
|
+
- When a step fails, the task stops and exits with an error.
|
|
10
|
+
|
|
11
|
+
## Task organization
|
|
12
|
+
|
|
13
|
+
<!-- level: all -->
|
|
14
|
+
|
|
15
|
+
- Use one declared task runner per project.
|
|
16
|
+
- Name tasks in kebab-case with a colon namespace, such as `check:fix` or `deploy:staging`.
|
|
17
|
+
- Use the runner's declarative commands and dependency ordering. Keep substantial parsing,
|
|
18
|
+
branching, and process control in the code that implements that behavior.
|
|
19
|
+
- Give each task a concise description in the runner's task list.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Working in a Repository
|
|
2
|
+
|
|
3
|
+
## Running processes
|
|
4
|
+
|
|
5
|
+
Check for a running instance before you start a dev server, a build watcher, an emulator, or a
|
|
6
|
+
database. Look at the port, the process list and the runner's output. Reuse what runs. Start a
|
|
7
|
+
second instance only for a test that needs isolation, or when the user asks in this
|
|
8
|
+
conversation. A framework that moves to the next free port hides the duplicate: two servers then
|
|
9
|
+
serve different code. Stop what you started when the task ends.
|
|
10
|
+
|
|
11
|
+
## Thinking before coding
|
|
12
|
+
|
|
13
|
+
Read the relevant code before touching it. Understand the public interfaces, data flow,
|
|
14
|
+
and how the modules work together. Then think through your approach:
|
|
15
|
+
|
|
16
|
+
- Which change solves the problem correctly with the fewest steps?
|
|
17
|
+
- Which failures can occur? What happens with bad input, missing data, concurrent access, network failures?
|
|
18
|
+
- Does this change affect other parts of the system? Trace the call chain.
|
|
19
|
+
|
|
20
|
+
When you rename or move a file, update every reference: imports, documentation, configuration, and scripts.
|
|
21
|
+
|
|
22
|
+
Before adding a new module, directory, or helper, identify the module that implements
|
|
23
|
+
the behavior. When you add a file, tell the user why that module needs it.
|
|
24
|
+
|
|
25
|
+
## Scope discipline
|
|
26
|
+
|
|
27
|
+
- Complete the requested task. Do not expand scope.
|
|
28
|
+
- If you discover something unrelated that needs fixing, mention it to the user. Do not silently fix it unless the fix takes one small edit in a file you already edit.
|
|
29
|
+
- Do not add features, refactor surrounding code, or make unrequested improvements.
|
|
30
|
+
|
|
31
|
+
## Verification and tests
|
|
32
|
+
|
|
33
|
+
A check reports what it finds as a finding, and `gspot explain <check>` describes the check.
|
|
34
|
+
|
|
35
|
+
Do not run verification broader than the change. Run no full test suite, build, scan, or Docker
|
|
36
|
+
check unless the user asks for it or the checks of the repository include it.
|
|
37
|
+
|
|
38
|
+
Write tests when the user asks or a check requires them. When your change breaks a test, fix the
|
|
39
|
+
test. Language and framework instructions say how to write a test, not when.
|
|
40
|
+
|
|
41
|
+
## No defensive logic
|
|
42
|
+
|
|
43
|
+
Do not add guards, fallbacks, retries, defaults, or wrappers for states the public interface rules
|
|
44
|
+
out. Handle known failure modes where failures can occur: user input, network calls, persistence,
|
|
45
|
+
permissions, and external services. Trust an internal invariant once the public interface establishes it. When an invariant lacks a clear promise, trace the code and clarify the promised behavior instead of adding speculative protection.
|
|
46
|
+
|
|
47
|
+
## Abstractions
|
|
48
|
+
|
|
49
|
+
<!-- level: all -->
|
|
50
|
+
|
|
51
|
+
Keep one implementation for each concept in the module that implements it. Extract shared behavior only
|
|
52
|
+
when real callers need the same behavior and the extraction removes complexity. Do not add
|
|
53
|
+
forwarding wrappers, one-caller helpers, or abstractions for hypothetical reuse. Prefer local
|
|
54
|
+
duplication when callers have different responsibilities. Remove abstractions whose cost exceeds their benefit.
|
|
55
|
+
|
|
56
|
+
- An abstraction that gains flags, modes, optional branches, or caller-specific conditions needs a different design. Do not box loosely related behavior into one function with a parameter that
|
|
57
|
+
picks the behavior.
|
|
58
|
+
- Inline a wrong abstraction into each caller, delete the branches each caller does not need,
|
|
59
|
+
and extract only the common behavior that remains.
|
|
60
|
+
- You can prepare the code to support the requested change: first keep the
|
|
61
|
+
behavior, then change it, in separate commits.
|
|
62
|
+
- Replace positional booleans and ambiguous arguments with an options parameter using named fields.
|
|
63
|
+
- Pass a function in only when it replaces several option flags across real callers.
|
|
64
|
+
- Prefer plain functions, data structures, and explicit data flow to classes, factories,
|
|
65
|
+
strategies, and inheritance. Push state and I/O outward, and keep the core close to pure.
|
|
66
|
+
|
|
67
|
+
## No backward compatibility
|
|
68
|
+
|
|
69
|
+
<!-- level: all -->
|
|
70
|
+
|
|
71
|
+
Never introduce compatibility layers, wrapper functions, re-exports for renamed symbols, deprecated-but-kept code, or any other form of backward-compatible scaffolding. A published API follows the deprecation policy its project declares instead.
|
|
72
|
+
|
|
73
|
+
When you replace or rename something:
|
|
74
|
+
|
|
75
|
+
- Delete the old implementation entirely.
|
|
76
|
+
- Update every call site to use the new version.
|
|
77
|
+
|
|
78
|
+
## Structure
|
|
79
|
+
|
|
80
|
+
<!-- level: all -->
|
|
81
|
+
|
|
82
|
+
Group constants, types, and schemas by the behavior they belong to. Do not mirror the source
|
|
83
|
+
tree in tests.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Accessibility
|
|
2
|
+
|
|
3
|
+
## Structure
|
|
4
|
+
|
|
5
|
+
- Use semantic elements and roles: headings in order, landmarks, lists for lists, tables for data,
|
|
6
|
+
native controls such as `button`, `a`, `input`, `select` before custom ones.
|
|
7
|
+
- Every page has one `h1` and a document language.
|
|
8
|
+
- Reading order matches visual order.
|
|
9
|
+
|
|
10
|
+
## Names and descriptions
|
|
11
|
+
|
|
12
|
+
- Every interactive control has an accessible name. An icon-only control gets a label attribute; a
|
|
13
|
+
form field gets a visible label; an image gets `alt` that states its purpose, or empty `alt` when
|
|
14
|
+
decorative.
|
|
15
|
+
- Link each error and hint to its field with `aria-describedby` on the web or `accessibilityHint` on iOS.
|
|
16
|
+
Announce an error when it appears.
|
|
17
|
+
- Do not convey meaning by color, position, shape, or icon alone. State it in text.
|
|
18
|
+
|
|
19
|
+
## Keyboard and focus
|
|
20
|
+
|
|
21
|
+
- Let keyboard users reach everything a pointer can reach, in a sensible order.
|
|
22
|
+
- Show focus. Do not remove the focus indicator without replacing it.
|
|
23
|
+
- Move focus deliberately: into a dialog when it opens, back to the trigger when it closes, to the
|
|
24
|
+
first error on failed submission, to the new content on route change.
|
|
25
|
+
- No keyboard traps. Escape closes a dialog, menu, or popover and returns focus to its trigger.
|
|
26
|
+
|
|
27
|
+
## Motion, size, and contrast
|
|
28
|
+
|
|
29
|
+
- Honor the reduced-motion setting. No information depends on an animation.
|
|
30
|
+
- Text scales with the user's size preference through Dynamic Type or browser zoom without clipping.
|
|
31
|
+
- Tap and click targets meet the platform minimum size.
|
|
32
|
+
- Text and essential graphics meet the platform contrast minimum in every theme.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Command-Line Programs
|
|
2
|
+
|
|
3
|
+
These rules apply to command-line programs the project ships for people or automation. Internal build tasks follow the task runner's interface.
|
|
4
|
+
|
|
5
|
+
## Streams and exit status
|
|
6
|
+
|
|
7
|
+
- Data goes to stdout. Diagnostics, progress, prompts, and errors go to stderr.
|
|
8
|
+
- Preserve established exit codes. New commands use `0` on success, `1` on failure, and `2`
|
|
9
|
+
on usage error unless their protocol defines other behavior. List each exit code in `--help`.
|
|
10
|
+
- Keep machine-readable `--json` output complete, stable, and free of progress text.
|
|
11
|
+
- Omit color and terminal control sequences unless stdout connects to a terminal and `NO_COLOR` has no value.
|
|
12
|
+
|
|
13
|
+
## Interface
|
|
14
|
+
|
|
15
|
+
- `--help` prints usage, every flag with its default, and one example. `--version` prints the
|
|
16
|
+
version and exits.
|
|
17
|
+
- Every value a prompt asks for also has a flag. If the process has no terminal, fail. Name the missing flag.
|
|
18
|
+
- A destructive command asks for confirmation on a terminal and requires `--yes` otherwise.
|
|
19
|
+
|
|
20
|
+
## Behavior
|
|
21
|
+
|
|
22
|
+
- Validate every argument before doing any work. Fail with an actionable message that names the
|
|
23
|
+
argument.
|
|
24
|
+
- Idempotent where the operation allows it: running twice produces the same state.
|
|
25
|
+
- Long operations report progress on stderr and honor interruption: catch the termination signal,
|
|
26
|
+
clean up, exit with the signal's status.
|
|
27
|
+
- Resolve a relative path against the directory the user ran the command in, or against an
|
|
28
|
+
explicit argument. Never resolve it against the script's own folder.
|
|
29
|
+
- Create temporary files with the platform's secure call such as `mktemp`, `tempfile.mkstemp`, and
|
|
30
|
+
delete them on exit.
|
|
31
|
+
|
|
32
|
+
## Flag naming
|
|
33
|
+
|
|
34
|
+
<!-- level: all -->
|
|
35
|
+
|
|
36
|
+
Use `--kebab-case` for flags. Boolean switches take no value; use `--no-flag` for negation.
|
|
37
|
+
Preserve names defined by an existing public interface.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Comments
|
|
2
|
+
|
|
3
|
+
## What a comment says
|
|
4
|
+
|
|
5
|
+
<!-- level: all -->
|
|
6
|
+
|
|
7
|
+
A comment explains why, not what, and describes the code in its current form.
|
|
8
|
+
|
|
9
|
+
Bad: `# Removed the old cache loader.`
|
|
10
|
+
Good: `# Reads cached responses from the configured cache directory.`
|
|
11
|
+
|
|
12
|
+
A doc comment says what a function does, what its parameters mean, and what it returns.
|
|
13
|
+
|
|
14
|
+
## When to comment
|
|
15
|
+
|
|
16
|
+
<!-- level: all -->
|
|
17
|
+
|
|
18
|
+
Write the doc comment that the language check asks for. Add other comments only when a function:
|
|
19
|
+
|
|
20
|
+
- handles a failure that its public interface does not explain
|
|
21
|
+
- has concurrency, cancellation, or isolation requirements
|
|
22
|
+
- makes a security or privacy decision
|
|
23
|
+
- encodes a domain invariant such as `idempotent` or `retry-safe`
|
|
24
|
+
- sits on a hot path
|
|
25
|
+
- takes more than ten seconds to understand from its signature and body
|
|
26
|
+
|
|
27
|
+
## Keep comments true
|
|
28
|
+
|
|
29
|
+
When you change a function, update its doc comment: summary, parameters, return value, and errors.
|
|
30
|
+
Rewrite or delete a comment that describes behavior the code lacks, or the reason for a decision
|
|
31
|
+
you undo.
|
|
32
|
+
|
|
33
|
+
## Deferred work
|
|
34
|
+
|
|
35
|
+
<!-- level: all -->
|
|
36
|
+
|
|
37
|
+
Track unfinished work in the issue tracker. Do not leave `TODO`, `FIXME`, `XXX`, or `HACK` in
|
|
38
|
+
comments. An issue link may explain an existing constraint, never promise a later implementation.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
## Validate external values
|
|
4
|
+
|
|
5
|
+
- A missing or invalid value stops startup. The message names the variable and never prints its
|
|
6
|
+
value.
|
|
7
|
+
- Parse booleans from an explicit accepted set, numbers with bounds, URLs through the URL parser,
|
|
8
|
+
and lists with a declared separator. Treat an empty required value as missing.
|
|
9
|
+
|
|
10
|
+
## Reading configuration
|
|
11
|
+
|
|
12
|
+
<!-- level: all -->
|
|
13
|
+
|
|
14
|
+
- Each process reads the environment in one module and passes the values in.
|
|
15
|
+
- Parse each value once at startup and expose a typed, immutable configuration object.
|
|
16
|
+
- Do not add a hierarchy or a generic configuration module for one value.
|
|
17
|
+
|
|
18
|
+
## Configuration structure
|
|
19
|
+
|
|
20
|
+
<!-- level: all -->
|
|
21
|
+
|
|
22
|
+
- A configuration file imports no application code.
|
|
23
|
+
- Defaults live in the schema that validates the file, not scattered through readers.
|
|
24
|
+
- State one precedence order in the configuration module: command-line flag, environment variable, project file,
|
|
25
|
+
default. That module resolves it; readers never merge sources themselves.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Errors
|
|
2
|
+
|
|
3
|
+
## Error taxonomy
|
|
4
|
+
|
|
5
|
+
- Return a typed result or throw a typed error for an expected operational failure. Invalid input, missing resources, denied permission, and provider timeouts need results the caller can act on.
|
|
6
|
+
- Throw a programmer error for a broken invariant or impossible state. Log its stack and show a generic failure. Never catch it to keep going.
|
|
7
|
+
- A startup failure fails fast before the process accepts work.
|
|
8
|
+
- On shutdown, set readiness to false, stop accepting work, drain in-flight work for a bounded
|
|
9
|
+
time, close resources, and exit.
|
|
10
|
+
- A fatal runtime error stops new work, reports the failure, and exits. Last-resort handlers never
|
|
11
|
+
keep serving.
|
|
12
|
+
|
|
13
|
+
## Raising and catching
|
|
14
|
+
|
|
15
|
+
- Catch the narrowest type. Never a bare catch-all unless the block re-raises or deliberately isolates an operation and records the failure.
|
|
16
|
+
- Keep the try block around the one operation that can fail.
|
|
17
|
+
- Preserve the cause when wrapping: `new Error(message, { cause })`, `raise ... from error`, `Error` conformance with an underlying error.
|
|
18
|
+
- Do not swallow failures. Handle, record, or re-raise each caught error.
|
|
19
|
+
- Run required cleanup in `finally` or the language's equivalent.
|
|
20
|
+
|
|
21
|
+
## Error messages
|
|
22
|
+
|
|
23
|
+
A developer tool may name the file, line, and setting that the user must fix. Keep unrelated
|
|
24
|
+
private data out of every output.
|
|
25
|
+
|
|
26
|
+
**Keep out of public service responses:**
|
|
27
|
+
|
|
28
|
+
- Schema names, table names, column names, or function names.
|
|
29
|
+
- Internal identifiers such as row IDs, user IDs, or session tokens.
|
|
30
|
+
- Stack traces or file paths.
|
|
31
|
+
- Raw upstream, provider, or database errors.
|
|
32
|
+
- Implementation details such as trigger names, policy names, or internal state like "deleted" flags.
|
|
33
|
+
|
|
34
|
+
**Always:**
|
|
35
|
+
|
|
36
|
+
- Make messages actionable: tell the user what went wrong, not how the system works.
|
|
37
|
+
- Put the failing value in its own field, not in the message text.
|
|
38
|
+
- Keep message text stable so readers can search for it.
|
|
39
|
+
|
|
40
|
+
## User-facing messages
|
|
41
|
+
|
|
42
|
+
- Convert technical errors to user-facing messages in the code that displays them.
|
|
43
|
+
|
|
44
|
+
## Message style
|
|
45
|
+
|
|
46
|
+
<!-- level: all -->
|
|
47
|
+
|
|
48
|
+
Use sentence case for error messages. Keep their tone and casing consistent across the repository.
|
|
49
|
+
Preserve diagnostic text from external tools when callers depend on its exact form.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# HTTP
|
|
2
|
+
|
|
3
|
+
Rules for any HTTP service, whatever framework serves it, on top of the security, error, and
|
|
4
|
+
logging rules.
|
|
5
|
+
|
|
6
|
+
## Requests
|
|
7
|
+
|
|
8
|
+
- Validate input once where the request enters the service, with a schema. Handlers read the
|
|
9
|
+
validated value, never the raw request.
|
|
10
|
+
- Reject unsupported content types on endpoints that take a body. Limit the body size per route,
|
|
11
|
+
and keep the proxy's body limit equal to the application parser's.
|
|
12
|
+
- Handlers adapt transport to domain calls. They define no validation policy, database access,
|
|
13
|
+
provider mechanics, caching, or business decision.
|
|
14
|
+
- Middleware validates, authenticates, rate-limits, and attaches context, and makes no feature
|
|
15
|
+
decision.
|
|
16
|
+
|
|
17
|
+
## Responses
|
|
18
|
+
|
|
19
|
+
- One handler formats error responses. Feature code throws and never builds an HTTP error body.
|
|
20
|
+
- Give clients generic, stable messages. Detail stays in server diagnostics.
|
|
21
|
+
- The service documents one success shape and one error shape and keeps both stable.
|
|
22
|
+
- Use precise status codes: 201 for creation, 204 with no body, 4xx for caller errors, and 5xx
|
|
23
|
+
only for failures the caller cannot fix.
|
|
24
|
+
- The endpoint or module maps provider and database shapes into response shapes. Response
|
|
25
|
+
use API field names rather than storage names, unless the public interface explicitly uses the provider's format.
|
|
26
|
+
- Escape HTML for its rendering context, and never pre-escape JSON field values.
|
|
27
|
+
|
|
28
|
+
## Sessions and transport
|
|
29
|
+
|
|
30
|
+
- Terminate TLS at the proxy, and trust forwarding headers only from that proxy.
|
|
31
|
+
- When the service issues tokens, a revocation reaches every instance.
|
|
32
|
+
|
|
33
|
+
## Wire names
|
|
34
|
+
|
|
35
|
+
<!-- level: all -->
|
|
36
|
+
|
|
37
|
+
- Keep existing protocol header names, and a new header carries no `X-` prefix, as
|
|
38
|
+
[Request for Comments (RFC) 6648](https://www.rfc-editor.org/rfc/rfc6648) recommends.
|
|
39
|
+
|
|
40
|
+
## Operations
|
|
41
|
+
|
|
42
|
+
- Keep health and readiness endpoints cheap. Call no provider from them.
|
|
43
|
+
- Broad rate limits sit at the edge, application limits in middleware, and route limits beside
|
|
44
|
+
the route.
|
|
45
|
+
- Either the proxy or the application compresses responses, not both. Under heavy traffic, the
|
|
46
|
+
reverse proxy compresses responses.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Logging
|
|
2
|
+
|
|
3
|
+
## One logger
|
|
4
|
+
|
|
5
|
+
<!-- level: all -->
|
|
6
|
+
|
|
7
|
+
- One logging module per process, configured at the entrypoint: level, format, redaction, transports.
|
|
8
|
+
- Feature code obtains a logger from that module. It never instantiates, configures, or adds transports.
|
|
9
|
+
- A service logs to stdout. Configure other transports at the logger.
|
|
10
|
+
|
|
11
|
+
## Levels
|
|
12
|
+
|
|
13
|
+
<!-- level: all -->
|
|
14
|
+
|
|
15
|
+
- `debug`: noisy diagnostic detail, off in production.
|
|
16
|
+
- `info`: normal lifecycle events and status.
|
|
17
|
+
- `warn`: degraded, retryable, or unexpected but survivable conditions.
|
|
18
|
+
- `error`: an operation failed and no caller recovered.
|
|
19
|
+
- `fatal`: the process cannot go on and stops.
|
|
20
|
+
- Do not add custom levels.
|
|
21
|
+
|
|
22
|
+
## Structure
|
|
23
|
+
|
|
24
|
+
- Write a stable, human-readable message string that describes the event. Values go in structured fields, never interpolated into the message.
|
|
25
|
+
- Preserve declared event names and field keys. Before you rename one, tell the user because
|
|
26
|
+
dashboards and alerts may read it.
|
|
27
|
+
- Include the request trace when the request provides one.
|
|
28
|
+
- Use stable names for request IDs, correlation IDs, provider request IDs, operation IDs, resource IDs, and safe user IDs. Propagate them to provider calls when supported.
|
|
29
|
+
- Put an error object in the field the logger serializes errors from, so the logger keeps the stack and cause.
|
|
30
|
+
- Summarize: counts, IDs, statuses, provider names, durations. No large, deeply nested, or expensive-to-compute fields.
|
|
31
|
+
- Do not compute expensive log arguments when the logger disables the level.
|
|
32
|
+
|
|
33
|
+
### Field naming
|
|
34
|
+
|
|
35
|
+
<!-- level: all -->
|
|
36
|
+
|
|
37
|
+
Use `lower_snake_case` for new event names and field keys unless an existing logging interface defines their spelling.
|
|
38
|
+
|
|
39
|
+
## Sensitive values
|
|
40
|
+
|
|
41
|
+
Follow the secrets rules for values that must never reach logs.
|
|
42
|
+
|
|
43
|
+
- Personal data, raw user content, full request or response bodies, provider payloads, database rows.
|
|
44
|
+
|
|
45
|
+
Redaction lives in the logging module. When a new sensitive key can reach logs, update the redaction list; do not filter at one call site.
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
// Bad.
|
|
49
|
+
logger.info({ headers: req.headers }, 'Incoming request');
|
|
50
|
+
|
|
51
|
+
// Good.
|
|
52
|
+
logger.info({ path: req.path, method: req.method, requestId }, 'Incoming request');
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
A logging test asserts the fields and redaction, not that the logger ran.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Testing
|
|
2
|
+
|
|
3
|
+
Tests exist to catch bugs. A useful test fails when the behavior it covers breaks.
|
|
4
|
+
|
|
5
|
+
## Assertions
|
|
6
|
+
|
|
7
|
+
- Use Arrange, Act, Assert. Test behavior, not private implementation details.
|
|
8
|
+
- Assert exact values that the public interface defines, such as status codes, exit codes, and
|
|
9
|
+
messages. Do not pin incidental configuration or internal representation.
|
|
10
|
+
- Cover relevant empty and null inputs, limits, expected errors, and unexpected internal errors.
|
|
11
|
+
- Assert every changed outcome: responses, stored rows, outbound requests, side effects, and logs.
|
|
12
|
+
- A test has meaningful assertions; it does not merely prove that the code called a collaborator or
|
|
13
|
+
that a mock returns the value supplied to it.
|
|
14
|
+
- Use snapshots only for stable data, and review every change to them.
|
|
15
|
+
- Do not add test-only authentication bypasses, magic headers, or bypass routes.
|
|
16
|
+
|
|
17
|
+
## Mocks
|
|
18
|
+
|
|
19
|
+
- Mock only what leaves the process: network, filesystem, subprocesses, clock, and database.
|
|
20
|
+
Never mock the code under test or provider SDK internals.
|
|
21
|
+
- Mock the module that talks to the network or database. Use dependency injection when the
|
|
22
|
+
code declares the dependencies. Replace that whole module rather than hiding selected behavior.
|
|
23
|
+
- Keep mocks that affect the outcome in the arrange step. Reset or redefine shared mocks before
|
|
24
|
+
each test; do not use surprising global auto-mocks.
|
|
25
|
+
- Restore environment variables, globals, fake timers, and spies changed by a test.
|
|
26
|
+
|
|
27
|
+
## Placement and names
|
|
28
|
+
|
|
29
|
+
<!-- level: all -->
|
|
30
|
+
|
|
31
|
+
- Follow the framework or runner's test layout and keep one layout in each repository.
|
|
32
|
+
- Put builders, fakes, servers, and database support in the declared test support folder, never
|
|
33
|
+
in `mocks/`, `helpers/`, or `utils/`. Support files contain no assertions or test blocks.
|
|
34
|
+
- A test name states the scenario and expected outcome. Never use `test1`, `works`, `edge cases`,
|
|
35
|
+
or `happy path`. Group tests by unit, then scenario.
|
|
36
|
+
- Prefer role and label queries. Use a test ID last; name it in camelCase for its control, such
|
|
37
|
+
as `submitButton`. Never put visible text, user data, or record IDs in it.
|
|
38
|
+
|
|
39
|
+
## Test data
|
|
40
|
+
|
|
41
|
+
- Each test creates its records directly or through an explicit builder. It does not depend on
|
|
42
|
+
execution order, mystery seed state, or a globally empty database.
|
|
43
|
+
- Use fixed, descriptive names, emails, IDs, and references. Add a per-run suffix only for rows
|
|
44
|
+
in a shared database.
|
|
45
|
+
- Do not share mutable IDs between tests or count unrelated data. Add unrelated records when a
|
|
46
|
+
test must prove that the code leaves them unchanged.
|
|
47
|
+
- Use unique queue names, event IDs, operation IDs, or correlation IDs for event-driven tests.
|
|
48
|
+
Never purge shared queues or tables as a substitute for isolated data.
|
|
49
|
+
- Do not use fixed sleeps. Use bounded polling, fake timers, or a signal that proves completion.
|
|
50
|
+
|
|
51
|
+
## Network and providers
|
|
52
|
+
|
|
53
|
+
- Block unexpected external HTTP calls. Allow only the local service under test unless the
|
|
54
|
+
suite explicitly opts into a real provider through an environment variable absent by default.
|
|
55
|
+
- Assert outbound URLs, methods, safe headers, timeouts, and bodies. Never assert on secrets or
|
|
56
|
+
full sensitive payloads.
|
|
57
|
+
- Where the module recovers, test timeouts, 5xx, 429, malformed JSON, missing fields, and rejected
|
|
58
|
+
promises. Fake responses fail when a payload lacks required fields.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
allowed_words = ["JSON", "TOML", "YAML"]
|
|
2
|
+
[configuration]
|
|
3
|
+
title = "JSON, YAML, TOML, and XML files"
|
|
4
|
+
always_selected = true
|
|
5
|
+
description = "Checks JSON, YAML, TOML, XML, and related formats. Its tool files configure the tools that read these files."
|
|
6
|
+
|
|
7
|
+
[files]
|
|
8
|
+
extensions = [".json", ".jsonc", ".json5", ".yaml", ".yml", ".toml", ".xml"]
|
|
9
|
+
|
|
10
|
+
[[tool]]
|
|
11
|
+
name = "taplo"
|
|
12
|
+
version = "0.10.0"
|
|
13
|
+
min_version = "0.9.0"
|
|
14
|
+
mise = "taplo"
|
|
15
|
+
brew = "taplo"
|
|
16
|
+
cargo = "taplo-cli"
|
|
17
|
+
# No npm pin: the npm build of Taplo checks no file on Windows, so every platform takes the native release.
|
|
18
|
+
github = { name = "tamasfe/taplo", version = "0.10.0" }
|
|
19
|
+
[[tool.replace]]
|
|
20
|
+
file = "taplo.toml"
|
|
21
|
+
shared = false
|
|
22
|
+
|
|
23
|
+
[[tool.replace]]
|
|
24
|
+
file = ".taplo.toml"
|
|
25
|
+
shared = false
|
|
26
|
+
|
|
27
|
+
[[tool]]
|
|
28
|
+
name = "yamllint"
|
|
29
|
+
version = "1.38.0"
|
|
30
|
+
mise = "pipx:yamllint"
|
|
31
|
+
pypi = "yamllint"
|
|
32
|
+
brew = "yamllint"
|
|
33
|
+
[[tool.replace]]
|
|
34
|
+
file = ".yamllint"
|
|
35
|
+
shared = false
|
|
36
|
+
|
|
37
|
+
[[tool.replace]]
|
|
38
|
+
file = ".yamllint.yml"
|
|
39
|
+
shared = false
|
|
40
|
+
|
|
41
|
+
[[tool.replace]]
|
|
42
|
+
file = ".yamllint.yaml"
|
|
43
|
+
shared = false
|
|
44
|
+
|
|
45
|
+
[[tool]]
|
|
46
|
+
name = "v8r"
|
|
47
|
+
requires = ["ajv"]
|
|
48
|
+
version = "6.1.0"
|
|
49
|
+
mise = "npm:v8r"
|
|
50
|
+
npm = "v8r"
|
|
51
|
+
|
|
52
|
+
# v8r imports this optional peer when it loads ajv-draft-04. Tool projects must install it.
|
|
53
|
+
|
|
54
|
+
[[tool]]
|
|
55
|
+
name = "ajv"
|
|
56
|
+
kind = "library"
|
|
57
|
+
version = "8.20.0"
|
|
58
|
+
npm = "ajv"
|
|
59
|
+
|
|
60
|
+
[[tool]]
|
|
61
|
+
name = "xmllint"
|
|
62
|
+
system = true
|
|
63
|
+
brew = "libxml2"
|
|
64
|
+
apt = "libxml2-utils"
|
|
65
|
+
|
|
66
|
+
[[tool_file]]
|
|
67
|
+
target = ".gspot/config/taplo.toml"
|
|
68
|
+
tool = "taplo"
|
|
69
|
+
|
|
70
|
+
[[tool_file]]
|
|
71
|
+
target = ".gspot/config/yamllint.yml"
|
|
72
|
+
tool = "yamllint"
|
|
73
|
+
per_scope = true
|
|
74
|
+
rule_keys = ["rules"]
|
|
75
|
+
|
|
76
|
+
[[tool_file]]
|
|
77
|
+
target = ".gspot/config/v8r.yml"
|
|
78
|
+
tool = "v8r"
|
|
79
|
+
|
|
80
|
+
[[check]]
|
|
81
|
+
name = "taplo"
|
|
82
|
+
example = "The TOML line `enabled =` lacks a value and reports a parse error. Use `enabled = true` when the setting is a boolean."
|
|
83
|
+
level = "recommended"
|
|
84
|
+
stage = "commit"
|
|
85
|
+
command = ["taplo", "check", "--config", "{tool_file:taplo}", "--colors", "never", "{files}"]
|
|
86
|
+
files = { extensions = [".toml"] }
|
|
87
|
+
output = { format = "regex", pattern = "^\\s*┌─ (?<file>(?:[A-Za-z]:)?[^:]+):(?<line>\\d+):(?<column>\\d+)$", message = "The file does not parse as TOML." }
|
|
88
|
+
summary = "Parses every TOML file with taplo; the schema check runs at push through v8r."
|
|
89
|
+
why = "A TOML file that does not parse stops the tool that reads it at the worst moment."
|
|
90
|
+
help = "Fix the line taplo names."
|
|
91
|
+
|
|
92
|
+
[[check]]
|
|
93
|
+
name = "taplo-format"
|
|
94
|
+
example = "The TOML assignment `enabled=true` differs from the configured formatter output. Run the formatter to obtain `enabled = true` and rerun."
|
|
95
|
+
level = "recommended"
|
|
96
|
+
stage = "commit"
|
|
97
|
+
command = ["taplo", "fmt", "--config", "{tool_file:taplo}", "--colors", "never", "--check", "--diff", "{files}"]
|
|
98
|
+
fix = ["taplo", "fmt", "--config", "{tool_file:taplo}", "--colors", "never", "{files}"]
|
|
99
|
+
files = { extensions = [".toml"] }
|
|
100
|
+
output = { format = "regex", pattern = "^(?:--- a/(?<file>.+)|ERROR taplo:format_files: the file is not properly formatted path=\"(?<file>[^\"]+)\")$", message = "The file is not formatted with the configured TOML settings." }
|
|
101
|
+
summary = "Checks that every TOML file is formatted the way taplo formats it with the shared settings."
|
|
102
|
+
why = "One formatter keeps a diff about the values, not the spacing."
|
|
103
|
+
help = "Run gspot check --fix."
|
|
104
|
+
|
|
105
|
+
[[check]]
|
|
106
|
+
name = "yamllint"
|
|
107
|
+
example = "Two `enabled` keys in the same YAML mapping report a duplicate-key finding. Keep the one intended value and remove the duplicate."
|
|
108
|
+
level = "recommended"
|
|
109
|
+
stage = "commit"
|
|
110
|
+
command = ["yamllint", "-c", "{tool_file:yamllint}", "-f", "parsable", "-s", "{files}"]
|
|
111
|
+
files = { extensions = [".yaml", ".yml"] }
|
|
112
|
+
output = { format = "regex", pattern = "^(?<file>[^:]+):(?<line>\\d+):(?<column>\\d+): \\[(?:error|warning)\\] (?<message>.*?)(?: \\((?<rule>[a-z-]+)\\))?$" }
|
|
113
|
+
summary = "Parses every YAML file and checks its indentation, keys, and values with yamllint."
|
|
114
|
+
why = "A YAML file that parses to the wrong shape fails silently: a duplicated key wins, a stray tab changes the nesting."
|
|
115
|
+
help = "Fix the line yamllint names, or set the rule's options with gspot set tools.yamllint.rules."
|
|
116
|
+
|
|
117
|
+
[[check]]
|
|
118
|
+
name = "v8r"
|
|
119
|
+
example = "A governed JSON file with a string where its selected schema requires a boolean reports a schema mismatch. Replace the value with the intended boolean and rerun against the same schema."
|
|
120
|
+
level = "recommended"
|
|
121
|
+
stage = "push"
|
|
122
|
+
needs = ["network"]
|
|
123
|
+
command = ["v8r", "--output-format", "text", "{files}"]
|
|
124
|
+
env = { V8R_CONFIG_FILE = "{tool_file:v8r}" }
|
|
125
|
+
files = { extensions = [".json", ".jsonc", ".yaml", ".yml", ".toml"] }
|
|
126
|
+
output = { format = "regex", pattern = "^(?<file>[^#\\s]+)#(?<message>.+)$" }
|
|
127
|
+
summary = "Validates every tool file that has a known schema against it: package.json, tsconfig.json, mise, workflows and the rest of the SchemaStore catalog."
|
|
128
|
+
why = "A key the schema refuses is a setting that never applies, and nobody finds out until the behavior it was meant to change does not change."
|
|
129
|
+
help = "Fix the key v8r names, or map the file to its schema under tools.v8r.schema."
|
|
130
|
+
|
|
131
|
+
[[check]]
|
|
132
|
+
name = "xmllint"
|
|
133
|
+
example = "The XML text `<settings><enabled>true</settings>` has mismatched tags. Close the child element as `<enabled>true</enabled>` before closing `settings`."
|
|
134
|
+
level = "recommended"
|
|
135
|
+
stage = "commit"
|
|
136
|
+
command = ["xmllint", "--noout", "{files}"]
|
|
137
|
+
files = { extensions = [".xml", ".storyboard", ".xib"] }
|
|
138
|
+
output = { format = "regex", pattern = "^(?<file>[^:]+):(?<line>\\d+): (?<message>.*)$" }
|
|
139
|
+
summary = "Parses every XML file with xmllint."
|
|
140
|
+
why = "Malformed XML is refused by the reader at the worst moment."
|
|
141
|
+
help = "Fix the line xmllint names."
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# YAML
|
|
2
|
+
|
|
3
|
+
Rules for every `.yml` and `.yaml` file.
|
|
4
|
+
|
|
5
|
+
- Keep one document per file unless the consumer requires a stream.
|
|
6
|
+
- Quote strings that YAML otherwise reinterprets: `yes`, `no`, `on`, `off`, `null`, `~`,
|
|
7
|
+
version numbers such as `1.10`, octal-looking values, and anything starting with `*`, `&`, `!`,
|
|
8
|
+
`%`, `@`, or a backtick.
|
|
9
|
+
- Keep anchors and aliases inside one file. Name them for what they carry. No merge keys
|
|
10
|
+
across documents.
|
|
11
|
+
- Long strings use a block scalar, `|` or `>`, rather than a quoted string with escapes.
|
|
12
|
+
|
|
13
|
+
## Organization
|
|
14
|
+
|
|
15
|
+
<!-- level: all -->
|
|
16
|
+
|
|
17
|
+
- Order keys as the consumer documents, then alphabetically. Do not reorder keys in a file
|
|
18
|
+
you did not otherwise change.
|
|
19
|
+
- Use `.yml` for GitHub workflows, `compose.yaml` for Compose, and `.yaml` elsewhere.
|