Skip to content

Demo: repo-wide style enforcement (.editorconfig, Prettier, .gitattributes)#18

Open
joewiz wants to merge 3 commits into
pr/modernize-eXide-cleanfrom
chore/style-enforcement-demo
Open

Demo: repo-wide style enforcement (.editorconfig, Prettier, .gitattributes)#18
joewiz wants to merge 3 commits into
pr/modernize-eXide-cleanfrom
chore/style-enforcement-demo

Conversation

@joewiz
Copy link
Copy Markdown
Owner

@joewiz joewiz commented May 20, 2026

Note: This PR is opened on the joewiz fork (not eXist-db/eXide) to facilitate discussion among the eXide devs before deciding whether/how to land this upstream.

Goals

After noticing eXist-db#796 silently flipped a few lines from spaces to tabs in src/util.js, we wanted to look at what it would take to enforce a consistent style across the repo automatically — so reviewers don't have to spot indent flips by eye and so contributors get correct formatting from their editor with zero local setup.

This PR explores three lightweight, complementary mechanisms plus a demonstration of the effect:

  1. .editorconfig — picked up automatically by VS Code, JetBrains, Vim plugins, etc. Establishes baseline indentation and line-ending rules without requiring any tooling.
  2. .gitattributes — pins eol=lf so Windows contributors can't introduce CRLF churn.
  3. Prettier config — eXide already depends on prettier, @prettier/plugin-xml, and prettier-plugin-xquery (used internally by the editor's Format command). This PR exposes that same formatter as a repo-level check.

What's in here

Commit 1 — config files only (no source changes)

File Purpose
.editorconfig 2-space indent for JS/TS/CSS/JSON/YAML/Markdown (modern community convention); 4-space for XQuery/XML/HTML/template (existing project style). LF, trim trailing whitespace, final newline.
.gitattributes text=auto eol=lf + binary file list.
.prettierrc.json Global tabWidth 2; XML/XQuery overrides bump back to 4. xmlSelfClosingSpace: false so <br/> and <?xml ... ?> emit without the (long-obsolete) XHTML-compat leading space.
.prettierignore Skips generated bundles, REx-generated parsers, vendored support tree, build output, lockfiles.
package.json Adds npm run format and npm run format:check.
.gitignore Allowlists the four new dotfiles past the existing .* rule.

Landing just commit 1 is essentially free — no source changes, just future safety.

Commit 2 — demo: npm run format applied across the repo

This is the "what would happen if we hit the button" commit. 143 files changed, ~31.6k inserts / ~27.2k deletes.

File type Files Lines inserted Indent
.js 95 20,966 2
.css 5 3,502 2
.svg 3 2,266 2
.xqm 15 1,593 4
.json 4 1,557 2
.tmpl 2 840 4
.xq 7 428 4
.xml 4 240 4
.xsd 1 98 4
.html 2 63 4
.md 2 35 2
.yml 2 30 2
.xconf 1 1 4

All 179 unit tests pass after the sweep.

How to run the checks

npm run format:check  # read-only — exits non-zero if any file would change
npm run format        # apply
npx prettier --check src/util.js   # one file

A CI gate (prettier --check . in GitHub Actions) is the natural follow-up — soft warning first, then hard fail.

Options for landing this

Commits are organized so that we can land just commit 1 (config baseline, no source churn), or both. The big format sweep is optional and deliberately separable. A few plausible paths:

  1. Land config only. Future PRs run prettier on touched files; everything else stays as-is. Slow but invisible.
  2. Land config + sweep as a single commit on develop. One-time disruption, clean baseline going forward. Pair with .git-blame-ignore-revs so git blame skips the format-only commit on GitHub.
  3. Split the sweep into per-file-type PRs to ease review.
  4. Drop the sweep, just land config + CI check. New PRs are automatically formatted; old code drifts toward correctness over time.

Open questions for discussion

  • 2-space vs 4-space JS. Modern norm is 2-space (Airbnb/Standard/Google/npm); eXide is currently mixed (some tabs, some 4-space). This PR proposes 2-space. The 4-space variant produces ~12k inserted lines instead of ~21k — smaller diff but locks in a less-conventional style. Genuinely open to flipping.
  • XQuery formatter scope. prettier-plugin-xquery (DrRataplan) only supports XQuery 3.1. If we have any 4.0-specific syntax in .xq/.xqm files, they need an explicit ignore.
  • Timing. A 143-file diff invalidates every open PR's merge base. Best landed during a quiet window.
  • Hooks? Should we also add lint-staged + a pre-commit hook so contributors don't have to remember to run npm run format? Or just rely on CI to nag them?

Risk / verification

  • 179 unit tests pass before and after the sweep.
  • No semantic changes — pure formatting.
  • Generated bundles, REx parsers, and the support/ tree are excluded so we don't fight the build pipeline.

Credits

Initiated after noticing eXist-db#796 flipped indentation in src/util.js from spaces to tabs. Cc @duncdrum, @line-o, @wolfgangmm, @dizzzz, @reinhapa for input.

🤖 [This PR description was co-authored with Claude Code. -Joe]

joewiz and others added 2 commits May 19, 2026 22:56
Establishes baseline style enforcement without changing any source files:

- .editorconfig — 2-space indent for JS/TS/CSS/JSON/YAML/Markdown
  (modern community convention); 4-space for XQuery/XML/HTML/template
  (per existing project style). LF, trim trailing whitespace, final
  newline. Picked up by VS Code, JetBrains, Vim, etc.
- .gitattributes (text=auto eol=lf + binary list) — prevents CRLF
  churn from Windows contributors.
- .prettierrc.json with overrides for XML, XQuery, Markdown, JSON, YAML;
  wires up @prettier/plugin-xml and prettier-plugin-xquery. Global
  tabWidth: 2; XML/XQuery overrides bump back to 4. XML parser uses
  xmlSelfClosingSpace: false so <br/> and <?xml ... ?> emit without
  the XHTML-compat leading space.
- .prettierignore for generated bundles, REx-generated parsers, the
  vendored support/ tree, build output, lockfiles.
- npm scripts: `format` (write) and `format:check` (read-only CI check).
- .gitignore: allowlist the four new dotfiles past the `.*` rule.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Demonstrates the effect of adopting the style config in the prior
commit. Files reformatted across JS, XQuery, XML, CSS, JSON, YAML,
Markdown, SVG, HTML/template. All 179 unit tests pass. No semantic
changes.

JS lines comprise most of the diff because Prettier flips 4-space
indent (and original mixed tabs) to 2-space — the dominant modern JS
convention (Airbnb, Standard, Google style guide, npm packages).
XQuery/XML/HTML stay at 4-space per existing project style.

This commit is the "what would happen if we ran npm run format" demo
and is meant to be inspected, not necessarily merged as-is. Options:
  - keep as a single mechanical sweep
  - split per directory / file type for easier review
  - drop and let prettier apply file-by-file as code is touched

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@duncdrum
Copy link
Copy Markdown

duncdrum commented May 20, 2026

Leave the two commits, and add the prehook.

As for churn now is a good time. 2 spaces is fine for js.

Xq4 is not for this release, but I have faith in prettier support coming soon™

Per @duncdrum's review on #18: add a pre-commit hook so
contributors don't need to remember `npm run format`. Staged files
matching the prettier-managed patterns are auto-formatted before each
commit; the commit is rejected if prettier can't parse the file (e.g.
syntax errors).

