We welcome contributions in the form of pull requests and issues.
Note that this codebase isn't yet extensively documented. If you get stuck, please ask for help on Discord.
A high-level overview of tools you need to have installed:
- Rust toolchain: for compiling the codebase. You'll need
rustcv1.74 or newer.- To create WASM builds, run
rustup target install wasm32-unknown-unknown.
- To create WASM builds, run
- C/C++ compiler. macOS: Xcode Command Line Tools via
xcode-select --install, Linux: gcc, Windows: Microsoft Visual C++. - Emscripten: a C/C++ compiler toolchain for WASM. Install v3.1.56 with
emsdk. - Node.js runtime:
node,npm,npxare used to generate parsers fromgrammar.jsfiles. You'll neednodev18.5.0 or newer. - Yarn package manager. You'll need
yarn(classic). Install v1.22.19 withnpm install --global yarn. - Tree-Sitter CLI: provides
tree-sitterbinary for testing grammars. Install v0.22.2 withnpm install --global tree-sitter-cli. - Terraform CLI. Install
terraformwithbrew tap hashicorp/tap && brew install hashicorp/tap/terraform. - For snapshot testing review, you should install the cargo insta plugin:
curl -LsSf https://insta.rs/install.sh | sh(https://insta.rs/docs/cli/)
Use git to clone this repository into a location of your choice.
git clone https://github.com/getgrit/gritql.gitChange into the cloned repository and make sure all submodules are correctly set up, including any nested submodules:
cd gritql
git submodule update --init --recursiveBefore making any changes to the code, make sure you can run the tests and everything is initially passing:
cargo test --workspaceWe use feature flags to control which parts of the codebase are compiled.
Note that some proprietary server-only integrations are hidden behind the "server" feature flag. This flag is disabled by default, and code should compile without any additions.
For major changes, we put new features should be put into the grit_alpha feature flag. Features that are ready for broad release should be put into the grit_beta feature flag. This is used for all public releases.
Features that should be tested in CI should be put into the grit_ci feature flag. This is used for all CI tests.
If GritQL is failing to match a code snippet, this can typically be fixed simply by adjusting the metavariable grammar for the target language.
Metavariable grammars are found under ./resources/metavariable-grammars. Typical fixes include:
- Adding a new named field for a relevant node you want to manipulate.
- Adding a
grit_metavariablenode as a choice in the corresponding spot where you want to substitute the metavariable. - Check this guide to debug grammars generally.
After making your changes, run the ./resources/edit_grammars.mjs script to regenerate the matching grammar. You can specify the language you want to regenerate to speed up the process.
For example:
node ./resources/edit_grammars.mjs yamlSnippet contexts help when a snippet is a valid AST subtree, but needs to be in a larger tree to parse. For example, matching on a table name like $schema.$table in SQL is not valid SQL by itself, only when surrounded by something like SELECT x from $schema.$table is the snippet valid.
Snippet contexts are defined by implementing the snippet_context_strings method in the Language trait. This method returns a list of strings that are used to match the snippet in the larger tree. For example, the SQL implementation returns ["SELECT 1 from ", ";"] to match a table name in a SQL query.
Note: Grit involves two languages:
- GritQL is our query language for searching and transforming codebases.
- The “target language” is the language we are transforming (ex. Python). This document describes the process of adding new target languages to Grit.
Most of these steps involve iteration over a set of sample programs to get closer to correctness. The initial work for a language can typically be done in a day or two.
Here are the steps for adding a new target language:
- Add the language as a supported language in the GritQL grammar, like this.
- Find a tree sitter grammar for the language and add it as a submodule under
resources/language-submodules. - Add a simple parse test in
crates/core/src/test.rsto ensure that the grammar is working. - Copy the grammar file into
resources/metavariable-grammars. This alternative grammar is used for parsingsnippetsin GritQL. - Patch the metavariable grammar to include
$.grit_metavariableanywhere we want to substitute a metavariable. This is usually at least$identifierand$literal.- For a snippet to match, it also needs to be a field. Often you’ll want to wrap
$thinglike:field('thing', choice($.grit_metavariable, $thing))
- For a snippet to match, it also needs to be a field. Often you’ll want to wrap
- Add a new language implementation in
crates/core/languages/src. This involves implementing theLanguagetrait and adding a newLanguageenum variant. - Add
snippet_context_stringslike this to provide context for snippets to match in. - Add test cases for the language in
crates/core/src/test.rs. This is a good time to add a few dozen test cases to ensure that the language is parsed correctly, and that the metavariable grammar is working.
These steps are done in our cloud environment and are not necessary for contributors to do.
- grep for an existing language like
Solfor solidity, and add it to all theLanguageenums you find.- Add the language to
apps/web/src/views/project/details.tsx, so repos with this language don’t get an “unsupported language” warning. (5 minutes) - LSP target languages list: https://github.com/getgrit/rewriter/pull/7734/files#diff-f9d4f097b08d33241c5c8d15a2fbde0e37086c265ce0eba8decac20d5cd989c6R23
- VS Code client list: https://github.com/getgrit/rewriter/blob/f992490394a4807789504f1cea6a04b934ad3b24/apps/poolish/src/lsp-client.ts
- VS Code command palette triggers: https://github.com/getgrit/rewriter/pull/7734/files#diff-b38f1d6304993a250903310722206e6c89c58c52c2d1bd4b6fdd8f7218810570R103
- Add the language to
- There are also
exhaustiveruntime checks that error if a switch case doesn’t handle a language, likemakeSingleLineComment. Search forexhaustive(langand fill those out too. - Regenerate both DB/prisma types to add it to the DB schema and GraphQL types.
- Add the language to
language-selector.tsx. Pick an icon from https://react-icons.github.io, usually from the Simple Icons category.
Many tests depend on the standard library. If you see unexpected failures, you might have an outated copy of the standard library.
Try deleting target/.grit and running cargo test --workspace again.