- JavaScript 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| bin | ||
| eslint | ||
| prettier | ||
| .gitignore | ||
| bun.lock | ||
| bunfig.toml | ||
| editorconfig | ||
| lefthook.yml | ||
| LICENSE | ||
| package.json | ||
| prettier.config.js | ||
| README.md | ||
| rustfmt.toml | ||
@opengrind/config
Shared ESLint, Prettier, lefthook, rustfmt and EditorConfig settings for the Open Grind repositories.
Install
Point the scope at the Forgejo registry in bunfig.toml:
[install.scopes]
"@opengrind" = { url = "https://git.opengrind.org/api/packages/open-grind/npm/" }
bun add -d @opengrind/config
Consumers declare only eslint and prettier. Every plugin is a dependency of this package and resolves from it.
Keep it in devDependencies. It is lint-time only and must never enter a bundler's import graph, or it becomes part of a reproducible build.
ESLint
SvelteKit app:
import { sveltekit } from "@opengrind/config/eslint/svelte";
import { defineConfig } from "eslint/config";
import svelteConfig from "./svelte.config.js";
export default defineConfig(
...sveltekit({
svelteConfig,
tailwindEntry: "src/layout.css",
vendoredGlob: "src/lib/components/ui/**",
ignores: [
"src-tauri/",
"reverse/",
"docs/",
"contrib/",
"static/",
"scripts/",
],
}),
);
svelteConfig is passed in because a repo's svelte.config.js may run arbitrary code at import time, so this package cannot import it.
Browser extension:
import { webextension } from "@opengrind/config/eslint/webext";
export default webextension();
Plain TypeScript:
import { typescriptBase } from "@opengrind/config/eslint";
Prettier
// prettier.config.js
import { sveltekit } from "@opengrind/config/prettier/svelte";
export default sveltekit({ tailwindStylesheet: "./src/layout.css" });
Non-Svelte repos can use the package.json field instead:
{ "prettier": "@opengrind/config/prettier" }
Git hooks
Every repo uses lefthook, installed as a dev dependency so it bootstraps with bun install:
bun add -d lefthook
bunx lefthook install
# lefthook.yml
extends:
- node_modules/@opengrind/config/lefthook.yml
Clippy and cargo test are not shared, because they need a manifest path that differs per repo (src-tauri/Cargo.toml in the Tauri apps, the root in the library crates), and a consumer cannot correct a shared command because the shared file wins on a name clash. Each Rust repo adds its own:
pre-commit:
commands:
clippy:
glob: "*.rs"
run: cargo clippy --manifest-path src-tauri/Cargo.toml --all-targets
A repo can add commands and can opt out of a shared one with skip: true, but it cannot override a shared command's run.
Clippy runs without -D warnings, deny warnings in CI instead.
rustfmt and EditorConfig
rustfmt has no extends mechanism and does not read .editorconfig, so these two ship as files to copy:
cp node_modules/@opengrind/config/rustfmt.toml rustfmt.toml
cp node_modules/@opengrind/config/editorconfig .editorconfig
Guard against drift in CI:
diff -q rustfmt.toml node_modules/@opengrind/config/rustfmt.toml
diff -q .editorconfig node_modules/@opengrind/config/editorconfig
The comparison is against the pinned package, so it needs no network and fails only after you bump the version.
max_line_length = 80 matches Prettier's default printWidth and rustfmt's max_width. Prettier reads .editorconfig, so changing it reformats the tree.
Releasing
OG_REGISTRY_TOKEN=<forgejo-token> bun publish
Bump version first. The registry rejects a re-publish of an existing name and version.