gdstyle
A fast, opinionated linter and formatter for GDScript (Godot 4.x), built in Rust.
gdstyle catches style violations, naming inconsistencies, and common code-quality issues, and auto-formats GDScript to the official Godot style guide. Many of the conventions are taken from Nathan Lovato and GDQuest's GDScript style guide.
Features
- 57 lint rules across syntax, naming, formatting, ordering, and code quality.
- Formatter (
gdstyle fmt) that's in-place and idempotent, and reorders class members into the canonical Godot order. - Auto-fix:
--fixfor the safe ones,--unsafe-fixfor renames. Renames follow into other.gdfiles and into the.tscn/.tresscene wiring. - Single static binary. No Python, no Rust toolchain, no Godot install required to run it.
- Optional Godot editor plugin: bottom panel with clickable diagnostics, single-click fixes, Lint/Format on save. Uses the GDExtension when present, falls back to the CLI binary otherwise.
- pre-commit framework integration out of the box (
gdstyleandgdstyle-fmthooks). - Text and JSON output with configurable exit codes, so it slots into CI.
- TOML config (
gdstyle.toml) with per-rule overrides and CLI flags for one-off tweaks. - Per-line (
# gdstyle:ignore) and per-file (# gdstyle:ignore-file) suppression comments, both with optional rule-list narrowing. - Usable as a Rust library, not just a CLI.
Installation
Pre-built binaries are available for all major platforms. You don't need a Rust toolchain unless you want to build from source.
Pre-built binaries (recommended)
- Go to the latest release
- Download the archive for your platform:
- Linux:
gdstyle-x86_64-unknown-linux-gnu.tar.gz - macOS (Intel):
gdstyle-x86_64-apple-darwin.tar.gz - macOS (Apple Silicon):
gdstyle-aarch64-apple-darwin.tar.gz - Windows:
gdstyle-x86_64-pc-windows-msvc.zip
- Linux:
- Extract the
gdstylebinary and place it somewhere on yourPATH:
# Example for Linux / macOS
Building from source
To build from source you need a Rust toolchain.
# The binary is at target/release/gdstyle
From crates.io
Quick start
# Lint the current directory (recursively finds all .gd files)
# Lint specific files or directories
# Auto-fix safe violations
# Auto-fix all violations including unsafe ones
# Format all GDScript files in place
# Check formatting without modifying files (exit 1 if changes needed)
# Show formatting diff without modifying files
# Output lint results as JSON (for CI integration)
# List all available rules
# Generate a starter config file
# Only check naming rules
# Ignore specific rules
# Override max line length
Rules
gdstyle ships with 57 rules organized into five categories. Most rules are enabled by default (a few advisory rules are opt-in).
Syntax (2 rules)
| Rule | Description | Fixable |
|---|---|---|
syntax/lex-error |
Report lexer errors: unterminated strings, invalid numbers, unexpected characters | - |
syntax/reserved-identifier |
Reserved words (namespace, trait, yield, self, ...) used as a function, parameter, variable, constant, signal, enum, class or loop-variable name. Godot refuses to parse these files, so this defaults to error |
- |
Naming (11 rules)
| Rule | Description | Fixable |
|---|---|---|
naming/class-name-pascal-case |
Class names must use PascalCase |
unsafe |
naming/function-name-snake-case |
Function names must use snake_case |
unsafe |
naming/variable-name-snake-case |
Variable names must use snake_case |
unsafe |
naming/constant-name-screaming-case |
Constants must use SCREAMING_SNAKE_CASE (or PascalCase for preloads) |
unsafe |
naming/signal-name-snake-case |
Signal names must use snake_case |
unsafe |
naming/enum-name-pascal-case |
Enum type names must use PascalCase |
unsafe |
naming/enum-member-screaming-case |
Enum members must use SCREAMING_SNAKE_CASE |
unsafe |
naming/file-name-snake-case |
File names must use snake_case |
- |
naming/signal-past-tense |
Signal names should use past tense (handles irregular verbs, gerunds, nouns) | unsafe |
naming/private-underscore-prefix |
Private members with _ should not have @export |
- |
naming/node-name-pascal-case |
$NodePath references should use PascalCase |
unsafe |
Formatting (20 rules)
| Rule | Description | Fixable |
|---|---|---|
format/max-line-length |
Lines must not exceed the configured max length (default: 100) | fmt |
format/trailing-whitespace |
No trailing whitespace on any line | safe |
format/trailing-newline |
Files must end with a newline character | safe |
format/no-tabs-as-spaces |
Indentation must use tabs (configurable to spaces) | safe |
format/boolean-operators |
Use and/or/not instead of &&/||/! |
safe |
format/double-quotes |
Prefer double quotes for strings | safe |
format/comment-spacing |
Comments must have a space after # |
safe |
format/no-unnecessary-parens |
No unnecessary parentheses in if/while/elif conditions |
safe |
format/number-literals |
Hex digits must be lowercase (0xff, not 0xFF) |
safe |
format/one-statement-per-line |
One statement per line (no semicolons to separate statements). Match arms and inline callable bodies are exempt, since their statements are not peers of the enclosing line | safe |
format/blank-lines |
Collapse 3+ blank lines to 2 | safe |
format/trailing-comma |
Trailing comma on last item of multi-line collections whose closing bracket starts its own line | safe |
format/operator-spacing |
One space around binary operators | safe |
format/colon-spacing |
No space before :, one space after (except :=, end of line, or before ,) |
safe |
format/comma-spacing |
No space before ,, one space after (except newline, closing bracket, or before another ,) |
safe |
format/brace-spacing |
Single-line dictionary literals need a space after { and before } |
safe |
format/call-paren-spacing |
No space between a callee and its opening ( |
safe |
format/float-literal-zeros |
Float literals need leading/trailing zeros (0.5, not .5) |
safe |
format/large-number-underscores |
Numbers at or above large_number_threshold (default 10_000) should use underscores (10_000). Covers ints and the integer part of floats (1_000_000.5); hex/binary literals are skipped |
safe |
format/enum-one-per-line |
Each enum member on its own line, including enums in inner classes | safe |
Ordering (1 rule)
| Rule | Description | Fixable |
|---|---|---|
order/class-member-order |
Class members must follow the canonical Godot ordering | fmt |
The canonical ordering enforced by order/class-member-order is:
@tool@iconclass_nameextends- Doc comments (
##) - Signals
- Enums
- Constants
- Static variables
@exportvariables- Regular variables
@onreadyvariables- Virtual methods (
_init,_ready,_process, etc.) - Regular methods
- Inner classes
Quality (23 rules)
| Rule | Description | Default | Fixable |
|---|---|---|---|
quality/max-function-length |
Functions must not exceed the configured max body length (default: 50 lines) | on | - |
quality/max-file-length |
Files must not exceed the configured max length (default: 1000 lines) | on | - |
quality/max-parameters |
Functions must not have more than the configured max parameters (default: 5) | on | - |
quality/unnecessary-pass |
pass alongside other statements is unnecessary |
on | - |
quality/no-debug-print |
Debug print()/prints()/printerr() calls left in code |
off | - |
quality/self-comparison |
Comparing a value with itself (x == x) |
on | - |
quality/no-self-assign |
Self-assignment (x = x) |
on | - |
quality/duplicate-dict-key |
Duplicate keys in dictionary literals | on | - |
quality/duplicated-load |
Same path passed to load()/preload() multiple times |
on | - |
quality/type-hint |
Missing type hints on variables, parameters, and return types | off | - |
quality/empty-function |
Empty or pass-only functions | off | - |
quality/max-class-variables |
Too many class-level variables (default: 15) | on | - |
quality/max-public-methods |
Too many public methods per class (default: 20) | on | - |
quality/max-inner-classes |
Too many inner classes per file, nested ones included (default: 5) | on | - |
quality/no-else-return |
Unnecessary else/elif after return |
on | - |
quality/unreachable-code |
Code after return, break, or continue |
on | - |
quality/await-in-loop |
await used inside a for/while loop |
on | - |
quality/allocation-in-loop |
Object allocation (.new()) inside a loop |
on | - |
quality/process-get-node |
Node lookups ($, get_node()) in _process/_physics_process |
on | - |
quality/max-nesting-depth |
Nesting depth exceeds limit (default: 4) | on | - |
quality/max-returns |
Too many return statements per function (default: 6) |
on | - |
quality/max-branches |
Too many branches (if/elif/match) per function (default: 8) |
on | - |
quality/max-local-variables |
Too many local variables per function (default: 10) | on | - |
Auto-fix
gdstyle can automatically fix many violations:
# Fix safe violations only (formatting, naming conventions)
# Fix all violations including unsafe ones (signal renaming, member reordering)
Fixes are written to disk in place. There's no backup and no confirmation prompt. Commit or stash before running
--fixor--unsafe-fix, then review the diff. (gdstyle fmt --diffpreviews formatter changes without writing.)
Safe fixes preserve behavior. Unsafe fixes can change semantics (renaming signals, variables, and other identifiers), so review the diff before committing.
When --unsafe-fix renames an identifier, gdstyle follows the rename across every .gd file in the project and into the .tscn/.tres scene files that wire signals or methods to that name. Anything it can't safely rewrite is reported as a warning so you can fix it by hand.
Formatter
The fmt subcommand reformats GDScript files in a single pass:
# Format all .gd files in place
# Check if files are already formatted (exit 1 if not)
# Show a diff of what would change
The formatter normalizes indentation, trailing whitespace, blank lines (including the spacing between class members), boolean operators (&&/||/! to and/or/not), string quotes, comment spacing, colon and comma spacing, float and hex literals, trailing newlines, and single-line enums (expanded to multi-line). It reorders class members to match the canonical style guide order, and wraps long lines at commas inside parentheses, brackets, and braces. Running it twice produces the same output.
The contents of multi-line strings are data, so the formatter leaves them alone: indentation, trailing whitespace, blank lines and line length inside a string that spans lines (a """...""" literal, or a quoted string with a raw newline or a backslash continuation) are kept. The layout rules don't report those lines either. The one exception is format/max-line-length on a string's closing line: when the code after the closing quote is what makes the line too long, it is still reported.
Line endings are kept too, by fmt and check --fix alike. A file keeps the style most of its line breaks outside strings use, so a CRLF file stays CRLF. A string keeps its own line endings even when they differ from the rest of the file, because Godot keeps a \r inside a string as part of its value.
Note: Line wrapping breaks at comma boundaries inside delimiters (parentheses, brackets, braces),
and/oroperators inif/elif/whileconditions, and word boundaries in long comments. Lines without any breakable pattern (e.g., long strings, property chains, continuation lines without enclosing delimiters) are left alone.
Configuration
gdstyle looks for a config file named gdstyle.toml or .gdstyle.toml in the current directory and walks up the directory tree until it finds one. You can also specify a config file explicitly with --config, or generate a starter one:
Example config file
# gdstyle.toml
# Maximum line length (default: 100)
= 100
# Use tabs for indentation (default: true)
= true
# Maximum function body length in lines (default: 50)
= 50
# Maximum file length in lines (default: 1000)
= 1000
# Maximum number of function parameters (default: 5)
= 5
# Maximum return statements per function (default: 6)
= 6
# Maximum nesting depth inside a function (default: 4)
= 4
# Maximum local variables per function (default: 10)
= 10
# Maximum branches (if/elif/match) per function (default: 8)
= 8
# Maximum class-level variables (default: 15)
= 15
# Maximum public methods per class (default: 20)
= 20
# Maximum inner classes per file (default: 5)
= 5
# Smallest number format/large-number-underscores asks to group (default: 10_000).
# For floats the integer part is compared. Raise it to 1_000_000 to leave
# five- and six-digit constants (sample rates, PCM limits) ungrouped.
= 10_000
# Put one blank line between public and private (`_`-prefixed) constants and
# variables of the same kind when formatting (default: false). Applies to
# script-level members; inner-class bodies keep their blank lines as written.
= false
# File/directory patterns to exclude
= [".godot", "addons"]
# Patterns to force-include even when `exclude` matches them. An include always
# wins over an exclude, so you can lint one plugin inside an otherwise-excluded
# directory. Empty by default.
= ["addons/my_plugin"]
# Per-rule severity overrides
# Values: "off", "warn", "error"
[]
= "off" # Disable a rule entirely
= "error" # Escalate to error
= "warn" # Keep as warning
= "warn" # Enable an off-by-default rule
Default configuration
When no config file is found, gdstyle uses these defaults:
| Setting | Default |
|---|---|
max_line_length |
100 |
use_tabs |
true |
max_function_length |
50 |
max_file_length |
1000 |
max_parameters |
5 |
max_returns |
6 |
max_nesting_depth |
4 |
max_local_variables |
10 |
max_branches |
8 |
max_class_variables |
15 |
max_public_methods |
20 |
max_inner_classes |
5 |
large_number_threshold |
10_000 |
blank_line_between_public_and_private |
false |
exclude |
[".godot", "addons"] |
include |
[] |
Most rules are enabled by default with warn severity. Three advisory rules (quality/type-hint, quality/empty-function, quality/no-debug-print) are off by default and must be explicitly enabled.
Severity is the CI knob: check exits 1 as soon as one diagnostic has
error severity, and 0 when everything is a warning. Set the rules you
want to block a build to "error" in [rules], or use
--max-warnings <N> to cap warnings without escalating
individual rules.
A [rules] key that matches no known rule is reported on stderr rather
than silently ignored, so a typo doesn't look like a setting that took
effect:
$ gdstyle check
warning: unknown rule name in [rules]: naming/variable-snake-case
run `gdstyle rules` to see the available rules
Suppressing diagnostics
gdstyle has two ways to silence a warning from source: per-line for
spot exemptions and per-file for class- or file-scope rules. Both
use a # gdstyle:ignore comment, with the same =rule1,rule2 syntax
for narrowing to specific rules.
| Directive | Scope | Form |
|---|---|---|
# gdstyle:ignore |
the next code line | standalone (own line) |
# gdstyle:ignore |
the same code line | inline (end of a code line) |
# gdstyle:ignore-file |
every diagnostic in the file | anywhere in the file |
Add =rule1,rule2 to any of the above to narrow the suppression to a
comma-separated list of rule IDs. Without the =... suffix, every rule
is suppressed within that scope. Rule IDs are the full
category/rule-name shown in the diagnostic output (e.g.
naming/variable-name-snake-case).
Per-line suppression
Standalone (applies to the next code line):
# gdstyle:ignore=naming/variable-name-snake-case
var BadName: int = 5
Inline (applies to the same line):
var BadName: int = 5 # gdstyle:ignore=naming/variable-name-snake-case
Bare (suppresses every rule on the target line):
# gdstyle:ignore
var BadName: int = 5
Multiple rules in one directive:
# gdstyle:ignore=naming/variable-name-snake-case,format/max-line-length
var SomeReallyLongVariableNameThatExceedsTheMaxLineLengthAndAlsoUsesTheBadNamingConvention: int = 5
Per-file suppression
Use # gdstyle:ignore-file when the diagnostic isn't attached to a
single line, or when you genuinely want a whole-file exemption.
Anchor it at the top of the file by convention so future readers see
it immediately, but the parser accepts it anywhere.
# gdstyle:ignore-file=quality/max-public-methods
class_name OrchestrationFacade
extends Node
# ... 25 public methods follow
Multiple rules on one directive, or several directives stacked, both work:
# gdstyle:ignore-file=quality/max-public-methods,quality/max-class-variables
# gdstyle:ignore-file=quality/max-inner-classes
class_name BigConfigDocument
A bare # gdstyle:ignore-file (no =...) disables every rule in
the file. Useful for generated code or third-party drops you don't
own:
# gdstyle:ignore-file
# This file is generated by build/gen.py, do not edit.
When to use which
-
Per-line is the right tool for one-off exemptions where the diagnostic clearly belongs to a single line (a deliberately weird variable name, a long string literal, a public field you want to keep snake_case-violating because it mirrors a JSON key).
-
Per-file is the right tool for rules that report against the whole class or file rather than a specific statement:
quality/max-public-methods(reports at the class header)quality/max-class-variables(same)quality/max-inner-classes(same)quality/max-file-length(reports at line 1)- Generated files where any rule is moot.
Trying to suppress these per-line is awkward at best (you have to put the comment inline on the
class_nameline, which makes the signature noisy) and impossible at worst (generated files have no natural spot for 50 inline comments).
Project-wide silencing
If you want to disable a rule across the entire project rather than
file-by-file, set it to "off" in gdstyle.toml instead:
[]
= "off"
The TOML config and inline suppressions are independent; either one silencing a rule is enough to drop the diagnostic.
Pinning a member against reordering
order/class-member-order is enforced by the formatter, so ignoring it
does double duty: it silences the check diagnostic and pins the
member where you wrote it, so gdstyle fmt won't move it. Everything
else still reorders around the pinned member. This is handy when two
declarations are meant to sit together, for example a const lookup
table kept next to the enum it mirrors:
enum SaveGameFormat {
BINARY,
TEXT,
}
# gdstyle:ignore=order/class-member-order
const SAVE_GAME_FORMAT_DISPLAY_NAMES: PackedStringArray = [
"OPTIONS_GENERAL_BINARY",
"OPTIONS_GENERAL_TEXT",
]
The directive may sit directly above the declaration (or above its
annotations). A # gdstyle:ignore-file=order/class-member-order pins
every member, disabling reordering for the whole file.
When the formatter leaves the order alone
gdstyle fmt skips reordering a file when moving members could change
what the code does:
- A class-level
var/constinitializer refers to another class-level declaration. GDScript runs initializers in source order. - The move would change which code sits between
@warning_ignore_startand@warning_ignore_restore. The region would otherwise end up silencing warnings on different members.
check still reports order/class-member-order for such a file, so you
can fix the order by hand.
CLI reference
gdstyle [COMMAND] [OPTIONS] [PATHS]...
Subcommands
| Command | Description |
|---|---|
check |
Lint files (default when no subcommand given) |
fmt |
Format files in place |
rules |
List all available lint rules |
init |
Generate a starter gdstyle.toml configuration file |
check options
| Option | Description |
|---|---|
--fix |
Auto-fix safe violations |
--unsafe-fix |
Auto-fix all violations including unsafe ones |
--format <FORMAT> |
Output format: text (default) or json |
-c, --config <PATH> |
Path to configuration file |
--select <RULES> |
Only check specific rules (comma-separated, supports partial matching) |
--ignore <RULES> |
Ignore specific rules (comma-separated) |
--max-line-length <N> |
Override the maximum line length |
--max-warnings <N> |
Exit 1 when more than N warnings are found |
--no-color |
Disable colored output |
fmt options
| Option | Description |
|---|---|
--check |
Dry-run: exit 1 if any file would change |
--diff |
Print a diff of what would change |
-c, --config <PATH> |
Path to configuration file |
--no-color |
Disable colored output |
init options
| Option | Description |
|---|---|
--force |
Overwrite existing config file |
Exit codes
| Code | Meaning |
|---|---|
0 |
Linting/formatting completed (warnings only, or no issues) |
1 |
Linting completed with errors, --max-warnings was exceeded, or fmt --check found changes |
2 |
Configuration error |
There are two ways to make warnings fail a build. Set the rules you care
about to "error" in [rules] to fail on those specifically, or pass
--max-warnings <N> to cap the total regardless of rule. --max-warnings 0
means "no warnings at all"; --max-warnings 5 fails only at six or more.
CI/CD integration
GitHub Actions
name: GDScript Style
on:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install gdstyle
run: cargo install gdstyle
- name: Check formatting
run: gdstyle fmt --check
- name: Lint GDScript files
run: gdstyle check
# Or fail on warnings too, without escalating individual rules:
# run: gdstyle check --max-warnings 0
Pre-commit hook
gdstyle ships hooks for the pre-commit framework.
Add the following to your project's .pre-commit-config.yaml:
repos:
- repo: https://github.com/atelico/gdstyle
rev: v0.4.0 # pin to a released tag; bump with `pre-commit autoupdate`
hooks:
- id: gdstyle # lint (fails the commit on diagnostics)
- id: gdstyle-fmt # format in place
Then install the git hook with pre-commit install. The first run builds
gdstyle from source via cargo, so the user needs a Rust toolchain on their
machine; subsequent runs are cached.
If you'd rather not depend on the pre-commit framework, a minimal raw git hook also works:
#!/bin/bash
# .git/hooks/pre-commit
GD_FILES=
if [; then
if [; then
fi
fi
JSON output format
When using --format json, gdstyle outputs a JSON array of diagnostics:
Using as a library
You can also use gdstyle as a Rust library. Full API docs live at docs.rs/gdstyle.
use Config;
use linter;
use formatter;
Project structure
gdstyle/
├── src/
│ ├── main.rs # CLI entry point (clap subcommands)
│ ├── lib.rs # Library root
│ ├── token.rs # Token types (Span, TokenKind, Token)
│ ├── lexer.rs # Tokenizer (indentation-aware, GDScript 4.x)
│ ├── ast.rs # AST node types for linting
│ ├── parser.rs # Lightweight parser (just enough for linting)
│ ├── diagnostic.rs # Diagnostic, Fix, and Replacement types
│ ├── config.rs # TOML configuration loading
│ ├── linter.rs # Main lint pipeline (tokenize -> parse -> rules -> filter)
│ ├── reporter.rs # Text and JSON output formatting
│ ├── fixer.rs # Auto-fix engine (applies replacements)
│ ├── formatter.rs # Multi-pass formatter
│ └── rules/
│ ├── mod.rs # Rule dispatcher
│ ├── naming.rs # 11 naming convention rules
│ ├── formatting.rs # 20 formatting rules
│ ├── ordering.rs # Class member ordering rule
│ └── quality.rs # 23 code quality rules
├── gdstyle-gdext/ # GDExtension wrapper (exposes linter/formatter to Godot)
│ ├── Cargo.toml
│ └── src/lib.rs
├── godot-plugin/ # Godot 4.x editor plugin
│ └── addons/gdstyle/
│ ├── plugin.cfg
│ ├── plugin.gd
│ ├── gdstyle_panel.gd
│ └── gdstyle.gdextension
├── tests/
│ ├── integration_test.rs # End-to-end integration tests
│ └── fixtures/ # GDScript test fixtures
├── .github/workflows/
│ ├── ci.yml # rustfmt, clippy, and tests on every PR
│ └── release.yml # builds + publishes CLI + GDExtension for all platforms
├── examples/ # Example GDScript files for trying out gdstyle
├── Cargo.toml
└── gdstyle.example.toml
Examples
The examples/ directory contains sample GDScript files you can use to try out linting and formatting:
# Lint the examples. Expect warnings about naming, formatting, and quality.
# See what the formatter would change
# Auto-fix all safe violations
# Format everything
Testing
gdstyle has 383 tests: 161 unit tests, 219 integration tests, and 3 doctests.
Godot editor plugin
A Godot 4.x editor plugin lives in godot-plugin/. It adds a bottom panel that runs gdstyle and shows clickable diagnostics inside the editor.
The plugin supports two backends:
- GDExtension (native). If the GDExtension library is present, it calls into Rust directly with no process overhead. Requires Godot 4.6+.
- CLI fallback. Spawns the
gdstylebinary. If it isn't onPATH, a Download button fetches the right release from GitHub.
You can switch between backends at any time from the mode dropdown in the toolbar.
Plugin features
- Lint Project / Lint File. Run the linter on every script in the project, or just the one you have open. Project-wide runs honor your
exclude/includeconfig, matching the CLI. - Fix File. Apply all available auto-fixes to the current script in one click.
- Format Project / Format File. Same split for the formatter (also config-aware for project runs).
- Lint on Save. Lint after every save (on by default).
- Format on Save. Format before linting on save.
- Right-click Fix. Right-click any diagnostic with an auto-fix to apply it in place.
- Click to navigate. Double-click a diagnostic to jump to the source line.
- In-memory editing. Lint, fix, and format work directly on the editor buffer, no disk I/O.
Installation (pre-built plugin)
- Download
gdstyle-godot-plugin.zipfrom the latest release - Extract the
addons/gdstyle/folder into your Godot project - Enable the plugin in Project > Project Settings > Plugins
GDExtension API
When using the GDExtension backend, you can use GdStyle directly in GDScript:
var style = GdStyle.new()
# Lint a file.
var diagnostics = style.lint_res_file("res://player.gd")
for d in diagnostics:
print("Line %d: [%s] %s" % [d["line"], d["rule"], d["message"]])
if d["has_fix"]:
print(" (auto-fixable, safe=%s)" % d["is_safe_fix"])
# Format a source string.
var formatted = style.format_source(source_code)
# Auto-fix violations.
var fixed = style.fix_source(source_code, "player.gd")
# Fix a single diagnostic by line and rule.
style.fix_at_line("res://player.gd", 12, "naming/variable-name-snake-case")
# Configure.
style.set_max_line_length(120)
style.disable_rule("format/double-quotes")
style.load_config_res("res://gdstyle.toml")
# Set a rule's severity: "off", "warn", or "error", the same vocabulary
# gdstyle.toml uses. Returns false and logs an error for anything else.
style.set_rule_severity("naming/variable-name-snake-case", "error")
# Report [rules] keys in the loaded config that match no known rule.
for name in style.unknown_rule_names():
push_warning("gdstyle: unknown rule name %s" % name)
# Collect the project's .gd files the config would lint (honors exclude/include).
# Load the config first so the walk reflects it.
for res_path in style.collect_project_gd_files():
style.lint_res_file(res_path)
Contributing
- Fork the repository
- Create a feature branch:
git checkout -b my-feature - Write tests first, then implement
- Run the full test suite:
cargo test - Run clippy:
cargo clippy - Commit and push
- Open a pull request
License
MIT