Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 27, 2025

Implementation Complete: Template Generation CLI Support (Issue #41)

This PR implements the template subcommand for the create command, allowing users to generate configuration file templates via the CLI.

Implementation Checklist ✅

  • Update CLI command structure to support create subcommands (environment/template)
  • Add CreateAction enum with Environment and Template variants
  • Implement handle_template_generation() handler that calls domain method
  • Add user-friendly success messages with next steps
  • Update command routing to handle new subcommand structure
  • Add unit tests for CLI argument parsing
  • Add integration tests for template generation via CLI
  • Update CLI module tests to reflect new command structure
  • Manual testing of CLI commands
  • Linting and formatting (clippy and rustfmt)
  • Code review (passed with no comments)
  • Fix clippy pedantic warnings

Security Summary

No new security vulnerabilities introduced.

This implementation is a thin CLI wrapper that:

  • Delegates to existing domain method EnvironmentCreationConfig::generate_template_file()
  • Uses standard async runtime for file operations
  • Properly propagates domain-layer errors with .help() methods
  • Creates parent directories safely using tokio::fs::create_dir_all()
  • Writes files safely using tokio::fs::write()

The security posture is maintained by:

  • No raw file operations - delegates to tokio's safe async file APIs
  • No user input validation required (paths are already validated)
  • Error handling includes proper context and actionable guidance
  • No secrets or sensitive data in template generation

Test Results

  • 971 tests pass (4 new template tests + 967 existing)
  • Clippy: ✅ No warnings (all pedantic lints pass)
  • Rustfmt: All code formatted
  • Manual testing: All CLI commands work as expected

CLI Usage Examples

# Generate template with default path
$ torrust-tracker-deployer create template
⏳ Generating configuration template...
✅ Configuration template generated: environment-template.json

# Generate template with custom path
$ torrust-tracker-deployer create template ./config/my-env.json
✅ Configuration template generated: ./config/my-env.json

# Create environment from config
$ torrust-tracker-deployer create environment --env-file config.json

Closes

Original prompt

This section details on the original issue you should resolve

<issue_title>[Subissue 7/7] Template Generation Support (Optional)</issue_title>
<issue_description>Parent Epic: #34 - Implement Create Environment Command
Depends On: #40 - Template System Integration
Status: OPTIONAL ENHANCEMENT
Estimated Time: 1-2 hours

⚠️ Note: This is an optional enhancement that can be deferred. It requires #40 (Template System Integration) to be completed first.

Overview

Implement the template subcommand for the create command, allowing users to generate configuration file templates. This enhances user experience by providing a starting point for configuration creation.

Goals

  • Implement template subcommand in the create command structure
  • Generate JSON configuration template files
  • Support custom output paths for template generation
  • Provide helpful placeholder content with clear replacement instructions
  • Integrate with existing CLI subcommand architecture

Architecture Requirements

DDD Layer: Presentation (CLI interface) + Infrastructure (template generation)
Module Path: src/presentation/console/subcommands/create/ + src/infrastructure/templates/
Pattern: CLI Subcommand + Template Generation

Dependencies: Requires #40 (Template System Integration) to be completed first.

CLI Interface

# Generate template configuration file (JSON format)
torrust-tracker-deployer create template
# Creates: ./environment-template.json in current working directory

# Generate template in specific directory
torrust-tracker-deployer create template ./config/environment.json

# Generate template with custom filename
torrust-tracker-deployer create template ./my-environment.json

# Show help for template subcommand
torrust-tracker-deployer create template --help

Template Example

{
  "environment": {
    "name": "my-environment"
  },
  "ssh_credentials": {
    "private_key_path": "~/.ssh/id_rsa",
    "public_key_path": "~/.ssh/id_rsa.pub",
    "username": "torrust",
    "port": 22
  }
}

Acceptance Criteria

  • create template subcommand generates valid JSON template
  • Template includes helpful placeholder values
  • Template includes comments explaining each field (if JSON supports it, or in separate docs)
  • Custom output paths are supported
  • Default filename is environment-template.json
  • Error handling follows tiered help system pattern
  • Help text provides clear usage examples

Implementation Notes

  • Extend existing CLI subcommand structure from Subissue 3
  • Use TemplateManager from Subissue 6 for template generation
  • Follow existing patterns for CLI subcommands
  • Ensure template content matches environment configuration schema

For detailed specification, see: docs/issues/epic-create-environment-command-subissue-7-template-generation-support.md</issue_description>

<agent_instructions>@copilot Please implement this issue using the v2 specification:

📋 Use this spec: docs/issues/41-subissue-7-template-generation-support-v2.md

⚠️ Important: The v1 spec is outdated. PR #48 already implemented template generation in the domain layer (EnvironmentCreationConfig::generate_template_file()).

This is a simple CLI integration task - just add the template subcommand and call the existing domain method. Don't create new template generation logic or infrastructure modules.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@josecelano ## ✅ Issue Documentation Updated

The issue specification has been updated to reflect the implementation completed in PR #48.

Key Changes

Previous specification was outdated - it was written before PR #48 implemented struct-based template generation in the domain layer.

New v2 specification: docs/issues/41-subissue-7-template-generation-support-v2.md

What Changed

  1. Architecture: Domain layer (not infrastructure) - template generation already implemented
  2. Implementation scope: Thin CLI wrapper only (1-2 hours of work)
  3. API: Use existing EnvironmentCreationConfig::generate_template_file() method
  4. Error handling: Use existing CreateConfigError enum
  5. Testing: Focus on CLI integration tests (domain logic already tested)

What's Already Done ✅

  • Template generation logic in src/domain/config/environment_config.rs
  • Error handling with .help() methods
  • Comprehens...

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits October 27, 2025 08:42
This implements the template generation CLI subcommand, allowing users to generate configuration file templates via the CLI.

Changes:
- Updated CLI command structure to support create subcommands (environment/template)
- Added CreateAction enum with Environment and Template variants
- Implemented handle_template_generation() handler that calls existing domain method
- Added user-friendly success messages with next steps instructions
- Updated command routing to handle new subcommand structure
- Added comprehensive tests for CLI argument parsing and template generation
- Updated existing tests to work with new subcommand structure

The implementation is a thin CLI wrapper that delegates to the existing
EnvironmentCreationConfig::generate_template_file() method from the domain layer.

CLI Usage:
- Generate template: torrust-tracker-deployer create template
- Custom path: torrust-tracker-deployer create template ./config/my-env.json
- Create environment: torrust-tracker-deployer create environment --env-file <file>

Co-authored-by: josecelano <[email protected]>
@josecelano
Copy link
Member

@copilot linting workflow is failing:

     Running `target/debug/linter all`
2025-10-27T08:53:23.115265Z  INFO torrust_linting::cli: Running All Linters
2025-10-27T08:53:23.116760Z  INFO torrust_linting::utils: Installing markdownlint-cli...
2025-10-27T08:53:30.348705Z  INFO torrust_linting::utils: markdownlint-cli installed successfully
2025-10-27T08:53:30.348760Z  INFO markdown: Scanning markdown files...
2025-10-27T08:53:32.373088Z  INFO markdown: All markdown files passed linting!
2025-10-27T08:53:32.374204Z  INFO yaml: Scanning YAML files...
2025-10-27T08:53:33.103508Z  INFO yaml: All YAML files passed linting!
2025-10-27T08:53:33.104737Z  INFO torrust_linting::linters::toml: Installing Taplo CLI...
2025-10-27T08:55:31.049797Z  INFO torrust_linting::linters::toml: Taplo CLI installed successfully
2025-10-27T08:55:31.049831Z  INFO toml: Scanning TOML files...
2025-10-27T08:55:31.096702Z  INFO toml: All TOML files passed linting and formatting checks!
2025-10-27T08:55:31.097824Z  INFO torrust_linting::utils: Installing cspell...
2025-10-27T08:55:35.853465Z  INFO torrust_linting::utils: cspell installed successfully
2025-10-27T08:55:35.853503Z  INFO cspell: Running spell check on all files...
2025-10-27T08:55:40.095593Z  INFO cspell: All files passed spell checking!
2025-10-27T08:55:40.095632Z  INFO clippy: Running Rust Clippy linter...
error: these match arms have identical bodies
   --> src/presentation/commands/create/errors.rs:153:13
    |
153 |             Self::ConfigValidationFailed(inner) => inner.help(),
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
154 |             Self::CommandFailed(inner) => inner.help(),
155 |             Self::TemplateGenerationFailed(inner) => inner.help(),
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: if this is unintentional make the arms return different values
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#match_same_arms
    = note: `-D clippy::match-same-arms` implied by `-D clippy::pedantic`
    = help: to override `-D clippy::pedantic` add `#[allow(clippy::match_same_arms)]`
help: otherwise merge the patterns into a single arm
    |
153 ~             Self::ConfigValidationFailed(inner) | Self::TemplateGenerationFailed(inner) => inner.help(),
154 |             Self::CommandFailed(inner) => inner.help(),
155 ~             }
    |

