Skip to content

Releases: atelico/gdstyle

v0.1.7

09 Jun 18:12

Choose a tag to compare

gdstyle 0.1.7

Editor plugin patch release fixing a startup file-lock warning on
Windows.

Fixed

  • Godot plugin no longer fails to write settings.json on startup.
    Reported on Windows as "Unable to write to file 'settings.json',
    file in use, locked or lacking permissions", with an orphan
    settings.json#######.tmp left behind every project startup.

    Cause: _load_settings opened the file for READ, then assigned
    _auto_lint_check.button_pressed = X and
    _auto_format_check.button_pressed = X. Those assignments fire
    the toggled signal synchronously, the handler calls
    _save_settings, and _save_settings opens the same file for
    WRITE while the READ handle is still alive on the call stack. On
    Windows file locks are exclusive so the WRITE open fails, Godot's
    atomic-save rename orphans the .tmp, and the warning surfaces.

    The plugin now uses set_pressed_no_signal() for both checkboxes
    during load (the idiomatic Godot fix), wraps the load body in a
    _loading_settings guard flag, and adds an explicit file.close()
    plus a push_warning on open failure so a future regression
    surfaces with a real error instead of silence.

    Reported in #6.

How to upgrade

After installing v0.1.7, delete any leftover
settings.json#######.tmp files in addons/gdstyle/ (Godot left
them behind from previous startups because the rename kept failing),
then restart Godot.

Install

CLI from crates.io:

cargo install gdstyle

Or grab a prebuilt binary from this release page, drop it on your
PATH, and run gdstyle in your project directory.

For the Godot editor plugin: download gdstyle-godot-plugin.zip from
this release, extract the addons/gdstyle/ folder into your Godot
project, then enable the plugin in Project > Project Settings >
Plugins
.

For the pre-commit framework, bump your
config to:

- repo: https://github.com/atelico/gdstyle
  rev: v0.1.7
  hooks:
    - id: gdstyle
    - id: gdstyle-fmt

or run pre-commit autoupdate.

Full documentation, rule list, configuration reference, and the
GDExtension API live in the README.

Full Changelog: v0.1.6...v0.1.7

v0.1.6

04 Jun 06:13

Choose a tag to compare

gdstyle 0.1.6

Patch release fixing a parser bug that caused order/class-member-order
false positives on inner classes whose first body line was a comment.

