How to use ast-grep with GraphQL
ast-grep is a code search + replace tool that uses the abstract syntax tree (AST). It has language support for TypeScript, Python, and others, but it doesn't support GraphQL out of the box. However, there is documentation for supporting other languages: Custom Language Support.
These are my notes using that Custom Language Support documentation along with the Multi-Language Documents documentation to set up GraphQL support for ast-grep on macOS.
Prepare Tree-sitter Tool and Parser
Install tree-sitter CLI
brew install tree-sitter(Alternatively,
npm install -g tree-sitter-cli)Test tree-sitter is installed
tree-sitter --versiontree-sitter 0.23.0Use a working directory
I'll use
/tmpas my working directory, but a different directory can be usedcd /tmpGet the tree-sitter GraphQL grammar
git clone https://github.com/bkegley/tree-sitter-graphql.git(This is the repo used by the neovim tree-sitter library.)
Compile the Parser as a Dynamic Library
Compile the GraphQL parser as a dynamic library
cd tree-sitter-graphql export TREE_SITTER_LIBDIR=/tmp tree-sitter testNote: I got the following error when I ran this. If anyone knows what is going on, please let me know.
Error in query file "formatter.scm" Caused by: Query error at 5:31. Impossible pattern: (input_object_type_definition (input_value_definition) @field_definition)However, it still generated the
graphql.dylibfile in/tmp. Note: according to ChatGPT,.dylibis used on Mac,.sois used on Linux, and.dllis used on Windows.
Register Language in sgconfig.yml
Create a new ast-grep project
cd /tmp sg newNo sgconfig.yml found. Creating a new ast-grep project... > Where do you want to have your rules? rules > Do you want to create rule tests? No > Do you want to create folder for utility rules? No Your new ast-grep project has been created!Edit
sgconfig.ymlto add GraphQL as a custom language/tmp/sgconfig.yml:ruleDirs: - ./rules customLanguages: graphql: libraryPath: graphql.dylib extensions: [graphql] expandoChar: $
Use It!
Search for all
inputtypes in/path/to/my/schema.graphqlsg -p "input" -l graphql /path/to/my/schema.graphql/path/to/my/schema.graphql 6│input AddOrUpdateResidualWorksheetInputType { 120│input AutoAssignStyleCodeInputType { 478│input BulkCreateVehicleReleaseInputType { 483│input BulkDeleteVehicleReleaseInputType { 487│input BulkEditVehicleReleaseInputType { 492│input BulkImportStyleFromCppInputType { 949│input CloneModelInputType { 958│input CloneModelStyleInputType { 973│input CloneStyleInputType { 1749│input CppConfigurationInputType {Search for all
DateTimeinput fields (but not output fields) in/path/to/my/schema.graphql. Note: thetree-sitter-graphqlgrammer.js file contains differentkinds that can be used for filtering.sg scan --inline-rules ' id: datetimeinputs language: graphql rule: regex: "DateTime" kind: input_value_definition ' /path/to/my/schema.graphqlhelp[datetimeinputs]: ┌─ /path/to/my/schema.graphql:2356:3 │ 2356 │ configurationLastUpdatedAt: DateTime │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help[datetimeinputs]: ┌─ /path/to/my/schema.graphql:8331:69 │ 8331 │ previousStyleSnapshot(styleSnapshotRowId: Guid, styleRowId: Long, versionDate: DateTime): StyleSnapshotTypeOrOperationErrorType │ ^^^^^^^^^^^^^^^^^^^^^ help[datetimeinputs]: ┌─ /path/to/my/schema.graphql:8794:16 │ 8794 │ whatsChanged(date: DateTime!, flags: [WhatsChangedFilterFlagsEnumType], includeCppOrEmbargoedData: CppEmbargoedDataFilterEnumType): WhatsChangedType │ ^^^^^^^^^^^^^^^ help[datetimeinputs]: ┌─ /path/to/my/schema.graphql:11536:3 │ 11536 │ configurationLastUpdatedAt: DateTime │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
