Skip to content

Conversation

@sdqede
Copy link
Contributor

@sdqede sdqede commented Nov 24, 2025

Summary

This PR refactors create-gen-app to be a pure API library by moving all CLI tooling to create-gen-app-test, and adds built-in template caching using appstash to improve performance.

Changes

Architecture Refactoring

  • Separate CLI from library: Moved CLI implementation (src/cli.ts) and tests from create-gen-app to create-gen-app-test package

    • create-gen-app is now API-only, suitable for programmatic use
    • CLI functionality preserved in create-gen-app-test for integration testing
    • Removed bin field and minimist dependency from create-gen-app
  • Move dev helper script: Relocated dev/index.ts and dev/README.md to create-gen-app-test/dev/

    • Development tooling consolidated in test package
    • Updated package scripts accordingly
  • Fix TypeScript build errors: Moved integration-helpers.ts to create-gen-app-test/src/test-utils/ to resolve rootDir boundary issues

New Features

  • Template caching with appstash: Added built-in caching to avoid repeated git clone operations

    • Caches repositories under ~/.<toolName>/cache/repos using appstash
    • Cache-first logic: checks cache before cloning
    • Configurable via CreateGenOptions.cache (toolName, baseDir, enabled)
    • Tests use isolated temp directories to avoid polluting developer's home directory
    • Enabled by default for better performance
  • Git clone optimizations:

    • Added --depth 1 for shallow clones (already implemented)
    • Uses --single-branch when branch is specified

Bug Fixes

  • Test updates: Fixed all tests to match camelCase variable naming convention
    • Updated assertions from PROJECT_NAME to projectName format
    • Fixed prompt/replace tests to use correct answer key names
    • Updated cloneRepo tests to allow --depth 1 flag
    • Replaced execSync spy in cache tests with console.log assertions

Testing

  • All existing tests updated and passing
  • New cache integration tests added with proper isolation
  • CLI tests moved to create-gen-app-test package

Breaking Changes

  • create-gen-app no longer provides CLI binaries (create-gen-app / cga)
  • CLI functionality now only available via create-gen-app-test package (internal use)

Migration Guide

For programmatic usage, continue using createGen() API as before. For CLI access, use the create-gen-app-test package internally (not published).

Related Issues

https://github.com/hyperweb-io/projects-issues/issues/240

- Added a depth argument to the git clone command for a shallow clone to enhance performance.
Remove CLI entry point from create-gen-app package to make it a pure
library API. The CLI implementation and tests are now housed in the
create-gen-app-test package for integration testing purposes.

Changes:
- Remove src/cli.ts and __tests__/cli.test.ts from create-gen-app
- Remove bin field and minimist dependencies from create-gen-app/package.json
- Update README.md to clarify that the published package is API-only
- Port CLI code to create-gen-app-test/src/cli.ts
- Add CLI tests to create-gen-app-test/src/__tests__/cli.test.ts
- Add minimist and inquirerer dependencies to create-gen-app-test
- Update CLI imports to use create-gen-app library APIs

This separation ensures create-gen-app remains focused on its core
template generation functionality while maintaining CLI testing capabilities
in the dedicated test harness package.
…rootDir error

Move integration-helpers.ts from create-gen-app/test-utils to create-gen-app-test/src/test-utils
to resolve TS6059 error where files outside rootDir cannot be imported during build.

Changes:
- Copy integration-helpers.ts to create-gen-app-test/src/test-utils/
- Update cli.test.ts import path to use local test-utils
- Update cached-template.test.ts.snap to reflect latest template structure

This ensures all source files are within the package's rootDir boundary,
fixing the CI build error: "File is not under 'rootDir'".
Relocate the development helper script from create-gen-app to create-gen-app-test
to keep the main package API-only. The dev script now lives alongside other CLI
tooling in the test harness package.

Changes:
- Move dev/index.ts and dev/README.md to create-gen-app-test/dev/
- Update dev script imports to use create-gen-app workspace package
- Remove dev script from create-gen-app/package.json
- Add dev script to create-gen-app-test/package.json
- Update create-gen-app README to remove dev/README reference

This ensures create-gen-app remains focused on its core library functionality
while development tooling is consolidated in the test package.
Add built-in template caching to avoid repeated git clones from GitHub.
Templates are cached locally using appstash, significantly speeding up
subsequent runs when using the same repository and branch.

Changes:
- Add cache.ts helper with getCachedRepo/cloneToCache/prepareTemplateDirectory
- Extend CreateGenOptions with optional cache configuration (toolName, baseDir, enabled)
- Update cloneRepo to support cache-aware cloning
- Integrate caching into createGen pipeline with cache-first logic
- Add cache.test.ts with isolated temp baseDir to avoid touching user's home
- Update README with caching documentation and usage examples
- Add appstash dependency to package.json

The cache is enabled by default and stores repositories under ~/.<toolName>/cache/repos.
Tests use temporary directories (via baseDir) to prevent pollution of the
developer's home directory, following the pattern from appstash tests.
Fix test assertions to align with camelCase variable extraction (e.g.,
projectName instead of PROJECT_NAME). Also fix cache test spy issue.

Changes:
- Update extractVariables tests to expect camelCase variable names
- Fix promptUser tests to use correct answer key names (fullName, moduleDesc)
- Update cloneRepo tests to allow --depth 1 flag in git clone commands
- Fix replaceVariables tests to use camelCase answer keys
- Replace execSync spy in cache.test.ts with console.log assertion to
  avoid "Cannot redefine property" error

All tests now correctly validate the camelCase variable naming convention
used throughout the codebase.
@sdqede sdqede requested a review from pyramation November 24, 2025 10:48
MODULENAME: `Test Module ${suffix}`,
MODULEDESC: `Integration test module ${suffix}`,
REPONAME: `integration-${safeSuffix}`,
USERNAME: `tester-${safeSuffix}`,
Copy link
Contributor

Choose a reason for hiding this comment

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

why are these ALL CAPS?

import { CacheOptions } from "./types";
import { cloneRepo, normalizeGitUrl } from "./clone";

const DEFAULT_TOOL = "pgpm";
Copy link
Contributor

Choose a reason for hiding this comment

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

this should be configured in a constructor or similar

'Unknown Author';
getAnswer(answers, [
"USERFULLNAME",
"AUTHOR",
Copy link
Contributor

Choose a reason for hiding this comment

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

why ALL CAPS again?

/**
* Options that control template caching behavior
*/
export interface CacheOptions {
Copy link
Contributor

Choose a reason for hiding this comment

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

I was actually envisioning some of this in another package, but I think we may be able to make it work

@pyramation pyramation merged commit 12fc02c into main Nov 25, 2025
34 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.

3 participants