Fixed

  • order/class-member-order no longer fires on every inner-class
    member
    when the inner class body starts with a comment-only line
    (# or ## on its own line, e.g. a leading doc comment). The lexer
    was preserving the indent stack on any comment-only line, so the
    parser saw no Indent at the start of the body, returned an empty
    inner class, and the following var/func tokens fell back to the
    outer parse loop. Every inner-class member then looked like a
    sibling of the inner class and tripped the ordering rule.

    The lexer now splits comment-only line handling into three cases
    by relative indent: same indent preserves the stack (unchanged),
    shallower indent uses the existing peek-ahead to disambiguate
    boundary vs mid-body noise (unchanged), and deeper indent falls
    through to Indent emission so the leading comment opens the new
    block.

    Reported in #5 with
    a full root-cause trace from the reporter.

Install

CLI from crates.io:

cargo install gdstyle

Or grab a prebuilt binary from this release page, drop it on your
PATH, and run gdstyle in your project directory.

For the Godot editor plugin: download gdstyle-godot-plugin.zip from
this release, extract the addons/gdstyle/ folder into your Godot
project, then enable the plugin in Project > Project Settings >
Plugins
.

For the pre-commit framework, bump your
config to:

- repo: https://github.com/atelico/gdstyle
  rev: v0.1.6
  hooks:
    - id: gdstyle
    - id: gdstyle-fmt

or run pre-commit autoupdate.

Full documentation, rule list, configuration reference, and the
GDExtension API live in the README.

Full Changelog: v0.1.5...v0.1.6

v0.1.5

03 Jun 22:47

Choose a tag to compare

gdstyle 0.1.5

Patch release fixing a formatter explosion on @abstract (and any
other unrecognised class-level annotation).

Fixed

  • gdstyle fmt no longer duplicates @abstract / class_name
    blocks.
    When an unrecognised top-level annotation
    (@abstract in Godot 4.6+, also @experimental and @deprecated)
    appeared above class_name/extends with a function later in the
    file, the parser held it in pending state and silently attached it
    to that function. The formatter then treated lines 1..N as part of
    the function's "block" and re-emitted them on every pass — the
    multi-pass loop could blow the file up to 30+ duplicate
    @abstract\nclass_name Pickup\n chunks before stabilising.

    The parser now flushes pending unknown annotations into a new
    class-level ClassAnnotation node at six boundary points where the
    pending annotation can't legitimately attach:
    class_name, extends, signal, enum, const, inner class,
    and end-of-file.

    Function-level @abstract (@abstract\nfunc to_implement():) still
    attaches to its method as before — abstract method declarations are
    unaffected.

    Reported in #4.

Behaviour notes

  • The fix is structural (by member kind), not name-based. Any future
    Godot annotation that lands at the top of a file will sort with
    @tool/@icon/@static_unload automatically without a code change.
  • A trailing top-level annotation at EOF with no following declaration
    used to be silently dropped; it now survives a round-trip through
    gdstyle fmt.
  • A leading annotation directly above an inner class Inner: is
    attributed to the OUTER class (the AST doesn't yet model
    inner-class annotations). If that becomes a practical issue, file
    one and we'll wire annotation slots through inner-class parsing.

Install

CLI from crates.io:

cargo install gdstyle

Or grab a prebuilt binary from this release page, drop it on your
PATH, and run gdstyle in your project directory.

For the Godot editor plugin: download gdstyle-godot-plugin.zip from
this release, extract the addons/gdstyle/ folder into your Godot
project, then enable the plugin in Project > Project Settings >
Plugins
.

For the pre-commit framework, bump your
config to:

- repo: https://github.com/atelico/gdstyle
  rev: v0.1.5
  hooks:
    - id: gdstyle
    - id: gdstyle-fmt

or run pre-commit autoupdate.

Full documentation, rule list, configuration reference, and the
GDExtension API live in the README.

Full Changelog: v0.1.4...v0.1.5

v0.1.4

02 Jun 00:05

Choose a tag to compare

gdstyle 0.1.4

Adds file-scope suppression so class- and file-level rules can be
silenced cleanly.

Added

  • # gdstyle:ignore-file directive for file-scope suppression.

    # gdstyle:ignore-file=quality/max-public-methods,quality/max-class-variables
    class_name OrchestrationFacade
    extends Node
    # ... 25 public methods follow

    Anchor it at the top of the file by convention, but the parser
    accepts it anywhere. A bare # gdstyle:ignore-file (no =...)
    suppresses every rule in the file — for generated code or
    third-party drops.

    This is the right tool for the four rules whose diagnostic anchors
    at the class header or line 1 of the file and which previously
    couldn't be silenced without uglifying the signature:
    quality/max-public-methods, quality/max-class-variables,
    quality/max-inner-classes, quality/max-file-length.

    Per-line # gdstyle:ignore is unchanged and remains the right tool
    for spot exemptions on a single line.

Documentation

  • README's Inline suppression section is now Suppressing
    diagnostics
    with a directive/scope table, separate per-line and
    per-file subsections, and a "when to use which" guide.

Install

CLI from crates.io:

cargo install gdstyle

Or grab a prebuilt binary from this release page, drop it on your
PATH, and run gdstyle in your project directory.

For the Godot editor plugin: download gdstyle-godot-plugin.zip from
this release, extract the addons/gdstyle/ folder into your Godot
project, then enable the plugin in Project > Project Settings >
Plugins
.

For the pre-commit framework, bump your
config to:

- repo: https://github.com/atelico/gdstyle
  rev: v0.1.4
  hooks:
    - id: gdstyle
    - id: gdstyle-fmt

or run pre-commit autoupdate.

Full documentation, rule list, configuration reference, and the
GDExtension API live in the README.

Full Changelog: v0.1.3...v0.1.4

v0.1.3

01 Jun 08:33

Choose a tag to compare

gdstyle 0.1.3

Patch release fixing a false positive in quality/unreachable-code.

Fixed

  • quality/unreachable-code no longer flags the closing ) of a
    multi-line return statement as unreachable. The previous
    implementation was line-based and walked forward from each
    return/break/continue looking for any same-indent non-blank
    line. The closing ) of return floori(\n\t\t1.2\n\t) lands at the
    same indent as return, so it was wrongly reported.

    The rule now tracks open-bracket depth (( [ {) and backslash
    continuation across lines, masking delimiters inside string literals
    and trailing # comments. While a return statement is still
    syntactically open, subsequent lines are treated as continuation of
    that same statement. True positives — actual code at the same indent
    AFTER the statement closes — are still flagged.

    Reported in #3.

Install

CLI from crates.io:

cargo install gdstyle

Or grab a prebuilt binary from this release page, drop it on your
PATH, and run gdstyle in your project directory.

For the Godot editor plugin: download gdstyle-godot-plugin.zip from
this release, extract the addons/gdstyle/ folder into your Godot
project, then enable the plugin in Project > Project Settings >
Plugins
.

For the pre-commit framework, bump your
config to:

- repo: https://github.com/atelico/gdstyle
  rev: v0.1.3
  hooks:
    - id: gdstyle
    - id: gdstyle-fmt

or run pre-commit autoupdate.

Full documentation, rule list, configuration reference, and the
GDExtension API live in the README.

Full Changelog: v0.1.2...v0.1.3

v0.1.2

31 May 22:17

Choose a tag to compare

gdstyle 0.1.2

Patch release focused on one user-reported formatter bug. The fix is
under the hood in the lexer, so existing CI and editor workflows pick
it up automatically — no config changes required.

Fixed

  • Formatter no longer detaches ## doc strings from their function
    when the previous function's body ended with a nested indented block
    (e.g. a top-level if after a match, leaving two open indent
    levels at the body's tail). The lexer was emitting the doc comment
    token before the dedents that close the previous body, so the parser
    consumed the doc as part of the wrong function. The formatter then
    inserted its canonical between-functions blank-line gap between the
    orphan doc and the function it actually documents — visible to users
    as docstrings that the Godot editor tooltip and the class_docs
    export no longer recognised.

    Fixed in the lexer with read-only peek-ahead: when a comment sits at
    shallower indent than the current block, look at the next real line
    (skipping blanks and more comments). If that line is deeper than the
    comment, the comment is mid-body noise and the block continues; if
    it's at the comment's indent or lower, it's a true boundary and
    dedents fire correctly.

    The fix also tightens spacing between inner-class methods: when the
    previous formatter was confused about member boundaries it was
    inflating single blank lines to double; member-aware spacing now
    produces the canonical PEP-8 / Godot-style single blank between
    methods within a class.

Install

CLI from crates.io:

cargo install gdstyle

Or grab a prebuilt binary from this release page, drop it on your
PATH, and run gdstyle in your project directory.

For the Godot editor plugin: download gdstyle-godot-plugin.zip from
this release, extract the addons/gdstyle/ folder into your Godot
project, then enable the plugin in Project > Project Settings >
Plugins
.

For the pre-commit framework, bump your
config to:

- repo: https://github.com/atelico/gdstyle
  rev: v0.1.2
  hooks:
    - id: gdstyle
    - id: gdstyle-fmt

or run pre-commit autoupdate.

Full documentation, rule list, configuration reference, and the
GDExtension API live in the README.

Full Changelog: v0.1.1...v0.1.2

v0.1.1

31 May 21:41

Choose a tag to compare

gdstyle 0.1.1

Small follow-up to the initial release: one false-positive fix and a
pre-commit integration that came out of community feedback.

Fixes

  • quality/no-self-assign no longer flags obj.field = field style
    assignments. The previous implementation compared one identifier on
    each side of =, so moon.size = size * 0.5 matched size == size
    even though the LHS is the property moon.size and the RHS is the
    local size. Same bug hit self.position = position and
    x = x + 1. The rule now compares full dotted paths (including
    self. / super. heads) and only flags when the assignment ends
    at a statement terminator. True positives like
    obj.foo = obj.foo and self.player.health = self.player.health
    still trigger.

Added

  • Pre-commit framework integration. gdstyle now ships a
    .pre-commit-hooks.yaml at the repo root, exposing two hooks for
    pre-commit: gdstyle (lint) and
    gdstyle-fmt (format in place). Drop this into your project's
    .pre-commit-config.yaml:

    repos:
      - repo: https://github.com/atelico/gdstyle
        rev: v0.1.1
        hooks:
          - id: gdstyle
          - id: gdstyle-fmt

    Then pre-commit install. First run builds gdstyle from source via
    cargo (Rust toolchain required); subsequent runs are cached.

Install

CLI from crates.io:

cargo install gdstyle

Or grab a prebuilt binary from this release page, drop it on your PATH,
and run gdstyle in your project directory.

For the Godot editor plugin: download gdstyle-godot-plugin.zip from
this release, extract the addons/gdstyle/ folder into your Godot
project, then enable the plugin in Project > Project Settings > Plugins.

Full documentation, rule list, configuration reference, and the
GDExtension API live in the README.

Full Changelog: https://github.com/atelico/gdstyle/commits/v0.1.1

v0.1.0

28 May 22:53

Choose a tag to compare

gdstyle 0.1.0

First public release. gdstyle is a fast, opinionated linter and formatter for
GDScript (Godot 4.x), written in Rust, that ships as a single static binary
plus an optional Godot editor plugin.

We've been using it inside the studio for a while and figured the wider Godot
community might get the same mileage out of it. Open-sourcing it under MIT.

What's in the box

  • CLI: prebuilt binaries for Linux, macOS (Intel + Apple Silicon), and
    Windows. No Python, no Rust toolchain, no Godot install required to run it.
  • Lint: 54 rules across syntax, naming, formatting, ordering, and code
    quality. Most are safely auto-fixable.
  • Format: in-place, idempotent, member-aware. Same input always produces
    the same output.
  • Scene-aware autofix: --unsafe-fix follows renamed signals and methods
    into .tscn and .tres files, so a refactor doesn't quietly break editor
    wiring.
  • Godot editor plugin: bottom panel with clickable diagnostics, single
    right-click fixes, Lint/Format on save. Uses the GDExtension when present,
    falls back to the CLI binary otherwise.
  • TOML config (gdstyle.toml): per-rule severity overrides, limit knobs,
    exclude patterns. gdstyle searches up from the file's directory so each
    subproject or vendored addon can carry its own rules.

What it draws on

The defaults follow the official Godot GDScript style guide
and the conventions Nathan Lovato and GDQuest
have done so much to popularise. Scony's gdtoolkit
and GDQuest's GDScript Formatter
got there first and are still excellent options; gdstyle owes them a debt.

Heads up for a first release

It's young, and almost certainly wrong about something on a codebase that
isn't ours. We validated it against 30+ open-source Godot projects before
this release, which covers a lot of ground, but the wild is much bigger than
that. If you run gdstyle on your project and it flags something it shouldn't
(or misses something it should), an issue or PR is the most useful thing you
can send our way. Rule suggestions welcome too.

Install

CLI from crates.io:

cargo install gdstyle

Or grab a prebuilt binary from this release page, drop it on your PATH, and
run gdstyle in your project directory.

For the Godot editor plugin: download gdstyle-godot-plugin.zip from this
release, extract the addons/gdstyle/ folder into your Godot project, then
enable the plugin in Project > Project Settings > Plugins.

Full documentation, rule list, configuration reference, and the GDExtension
API live in the README.

Full Changelog: https://github.com/atelico/gdstyle/commits/v0.1.0