# Git hooks (Husky + lint-staged)

Local quality gates for this monorepo:

| Hook         | When         | What runs                                                                                                                                                                |
| ------------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `pre-commit` | `git commit` | [lint-staged](https://github.com/lint-staged/lint-staged): **Prettier write** (restaged) **+** Nx-scoped ESLint `--fix` on staged files via `scripts/lint-staged-nx.mjs` |
| `pre-push`   | `git push`   | `npm test` (utilities + media-player build/test, then `@tgmc/web` Vitest)                                                                                                |

Lint always includes Prettier, then Nx ESLint:

| Script                             | Prettier                           | ESLint                                                                               |
| ---------------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------ |
| `npm run lint`                     | `prettier -wl .` (`format`)        | `nx run-many -t lint` (all packages with lint)                                       |
| `npm run lint:affected`            | `prettier -wl .` (`format`)        | `nx affected -t lint`                                                                |
| `npm run lint:staged` / pre-commit | `prettier --write` on staged files | `scripts/lint-staged-nx.mjs` (Nx affected projects → ESLint `--fix` on staged paths) |

Nx lint covers every project that defines a `lint` target (inferred via `@nx/eslint`): `@tgmc/web`, `tgmc-web-layer-base`, `@tgmc/utilities`, `@tgmc/media-player`, `@tgmc/web-e2e`.

**Prettier does not execute on GitHub.** `eslint-plugin-prettier` stays in the ESLint config; when `GITHUB_ACTIONS=true`, `prettier/prettier` is set to `off` so CI does not run Prettier. Formatting is enforced by husky/lint-staged and `npm run format` locally.

## Line endings (LF only)

All text files use **LF** (`\n`), never CRLF:

| Layer        | Setting                                 |
| ------------ | --------------------------------------- |
| Prettier     | `"endOfLine": "lf"` in `.prettierrc`    |
| EditorConfig | `end_of_line = lf` in `.editorconfig`   |
| Git          | `.gitattributes` → `* text=auto eol=lf` |

On Windows, set the **local** clone (not global) so Git does not rewrite checkouts to CRLF:

```bash
git config core.autocrlf false
git config core.eol lf
```

If Prettier/ESLint report `Delete ␍`, renormalize once: `git add --renormalize .` then commit the line-ending-only changes (or run `npm run format` on the affected paths).

## Setup

Hooks install automatically via the root `prepare` script (`node scripts/husky-prepare.mjs`) after local `npm install`.

**GitHub Actions / CI:** Husky is not used. `scripts/husky-prepare.mjs` skips when `CI`, `GITHUB_ACTIONS`, or `HUSKY=0` is set; workflows set `HUSKY=0` so `npm ci` and bot commits never install or run hooks.

```bash
npm install
# equivalent: npm run prepare
```

Skip hooks for a single local command when needed:

```bash
HUSKY=0 git commit -m "..."
HUSKY=0 git push
```

## Manual runs

```bash
# Same as pre-commit (against currently staged files)
npm run lint:staged

# Prettier (whole repo) + lint all Nx packages with a lint target
npm run lint

# Prettier (whole repo) + lint projects affected by the working tree
npm run lint:affected

# Format only
npm run format

# Same as pre-push
npm test
```

## Config

- Prettier: root `.prettierrc` / `.prettierignore`
- lint-staged: `lint-staged.config.mjs` + `scripts/lint-staged-nx.mjs` (Prettier + Nx project selection + ESLint `--fix` on staged files)
- Full-package Nx lint: `@nx/eslint` plugin (`nx.json`) → `nx run-many -t lint` / `nx affected -t lint` (used by `npm run lint` / `lint:affected`)
- Hooks: `.husky/pre-commit`, `.husky/pre-push` (installed by local `prepare` → `scripts/husky-prepare.mjs`; skipped in CI)