error: could not compile `torrust-tracker-deployer` (lib) due to 1 previous error
error: wildcard matches only a single variant and will also match any future added variants
   --> src/presentation/cli/mod.rs:187:17
    |
187 |                 _ => panic!("Expected Environment action"),
    |                 ^ help: try: `crate::presentation::cli::CreateAction::Template { .. }`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#match_wildcard_for_single_variants
    = note: `-D clippy::match-wildcard-for-single-variants` implied by `-D clippy::pedantic`
    = help: to override `-D clippy::pedantic` add `#[allow(clippy::match_wildcard_for_single_variants)]`


error: wildcard matches only a single variant and will also match any future added variants
   --> src/presentation/cli/mod.rs:209:17
    |
209 |                 _ => panic!("Expected Environment action"),
    |                 ^ help: try: `crate::presentation::cli::CreateAction::Template { .. }`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#match_wildcard_for_single_variants

error: wildcard matches only a single variant and will also match any future added variants
   --> src/presentation/cli/mod.rs:252:17
    |
252 |                 _ => panic!("Expected Environment action"),
    |                 ^ help: try: `crate::presentation::cli::CreateAction::Template { .. }`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#match_wildcard_for_single_variants

error: wildcard matches only a single variant and will also match any future added variants
   --> src/presentation/cli/mod.rs:298:17
    |
