cbrgm / structuresmith

Validate, Diff, Render - A powerful tool designed to automate the generation of project files using customizable templates.
https://cbrgm.net
Apache License 2.0
31 stars 2 forks source link
automation codegen directory files go rendering repository structure template yaml


structuresmith

Structuresmith is a powerful tool designed to automate the generation of project files, streamlining repository setup and more using customizable templates. It's ideal for developers looking to maintain consistency and efficiency in their project configurations.

GitHub release Go Report Card go-lint-test go-binaries container


Features 🌟

What can this tool do for you?

  1. Automated Project Setup: Streamline new project initialization with predefined templates, significantly reducing setup time.
  2. Standardization Across Projects: Ensure consistent file structures and setups across multiple projects or repositories, crucial for team coherence and project maintenance.
  3. Bootstrapping: Accelerate the creation of initial project structures for quick prototyping and development iterations.
  4. Custom Template Management: Efficiently manage and apply custom templates across various projects, especially beneficial in large teams or organizations.
  5. Configuration Auditing: Validate YAML configurations before deployment to ensure compliance with required standards and specifications, enhancing reliability and reducing configuration errors.

Installation

You can download the latest release of structuresmith with this one-liner on MacOS / Linux (amd64 + arm64):

wget -O structuresmith "https://github.com/cbrgm/structuresmith/releases/latest/download/structuresmith_$(uname -s)-$(uname -m)"

You may also download the latest pre-compiled binaries from the GitHub releases page or build structuresmith from source using Go (1.21+):

make build

CLI Usage

After installing, you can run Structuresmith with the following command-line arguments:

structuresmith -h

Validate

Validates the YAML configuration (anvil.yml) to ensure its integrity and checks for any potential issues.

structuresmith validate --config path/to/config.yaml

Diff

Conducts a dry-run to display the file paths that would be generated, helping to preview changes without actual file creation.

structuresmith diff --config path/to/config.yaml --output output/directory --templates path/to/templates project-to-render

Example output:

delete:     .gitignore
overwrite:  .golangci.yml
overwrite:  Dockerfile
overwrite:  LICENSE
new:        foobar.txt
overwrite:  sub/bar.txt
overwrite:  sub/foo.txt
delete:     sub/nested/foo.txt

Render

Processes and writes the templated files to the disk, applying the configurations to generate the specified project structure.

structuresmith render --config path/to/config.yaml --output output/directory --templates path/to/templates project-to-render

Container

podman run --rm -it ghcr.io/cbrgm/structuresmith:latest

GitHub Actions

Please check out the action.yml and the example workflow.

Configuration Overview

These examples showcase the versatility and capabilities of structuresmith, ranging from simple inline content to more complex configurations using template groups and nested values. Please take a look at the sample anvil.yml.

# Structuresmith YAML Configuration
# This configuration showcases the use of template groups, custom values for templating,
# and the definition of project-specific files. Modify paths and values as needed.

# Define projects to apply template groups
projects:

  # Example Go project configuration
  - name: "example/go-project"
    groups:
      - groupName: "commonFiles"
      - groupName: "goProjectFiles"
        values:
          packageName: "main"   # Custom value used in Go template

  # Example for a general project using inline content
  - name: "example/general-project"
    groups:
      - groupName: "commonFiles"
    files:
      - destination: "config.json"
        content: |
          {
            "setting": "value",
            "enabled": true
          }

# Define template groups with sets of files
templateGroups:

  # Common files for all projects
  commonFiles:
    - destination: ".gitignore"
      source: "templates/gitignore.tmpl"  # Template for .gitignore
    - destination: "README.md"
      source: "templates/readme.tmpl"     # Template for README.md

# Group for specific project types, e.g., Go projects
  goProjectFiles:
    - destination: "main.go"
      source: "templates/main.go.tmpl"    # Main file for Go project
    - destination: "Makefile"
      source: "templates/Makefile.tmpl"   # Makefile for build commands

# Uncomment to demonstrate downloading files from URLs
#   - destination: "Dockerfile"
#     sourceUrl: "https://example.com/Dockerfile"
# Uncomment to demonstrate copying whole directories
#   - destination: "docs/"
#     source: "docs_templates/"

Examples

