From 28883815709d212166599260b98accc0e50a987e Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Wed, 28 Jan 2026 08:09:44 +0000 Subject: [PATCH 1/2] feat(pgpm): rename --template-path to --template flag - Rename --template-path to --template with -t alias - --template parses 'dir/fromPath' format (e.g., --template pnpm/module) - When --template is provided, it takes precedence over --dir and positional args - Keep backward compatibility with --template-path (deprecated) - Update tests to use new --template flag --- pgpm/cli/__tests__/init.test.ts | 8 +++---- pgpm/cli/src/commands/init/index.ts | 29 ++++++++++++++++++++----- pgpm/cli/src/commands/init/workspace.ts | 7 +++--- pgpm/cli/src/index.ts | 4 +++- 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/pgpm/cli/__tests__/init.test.ts b/pgpm/cli/__tests__/init.test.ts index 29fb7efdc..a98567986 100644 --- a/pgpm/cli/__tests__/init.test.ts +++ b/pgpm/cli/__tests__/init.test.ts @@ -109,7 +109,7 @@ describe('cmds:init', () => { }); describe('with custom templates', () => { - it('initializes workspace with --template-path', async () => { + it('initializes workspace with --template', async () => { const { mockInput, mockOutput } = environment; const prompter = new Inquirerer({ input: mockInput, @@ -122,7 +122,7 @@ describe('cmds:init', () => { cwd: fixture.tempDir, name: 'test-workspace-template', workspace: true, - templatePath: 'default/workspace' + template: 'pgpm/workspace' }); await commands(argv, prompter, { @@ -139,7 +139,7 @@ describe('cmds:init', () => { expect(existsSync(path.join(workspaceDir, 'pgpm.json'))).toBe(true); }); - it('initializes module with --template-path', async () => { + it('initializes module with --template', async () => { // First create a workspace const workspaceDir = path.join(fixture.tempDir, 'test-workspace-for-module'); const { mockInput, mockOutput } = environment; @@ -170,7 +170,7 @@ describe('cmds:init', () => { name: 'test-module-template', moduleName: 'test-module-template', extensions: ['plpgsql'], - templatePath: 'default/module' + template: 'pgpm/module' }), prompter, { noTty: true, input: mockInput, diff --git a/pgpm/cli/src/commands/init/index.ts b/pgpm/cli/src/commands/init/index.ts index d48b15222..a0b7fa7cf 100644 --- a/pgpm/cli/src/commands/init/index.ts +++ b/pgpm/cli/src/commands/init/index.ts @@ -39,6 +39,7 @@ Options: --repo Template repo (default: https://github.com/constructive-io/pgpm-boilerplates.git) --from-branch Branch/tag to use when cloning repo --dir Template variant directory (e.g., supabase, drizzle) + --template, -t Full template path (e.g., pnpm/module) - combines dir and fromPath --boilerplate Prompt to select from available boilerplates Examples: @@ -46,6 +47,7 @@ Examples: ${binaryName} init workspace Initialize new workspace ${binaryName} init module Initialize new module explicitly ${binaryName} init workspace --dir Use variant templates + ${binaryName} init --template pnpm/module Use full template path (dir + type) ${binaryName} init --boilerplate Select from available boilerplates ${binaryName} init --repo owner/repo Use templates from GitHub repository ${binaryName} init --repo owner/repo --from-branch develop Use specific branch @@ -70,13 +72,30 @@ async function handleInit(argv: Partial>, prompter: Inquirer const { cwd = process.cwd() } = argv; const templateRepo = (argv.repo as string) ?? DEFAULT_TEMPLATE_REPO; const branch = argv.fromBranch as string | undefined; - const dir = argv.dir as string | undefined; const noTty = Boolean((argv as any).noTty || argv['no-tty'] || process.env.CI === 'true'); const useBoilerplatePrompt = Boolean(argv.boilerplate); // Get fromPath from first positional arg const positionalFromPath = argv._?.[0] as string | undefined; + // Handle --template flag: parses "dir/fromPath" format and extracts both components + // When --template is provided, it takes precedence over --dir and positional fromPath + const templateArg = argv.template as string | undefined; + let dir = argv.dir as string | undefined; + let templateFromPath: string | undefined; + + if (templateArg) { + // Parse template path like "pnpm/module" into dir="pnpm" and fromPath="module" + const slashIndex = templateArg.indexOf('/'); + if (slashIndex > 0) { + dir = templateArg.substring(0, slashIndex); + templateFromPath = templateArg.substring(slashIndex + 1); + } else { + // No slash - treat the whole thing as fromPath (e.g., --template workspace) + templateFromPath = templateArg; + } + } + // Handle --boilerplate flag: separate path from regular init if (useBoilerplatePrompt) { return handleBoilerplateInit(argv, prompter, { @@ -89,10 +108,10 @@ async function handleInit(argv: Partial>, prompter: Inquirer }); } - // Regular init path: default to 'module' if no fromPath provided - const fromPath = positionalFromPath || 'module'; - // Track if user explicitly requested module (e.g., `pgpm init module`) - const wasExplicitModuleRequest = positionalFromPath === 'module'; + // Regular init path: --template takes precedence, then positional arg, then default to 'module' + const fromPath = templateFromPath || positionalFromPath || 'module'; + // Track if user explicitly requested module (e.g., `pgpm init module` or `--template pnpm/module`) + const wasExplicitModuleRequest = positionalFromPath === 'module' || templateFromPath === 'module'; // Inspect the template to get its type const inspection = inspectTemplate({ diff --git a/pgpm/cli/src/commands/init/workspace.ts b/pgpm/cli/src/commands/init/workspace.ts index cdcb01bbd..2dd724c6f 100644 --- a/pgpm/cli/src/commands/init/workspace.ts +++ b/pgpm/cli/src/commands/init/workspace.ts @@ -31,8 +31,9 @@ export default async function runWorkspaceSetup( prompter.close(); const templateRepo = (argv.repo as string) ?? DEFAULT_TEMPLATE_REPO; - // Don't set default templatePath - let scaffoldTemplate use metadata-driven resolution - const templatePath = argv.templatePath as string | undefined; + // Don't set default template - let scaffoldTemplate use metadata-driven resolution + // Support both --template (new) and --template-path (deprecated) for backward compatibility + const template = (argv.template || argv.templatePath) as string | undefined; // Register workspace.dirname resolver so boilerplate templates can use it via defaultFrom/setFrom // This provides the intended workspace directory name before the folder is created @@ -42,7 +43,7 @@ export default async function runWorkspaceSetup( const dir = argv.dir as string | undefined; await scaffoldTemplate({ - fromPath: templatePath ?? 'workspace', + fromPath: template ?? 'workspace', outputDir: targetPath, templateRepo, branch: argv.fromBranch as string | undefined, diff --git a/pgpm/cli/src/index.ts b/pgpm/cli/src/index.ts index 91046269b..9623abf37 100644 --- a/pgpm/cli/src/index.ts +++ b/pgpm/cli/src/index.ts @@ -36,7 +36,9 @@ export const options: Partial = { v: 'version', h: 'help', 'from-branch': 'fromBranch', - 'template-path': 'templatePath' + // Support both --template and --template-path (deprecated) for backward compatibility + 'template-path': 'template', + t: 'template' } } }; From 16efbdbd3031f5a70972a4e9234d59730ed5b3eb Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Wed, 28 Jan 2026 08:40:41 +0000 Subject: [PATCH 2/2] fix(pgpm): add -w alias for --create-workspace and update README docs --- pgpm/cli/README.md | 4 +++- pgpm/cli/src/index.ts | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pgpm/cli/README.md b/pgpm/cli/README.md index 1f671f419..abf623b59 100644 --- a/pgpm/cli/README.md +++ b/pgpm/cli/README.md @@ -70,6 +70,8 @@ Here are some useful commands for reference: - `pgpm init` - Initialize a new module - `pgpm init workspace` - Initialize a new workspace +- `pgpm init --template ` - Initialize using a full template path (e.g., `pnpm/module`) +- `pgpm init -w` - Create a workspace first, then create the module inside it ### Development Setup @@ -142,7 +144,7 @@ pgpm deploy --createdb ## 🧰 Templates, Caching, and Updates -- `pgpm init` now scaffolds workspaces/modules from `https://github.com/constructive-io/pgpm-boilerplates.git` using `create-gen-app` with a one-week cache (stored under `~/.pgpm/cache/repos`). Override with `--repo`, `--from-branch`, and `--template-path`, or use a local template path. +- `pgpm init` now scaffolds workspaces/modules from `https://github.com/constructive-io/pgpm-boilerplates.git` using `create-gen-app` with a one-week cache (stored under `~/.pgpm/cache/repos`). Override with `--repo`, `--from-branch`, and `--template`, or use a local template path. - Run `pgpm cache clean` to wipe the cached boilerplates if you need a fresh pull. - The CLI performs a lightweight npm version check at most once per week (skipped in CI or when `PGPM_SKIP_UPDATE_CHECK` is set). Use `pgpm update` to upgrade to the latest release. diff --git a/pgpm/cli/src/index.ts b/pgpm/cli/src/index.ts index 9623abf37..4c51dbfb9 100644 --- a/pgpm/cli/src/index.ts +++ b/pgpm/cli/src/index.ts @@ -38,7 +38,10 @@ export const options: Partial = { 'from-branch': 'fromBranch', // Support both --template and --template-path (deprecated) for backward compatibility 'template-path': 'template', - t: 'template' + t: 'template', + // -w for --create-workspace flag + w: 'createWorkspace', + 'create-workspace': 'createWorkspace' } } };