298 |                 _ => panic!("Expected Template action"),
    |                 ^ help: try: `crate::presentation::cli::CreateAction::Environment { .. }`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#match_wildcard_for_single_variants

error: wildcard matches only a single variant and will also match any future added variants
   --> src/presentation/cli/mod.rs:322:17
    |
322 |                 _ => panic!("Expected Template action"),
    |                 ^ help: try: `crate::presentation::cli::CreateAction::Environment { .. }`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#match_wildcard_for_single_variants

error: could not compile `torrust-tracker-deployer` (lib test) due to 6 previous errors

2025-10-27T08:56:20.448678Z ERROR clippy: Clippy linting failed. Please fix the issues above.
2025-10-27T08:56:20.448749Z ERROR torrust_linting::cli: Rust clippy linting failed: Clippy linting failed
2025-10-27T08:56:20.448766Z  INFO rustfmt: Running Rust formatter check...
2025-10-27T08:56:21.466968Z  INFO rustfmt: Rust formatting check passed!
2025-10-27T08:56:21.467006Z  INFO shellcheck: Running ShellCheck on shell scripts...
2025-10-27T08:56:21.500486Z  INFO shellcheck: Found 7 shell script(s) to check
Error: Some linters failed
2025-10-27T08:56:22.635475Z  INFO shellcheck: shellcheck passed
2025-10-27T08:56:22.635519Z ERROR torrust_linting::cli: Some linters failed
Error: Process completed with exit code 1.
``

Copilot AI changed the title [WIP] Implement template generation support for create command Add template subcommand for create command Oct 27, 2025
Copilot AI requested a review from josecelano October 27, 2025 08:57
Copilot finished work on behalf of josecelano October 27, 2025 08:57
- Merge identical match arms in error help method
- Replace wildcard patterns with explicit variants in test assertions

Co-authored-by: josecelano <[email protected]>
Copy link
Contributor Author

Copilot AI commented Oct 27, 2025

@copilot linting workflow is failing:

...

Fixed in commit 48dd8a0. The clippy warnings have been resolved:

  1. Merged identical match arms for ConfigValidationFailed and TemplateGenerationFailed
  2. Replaced wildcard patterns with explicit CreateAction variants in all test assertions

All 971 tests pass and clippy runs cleanly with no warnings.

Copilot finished work on behalf of josecelano October 27, 2025 09:06
@josecelano josecelano marked this pull request as ready for review October 27, 2025 09:23
Copy link
Member

@josecelano josecelano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 48dd8a0

@josecelano josecelano merged commit 0eff71a into main Oct 27, 2025
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Subissue 7/7] Template Generation Support (Optional)

2 participants