Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"@pgpmjs/server-utils": "workspace:^",
"@pgpmjs/types": "workspace:^",
"find-and-require-package-json": "^0.8.2",
"inquirerer": "^4.1.2",
"inquirerer": "^4.2.0",
"js-yaml": "^4.1.0",
"minimist": "^1.2.8",
"pg-cache": "workspace:^",
Expand Down
2 changes: 1 addition & 1 deletion packages/csv-to-pg/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"@pgsql/types": "^17.6.2",
"@pgsql/utils": "^17.8.4",
"csv-parser": "^2.3.3",
"inquirerer": "^4.1.2",
"inquirerer": "^4.2.0",
"js-yaml": "^3.14.0",
"pgsql-deparser": "^17.15.0"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as path from 'path';

import { TestFixture } from '../test-utils';

describe('cmds:upgrade-modules - with initialized workspace and module', () => {
describe('cmds:upgrade - with initialized workspace and module', () => {
let fixture: TestFixture;
let workspaceDir: string;
let moduleDir: string;
Expand Down Expand Up @@ -45,7 +45,7 @@ describe('cmds:upgrade-modules - with initialized workspace and module', () => {
describe('when no modules are installed', () => {
it('reports no modules installed', async () => {
await fixture.runCmd({
_: ['upgrade-modules'],
_: ['upgrade'],
cwd: moduleDir,
});

Expand All @@ -65,10 +65,10 @@ describe('cmds:upgrade-modules - with initialized workspace and module', () => {
});

it('reports modules are up to date', async () => {
// Default behavior now upgrades all (no --all flag needed)
await fixture.runCmd({
_: ['upgrade-modules'],
_: ['upgrade'],
cwd: moduleDir,
all: true,
});

const pkgJson = JSON.parse(
Expand All @@ -88,7 +88,7 @@ describe('cmds:upgrade-modules - with initialized workspace and module', () => {

it('dry run does not modify package.json', async () => {
await fixture.runCmd({
_: ['upgrade-modules'],
_: ['upgrade'],
cwd: moduleDir,
'dry-run': true,
});
Expand All @@ -99,16 +99,16 @@ describe('cmds:upgrade-modules - with initialized workspace and module', () => {
expect(pkgJson.dependencies['@pgpm-testing/base32']).toBe('1.1.0');
});

it('--all flag upgrades from 1.1.0 to 1.2.0', async () => {
it('default behavior upgrades all from 1.1.0 to 1.2.0', async () => {
let pkgJson = JSON.parse(
fs.readFileSync(path.join(moduleDir, 'package.json'), 'utf-8')
);
expect(pkgJson.dependencies['@pgpm-testing/base32']).toBe('1.1.0');

// Default behavior now upgrades all (like pnpm upgrade)
await fixture.runCmd({
_: ['upgrade-modules'],
_: ['upgrade'],
cwd: moduleDir,
all: true,
});

pkgJson = JSON.parse(
Expand All @@ -117,17 +117,34 @@ describe('cmds:upgrade-modules - with initialized workspace and module', () => {
expect(pkgJson.dependencies['@pgpm-testing/base32']).toBe('1.2.0');
});

it('--modules flag filters to specific modules', async () => {
it('positional args filter to specific modules', async () => {
let pkgJson = JSON.parse(
fs.readFileSync(path.join(moduleDir, 'package.json'), 'utf-8')
);
expect(pkgJson.dependencies['@pgpm-testing/base32']).toBe('1.1.0');

// Positional args now used instead of --modules flag (like pnpm upgrade @pkg/name)
await fixture.runCmd({
_: ['upgrade-modules'],
_: ['upgrade', '@pgpm-testing/base32'],
cwd: moduleDir,
});

pkgJson = JSON.parse(
fs.readFileSync(path.join(moduleDir, 'package.json'), 'utf-8')
);
expect(pkgJson.dependencies['@pgpm-testing/base32']).toBe('1.2.0');
});

it('up alias works the same as upgrade', async () => {
let pkgJson = JSON.parse(
fs.readFileSync(path.join(moduleDir, 'package.json'), 'utf-8')
);
expect(pkgJson.dependencies['@pgpm-testing/base32']).toBe('1.1.0');

// Test the 'up' alias
await fixture.runCmd({
_: ['up'],
cwd: moduleDir,
modules: '@pgpm-testing/base32',
all: true,
});

pkgJson = JSON.parse(
Expand Down
4 changes: 2 additions & 2 deletions pgpm/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@
"@pgpmjs/types": "workspace:^",
"appstash": "^0.2.6",
"find-and-require-package-json": "^0.8.2",
"genomic": "^5.1.0",
"inquirerer": "^4.1.2",
"genomic": "^5.2.0",
"inquirerer": "^4.2.0",
"js-yaml": "^4.1.0",
"minimist": "^1.2.8",
"pg-cache": "workspace:^",
Expand Down
5 changes: 3 additions & 2 deletions pgpm/cli/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import migrate from './commands/migrate';
import _package from './commands/package';
import plan from './commands/plan';
import updateCmd from './commands/update';
import upgradeModules from './commands/upgrade-modules';
import upgrade from './commands/upgrade';
import remove from './commands/remove';
import renameCmd from './commands/rename';
import revert from './commands/revert';
Expand Down Expand Up @@ -64,7 +64,8 @@ export const createPgpmCommandMap = (skipPgTeardown: boolean = false): Record<st
analyze: pgt(analyze),
rename: pgt(renameCmd),
'test-packages': pgt(testPackages),
'upgrade-modules': pgt(upgradeModules),
upgrade: pgt(upgrade),
up: pgt(upgrade),
cache,
update: updateCmd
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
import { PgpmPackage } from '@pgpmjs/core';
import { Logger } from '@pgpmjs/logger';
import { CLIOptions, Inquirerer, OptionValue, Question } from 'inquirerer';
import { CLIOptions, Inquirerer, upgradePrompt, PackageInfo, createSpinner } from 'inquirerer';
import { ParsedArgs } from 'minimist';
import { fetchLatestVersion } from '../utils/npm-version';

const log = new Logger('upgrade-modules');
const log = new Logger('upgrade');

const upgradeModulesUsageText = `
Upgrade Modules Command:
const upgradeUsageText = `
Upgrade Command:

pgpm upgrade-modules [OPTIONS]
pgpm upgrade [PACKAGE...] [OPTIONS]

Upgrade installed pgpm modules to their latest versions from npm.
When used without arguments, upgrades all modules.

Options:
--help, -h Show this help message
--cwd <directory> Working directory (default: current directory)
--all Upgrade all modules without prompting
-i, --interactive Show outdated modules and select which ones to upgrade
--dry-run Show what would be upgraded without making changes
--modules <names> Comma-separated list of specific modules to upgrade
--workspace Upgrade modules across all packages in the workspace

Examples:
pgpm upgrade-modules Interactive selection of modules to upgrade
pgpm upgrade-modules --all Upgrade all installed modules
pgpm upgrade-modules --dry-run Preview available upgrades
pgpm upgrade-modules --modules @pgpm/base32,@pgpm/faker Upgrade specific modules
pgpm upgrade-modules --workspace --all Upgrade all modules across the entire workspace
pgpm upgrade Upgrade all installed modules
pgpm upgrade -i Interactive selection of modules to upgrade
pgpm upgrade @pgpm/base32 Upgrade specific module
pgpm upgrade @pgpm/base32 @pgpm/uuid Upgrade multiple specific modules
pgpm upgrade --dry-run Preview available upgrades
pgpm upgrade --workspace Upgrade all modules across the entire workspace
pgpm up Alias for upgrade
`;

interface ModuleUpdateInfo {
Expand Down Expand Up @@ -62,7 +64,7 @@ async function upgradeModulesForProject(
argv: Partial<ParsedArgs>,
prompter: Inquirerer,
dryRun: boolean,
upgradeAll: boolean,
interactive: boolean,
specificModules: string[] | undefined,
moduleName?: string
): Promise<boolean> {
Expand All @@ -78,10 +80,15 @@ async function upgradeModulesForProject(
}

const prefix = moduleName ? `[${moduleName}] ` : '';
log.info(`${prefix}Found ${installed.length} installed module(s). Checking for updates...`);


// Use spinner while checking for updates
const spinner = createSpinner(`${prefix}Checking ${installed.length} installed module(s) for updates...`);
spinner.start();

const moduleVersions = await fetchModuleVersions(installedVersions);
const modulesWithUpdates = moduleVersions.filter(m => m.hasUpdate);

spinner.succeed(`${prefix}Found ${modulesWithUpdates.length} module(s) with updates available`);

if (modulesWithUpdates.length === 0) {
log.success(`${prefix}All modules are already up to date.`);
Expand All @@ -101,9 +108,8 @@ async function upgradeModulesForProject(

let modulesToUpgrade: string[];

if (upgradeAll) {
modulesToUpgrade = modulesWithUpdates.map(m => m.name);
} else if (specificModules) {
if (specificModules && specificModules.length > 0) {
// Specific modules provided as positional arguments
modulesToUpgrade = modulesWithUpdates
.filter(m => specificModules.includes(m.name))
.map(m => m.name);
Expand All @@ -112,36 +118,26 @@ async function upgradeModulesForProject(
log.warn(`${prefix}None of the specified modules have updates available.`);
return false;
}
} else {
const options = modulesWithUpdates.map(mod => ({
} else if (interactive) {
// Interactive mode: use pnpm-style upgrade UI
const packages: PackageInfo[] = modulesWithUpdates.map(mod => ({
name: mod.name,
value: mod.name,
message: `${mod.name} (${mod.currentVersion} -> ${mod.latestVersion})`
current: mod.currentVersion,
latest: mod.latestVersion!,
type: 'dependencies' as const
}));

const questions: Question[] = [
{
name: 'selectedModules',
message: `${prefix}Select modules to upgrade:`,
type: 'checkbox',
options: options.map(o => o.message),
default: options.map(o => o.message)
}
];

const answers = await prompter.prompt(argv, questions);
const selectedOptions = (answers.selectedModules as OptionValue[])
.filter(opt => opt.selected)
.map(opt => opt.name);

modulesToUpgrade = modulesWithUpdates
.filter(mod => selectedOptions.includes(`${mod.name} (${mod.currentVersion} -> ${mod.latestVersion})`))
.map(m => m.name);
const result = await upgradePrompt(packages, 10);

if (modulesToUpgrade.length === 0) {
if (result.updates.length === 0) {
log.info(`${prefix}No modules selected for upgrade.`);
return false;
}

modulesToUpgrade = result.updates.map(u => u.name);
} else {
// Default behavior: upgrade all modules with updates (like pnpm upgrade)
modulesToUpgrade = modulesWithUpdates.map(m => m.name);
}

log.info(`\n${prefix}Upgrading ${modulesToUpgrade.length} module(s)...`);
Expand All @@ -158,16 +154,18 @@ export default async (
_options: CLIOptions
) => {
if (argv.help || argv.h) {
console.log(upgradeModulesUsageText);
console.log(upgradeUsageText);
process.exit(0);
}

const { cwd = process.cwd() } = argv;
const dryRun = Boolean(argv['dry-run']);
const upgradeAll = Boolean(argv.all);
const interactive = Boolean(argv.i || argv.interactive);
const workspaceMode = Boolean(argv.workspace);
const specificModules = argv.modules
? String(argv.modules).split(',').map(m => m.trim())

// Get specific modules from positional arguments (argv._)
const specificModules = argv._ && argv._.length > 0
? argv._.map((m: string) => String(m).trim())
: undefined;

const project = new PgpmPackage(cwd);
Expand All @@ -194,7 +192,7 @@ export default async (
argv,
prompter,
dryRun,
upgradeAll,
interactive,
specificModules,
moduleName
);
Expand All @@ -212,6 +210,6 @@ export default async (
throw new Error('You must run this command inside a PGPM module. Use --workspace to upgrade all modules in the workspace.');
}

await upgradeModulesForProject(project, argv, prompter, dryRun, upgradeAll, specificModules);
await upgradeModulesForProject(project, argv, prompter, dryRun, interactive, specificModules);
}
};
2 changes: 1 addition & 1 deletion pgpm/cli/src/utils/display.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const usageText = `
export Export database migrations from existing databases
update Update pgpm to the latest version
cache Manage cached templates (clean)
upgrade-modules Upgrade installed pgpm modules to latest versions
upgrade Upgrade installed pgpm modules to latest versions (alias: up)

Database Administration:
kill Terminate database connections and optionally drop databases
Expand Down
4 changes: 2 additions & 2 deletions pgpm/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"@pgsql/types": "^17.6.2",
"@types/pg": "^8.16.0",
"copyfiles": "^2.4.1",
"inquirerer": "^4.1.2",
"inquirerer": "^4.2.0",
"makage": "^0.1.9"
},
"dependencies": {
Expand All @@ -53,7 +53,7 @@
"@pgpmjs/server-utils": "workspace:^",
"@pgpmjs/types": "workspace:^",
"csv-to-pg": "workspace:^",
"genomic": "^5.1.0",
"genomic": "^5.2.0",
"glob": "^13.0.0",
"komoji": "^0.7.11",
"parse-package-name": "^1.0.0",
Expand Down
Loading