Skip to content

httpdss/struct

Repository files navigation

πŸš€ STRUCT: Automated Project Structure Generator

en es

Struct Banner

Warning

This project is still in development and may contain bugs. Use it at your own risk.

πŸ“„ Table of Contents

πŸ“¦ Introduction

STRUCT is a powerful and flexible script designed to automate the creation of project structures based on YAML configurations. It supports template variables, custom file permissions, remote content fetching, and multiple file handling strategies to streamline your development setup process.

This is targeted towards developers, DevOps engineers, and anyone who wants to automate the creation of project structures. It can be used to generate boilerplate code, configuration files, documentation, and more.

✨ Features

  • YAML Configuration: Define your project structure in a simple YAML file.
  • Template Variables: Use placeholders in your configuration and replace them with actual values at runtime. Also supports custom Jinja2 filters and interactive mode to fill in the variables.
  • Custom File Permissions: Set custom permissions for your files directly from the YAML configuration.
  • Remote Content Fetching: Include content from remote files by specifying their URLs.
  • File Handling Strategies: Choose from multiple strategies (overwrite, skip, append, rename, backup) to manage existing files.
  • Dry Run: Preview the actions without making any changes to your file system.
  • Configuration Validation: Ensure your YAML configuration is valid before executing the script.
  • Verbose Logging: Get detailed logs of the script's actions for easy debugging and monitoring.

πŸ› οΈ Installation

Using pip

You can install STRUCT using pip:

pip install git+https://github.com/httpdss/struct.git

From Source

Alternatively, you can clone the repository and install it locally. See the Development section for more details.

Using Docker

You can use the Docker image to run the script without installing it on your system. See the Quick Start section for more details.

🐳 Quick Start

Quick Start Using Docker

  1. Create a YAML configuration file for your project structure. See sample configuration here.
  2. Run the following command to generate the project structure:
docker run \
  -v $(pwd):/workdir \
  -u $(id -u):$(id -g) \
  ghcr.io/httpdss/struct:main generate \
  /workdir/example/structure.yaml \
  /workdir/example_output

Quick Start Using Docker Alpine

For testing, you can run an alpine Docker container and install the script inside it:

docker run -it --entrypoint="" python:3.10-alpine sh -l

Inside the container:

apk add python-pip git vim
pip install git+https://github.com/httpdss/struct.git
mkdir example
cd example/
touch structure.yaml
vim structure.yaml # copy the content from the example folder
struct generate structure.yaml .

πŸ“ Usage

Run the script with the following command using one of the following subcommands:

  • generate: Generate the project structure based on the YAML configuration.
  • validate: Validate the YAML configuration file.
  • info: Display information about the script and its dependencies.
  • list: List the available structs

For more information, run the script with the -h or --help option (this is also available for each subcommand):

struct -h

Simple Example

struct generate terraform-module ./my-terraform-module

More Complete Example

struct generate \
  --log=DEBUG \
  --dry-run \
  --backup=/path/to/backup \
  --file-strategy=rename \
  --log-file=/path/to/logfile.log \
  terraform-module \
  ./my-terraform-module

πŸ“„ YAML Configuration

Here is an example of a YAML configuration file:

structure:
  - README.md:
      content: |
        # {{@ project_name @}}
        This is a template repository.
  - script.sh:
      permissions: '0777'
      content: |
        #!/bin/bash
        echo "Hello, {{@ author_name @}}!"
  - LICENSE:
      remote_file: https://raw.githubusercontent.com/nishanths/license/master/LICENSE
  - src/main.py:
      content: |
        print("Hello, World!")
folders:
  - .devops/modules/mod1:
      struct: terraform-module
  - .devops/modules/mod2:
      struct: terraform-module
  - ./:
      struct:
        - docker-files
        - go-project
variables:
  - project_name:
      description: "The name of the project"
      default: "MyProject"
      type: string
  - author_name:
      description: "The name of the author"
      type: string
      default: "John Doe"

Template variables

You can use template variables in your configuration file by enclosing them in {{@ and @}}. For example, {{@ project_name @}} will be replaced with the value of the project_name variable at runtime. If this are not set when running the script, it will prompt you to enter the value interactively.

If you need to define blocks you can use starting block notation {%@ and end block notation %@}.

To define comments you can use the comment start notation {#@ and end comment notation @#}.

Default template variables

  • file_name: The name of the file being processed.
  • file_directory: The name of the directory of file that is being processed.

Interactive template variables

If you don't provide a default value for a variable, the script will prompt you to enter the value interactively.

The struct defined should define the variable on a specific section of the YAML file. For example:

variables:
  - author_name:
      description: "The name of the author"
      type: string
      default: "John Doe"

as you can see, the author_name variable is defined on the variables section of the YAML file. it includes a description, type and default value which is used if the user doesn't provide a value interactively.

Custom Jinja2 filters

latest_release

This filter fetches the latest release version of a GitHub repository. It takes the repository name as an argument.

structure:
  - README.md:
      content: |
        # MyProject
        Latest release: {{@ "httpdss/struct" | latest_release @}}

This uses PyGithub to fetch the latest release of the repository so setting the GITHUB_TOKEN environment variable will give you access to private repositories.

If there is an error in the process, the filter will return LATEST_RELEASE_ERROR.

NOTE: you can use this filter to get the latest release for a terraform provider. For example, to get the latest release of the aws provider, you can use {{@ "hashicorp/terraform-provider-aws" | latest_release @}} or datadog provider {{@ "DataDog/terraform-provider-datadog" | latest_release @}}.

slugify

This filter converts a string into a slug. It takes an optional argument to specify the separator character (default is -).

structure:
  - README.md:
      content: |
        # {{@ project_name @}}
        This is a template repository.
        slugify project_name: {{@ project_name | slugify @}}

πŸ‘©β€πŸ’» Development

To get started with development, follow these steps:

  • Clone the repository
  • Create a virtual environment
python3 -m venv .venv
source .venv/bin/activate
  • Install the dependencies
pip install -r requirements.txt
pip install -r requirements.dev.txt

πŸ› οΈ Command-Line Auto-Completion

This project uses argcomplete to provide command-line auto-completion for the struct script. Follow these steps to enable auto-completion:

  1. Install argcomplete:

    pip install argcomplete
  2. Enable global completion for your shell. This step is usually done once:

    activate-global-python-argcomplete
  3. Register the script for auto-completion. Add the following line to your shell's configuration file (e.g., .bashrc, .zshrc):

    eval "$(register-python-argcomplete struct)"
  4. Reload your shell configuration:

    source ~/.bashrc  # or source ~/.zshrc for Zsh users

After completing these steps, you should have auto-completion enabled for the struct script. You can test it by typing part of a command and pressing Tab to see the available options.

struct <Tab>

πŸ“œ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ’° Funding

If you find this project helpful, please consider supporting it through donations: patreon/structproject

🀝 Contributing

Contributions are welcome! Please open an issue or submit a pull request.

πŸ™ Acknowledgments

Special thanks to all the contributors who helped make this project possible.

🐞 Known Issues

  • TBD