Skip to content
/ genj Public

Command line tool based on rust to initialize Java project structure from templates

License

Notifications You must be signed in to change notification settings

mcgivrer/genj

Repository files navigation

genj

A command-line tool written in Rust to generate a Java project from a template (ZIP file or folder).

Principle

The binary reads a template (ZIP or folder), copies files to the destination directory while applying variable replacements in file paths and content. It also handles the transformation of the ${PACKAGE} variable into a Java folder hierarchy.

The main behavior is implemented in main via the Cli configuration structure and the extract_zip_with_replace, copy_dir_with_replace, and replace_package_in_path functions.

Available replacement variables

The following patterns are replaced in files and file names:

  • ${PROJECT_NAME}
  • ${AUTHOR_NAME}
  • ${AUTHOR_EMAIL}
  • ${PROJECT_VERSION}
  • ${PACKAGE} (transformed into folder hierarchy, e.g., com.example)
  • ${MAINCLASS}
  • ${PROJECT_YEAR}
  • ${JAVA}
  • ${VENDOR_NAME}

Build and environment generation

Depending on the --build option, the generator automatically adds:

  • Maven (pom.xml) if --build maven
  • Gradle (build.gradle) if --build gradle

A .sdkmanrc file is always created with:

  • java=<java_flavor> (e.g., 25-zulu)
  • maven=<version> if Maven build, or gradle=<version> if Gradle build

Generated files

After project generation, the following files and directories are created:

  • .genrc - Configuration file in JSON format containing all generation parameters:
    • Project metadata (name, version, author, email)
    • Build configuration (build tool, Java version, vendor name)
    • Generation timestamp (created_at in ISO 8601 format)
    • Generator metadata (generated_with: command name and version)
    • Template source path
    • Optional remote Git repository URL

Example .genrc content:

{
  "project_name": "MyApp",
  "author": "John Doe",
  "email": "john@example.com",
  "project_version": "1.0.0",
  "package": "com.example.app",
  "mainclass": "Application",
  "java_version": "21",
  "java_flavor": "21-zulu",
  "build_tool": "maven",
  "maven_version": "3.9.5",
  "gradle_version": "8.5",
  "vendor_name": "My Company",
  "template": "templates/basic-java",
  "remote_git_repository": null,
  "created_at": "2025-11-26T14:30:45.123456+00:00",
  "generated_with": {
    "cmd": "genj",
    "version": "1.3.1"
  }
}
  • .sdkmanrc - SDKMan environment configuration
  • .vscode/ - VSCode configuration directory with settings.json and launch.json
  • .git/ - Git repository initialized with initial commit
  • pom.xml or build.gradle - Build configuration based on --build option

Installation

Requires Rust/Cargo. To compile:

cargo build --release

Options (CLI)

Available shortcuts and options (see src/main.rs):

  • -t, --template <PATH>: Path to the template (ZIP or folder) [required]
  • -d, --destination <DIR>: Destination directory [required]
  • -n, --project_name <NAME>: Project name (default: Demo)
  • -a, --author <NAME>: Author (default: Unknown Author)
  • -e, --email <EMAIL>: Email (default: email@unknown.local)
  • -v, --project_version <VER>: Project version (default: 0.0.1)
  • -j, --java_version <VER>: JDK version to target (e.g., 25) also used in pom.xml/build.gradle (default: 25)
  • -f, --java_flavor <LABEL>: JDK flavor for sdkman (e.g., 25-zulu) (default: 25-zulu)
  • -k, --package <PKG>: Java package (default: com.demo)
  • -m, --mainclass <CLASS>: Main class (default: App)
  • -b, --build <maven|gradle>: Build tool (default: maven)
  • --maven_version <VER>: Maven version for .sdkmanrc (default: 3.9.5)
  • --gradle_version <VER>: Gradle version for .sdkmanrc (default: 8.5)
  • -l, --vendor_name <NAME>: Vendor name (usable in templates) (default: Vendor)
  • --verbose: Enable verbose output for detailed debugging information

Usage

Examples:

  • Generate from a template folder (Maven by default):
cargo run -- \
  --template templates/basic-java \
  --destination ./out \
  --project_name Demo \
  --author "Frédéric Delorme" \
  --email fred@example.com \
  --project_version 0.1.0 \
  --package com.demo \
  --mainclass App
  • Generate from a ZIP:
