Skip to content

Commit f75c4f8

Browse files
committed
chore: add Prettier, Husky pre-commit, and format config
- Add Prettier with package.json for YAML, JSON, Markdown - Add Husky pre-commit (Prettier check, Mago format/lint --staged) - Update .editorconfig: 2-space default, 4-space for PHP/composer.json - Add node_modules to .gitignore - Add composer check script and npm format/check aliases - Associate llms.txt as markdown in VS Code and Prettier
1 parent 6ac4737 commit f75c4f8

26 files changed

Lines changed: 1446 additions & 487 deletions

.editorconfig

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@ root = true
22

33
[*]
44
indent_style = space
5-
indent_size = 4
5+
indent_size = 2
66
end_of_line = lf
77
charset = utf-8
88
trim_trailing_whitespace = true
99
insert_final_newline = true
1010

1111
[*.md]
1212
trim_trailing_whitespace = false
13+
14+
[*.php]
15+
indent_size = 4
16+
17+
[composer.json]
18+
indent_size = 4

.github/workflows/ci.yml

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,55 @@
11
name: CI
22

33
on:
4-
push:
5-
branches: [main]
6-
pull_request:
7-
branches: [main]
8-
workflow_dispatch:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
workflow_dispatch:
99

1010
jobs:
11-
ci:
12-
name: Lint, Analyse, Test
13-
runs-on: ubuntu-latest
14-
timeout-minutes: 15
15-
16-
steps:
17-
- name: Checkout
18-
uses: actions/checkout@v4
19-
20-
- name: Setup PHP
21-
uses: shivammathur/setup-php@v2
22-
with:
23-
php-version: "8.3"
24-
tools: composer:v2
25-
coverage: none
26-
27-
- name: Get Composer cache directory
28-
id: composer-cache
29-
run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"
30-
31-
- name: Cache Composer packages
32-
uses: actions/cache@v4
33-
with:
34-
path: ${{ steps.composer-cache.outputs.dir }}
35-
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
36-
restore-keys: |
37-
${{ runner.os }}-composer-
38-
39-
- name: Validate Composer
40-
run: composer validate --strict --no-check-publish
41-
42-
- name: Install dependencies
43-
run: composer install --no-interaction --no-progress --prefer-dist
44-
45-
- name: Platform check
46-
run: composer platform-check
47-
48-
- name: Lint
49-
run: composer lint
50-
51-
- name: Static analysis
52-
run: composer analyse
53-
54-
- name: Tests
55-
run: composer test
11+
ci:
12+
name: Lint, Analyse, Test
13+
runs-on: ubuntu-latest
14+
timeout-minutes: 15
15+
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v4
19+
20+
- name: Setup PHP
21+
uses: shivammathur/setup-php@v2
22+
with:
23+
php-version: "8.3"
24+
tools: composer:v2
25+
coverage: none
26+
27+
- name: Get Composer cache directory
28+
id: composer-cache
29+
run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"
30+
31+
- name: Cache Composer packages
32+
uses: actions/cache@v4
33+
with:
34+
path: ${{ steps.composer-cache.outputs.dir }}
35+
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
36+
restore-keys: |
37+
${{ runner.os }}-composer-
38+
39+
- name: Validate Composer
40+
run: composer validate --strict --no-check-publish
41+
42+
- name: Install dependencies
43+
run: composer install --no-interaction --no-progress --prefer-dist
44+
45+
- name: Platform check
46+
run: composer platform-check
47+
48+
- name: Lint
49+
run: composer lint
50+
51+
- name: Static analysis
52+
run: composer analyse
53+
54+
- name: Tests
55+
run: composer test

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/vendor/
2+
/node_modules/
23
/temp/

.husky/pre-commit

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
npx lint-staged
2+
vendor/bin/mago format --staged
3+
vendor/bin/mago lint --staged

.prettierignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
vendor/
2+
node_modules/
3+
temp/
4+
*.lock
5+
package-lock.json
6+
composer.json
7+
.vscode/

.prettierrc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,8 @@
1-
{}
1+
{
2+
"overrides": [
3+
{
4+
"files": "llms.txt",
5+
"options": { "parser": "markdown" }
6+
}
7+
]
8+
}

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"editor.formatOnSave": true,
3+
"files.associations": {
4+
"llms.txt": "markdown"
5+
},
36
"files.exclude": {
47
"composer.lock": true,
58
"vendor": true

AGENTS.md

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,33 @@ PHP validation library inspired by Valibot and Zod. Type-safe, fluent API for pr
66

77
Core validation logic lives in `src/Lemmon/Validator/`. Tests in `tests/` follow `XValidatorTest.php` naming. Key project files:
88

9-
- `llms.txt` - Technical spec for external/consumer use; API signatures, null handling, transformation types
10-
- `ROADMAP.md` - Strategic planning and checkboxes
11-
- `TASKS.md` - Immediate task pool (keep short, no numbering)
12-
- `CHANGELOG` - Completed work
13-
- `IDEAS` - Exploration
9+
- `llms.txt` - Technical spec for external/consumer use; API signatures, null handling, transformation types
10+
- `ROADMAP.md` - Strategic planning and checkboxes
11+
- `TASKS.md` - Immediate task pool (keep short, no numbering)
12+
- `CHANGELOG` - Completed work
13+
- `IDEAS` - Exploration
1414

1515
## Architecture
1616

17-
- **Namespace:** `Lemmon\Validator` (runtime), `Lemmon\Tests` (tests)
18-
- **Core:** `Validator` static factory; `FieldValidator` base; `ValidationException` for errors
19-
- **Validators:** `isString`, `isInt`, `isFloat`, `isBool`, `isArray`, `isAssociative`, `isObject`
20-
- **Shared:** `NumericConstraintsTrait` (min, max, multipleOf, etc.); `PipelineType` enum; variant enums `IpVersion`, `Base64Variant`, `UuidVariant` for format methods
21-
- **String formats:** email, URL, UUID, IP, hostname, domain, time, base64, hex, regex, datetime, date
22-
- **Schema validation:** AssociativeValidator/ObjectValidator with nested error aggregation
23-
- **Logical combinators:** `Validator::allOf`, `anyOf`, `not`; instance `satisfiesAny`, `satisfiesAll`, `satisfiesNone`; `const()` for single allowed value; `enum()` for BackedEnum
24-
- **Behavior:** Optional by default (null allowed unless `required()`); form-safe coercion (empty string → null, not 0/false); pipeline order guaranteed; fail-fast per field; `satisfies()` accepts validators or callables with `(value, key, input)`; extend via `satisfies()`, not custom validators
17+
- **Namespace:** `Lemmon\Validator` (runtime), `Lemmon\Tests` (tests)
18+
- **Core:** `Validator` static factory; `FieldValidator` base; `ValidationException` for errors
19+
- **Validators:** `isString`, `isInt`, `isFloat`, `isBool`, `isArray`, `isAssociative`, `isObject`
20+
- **Shared:** `NumericConstraintsTrait` (min, max, multipleOf, etc.); `PipelineType` enum; variant enums `IpVersion`, `Base64Variant`, `UuidVariant` for format methods
21+
- **String formats:** email, URL, UUID, IP, hostname, domain, time, base64, hex, regex, datetime, date
22+
- **Schema validation:** AssociativeValidator/ObjectValidator with nested error aggregation
23+
- **Logical combinators:** `Validator::allOf`, `anyOf`, `not`; instance `satisfiesAny`, `satisfiesAll`, `satisfiesNone`; `const()` for single allowed value; `enum()` for BackedEnum
24+
- **Behavior:** Optional by default (null allowed unless `required()`); form-safe coercion (empty string → null, not 0/false); pipeline order guaranteed; fail-fast per field; `satisfies()` accepts validators or callables with `(value, key, input)`; extend via `satisfies()`, not custom validators
2525

2626
## Build, Test, and Development Commands
2727

28-
- `composer test` - Run Pest test suite
29-
- `composer lint` / `composer format` - Mago linting and formatting (dev dependency)
30-
- `composer analyse` - PHPStan at max level
31-
- `composer platform-check` - Verify PHP 8.3 and extension requirements
28+
- `composer test` - Run Pest test suite
29+
- `composer lint` / `composer format` - Mago linting and formatting (dev dependency)
30+
- `composer analyse` - PHPStan at max level
31+
- `composer platform-check` - Verify PHP 8.3 and extension requirements
32+
- `composer check` - Run all checks (platform, format, lint, Prettier, test, analyse); use before PR
33+
- `npm run format` - Prettier for YAML, JSON, Markdown
34+
- `npm run check` - Alias for `composer check`
35+
- Pre-commit hook (Husky): Prettier check, Mago format --staged, Mago lint --staged
3236

3337
`config.platform.php` is set to `8.3.0` so dependency resolution targets PHP 8.3; `composer update`/`install` will not add packages that require PHP above 8.3.
3438

@@ -40,21 +44,21 @@ PSR-12 for PHP. Mago for lint/format (`composer lint`, `composer format`). Prett
4044

4145
## Commit Message Guidelines
4246

43-
- Commit messages must follow Conventional Commits
44-
- Write messages so they make sense for commit-by-commit development: each commit describes the actual state change from the previous shipped state. Do not mention intermediate or throwaway steps (e.g. classes created and removed in the same session). Describe what the commit delivers, not the path taken to get there
45-
- Subject format: `<type>(<scope>): <summary>`; use `<type>: <summary>` when scope is omitted
46-
- Allowed `type` values: `feat`, `fix`, `refactor`, `perf`, `docs`, `test`, `build`, `ci`, `chore`, `revert`
47-
- `scope` is optional but recommended when it narrows the area (e.g. `StringValidator`, `FieldValidator`, `AssociativeValidator`)
48-
- Write summary lines in imperative mood, keep them concise (around 72 characters recommended, not strict), and omit trailing periods
49-
- Keep each commit focused on one concern; include related tests or validation updates in the same commit when applicable
50-
- Prefer bullet lists in commit bodies for concrete changes, with one logical change per bullet
51-
- Commit body bullets should start with a capitalized imperative verb and omit trailing periods
52-
- Never artificially break lines anywhere in a commit message; tools wrap naturally
53-
- Avoid unnecessary noise in commit bodies; include only explicit, intentional, non-obvious updates
54-
- Do not call out secondary artifact changes (for example lockfile refreshes) unless they carry non-obvious impact
55-
- Add a short prose paragraph only when extra context is needed (rationale, tradeoffs, migration notes, risks, or non-obvious impact)
56-
- Separate subject, body, and footers with blank lines
57-
- Use optional footers in `Key: Value` format; preferred keys: `Refs`, `Closes`, `Fixes`, `PR`, `BREAKING CHANGE`
58-
- Breaking changes must include a `BREAKING CHANGE:` footer
59-
- Release notes belong in CHANGELOG, not commit body. Tag format: annotated `vX.Y.Z - <headline>`; details in CHANGELOG/releases
60-
- Quick templates: `fix(scope): <imperative summary>` and `feat(scope): <imperative summary>`
47+
- Commit messages must follow Conventional Commits
48+
- Write messages so they make sense for commit-by-commit development: each commit describes the actual state change from the previous shipped state. Do not mention intermediate or throwaway steps (e.g. classes created and removed in the same session). Describe what the commit delivers, not the path taken to get there
49+
- Subject format: `<type>(<scope>): <summary>`; use `<type>: <summary>` when scope is omitted
50+
- Allowed `type` values: `feat`, `fix`, `refactor`, `perf`, `docs`, `test`, `build`, `ci`, `chore`, `revert`
51+
- `scope` is optional but recommended when it narrows the area (e.g. `StringValidator`, `FieldValidator`, `AssociativeValidator`)
52+
- Write summary lines in imperative mood, keep them concise (around 72 characters recommended, not strict), and omit trailing periods
53+
- Keep each commit focused on one concern; include related tests or validation updates in the same commit when applicable
54+
- Prefer bullet lists in commit bodies for concrete changes, with one logical change per bullet
55+
- Commit body bullets should start with a capitalized imperative verb and omit trailing periods
56+
- Never artificially break lines anywhere in a commit message; tools wrap naturally
57+
- Avoid unnecessary noise in commit bodies; include only explicit, intentional, non-obvious updates
58+
- Do not call out secondary artifact changes (for example lockfile refreshes) unless they carry non-obvious impact
59+
- Add a short prose paragraph only when extra context is needed (rationale, tradeoffs, migration notes, risks, or non-obvious impact)
60+
- Separate subject, body, and footers with blank lines
61+
- Use optional footers in `Key: Value` format; preferred keys: `Refs`, `Closes`, `Fixes`, `PR`, `BREAKING CHANGE`
62+
- Breaking changes must include a `BREAKING CHANGE:` footer
63+
- Release notes belong in CHANGELOG, not commit body. Tag format: annotated `vX.Y.Z - <headline>`; details in CHANGELOG/releases
64+
- Quick templates: `fix(scope): <imperative summary>` and `feat(scope): <imperative summary>`

0 commit comments

Comments
 (0)