Skip to content

Refactor project output layout into shared ProjectLayout domain type #448

Description

@cdsap

Problem

Filesystem layout rules for Language (KTS, GROOVY, BOTH) are duplicated across cli/src/main/kotlin/io/github/cdsap/projectgenerator/cli/GenerateProjectRequest.kt (resolveProjectRootPath) and project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/ProjectGenerator.kt (getProjectLanguageAttributes). The CLI picks a root path and the generator expands it into LanguageAttributes, but both encode the same policy with no single source of truth.

Why This Matters

This is domain policy, not CLI or I/O detail. If one side changes (for example how --output-dir interacts with Language.BOTH) without the other, the CLI can report one location while files are written elsewhere. Tests are split across GenerateProjectsCliTest and ProjectGeneratorTest, so regressions are easy to miss.

Proposed Change

Add ProjectLayout in project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/model/ with two pure functions: defaultRootPath(outputDir, language, projectName) (replacing resolveProjectRootPath) and languageAttributes(rootPath, language) (replacing getProjectLanguageAttributes). Update GenerateProjectRequest.resolve and ProjectGenerator.write() to delegate to it. Add focused unit tests in project-generator for all language/output-dir combinations.

Files

  • project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/model/ProjectLayout.kt
  • project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/ProjectGenerator.kt
  • cli/src/main/kotlin/io/github/cdsap/projectgenerator/cli/GenerateProjectRequest.kt
  • project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/model/ProjectLayoutTest.kt

Constraints

  • Preserve behavior.
  • Preserve current generated directory structure and CLI flag behavior.
  • Keep --output-dir precedence over default projects_generated/<name>/... paths.
  • Do not change LanguageAttributes field semantics (extension, projectName).
  • Keep this as a small refactor; do not perform a broad architecture migration.
  • Do not change public APIs unless the issue explicitly requires it.

Acceptance Criteria

  • ProjectGenerator and GenerateProjectRequest both call ProjectLayout; no duplicate layout logic remains in those files.
  • New ProjectLayoutTest covers KTS, GROOVY, BOTH with and without outputDir.
  • ./gradlew :project-generator:unitTest, ./gradlew :cli:test, and ./gradlew ktlintCheck pass without behavior changes.
  • Existing behavior is preserved.

Validation

  • ./gradlew :project-generator:unitTest
  • ./gradlew :cli:test
  • ./gradlew ktlintCheck

Notes

In clean-architecture terms, output layout is a domain policy consumed by the CLI adapter and the generation use case. Centralizing it in model/ keeps infrastructure (Clikt, File writers) separate from the rule of where each language variant lives on disk, and gives library callers the same layout contract the CLI uses.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    architectureArchitecture, module boundaries, or dependency directionquality-codeGenerated by Hermes Quality Code for small architecture refactorsrefactorCode change that preserves behavior while improving structure

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions