Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 5 additions & 18 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
[package]
name = "godot-arch"
version = "0.6.0"
edition = "2024"
license = "MIT"
[workspace]
members = ["godot-arch","godot-arch-cli"]
resolver = "3"

[dependencies]
colored = "3.0.0"
lazy_static = "1.5.0"
winapi = { version = "0.3", features = ["consoleapi", "processenv", "wincon", "handleapi", "winbase"] }
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.9.0"
glob-match = "0.2.1"
convert_case = "0.10.0"
predicates = "3.1.3"
godot-properties-parser = "0.4.0"
serde_json = "1.0.145"
regex = "1.12.2"
clap = { version = "4.5.53", features = ["derive"] }
[workspace.dependencies]
colored = "3.0.0"
5 changes: 3 additions & 2 deletions docs/command-line-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,9 @@ Example GitHub Actions workflow:

## Exit Codes

- **0**: All tests passed successfully
- **Non-zero**: One or more tests failed (the tool returns an error)
- **0**: All checks passed successfully
- **1**: Tests executed with failed checks
- **2**: There was a runtime issue/error while executing

The exit code can be used in CI/CD pipelines to fail builds when linting issues are detected.

Expand Down
123 changes: 123 additions & 0 deletions docs/rules/rule-allowed-custom-resource-location.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Rule: Allowed Custom Resource Location

Ensures that custom resource files are located in designated directories.

## Purpose

This rule helps maintain a consistent project structure by restricting where custom resource files can exist. For example, you might want all `Hat` resources to be in the `resources/hats/all` folder.

## Configuration

This rule is configured via the `allowedCustomResourceLocations` map in your config file. Unlike other rules, it doesn't use `includePatterns` as the inclusion is implicitly defined via the `allowedCustomResourceLocations` configuration (see below for more information).

Additionally, the `failUnmatchedCustomResources` flag can be used to enforce stricter validation, as it fails if a custom resource has not been included in `allowedCustomResourceLocations`.

```yaml
allowedCustomResourceLocations:
"File":
- ./resources/**
- ./assets/resources/**
failUnmatchedCustomResources: true
```

**Format:**

- **Key:** The name of the custom resource type (e.g., `File`)
- **Value:** An array of glob patterns defining where those files are allowed
- **failUnmatchedCustomResources:** A boolean flag to determine whether unmatched custom resources should cause validation to fail.

## Examples

### Example 1: Custom Resource Files in Resources Folder

```yaml
allowedCustomResourceLocations:
"File":
- ./resources/**
```

✅ Allowed:

- `./resources/config.tres`
- `./resources/subfolder/data.tres`

❌ Not Allowed:

- `./config.tres`
- `./assets/config.tres`

### Example 2: Multiple Allowed Locations

```yaml
allowedCustomResourceLocations:
"File":
- ./resources/**
- ./assets/resources/**
```

✅ Allowed:

- `./resources/config.tres`
- `./assets/resources/config.tres`

❌ Not Allowed:

- `./config.tres`
- `./assets/config.tres`

## Ignore Patterns

You can exclude specific files or folders from this rule:

```yaml
ignorePatterns:
"rule-allowed-custom-resource-location":
- ./test/**
- ./examples/**
```

Or use global ignores:

```yaml
ignorePatterns:
overall:
- ./addons/**
```

## How to Fix Violations

When a file is in a disallowed location, you have several options:

1. **Move the file** to one of the allowed locations
2. **Add a new allowed location** to the configuration
3. **Add an ignore pattern** for that specific file or folder
4. **Remove the restriction** by deleting the entry from `allowedCustomResourceLocations`

## Common Use Cases

### Enforce Custom Resource Organization

```yaml
allowedCustomResourceLocations:
"File":
- ./resources/**
"Shader":
- ./shaders/**
```

### Separate by Resource Type

```yaml
allowedCustomResourceLocations:
"File":
- ./resources/**
"Shader":
- ./shaders/**
"Material":
- ./materials/**
```

## Related Documentation

