Checker YAML Interface
Custom checkers in Globstar are defined using YAML files in your .globstar directory. Each checker is a separate YAML file that defines what to look for and how to report issues.
Example Checker
yaml
# .globstar/no_console_log.yml
language: js
name: js_no_console_log
message: "Avoid using console.log in production code"
category: style
severity: warning
pattern: |
(
call_expression
(member_expression
object: (identifier) @console (#eq? @console "console")
property: (property_identifier) @method (#eq? @method "log"))
) @js_no_console_log
filters:
- pattern-inside: (function_declaration)
- pattern-not-inside: (catch_clause)
exclude:
- "test/**"
description: |
Using console.log in production code can impact performance and accidentally
expose sensitive information. Use a proper logging library instead.Required Fields
language
- Type:
string - Description: The programming language this checker applies to
- Supported values:
- JavaScript:
js,javascript - TypeScript:
ts,typescript - JSX/TSX:
jsx,tsx - Python:
py,python - Go:
go - Ruby:
rb,ruby - Java:
java - And many more
- JavaScript:
name
- Type:
string - Description: Unique identifier for the checker. There should be at least one matching capture in the pattern query with this name.
- Pattern:
[a-z][a-z0-9_]* - Example:
js_no_console_log
message
- Type:
string - Description: Message shown when an issue is found
- Supports variable substitution using
@capture_name - Example:
"Avoid using console.log, found: @console_log"
pattern
- Type:
string - Description: Tree-sitter query pattern to match
- Must include at least one capture that matches the checker's name
- Alternative: Use
patternsfor multiple patterns
Optional Fields
category
- Type:
string - Default:
"bug-risk" - Allowed values:
stylebug-riskantipatternperformancesecurity
severity
- Type:
string - Default:
"error" - Allowed values:
criticalerrorwarninginfo
filters
- Type:
object[] - Description: Refine where patterns match using parent node conditions
- Supported filters:
pattern-inside: Match only if inside this patternpattern-not-inside: Match only if not inside this pattern
exclude
- Type:
string[] - Description: Glob patterns for files to exclude
- Example:
["test/**", "**/*.test.js"]
include
- Type:
string[] - Description: Glob patterns for files to include. If specified, only files matching these patterns will be analyzed.
- Example:
["src/**", "lib/**"]
description
- Type:
string - Description: Detailed explanation of the checker
- Supports markdown formatting
Pattern Writing Guide
Patterns use tree-sitter's query syntax to match AST nodes. Here are the key concepts:
- Basic pattern structure:
yaml
name: js_no_console_log
pattern: |
(
call_expression
(member_expression
object: (identifier) @console
property: (property_identifier) @method)
) @js_no_console_log- Using predicates to match specific values:
yaml
# Match only when identifier is "console" and property is "log"
pattern: |
(
call_expression
(member_expression
object: (identifier) @console (#eq? @console "console")
property: (property_identifier) @method (#eq? @method "log"))
) @js_no_console_log- Filters for context-aware matching:
yaml
pattern: |
(call_expression) @js_no_console_log
filters:
- pattern-inside: "(function_declaration)" # Must be inside a function
- pattern-not-inside: "(catch_clause)" # But not inside error handling- Using captures in messages:
yaml
message: "Found console.@method call"
pattern: |
(
member_expression
object: (identifier) @console (#eq? @console "console")
property: (property_identifier) @method
)Common predicates:
#eq?: Exact string match#match?: Regex pattern match#not-eq?: String doesn't match#not-match?: Regex doesn't match
For a deeper dive into tree-sitter queries:
Testing Checkers
Every checker can have an associated test file to verify its behavior. The test file should have the same name as the checker but with a .test suffix followed by the appropriate file extension.
Test File Structure
For a checker no_console_log.yml, create a corresponding test file:
js
// .globstar/no_console_log.test.js
function test() {
// This should be caught inside a function
// <expect-error>
console.log("inside function");
try {
something();
} catch (err) {
// This should NOT be caught (pattern-not-inside: catch_clause)
console.log(err);
}
}Test Directives
<expect-error>: Place this comment above a line that should trigger the checker
Running Tests
Use the test command to run all checker tests:
bash
globstar testThis will:
- Find all test files in the
.globstardirectory - Run the associated checkers against each test file
- Verify that errors are reported exactly where expected
- Exit with status code 1 if any test fails
Test Writing Tips
- Test both positive and negative cases:
js
// Should trigger
// <expect-error>
console.log("debug");
// Should not trigger
console.info("info");- Test edge cases and variations:
js
// <expect-error>
console.log(); // Empty call
// <expect-error>
console.log(1, "two", {three: 3}); // Multiple arguments
// <expect-error>
console["log"]("computed property"); // Different syntax- Test filter conditions:
js
// Should not trigger (not in a function)
console.log("outside");
function test() {
// <expect-error>
console.log("inside function"); // Should trigger
try {
something();
} catch (err) {
console.log(err); // Should not trigger (in catch clause)
}
}