Skip to content

feat(pgpm): default pgpm init to no extensions (opt-in via flags)#1355

Merged
pyramation merged 1 commit into
mainfrom
feat/pgpm-init-no-default-extensions
Jul 11, 2026
Merged

feat(pgpm): default pgpm init to no extensions (opt-in via flags)#1355
pyramation merged 1 commit into
mainfrom
feat/pgpm-init-no-default-extensions

Conversation

@pyramation

Copy link
Copy Markdown
Contributor

Summary

pgpm init no longer forces an extensions decision. A bare pgpm init now scaffolds a module with no extensions — its .control has no requires = line — matching the zero-config init of comparable tools (sqitch, prisma, drizzle, dbmate, supabase, ...). Extensions become an explicit, lazy opt-in.

This is PR A of the extensions-DX cleanup. plpgsql is always present in Postgres (requiring it was noise) and uuid-ossp is legacy (gen_random_uuid() is core since PG13), so neither belongs in the default scaffold. Follow-ups: PR B hardens pgpm extension as the canonical enable-later path (non-destructive .control rewrite + --add/--set/--remove); PR C refreshes the tutorials.

What changed

The forced checkbox in pgpm/cli/src/commands/init/index.ts was:

// before: always prompted, pre-checked, and required
moduleQuestions.push({ name: 'extensions', type: 'checkbox',
  required: true, default: ['plpgsql', 'uuid-ossp'] });

Now the question is only added when the user opts in, and never defaults anything:

if (typeof argv.extensions === 'string')            // normalize `--extensions a,b`
  argv.extensions = argv.extensions.split(',').map(s => s.trim()).filter(Boolean);

const extensionsProvided   = argv.extensions !== undefined;      // `--extensions a,b`
const wantExtensionsPrompt = Boolean(argv.withExtensions || argv['with-extensions']);

if (isPgpmTemplate && project.workspacePath &&
    (extensionsProvided || wantExtensionsPrompt)) {
  moduleQuestions.push({ name: 'extensions', type: 'checkbox',
    allowCustomOptions: true, default: [] });   // no `required`, no default
}

So:

  • pgpm init → no extensions (no requires line).
  • pgpm init --extensions uuid-ossp,citext → non-interactive knob (unchanged extraction path; also the back-compat bridge).
  • pgpm init --with-extensions → interactive picker, empty default, not required.

No core changes needed — generateControlFileContent already omits requires = for an empty list, and deploy already skips CREATE EXTENSION when there are none.

Tests

  • Added regression test: bare pgpm init produces a .control with no requires line and getRequiredModules() === [].
  • Existing init/install/extensions/package suites pass unchanged — they pass extensions explicitly, so they exercise the opt-in path. Snapshots regenerated for the new test only.

Note: repo-wide pnpm lint currently fails on an unrelated pre-existing ESLint v9 config issue (no eslint.config.js); tsc --noEmit and the package build are clean.

Link to Devin session: https://app.devin.ai/sessions/424b76f81a60499493ac946b57136ad9
Requested by: @pyramation

@pyramation pyramation self-assigned this Jul 11, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@pyramation
pyramation merged commit 6f26a87 into main Jul 11, 2026
37 checks passed
@pyramation
pyramation deleted the feat/pgpm-init-no-default-extensions branch July 11, 2026 03:05
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.

1 participant