Skip to main content

Dependency analyzer for Godot/GDScript projects

Project description

gdcruiser

Static dependency analyzer for Godot projects, inspired by dependency-cruiser. Parses GDScript (.gd) and scene (.tscn) files to build a full dependency graph, detect circular dependencies, enforce architectural rules, and export the results as text, JSON, GraphViz DOT, or Mermaid diagrams. Designed to run locally or in CI pipelines.

Features

  • Parses .gd and .tscn files — extends, preload(), load(), class_name, and scene script references
  • Detects circular dependencies
  • Resolves class_name declarations to map symbolic inheritance
  • Configurable architectural rules (forbidden, allowed, required, circular, orphan) via .gdcruiser.json or pyproject.toml
  • Multiple output formats: human-readable text, JSON, GraphViz DOT, and Mermaid
  • --exclude flag to filter paths from analysis
  • Non-zero exit code on cycles or rule violations (CI-friendly)

Installation

Requires Python 3.13+.

pip install gdcruiser

Or with uv:

uv tool install gdcruiser

Usage

gdcruiser [-h] [-f {text,json,dot,mermaid}] [-o FILE] [--no-cycles] [-v] [path]
Option Description
path Godot project path (default: current directory)
-f, --format Output format: text (default), json, dot, or mermaid
-o, --output Write output to file instead of stdout
--no-cycles Skip cycle detection
-v, --verbose Verbose output

Examples

Analyze the current directory:

gdcruiser .

Analyze a specific project and output JSON:

gdcruiser /path/to/godot/project -f json

Generate a GraphViz DOT file:

gdcruiser . -f dot -o deps.dot
dot -Tpng deps.dot -o deps.png

Generate a Mermaid diagram:

gdcruiser . -f mermaid

Output Formats

Text (default)

============================================================
GDScript Dependency Analysis
============================================================

Modules: 9
Dependencies: 8

----------------------------------------
CIRCULAR DEPENDENCIES (1 found)
----------------------------------------

Cycle 1:
  -> res://cycle_b.gd
  -> res://cycle_a.gd
  -> res://cycle_b.gd (back to start)

----------------------------------------
MODULE DEPENDENCIES
----------------------------------------

res://player.gd
  class_name: Player
  extends_class: res://base_entity.gd:2
  preload: res://inventory.gd:5

JSON

{
  "graph": {
    "modules": {
      "res://player.gd": {
        "path": "res://player.gd",
        "class_name": "Player",
        "dependencies": [
          {
            "target": "res://base_entity.gd",
            "type": "extends_class",
            "line": 2,
            "resolved": true
          }
        ]
      }
    },
    "stats": {
      "module_count": 9,
      "dependency_count": 8
    }
  },
  "cycles": [],
  "symbols": {
    "Player": "res://player.gd"
  },
  "errors": []
}

GraphViz DOT

digraph dependencies {
    rankdir=LR;
    node [shape=box, fontname="monospace"];

    "res://player.gd" [label="Player\nplayer.gd"];
    "res://base_entity.gd" [label="BaseEntity\nbase_entity.gd"];

    "res://player.gd" -> "res://base_entity.gd" [label="extends"];
}

Nodes involved in cycles are highlighted in red.

Mermaid

Produces a Mermaid flowchart that renders natively on GitHub, GitLab, Notion, and other Markdown tools — no external tooling required.