- [Configuration Reference](../configuration.md)
- [Glob Patterns Guide](../glob-patterns.md)
7 changes: 0 additions & 7 deletions docs/rules/rule-allowed-file-location.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,6 @@ allowedFileLocations:
- ./utils/**
```

## Tips

- Start broad and tighten restrictions as your project grows
- Use the `overall` ignore pattern for third-party folders like `addons/`
- Consider your team's workflow when defining locations
- Document your chosen structure in your project's README

## Related Documentation

- [Configuration Reference](../configuration.md)
Expand Down
7 changes: 0 additions & 7 deletions docs/rules/rule-filename-snake-case.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,6 @@ ignorePatterns:
- **Cross-platform:** No case-sensitivity issues
- **Convention:** Matches common Python/GDScript style

## Tips

- Apply this rule project-wide for maximum consistency
- Set it up early in your project to avoid mass renaming later
- Use with [Parent Has Same Name](./rule-parent-has-same-name.md) for a cohesive structure
- Remember: file extensions (`.gd`, `.tscn`) don't need to match the rule

## Related Documentation

- [Configuration Reference](../configuration.md)
Expand Down
8 changes: 0 additions & 8 deletions docs/rules/rule-node-depth-fits-max-depth.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,14 +212,6 @@ ignorePatterns:
- ./test/**
```

## Tips

- Start with `maxNodeDepth: 4` and adjust based on your needs
- Use subscenes for complex components
- Flatten unnecessary container nodes
- Consider scene composition over deep hierarchies
- Apply the rule to catch complexity early

## Related Documentation

- [Configuration Reference](../configuration.md)
Expand Down
6 changes: 0 additions & 6 deletions docs/rules/rule-root-node-is-file-name-pascal.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,6 @@ my_awesome_scene.tscn → MyAwesomeScene
player_controller.tscn → PlayerController
```

## Tips

- Use with [Filename Snake Case](./rule-filename-snake-case.md) for consistency
- Apply to all `.tscn` files for best results
- Great for onboarding new team members

## Related Documentation

- [Configuration Reference](../configuration.md)
Expand Down
7 changes: 0 additions & 7 deletions docs/rules/rule-root-node-script-in-same-folder.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,6 @@ ignorePatterns:
- ./addons/** # Third-party addons
```

## Tips

- Apply this rule to all `.tscn` files
- Use with [Parent Has Same Name](./rule-parent-has-same-name.md)
- Create a consistent folder-per-scene structure
- Great for team projects

## Related Documentation

- [Configuration Reference](../configuration.md)
Expand Down
8 changes: 8 additions & 0 deletions godot-arch-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "godot-arch-cli"
version = "0.1.0"
edition = "2024"

[dependencies]
clap = { version = "4.5.53", features = ["derive"] }
godot-arch = { path = "../godot-arch" }
File renamed without changes.
1 change: 1 addition & 0 deletions godot-arch-cli/src/interface/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod cli;
33 changes: 33 additions & 0 deletions godot-arch-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use std::process::exit;

use godot_arch::run_godot_arch;

mod interface;
use interface::cli::Args;
enum ExitCode {
/// Succesfully executed and all checks have passed
Success = 0,
/// Succesfully executed with failed checks
Failure = 1,
/// Ran into an error while executing
Error = 2,
}

fn main() {
let Args {
config_path,
project_path,
report_location,
} = Args::parse_args();

match run_godot_arch(&config_path, &project_path, report_location) {
Ok(test_results) => {
if test_results.files_failed > 0 {
exit(ExitCode::Failure as i32)
} else {
exit(ExitCode::Success as i32)
}
}
Err(_err) => exit(ExitCode::Error as i32),
}
}
17 changes: 17 additions & 0 deletions godot-arch/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "godot-arch"
version = "0.1.0"
edition = "2024"

[dependencies]
colored = {workspace = true }
lazy_static = "1.5.0"
winapi = { version = "0.3", features = ["consoleapi", "processenv", "wincon", "handleapi", "winbase"] }
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.9.0"
glob-match = "0.2.1"
convert_case = "0.10.0"
predicates = "3.1.3"
godot-properties-parser = "0.4.0"
serde_json = "1.0.145"
regex = "1.12.2"
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ pub struct Config {
#[serde(rename = "maxNodeDepth")]
#[serde(default = "default_max_node_depth")]
pub max_node_depth: usize,
#[serde(rename = "failUnmatchedCustomResources")]
#[serde(default)]
pub should_fail_unmatched_custom_resources: bool,
}

fn default_max_node_depth() -> usize {
Expand Down Expand Up @@ -87,3 +90,9 @@ pub struct IncludePatterns {
#[serde(default)]
pub node_depth_fits_max_depth: Vec<String>,
}

pub fn load_config(path: &str) -> Result<Config, Box<dyn std::error::Error>> {
let config_content = std::fs::read_to_string(path)?;
let config = serde_yaml::from_str(&config_content)?;
Ok(config)
}
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
pub mod cli;
pub mod config;
Loading
Loading