# GDScript Toolkit
[](https://github.com/Scony/godot-gdscript-toolkit/actions)
[](https://opensource.org/licenses/MIT)
[](https://github.com/psf/black)
[](https://ko-fi.com/pawel_lampe)
This project provides a set of tools for daily work with `GDScript`. At the moment it provides:
- A parser that produces a parse tree for debugging and educational purposes.
- A linter that performs a static analysis according to some predefined configuration.
- A formatter that formats the code according to some predefined rules.
- A code metrics calculator which calculates cyclomatic complexity of functions and classes.
## Installation
To install this project you need `python3` and `pip`.
Regardless of the target version, installation is done by `pip3` command and for stable releases, it downloads the package from PyPI.
### Godot 4
```
pip3 install "gdtoolkit==4.*"
# or
pipx install "gdtoolkit==4.*"
```
### Godot 3
```
pip3 install "gdtoolkit==3.*"
# or
pipx install "gdtoolkit==3.*"
```
### `master` (latest)
Latest version (potentially unstable) can be installed directly from git:
```
pip3 install git+https://github.com/Scony/godot-gdscript-toolkit.git
# or
pipx install git+https://github.com/Scony/godot-gdscript-toolkit.git
```
## Linting with gdlint [(more)](https://github.com/Scony/godot-gdscript-toolkit/wiki/3.-Linter)
To run a linter you need to execute `gdlint` command like:
```
$ gdlint misc/MarkovianPCG.gd
```
Which outputs messages like:
```
misc/MarkovianPCG.gd:96: Error: Function argument name "aOrigin" is not valid (function-argument-name)
misc/MarkovianPCG.gd:96: Error: Function argument name "aPos" is not valid (function-argument-name)
```
## Formatting with gdformat [(more)](https://github.com/Scony/godot-gdscript-toolkit/wiki/4.-Formatter)
**Formatting may lead to data loss, so it's highly recommended to use it along with Version Control System (VCS) e.g. `git`**
To run a formatter you need to execute `gdformat` on the file you want to format. So, given a `test.gd` file:
```
class X:
	var x=[1,2,{'a':1}]
	var y=[1,2,3,]     # trailing comma
	func foo(a:int,b,c=[1,2,3]):
		if a in c and \
		   b > 100:
			print('foo')
func bar():
	print('bar')
```
when you execute `gdformat test.gd` command, the `test.gd` file will be reformatted as follows:
```
class X:
	var x = [1, 2, {'a': 1}]
	var y = [
		1,
		2,
		3,
	]  # trailing comma
	func foo(a: int, b, c = [1, 2, 3]):
		if a in c and b > 100:
			print('foo')
func bar():
	print('bar')
```
## Parsing with gdparse [(more)](https://github.com/Scony/godot-gdscript-toolkit/wiki/2.-Parser)
To run a parser you need to execute the `gdparse` command like:
```
gdparse tests/valid-gd-scripts/recursive_tool.gd -p
```
The parser outputs a tree that represents your code's structure:
```
start
  class_def
    X
    class_body
      tool_stmt
      signal_stmt	sss
  class_def
    Y
    class_body
      tool_stmt
      signal_stmt	sss
  tool_stmt
```
## Calculating cyclomatic complexity with gdradon
To run cyclomatic complexity calculator you need to execute the `gdradon` command like:
```
gdradon cc tests/formatter/input-output-pairs/simple-function-statements.in.gd tests/gd2py/input-output-pairs/
```
The command outputs calculated metrics just like [Radon cc command](https://radon.readthedocs.io/en/latest/commandline.html#the-cc-command) does for Python code:
```
tests/formatter/input-output-pairs/simple-function-statements.in.gd
    C 1:0 X - A (2)
    F 2:1 foo - A (1)
tests/gd2py/input-output-pairs/class-level-statements.in.gd
    F 22:0 foo - A (1)
    F 24:0 bar - A (1)
    C 18:0 C - A (1)
tests/gd2py/input-output-pairs/func-level-statements.in.gd
    F 1:0 foo - B (8)
```
## Using gdtoolkit's GitHub action
In order to setup a simple action with gdtoolkit's static checks, the base action from this repo can be used:
```
name: Static checks
on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]
jobs:
  static-checks:
    name: 'Static checks'
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: Scony/godot-gdscript-toolkit@master
    - run: gdformat --check source/
    - run: gdlint source/
```
See the discussion in https://github.com/Scony/godot-gdscript-toolkit/issues/239 for more details.
## Using gdtookit in pre-commit
To add gdtookit as a pre-commit hook check the latest GitHub version (eg `4.2.2`) and add the followingto your `pre-commit-config.yaml` with the latest version.
```Yaml
repos:
  # GDScript Toolkit
  - repo: https://github.com/Scony/godot-gdscript-toolkit
    rev: 4.2.2
    hooks:
      - id: gdlint
        name: gdlint
        description: "gdlint - linter for GDScript"
        entry: gdlint
        language: python
        language_version: python3
        require_serial: true
        types: [gdscript]
      - id: gdformat
        name: gdformat
        description: "gdformat - formatter for GDScript"
        entry: gdformat
        language: python
        language_version: python3
        require_serial: true
        types: [gdscript]
```
## Development [(more)](https://github.com/Scony/godot-gdscript-toolkit/wiki/5.-Development)
Everyone is free to fix bugs or introduce new features. For that, however, please refer to existing issue or create one before starting implementation.
            
         
        Raw data
        
            {
    "_id": null,
    "home_page": "https://github.com/Scony/godot-gdscript-toolkit",
    "name": "gdtoolkit",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "GODOT, GDSCRIPT, PARSER, LINTER, FORMATTER",
    "author": "Pawel Lampe",
    "author_email": "pawel.lampe@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/de/39/041c1705dba6450c67e23be0c70d0fcff035e7d240b6695fc59efd8dafb6/gdtoolkit-4.5.0.tar.gz",
    "platform": null,
    "description": "# GDScript Toolkit\n[](https://github.com/Scony/godot-gdscript-toolkit/actions)\n[](https://opensource.org/licenses/MIT)\n[](https://github.com/psf/black)\n[](https://ko-fi.com/pawel_lampe)\n\nThis project provides a set of tools for daily work with `GDScript`. At the moment it provides:\n\n- A parser that produces a parse tree for debugging and educational purposes.\n- A linter that performs a static analysis according to some predefined configuration.\n- A formatter that formats the code according to some predefined rules.\n- A code metrics calculator which calculates cyclomatic complexity of functions and classes.\n\n## Installation\n\nTo install this project you need `python3` and `pip`.\nRegardless of the target version, installation is done by `pip3` command and for stable releases, it downloads the package from PyPI.\n\n### Godot 4\n\n```\npip3 install \"gdtoolkit==4.*\"\n# or\npipx install \"gdtoolkit==4.*\"\n```\n\n### Godot 3\n\n```\npip3 install \"gdtoolkit==3.*\"\n# or\npipx install \"gdtoolkit==3.*\"\n```\n\n### `master` (latest)\n\nLatest version (potentially unstable) can be installed directly from git:\n```\npip3 install git+https://github.com/Scony/godot-gdscript-toolkit.git\n# or\npipx install git+https://github.com/Scony/godot-gdscript-toolkit.git\n```\n\n## Linting with gdlint [(more)](https://github.com/Scony/godot-gdscript-toolkit/wiki/3.-Linter)\n\nTo run a linter you need to execute `gdlint` command like:\n\n```\n$ gdlint misc/MarkovianPCG.gd\n```\n\nWhich outputs messages like:\n\n```\nmisc/MarkovianPCG.gd:96: Error: Function argument name \"aOrigin\" is not valid (function-argument-name)\nmisc/MarkovianPCG.gd:96: Error: Function argument name \"aPos\" is not valid (function-argument-name)\n```\n\n## Formatting with gdformat [(more)](https://github.com/Scony/godot-gdscript-toolkit/wiki/4.-Formatter)\n\n**Formatting may lead to data loss, so it's highly recommended to use it along with Version Control System (VCS) e.g. `git`**\n\nTo run a formatter you need to execute `gdformat` on the file you want to format. So, given a `test.gd` file:\n\n```\nclass X:\n\tvar x=[1,2,{'a':1}]\n\tvar y=[1,2,3,]     # trailing comma\n\tfunc foo(a:int,b,c=[1,2,3]):\n\t\tif a in c and \\\n\t\t   b > 100:\n\t\t\tprint('foo')\nfunc bar():\n\tprint('bar')\n```\n\nwhen you execute `gdformat test.gd` command, the `test.gd` file will be reformatted as follows:\n\n```\nclass X:\n\tvar x = [1, 2, {'a': 1}]\n\tvar y = [\n\t\t1,\n\t\t2,\n\t\t3,\n\t]  # trailing comma\n\n\tfunc foo(a: int, b, c = [1, 2, 3]):\n\t\tif a in c and b > 100:\n\t\t\tprint('foo')\n\n\nfunc bar():\n\tprint('bar')\n```\n\n## Parsing with gdparse [(more)](https://github.com/Scony/godot-gdscript-toolkit/wiki/2.-Parser)\n\nTo run a parser you need to execute the `gdparse` command like:\n\n```\ngdparse tests/valid-gd-scripts/recursive_tool.gd -p\n```\n\nThe parser outputs a tree that represents your code's structure:\n\n```\nstart\n  class_def\n    X\n    class_body\n      tool_stmt\n      signal_stmt\tsss\n  class_def\n    Y\n    class_body\n      tool_stmt\n      signal_stmt\tsss\n  tool_stmt\n```\n\n## Calculating cyclomatic complexity with gdradon\n\nTo run cyclomatic complexity calculator you need to execute the `gdradon` command like:\n\n```\ngdradon cc tests/formatter/input-output-pairs/simple-function-statements.in.gd tests/gd2py/input-output-pairs/\n```\n\nThe command outputs calculated metrics just like [Radon cc command](https://radon.readthedocs.io/en/latest/commandline.html#the-cc-command) does for Python code:\n```\ntests/formatter/input-output-pairs/simple-function-statements.in.gd\n    C 1:0 X - A (2)\n    F 2:1 foo - A (1)\ntests/gd2py/input-output-pairs/class-level-statements.in.gd\n    F 22:0 foo - A (1)\n    F 24:0 bar - A (1)\n    C 18:0 C - A (1)\ntests/gd2py/input-output-pairs/func-level-statements.in.gd\n    F 1:0 foo - B (8)\n```\n\n## Using gdtoolkit's GitHub action\n\nIn order to setup a simple action with gdtoolkit's static checks, the base action from this repo can be used:\n\n```\nname: Static checks\n\non:\n  push:\n    branches: [ \"main\" ]\n  pull_request:\n    branches: [ \"main\" ]\n\njobs:\n  static-checks:\n    name: 'Static checks'\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v4\n    - uses: Scony/godot-gdscript-toolkit@master\n    - run: gdformat --check source/\n    - run: gdlint source/\n```\n\nSee the discussion in https://github.com/Scony/godot-gdscript-toolkit/issues/239 for more details.\n\n## Using gdtookit in pre-commit\n\nTo add gdtookit as a pre-commit hook check the latest GitHub version (eg `4.2.2`) and add the followingto your `pre-commit-config.yaml` with the latest version.\n\n```Yaml\nrepos:\n  # GDScript Toolkit\n  - repo: https://github.com/Scony/godot-gdscript-toolkit\n    rev: 4.2.2\n    hooks:\n      - id: gdlint\n        name: gdlint\n        description: \"gdlint - linter for GDScript\"\n        entry: gdlint\n        language: python\n        language_version: python3\n        require_serial: true\n        types: [gdscript]\n      - id: gdformat\n        name: gdformat\n        description: \"gdformat - formatter for GDScript\"\n        entry: gdformat\n        language: python\n        language_version: python3\n        require_serial: true\n        types: [gdscript]\n```\n\n## Development [(more)](https://github.com/Scony/godot-gdscript-toolkit/wiki/5.-Development)\n\nEveryone is free to fix bugs or introduce new features. For that, however, please refer to existing issue or create one before starting implementation.\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Independent set of tools for working with GDScript - parser, linter and formatter",
    "version": "4.5.0",
    "project_urls": {
        "Homepage": "https://github.com/Scony/godot-gdscript-toolkit"
    },
    "split_keywords": [
        "godot",
        " gdscript",
        " parser",
        " linter",
        " formatter"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "36feafcf23a58b3e20897484b546d86741a7ea0d8cf57ae616c1677482b47f61",
                "md5": "8353c58272df390ce9296258ebbb35f1",
                "sha256": "f25c5bf7f7fe861e1127164c5d73e0a7fb204ec74cf05d375b76a5dcf8610cdb"
            },
            "downloads": -1,
            "filename": "gdtoolkit-4.5.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8353c58272df390ce9296258ebbb35f1",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 62698,
            "upload_time": "2025-10-09T14:23:28",
            "upload_time_iso_8601": "2025-10-09T14:23:28.284363Z",
            "url": "https://files.pythonhosted.org/packages/36/fe/afcf23a58b3e20897484b546d86741a7ea0d8cf57ae616c1677482b47f61/gdtoolkit-4.5.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "de39041c1705dba6450c67e23be0c70d0fcff035e7d240b6695fc59efd8dafb6",
                "md5": "071d1743c545746be4dbd299a461b0be",
                "sha256": "1ab17fb5400d86e4ae66d9c94992f4e3a9b6c27d618d4094782e66101efb3e9a"
            },
            "downloads": -1,
            "filename": "gdtoolkit-4.5.0.tar.gz",
            "has_sig": false,
            "md5_digest": "071d1743c545746be4dbd299a461b0be",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 49728,
            "upload_time": "2025-10-09T14:23:29",
            "upload_time_iso_8601": "2025-10-09T14:23:29.145060Z",
            "url": "https://files.pythonhosted.org/packages/de/39/041c1705dba6450c67e23be0c70d0fcff035e7d240b6695fc59efd8dafb6/gdtoolkit-4.5.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-09 14:23:29",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Scony",
    "github_project": "godot-gdscript-toolkit",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "gdtoolkit"
}