Example 1: Simple Inline Content for a Single Project

Description: A basic configuration creating a README.md file with inline content.

YAML Configuration:

projects:
  - name: "simple-project"
    files:
      - destination: "README.md"
        content: "Welcome to Simple Project"

Output:

Example 2: Single File Template with Value

Description: Creating a config.txt file from a template, substituting a value. YAML Configuration:

templateGroups:
  configFile:
    - destination: "config.txt"
      source: "templates/config.tmpl"
projects:
  - name: "config-project"
    groups:
      - groupName: "configFile"
        values:
          setting: "Enabled"

Output:

Example 3: Templated File with Nested Values

Description: Creating a file with nested template values. YAML Configuration:

templateGroups:
  detailFile:
    - destination: "details.txt"
      source: "templates/details.tmpl"
projects:
  - name: "detail-project"
    groups:
      - groupName: "detailFile"
        values:
          user:
            name: "Alice"
            role: "Developer"

Output:

Example 4: Using Template Group with Overwritten Values

Description: Utilizing a template group with values defined in the group and overwritten in the project definition. YAML Configuration:

templateGroups:
  baseFiles:
    - destination: "base.txt"
      source: "templates/base.tmpl"
      values:
        defaultText: "Default"
projects:
  - name: "base-project"
    groups:
      - groupName: "baseFiles"
        values:
          defaultText: "Customized Text"

Output:

Example 5: Multiple Template Groups

Description: Combining multiple template groups in a single project. YAML Configuration:

templateGroups:
  commonFiles:
    - destination: "README.md"
      source: "templates/readme.tmpl"
  additionalFiles:
    - destination: "extra.txt"
      source: "templates/extra.tmpl"
projects:
  - name: "multi-group-project"
    groups:
      - groupName: "commonFiles"
      - groupName: "additionalFiles"

Output:

Example 6: Mix of Direct Files and Template Groups

Description: A project configuration using a mix of direct file definitions and template groups. YAML Configuration:

templateGroups:
  documentationFiles:
    - destination: "docs/intro.md"
      source: "templates/docs/intro.tmpl"
projects:
  - name: "mixed-project"
    files:
      - destination: "overview.txt"
        content: "Project Overview"
    groups:
      - groupName: "documentationFiles"

Output:

Example 7: Templating a Whole Directory

Description: Applying templates to an entire directory. YAML Configuration:

projects:
  completeDirectory:
    - destination: "config/"
      source: "templates/config_directory/"
      values:
        appName: "MyApp"

repositories:
  - name: "directory-project"
    groups:
      - groupName: "completeDirectory"

Output:

Example 8: Downloading Content from URLs

Description: Fetching a file from a URL and placing it into the project directory. YAML Configuration:

projects:
  - name: "download-project"
    files:
      - destination: "Dockerfile"
        sourceUrl: "https://raw.githubusercontent.com/exampleuser/project/main/Dockerfile"

Output:

Lockfile .anvil.lock

Structuresmith's anvil.lock file is vital for managing project files. It keeps a record of used files and templates, tracking updates since the last use of the tool. An important feature of Structuresmith is its ability to automatically remove files from the project's output directory that are no longer present in the original project configuration. This ensures the output remains synchronized with the current project setup.

Including anvil.lock in the project's versioning is beneficial. It provides a clear history of file changes, especially important in team settings to maintain consistency and prevent conflicts in the project's files.

Templating Explained

Structuresmith leverages Go's powerful templating system, allowing you to define dynamic content in your templates. This system provides a flexible way to insert values into your files, making your templates adaptable to different contexts.

How It Works

Go Templating Syntax

Contributing & License

We welcome and value your contributions to this project! πŸ‘ If you're interested in making improvements or adding features, please refer to our Contributing Guide. This guide provides comprehensive instructions on how to submit changes, set up your development environment, and more.

Please note that this project is developed in my spare time and is available for free πŸ•’πŸ’». As an open-source initiative, it is governed by the Apache 2.0 License. This license outlines your rights and obligations when using, modifying, and distributing this software.

Your involvement, whether it's through code contributions, suggestions, or feedback, is crucial for the ongoing improvement and success of this project. Together, we can ensure it remains a useful and well-maintained resource for everyone 🌍.