Add review instructions
The guide explains how to add custom review instructions for the entire project. Also, see the guide on how to configure CodeRabbit.
Path-based instructions
This section explains how to add custom code review instructions for the entire project or specific file paths in your project using glob patterns. Developers can provide tailored review guidelines based on the file paths. These instructions are needed only if you want CodeRabbit to follow specific instructions besides the standard review.
For example, you may want to enforce a style guide by file types or directories.
Sample Usage
Paths accept glob patterns. See the minimatch documentation for more information.
#...
reviews:
#...
path_instructions:
- path: "**/*.js"
instructions: |
Review the JavaScript code against the Google JavaScript style guide and point out any mismatches
- path: "tests/**.*"
instructions: |
Review the following unit test code written using the Mocha test library. Ensure that:
- The code adheres to best practices associated with Mocha.
- Descriptive test names are used to clearly convey the intent of each test.
Abstract Syntax Tree (AST) based instructions
This feature is available exclusively as part of the Pro plan and is not included in the Lite plan. Please refer to our pricing page for more information about our plans and features.
CodeRabbit offers review instructions based on Abstract Syntax Tree (AST)
patterns. Under the hood, CodeRabbit uses
ast-grep
to power this feature. ast-grep
is
written in Rust and uses the tree-sitter parser to generate the AST for popular
languages. ast-grep
is written and maintained by
Herrington Darkholme.
ast-grep
Playground is quite effective in designing and testing AST rules on
source code snippets. You can access the playground
here.
The additional context provided by this feature is only available during the automated code review process, and it's not available in the chat.
Moreover, this feature is only recommended for advanced users as there is a learning curve involved.
Deep dive into AST patterns and ast-grep
rules
- Abstract Syntax Tree (AST) Wikipedia article
ast-grep
official documentation for detailed guides.
This section explains how to add custom code review instructions using
ast-grep
rules. ast-grep
is a tool used for searching code using abstract
syntax trees (AST) patterns.
By default, you can add ast-grep
rules by following these steps:
- Create a directory that keeps all the
ast-grep
rules in your project directory. - Add individual
.yaml
files for eachast-grep
rule within the newly created directory. - Ensure that each
.yaml
file contains the necessaryast-grep
rule configurations. - Ensure that all rules contains a
message
property, that will be used in the review process. - Add the rules' directory to the
.coderabbit.yml
file undertools.ast-grep
configuration. - Optionally, you can add
packages
property to the configuration to specify the packages that should be installed before running theast-grep
tool. Please read thepackages
section for detailed information.
#...
reviews:
#...
tools:
ast-grep:
essential_rules: true # option to enable essential security rules
rule_dirs:
- "custom-name"
packages:
- "myorg/myawesomepackage" # custom package name following the format organization/repository
#...
The rule object
Rule object is the core concept of ast-grep
rule system and every other
feature is built on top of it.
Below is the full list of fields in a rule object. Every rule field is optional and can be omitted, but at least one field should be present in a rule. A node will match a rule if and only if it satisfies all fields in the rule object.
rule:
# atomic rule
pattern: "search.pattern"
kind: "tree_sitter_node_kind"
regex: "rust|regex"
# relational rule
inside: { pattern: "sub.rule" }
has: { kind: "sub_rule" }
follows: { regex: "can|use|any" }
precedes: { kind: "multi_keys", pattern: "in.sub" }
# composite rule
all: [{ pattern: "match.all" }, { kind: "match_all" }]
any: [{ pattern: "match.any" }, { kind: "match_any" }]
not: { pattern: "not.this" }
matches: "utility-rule"
Rule Categories
To summarize the rule object fields above, we have three categories of rules:
- Atomic Rule: the most basic rule that checks if AST nodes matches.
- Relational Rule: rules that check if a node is surrounded by another node.
- Composite Rule: rules that combine sub-rules together using logical operators.
These three categories of rules can be composed together to create more complex rules.
The rule object is inspired by the CSS selectors but with more composability and expressiveness. Thinking about how selectors in CSS works can help you understand the rule object!
Read
ast-grep
> documentation for detailed guides.
Atomic rule
Atomic rule defines the most basic matching rule that determines whether one
syntax node matches the rule or not. There are three kinds of atomic rule:
pattern
, kind
and regex
.
Official documentation guide on Atomic Rule
Relational rule
A relational rule defines the relationship between two syntax nodes. There are
four kinds of relational rule: inside
, has
, follows
and precedes
.
All four relational rules accept a sub-rule object as their value. The sub-rule will match the surrounding node, while the relational rule itself will match the target node.
Official documentation guide on Relational Rule
rule:
pattern: await $PROMISE
inside:
kind: for_in_statement
stopBy: end
Composite rule
A composite rule defines the logical relationship between multiple sub-rules.
There are three kinds of composite rule: all
, any
and not
.
all
The all
rule matches if all sub-rules match.
rule:
all:
- pattern: console.log('Hello World');
- kind: expression_statement
any
any
rule matches if any sub-rule matches.
rule:
any:
- pattern: var a = $A
- pattern: const a = $A
- pattern: let a = $A
not
not
applies negation to a sub-rule. It matches if the sub-rule does not match.
rule:
pattern: console.log($GREETING)
not:
pattern: console.log('Hello World')
Official documentation guide on Composite Rule
Reusing rule as utility
ast-grep
chooses to use YAML for rule representation. While this decision
makes writing rules easier, it does impose some limitations on the rule
authoring. One of the limitations is that rule objects cannot be reused.
Local utility rule
Local utility rules are defined in the utils field of the config file. Utils is a string-keyed dictionary.
For example, the following config file defines a local utility rule
is-literal
:
utils:
is-literal:
any:
- kind: string
- kind: number
- kind: boolean
rule:
matches: is-literal
Global utility rule
Global utility rules are defined in a separate file. But they are available across all rule configurations in the project.
To create global utility rules, you need to have the rules
directory created
on the root of your project and another utils
directory inside the root of
your project.
my-awesome-project # project root
|- rules # rule directory
| |- my-rule.yml
|- utils # utils directory
| |- is-literal.yml
Also, you need to add the
rules
andutils
directories to the.coderabbit.yml
file undertools.ast-grep
configuration. The rules can also be inside a package. If you have a package that contains rules, you can add the package name to thepackages
field in the.coderabbit.yml
file.
#...
reviews:
#...
tools:
ast-grep:
essential_rules: true
rule_dirs:
- "rules"
util_dirs:
- "utils"
packages:
- "my-awesome-org/my-awesome-package" # public repository that contains ast-grep rules
#...
# is-literal.yml
id: is-literal
language: TypeScript
rule:
any:
- kind: "false"
- kind: undefined
- kind: "null"
- kind: "true"
- kind: regex
- kind: number
- kind: string
Official documentation guide on Utility Rule