GritQL Custom Rules
GritQL is a powerful pattern-matching language that allows you to write custom lint rules for your FSH project.
What is GritQL?
Section titled “What is GritQL?”GritQL is a query language designed for code analysis and transformation. It lets you:
- Match code patterns using intuitive syntax
- Capture matched values in variables
- Apply complex predicates and conditions
- Generate diagnostic messages and fixes
Basic Syntax
Section titled “Basic Syntax”Simple Pattern Matching
Section titled “Simple Pattern Matching”Match a profile definition:
Profile: $nameThis matches any profile and captures its name in $name.
Field Matching
Section titled “Field Matching”Match profiles with specific properties:
Profile: $nameParent: PatientPattern Variables
Section titled “Pattern Variables”Variables capture matched content:
$name- Captures an identifier$_- Matches anything (anonymous)$...rest- Captures remaining items
Writing Custom Rules
Section titled “Writing Custom Rules”Rule File Structure
Section titled “Rule File Structure”Create .grit files in your custom rules directory:
// Rule metadatalanguage fshdescription "Profile constraints should have MS flag"severity warning
// Pattern to matchpattern { Profile: $profile_name * $path $card}
// Conditionwhere { // Check if MS flag is missing !contains($card, "MS")}
// Messagemessage "Add MS (Must Support) flag to constraint"Loading Custom Rules
Section titled “Loading Custom Rules”Configure custom rule directories in maki.json:
{ "linter": { "ruleDirectories": [ "./custom-rules", "./org-rules" ] }}Example Rules
Section titled “Example Rules”Require Must Support Flags
Section titled “Require Must Support Flags”language fshdescription "Profile constraints should use MS flag"severity warning
pattern { Profile: $_ * $path 1..1}
where { !contains($path, "MS")}
message "Add MS flag to required elements"Enforce Naming Patterns
Section titled “Enforce Naming Patterns”language fshdescription "ValueSets must end with 'VS'"severity error
pattern { ValueSet: $name}
where { !ends_with($name, "VS")}
message "ValueSet names should end with 'VS'"fix { ValueSet: `${name}VS`}Detect Missing Descriptions
Section titled “Detect Missing Descriptions”language fshdescription "Profiles must have descriptions"severity warning
pattern { Profile: $name $...body}
where { !contains($body, "Description:")}
message "Profile '${name}' is missing a description"Advanced Patterns
Section titled “Advanced Patterns”Using Wildcards
Section titled “Using Wildcards”// Match any resource type$resource_type: $namewhere { $resource_type in ["Profile", "Extension", "ValueSet"]}Nested Patterns
Section titled “Nested Patterns”Profile: $name* $path from $valueset (required)where { !exists($valueset)}message "ValueSet '${valueset}' not found"Multiple Conditions
Section titled “Multiple Conditions”Profile: $name* $path $cardwhere { $card == "1..1" and !contains($path, "MS") and !contains($path, "^")}Testing Custom Rules
Section titled “Testing Custom Rules”Test your rules before deploying:
# Run only custom rulesmaki lint --only-custom-rules **/*.fsh
# Test specific rulemaki lint --rule custom/require-ms-flag test.fshBest Practices
Section titled “Best Practices”- Start Simple - Begin with basic pattern matching
- Test Thoroughly - Test on various FSH files
- Provide Clear Messages - Help users understand the issue
- Include Fixes - Provide automated fixes when possible
- Document Rules - Explain why the rule exists
See Also
Section titled “See Also”- GritQL Documentation - Complete GritQL reference
- Built-in Rules - Examples of rule implementation
- Custom Rules Guide - Detailed guide