Grove is a cross-platform tool for defining, validating, and building directory trees based on user-defined schemas.
You can use the prebuilt binaries to validate or create directory structures, or integrate Grove into your Go projects.
- π Structure rules β define required, allowed, and denied files or folders
- π Flexible matching β support for both glob and regex patterns
- π³ Directory validation β validate entire directory trees from YAML schemas
- π§© .gro schema extension β optional extension for IDE syntax highlighting and tooling
- πΎ Cross-platform binaries β Linux, macOS, and Windows builds available
- π Composable schemas β include other schemas with cycle and duplicate detection
Download the latest release from GitHub Releases for your platform, or build from source:
go install github.com/cliper27/grove/cmd/grove@latestgrove helpOutput:
Validate project directory structure using schemas
Usage:
grove [command]
Available Commands:
check Validate a directory against a schema
completion Generate the autocompletion script for the specified shell
help Help about any command
version Print grove version
Flags:
-h, --help help for grove
-v, --version version for grove
Use "grove [command] --help" for more information about a command.grove check --helpOutput:
Validate a directory against a schema
Usage:
grove check <dir> <schema> [flags]
Flags:
--format string Output format. Options are 'json' or 'tree'
-h, --help help for check
-n, --no-color Suppress cmd colors. Colors are automatically suppressed when not using a terminal that supports them.
-o, --output string Output to specified file
-q, --quiet Suppress stdoutgrove check . go-project.grogrove check ./my-project ./schemas/go-project.gro --format "tree"grove check . ./schemas/go-project.gro --format "json" -q -o "result.json"Schemas are written in YAML. The file extension does not matter, but .gro is recommended for CLI autocompletion and the future VSCode extension. One file can only define one schema.
The name of the schema. Simple and short.
name: go-appBrief description of the schema.
description: Standard go app layoutThe list of patterns (see the next section) that MUST exist for the directory to be valid against this schema.
require:
cmd/:
schema: go-command
internal/:
schema: go-internal
README.md:
description: Project Documentation
.gitignore:
go.mod:
go.sum:Additional patterns that are allowed but not required. By default, any file or directory is allowed unless it is explicitly denied. For example: "Allow the folder cmd, but it must follow the schema cmd-folder". It can also define descriptions, either for folders or files.
allow:
pkg/:
schema: go-package
justfile:
description: Justfile with build recipesPatterns that are explicitly forbidden in the directory.
deny:
- node_modules/
- "*.exe"
- "~^temp_[0-9]+.bin$"If another schema is referenced in any other field, it must be specified here so that grove can find it. Each include is a path relative to the schema file.
include:
- ./cmd.package/go-package.gro
- ./cmd.package/go-command.gro
- ./go-internal.groA pattern represents a file or folder name. It can match a single item or a group of items depending on the pattern type.
Patterns are used as keys inside require and allow, and as values inside deny.
A pattern can be:
Matches a specific file or directory name exactly.
README.md:
src/:Matches multiple files using glob syntax.
"*.go":
"*.test.js":Matches names using a regular expression. Regex patterns are prefixed with ~.
"~^test_[0-9]+\\.txt$":Patterns defined under require or allow can have additional properties.
schema(String): Specifies that the matched directory must itself conform to another schema. This schema must be included in theincludefield.
cmd/:
schema: go-commandThis means every matching directory must validate against the go-command schema.
description(String): Same as the description of a schema. If bothdescriptionandschemaare specified,descriptionoverrides the referenced schema's description.
name: go-project
description: Standard Go project structure
include:
- ./cmd.package/go-package.gro
- ./cmd.package/go-command.gro
- ./go-internal.gro
require:
cmd/:
schema: go-command
internal/:
schema: go-internal
README.md:
description: Project Documentation
.gitignore:
go.mod:
go.sum:
allow:
pkg/:
schema: go-package
justfile:
description: Justfile with build recipes
deny:
- node_modules/
- "*.exe"
- "~^temp_[0-9]+.bin$" # ~ indicates regex