cargo run -- --template /path/to/template.zip --destination ./out --project_name Demo
  • Force Gradle and specify versions in .sdkmanrc:
cargo run -- \
  --template templates/basic-java \
  --destination ./out \
  --project_name Demo \
  --build gradle \
  --gradle_version 8.5 \
  --java_flavor 25-zulu
  • Target a specific JDK version for compilation (used in pom.xml and build.gradle):
cargo run -- --template templates/basic-java --destination ./out --project_name Demo -j 25

Verbose mode

Enable verbose output to see detailed information about each step of the generation process:

cargo run -- \
  --template templates/basic-java \
  --destination ./out \
  --project_name Demo \
  --verbose

Output with --verbose:

=== genj - Java Project Generator ===
Version: 1.3.1
Verbose mode enabled

[VERBOSE] Destination path will be: ./out/Demo
[VERBOSE] Generation timestamp: 2025-11-26T14:30:45.123456+00:00
[VERBOSE] Replacement variables:
  ${PROJECT_NAME} = Demo
  ${AUTHOR_NAME} = Unknown Author
  ...
[INFO] Reading template from: templates/basic-java
[VERBOSE] Template detected as directory
[VERBOSE] Scanning source directory: templates/basic-java
[VERBOSE] Created directory: ./out/Demo/src/main/java/com/demo
[VERBOSE] Copied and replaced: ./out/Demo/src/main/java/com/demo/App.java
[✓] Template directory copied
[INFO] Using build tool: maven
[VERBOSE] Generating pom.xml
[✓] pom.xml generated
[✓] .sdkmanrc generated
[✓] .genrc configuration file generated
[INFO] Configuring VSCode and Git repository...
[VERBOSE] Initializing Git repository
...
[✓] Java project 'Demo' generated successfully in ./out/Demo

=== Generation Summary ===
Project Name: Demo
Package: com.demo
Build Tool: maven
Java Version: 25
Location: ./out/Demo

Verbose mode is useful for:

  • Debugging template processing issues
  • Verifying variable replacements
  • Checking file and directory operations
  • Understanding the generation workflow
  • Troubleshooting file copy failures

Provided templates

Example templates can be found in templates/ (e.g., templates/basic-java). You can use them as is or create your own template (folder or ZIP). The structure can contain ${PACKAGE} in paths so that the generator creates the corresponding subfolders.

Important files

  • Cargo configuration: Cargo.toml
  • Program entry point and logic: src/main.rs

Notes

  • The program creates the destination directory <destination>/<project_name>.
  • If the template is a ZIP, the script attempts to remove a common root prefix present in the archive.
  • Binary files detected (non-text) are copied as is; only text files undergo replacements.
  • The .genrc file stores the exact parameters used for generation and can be used to regenerate similar projects.

Release and packaging scripts

Two helper scripts are provided to produce release artifacts and Debian packages:

  • build-release-full.sh

    • Purpose: compile a release build and collect artifacts (release binary, man pages, docs, LICENSE, README, etc.) into a release directory and an archive (tar.gz).
    • Usage:
      chmod +x build-release-full.sh
      ./build-release-full.sh
    • Result: a release archive (and/or release directory) is produced in the repository (see script output for exact path). Use this to distribute prebuilt binaries.
  • build_deb.sh

    • Purpose: build a Debian package (.deb) that installs the genj binary and man pages (section 1 and section 5), plus documentation.
    • Usage:
      chmod +x build_deb.sh
      ./build_deb.sh
    • Result: a Debian package genj_<version>_<arch>.deb is created in the project root. Install with:
      sudo dpkg -i genj_<version>_<arch>.deb

Make both scripts executable before running:

chmod +x build-release-full.sh build_deb.sh

Generate Debian package

The project includes build_deb.sh which automates packaging into a .deb. The script:

  1. Compiles the project in release mode
  2. Creates the Debian package layout (including /usr/bin and /usr/share/man)
  3. Copies and compresses man pages (genj.1 and genj-template.5) into appropriate sections
  4. Creates maintainer scripts (postinst, prerm, postrm) and documentation under /usr/share/doc/genj
  5. Builds the .deb

Installing the generated package:

sudo dpkg -i genj_1.2.2_amd64.deb

Verification:

which genj
man genj
man genj-template
genj --help

About

Command line tool based on rust to initialize Java project structure from templates

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published