gdcruiser tests/fixtures -f mermaid
graph LR
    res_base_entity_gd["BaseEntity<br/>base_entity.gd"]
    res_config_gd["config.gd"]
    res_cycle_a_gd["CycleA<br/>cycle_a.gd"]
    res_cycle_b_gd["CycleB<br/>cycle_b.gd"]
    res_enemy_gd["Enemy<br/>enemy.gd"]
    res_game_manager_gd["game_manager.gd"]
    res_inventory_gd["Inventory<br/>inventory.gd"]
    res_player_gd["Player<br/>player.gd"]
    res_player_tscn["player.tscn"]

    res_cycle_a_gd == preload ==> res_cycle_b_gd
    res_cycle_b_gd == preload ==> res_cycle_a_gd
    res_enemy_gd -- extends --> res_base_entity_gd
    res_game_manager_gd -- preload --> res_player_tscn
    res_game_manager_gd -- load --> res_config_gd
    res_player_gd -- extends --> res_base_entity_gd
    res_player_gd -- preload --> res_inventory_gd
    res_player_tscn -- script --> res_player_gd

    classDef cycle fill:#ffcccc,stroke:#cc0000
    class res_cycle_a_gd,res_cycle_b_gd cycle

Cycle nodes are highlighted with a red fill, and cycle edges use thick arrows.

Supported Dependency Patterns

gdcruiser detects the following GDScript patterns:

Pattern Example
extends (path) extends "res://path/to/script.gd"
extends (class) extends ClassName
class_name class_name MyClass
preload() preload("res://path/to/file.gd")
load() load("res://path/to/file.gd")

For .tscn files, it detects scripts attached to nodes via [ext_resource].

Pre-commit Hook

gdcruiser can run as a pre-commit hook to catch dependency violations on every commit. Add the following to your Godot project's .pre-commit-config.yaml:

repos:
  - repo: https://github.com/magicletur/gdcruiser
    rev: v1.0.0  # use the latest release tag
    hooks:
      - id: gdcruiser

By default the hook runs gdcruiser . --no-cycles and only triggers when .gd or .tscn files are changed.

To customize the behavior, pass additional arguments via args:

hooks:
  - id: gdcruiser
    args: ["--config", "rules.json"]
hooks:
  - id: gdcruiser
    args: ["--exclude", "addons"]

If any rule violation is found the hook exits with a non-zero code and blocks the commit.

Development

Install dependencies:

uv sync

Set up pre-commit hooks:

uv run pre-commit install

This installs hooks for pre-commit, commit-msg, and post-checkout stages. On every commit the hooks will:

  • Fix trailing whitespace and line endings
  • Lint and format with Ruff
  • Run the test suite with pytest
  • Enforce Conventional Commits for commit messages

Run the CLI:

uv run gdcruiser

Run tests:

uv run pytest

Run linter:

uv run ruff check .

Format code:

uv run ruff format .

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gdcruiser-1.3.0.tar.gz (16.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gdcruiser-1.3.0-py3-none-any.whl (26.8 kB view details)

Uploaded Python 3

File details

Details for the file gdcruiser-1.3.0.tar.gz.

File metadata

  • Download URL: gdcruiser-1.3.0.tar.gz
  • Upload date:
  • Size: 16.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for gdcruiser-1.3.0.tar.gz
Algorithm Hash digest
SHA256 92124369eae9cba8111599305310b4356152514d52e05b477909e5601408a378
MD5 9c2b4005e3677b9eae8565263e4ded45
BLAKE2b-256 407b3d00ff6b1cf27a28fffc510c49ba6eb529393322479ddf41d7c7a414c4ff

See more details on using hashes here.

Provenance

The following attestation bundles were made for gdcruiser-1.3.0.tar.gz:

Publisher: cd.yaml on Thurbeen/gdcruiser

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gdcruiser-1.3.0-py3-none-any.whl.

File metadata

  • Download URL: gdcruiser-1.3.0-py3-none-any.whl
  • Upload date:
  • Size: 26.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for gdcruiser-1.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d34bd2874e2a0d8404d0a4abc8ec52188bf46c2d64cedb666dd022d51e8da80e
MD5 e414b789ddb7a609021d28160892975a
BLAKE2b-256 ae45dac1432dc98e683ede881ec5b40e7ef331e5fcee3d87d3b5868c9c09d737

See more details on using hashes here.

Provenance

The following attestation bundles were made for gdcruiser-1.3.0-py3-none-any.whl:

Publisher: cd.yaml on Thurbeen/gdcruiser

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page