- Install `husky` and `lint-staged` as devDeps
- `package.json`: add `"prepare": "husky"` so the hook is wired up on
  fresh `npm install`; add `lint-staged` config covering js/css/json/
  yaml/md (2-space) and xq/xqm/xml/xsd/html/tmpl/xconf/svg (4-space)
- `.husky/pre-commit`: runs `npx lint-staged`
- `.gitignore`: allowlist `.husky/` past the `.*` rule (but keep
  `.husky/_` ignored — that's husky's runtime-generated dir)

`package-lock.json` is also re-indented from tabs to 2 spaces by this
install — npm's lockfile output now respects the project's
.editorconfig. Net cosmetic; future `npm install` runs will keep it
consistent.
@joewiz
Copy link
Copy Markdown
Owner Author

joewiz commented May 20, 2026

[This response was co-authored with Claude Code. -Joe]

Pushed e12c2cb adding the pre-commit hook per your feedback, @duncdrum. Summary of how I'm reading your comment:

  • ✅ "Leave the two commits" — kept (the new commit is a third one for the hook itself, separate from the config baseline + format sweep).
  • ✅ "Add the prehook" — done. husky + lint-staged, hook runs npx lint-staged on staged files. Smoke-tested locally: deliberately-misformatted JS gets caught, valid files get auto-prettied in place. The hook installs automatically on fresh npm install via the prepare script.
  • ✅ "Churn now is a good time" — agreed in principle, but I'd like to delay the upstream PR (eXist-db/eXide) until Modernize eXide: CM6 editor, REx parser, Roaster API, LSP integration eXist-db/eXide#794 lands and the freeze settles, to avoid invalidating its merge base today. This joewiz PR is fine to grow in the meantime.
  • ✅ "2 spaces is fine for js" — confirmed by the .prettierrc.json already in commit 1.
  • ✅ XQ4 deferred to future prettier-plugin-xquery support — noted, no action.

The diff is unfortunately noisy because the npm install for husky/lint-staged also re-indented package-lock.json from tabs to 2 spaces (npm now respects .editorconfig). The substantive changes are in package.json, .husky/pre-commit, and .gitignore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants