Guide for adding new YAML linting rules to pg2sqlite-rs. Use when implementing a new validation rule, creating a linting feature, or when the user mentions adding rules like "truthy", "comments", "braces", etc.
インストール
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
Guide for adding new YAML linting rules to pg2sqlite-rs. Use when implementing a new validation rule, creating a linting feature, or when the user mentions adding rules like "truthy", "comments", "braces", etc.
Adding New Validation Rules
This skill provides step-by-step guidance for implementing new YAML linting rules in the pg2sqlite-rs project.
Quick Checklist
When adding a new rule, complete these steps in order:
Create rule file: core/src/rules/<rule_name>.rs
Register in core/src/rules/mod.rs
Add to presets in core/src/config.rs
Add unit tests (minimum 10+ test cases)
Create test fixture: tests/fixtures/invalid/<rule-name>.yaml
Add integration test in core/tests/integration_tests.rs
Update docs/RULES.md
Update README.md rule list
Run make ci and make validate-fixtures to verify
Create PR
Step 1: Create Rule File
Create core/src/rules/<rule_name>.rs with this template:
// In with_default_preset():
config.rules.insert("<rule-name>".to_string(), RuleLevel::Error);
// or RuleLevel::Warning for less critical rules// In with_relaxed_preset():
config.rules.insert("<rule-name>".to_string(), RuleLevel::Warning);
Create an invalid YAML fixture file at tests/fixtures/invalid/<rule-name>.yaml:
# File demonstrating <rule-name> violations# This file should trigger the rule multiple times# Example for truthy rule:enabled:yesdisabled:noflag:on# Example for trailing-spaces rule:key:valueanother:test
Fixture Guidelines:
Include a comment at the top explaining the violations
Include multiple violations (3+ recommended)
Cover different scenarios the rule checks
Keep it focused on ONE rule per fixture file
Directory Structure:
tests/fixtures/
├── invalid/ # Files with lint errors
│ ├── <rule-name>.yaml
│ ├── trailing-spaces.yaml
│ └── ...
└── valid/ # Files that should pass all rules
├── simple.yaml
└── ...
Step 6: Add Integration Test
Edit core/tests/integration_tests.rs to add a test for the new rule:
#[test]fntest_<rule_name>_detected() {
letlinter = Linter::with_defaults();
letpath = fixture_path("invalid/<rule-name>.yaml");
letproblems = linter.lint_file(&path).expect("Failed to lint file");
assert!(!problems.is_empty(), "Expected to find <rule-name> violations");
// Verify expected number of problemsletrule_problems: Vec<_> = problems
.iter()
.filter(|p| p.rule == "<rule-name>")
.collect();
assert_eq!(
rule_problems.len(),
3, // Adjust based on your fixture"Expected 3 <rule-name> problems"
);
// Verify rule nameforproblemin &rule_problems {
assert_eq!(problem.rule, "<rule-name>");
}
}
Also update:
- Preset documentation (if rule is in default/relaxed)
- Remove from "Future Rules" section if listed there
## Step 8: Update README.md
Add to the "Implemented Rules" section:
```markdown
N. **<rule-name>** - <Brief description>
- Level: Error/Warning
- Options: `option1`, `option2` (if configurable)
Update "Future Rules" section if needed.
Step 9: Run CI
make ci # fmt-check + clippy + test
make validate-fixtures # Validate test fixtures
Fix any issues:
make fmt for formatting
Address clippy warnings
Fix failing tests
Fixture Validation:
make validate-fixtures runs the linter on all fixtures and verifies:
Valid fixtures produce 0 errors
Invalid fixtures produce expected errors
Step 10: Create PR
git checkout -b feature/<issue-number>-<rule-name>-rule
git add -A
git commit -m "feat: Add \`<rule-name>\` rule
<Description of what the rule does>
Closes #<issue-number>"
git push -u origin feature/<issue-number>-<rule-name>-rule
gh pr create --title "feat: Add \`<rule-name>\` rule" --body "..."
Common Patterns
Handling Quoted Strings
Use peekable iterator for proper YAML string parsing: