feat(update): enhance package manager detection, version reporting, and add verbose option
This commit is contained in:
@@ -16,6 +16,16 @@ export interface IPackageUpdateInfo {
|
||||
needsUpdate: boolean;
|
||||
}
|
||||
|
||||
export interface IPackageManagerInfo {
|
||||
name: TPackageManager;
|
||||
available: boolean;
|
||||
detectionMethod?: 'which' | 'version-command';
|
||||
path?: string;
|
||||
currentVersion?: string;
|
||||
latestVersion?: string | null;
|
||||
needsUpdate?: boolean;
|
||||
}
|
||||
|
||||
export class PackageManagerUtil {
|
||||
private shell = new plugins.smartshell.Smartshell({
|
||||
executor: 'bash',
|
||||
@@ -23,14 +33,92 @@ export class PackageManagerUtil {
|
||||
|
||||
/**
|
||||
* Check if a package manager is available on the system
|
||||
* Uses multiple detection methods for robustness across different shell contexts
|
||||
*/
|
||||
public async isAvailable(pm: TPackageManager): Promise<boolean> {
|
||||
public async isAvailable(pm: TPackageManager, verbose = false): Promise<boolean> {
|
||||
const info = await this.detectPackageManager(pm, verbose);
|
||||
return info.available;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect a package manager and return detailed info
|
||||
*/
|
||||
public async detectPackageManager(pm: TPackageManager, verbose = false): Promise<IPackageManagerInfo> {
|
||||
const info: IPackageManagerInfo = { name: pm, available: false };
|
||||
|
||||
// Primary method: try 'which' command
|
||||
try {
|
||||
const result = await this.shell.execSilent(`which ${pm} >/dev/null 2>&1 && echo "found"`);
|
||||
return result.exitCode === 0 && result.stdout.includes('found');
|
||||
const whichResult = await this.shell.execSilent(`which ${pm} 2>/dev/null`);
|
||||
if (whichResult.exitCode === 0 && whichResult.stdout.trim()) {
|
||||
info.available = true;
|
||||
info.detectionMethod = 'which';
|
||||
info.path = whichResult.stdout.trim();
|
||||
if (verbose) {
|
||||
console.log(` Checking ${pm}... found via 'which' at ${info.path}`);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
} catch {
|
||||
return false;
|
||||
// Continue to fallback
|
||||
}
|
||||
|
||||
// Fallback method: try running pm --version directly
|
||||
// This can find PMs that are available but not in PATH for 'which'
|
||||
try {
|
||||
const versionResult = await this.shell.execSilent(`${pm} --version 2>/dev/null`);
|
||||
if (versionResult.exitCode === 0 && versionResult.stdout.trim()) {
|
||||
info.available = true;
|
||||
info.detectionMethod = 'version-command';
|
||||
if (verbose) {
|
||||
console.log(` Checking ${pm}... found via '--version' (which failed)`);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
} catch {
|
||||
// Not available
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
console.log(` Checking ${pm}... not found`);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current and latest version of a package manager
|
||||
*/
|
||||
public async getPackageManagerVersion(pm: TPackageManager): Promise<{ current: string; latest: string | null }> {
|
||||
let current = 'unknown';
|
||||
let latest: string | null = null;
|
||||
|
||||
// Get current version
|
||||
try {
|
||||
const result = await this.shell.execSilent(`${pm} --version 2>/dev/null`);
|
||||
if (result.exitCode === 0 && result.stdout.trim()) {
|
||||
// Parse version from output - handle different formats
|
||||
const output = result.stdout.trim();
|
||||
// npm: "10.2.0", pnpm: "8.15.0", yarn: "1.22.19"
|
||||
// Some may include prefix like "v1.22.19"
|
||||
const versionMatch = output.match(/(\d+\.\d+\.\d+)/);
|
||||
if (versionMatch) {
|
||||
current = versionMatch[1];
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// Keep as unknown
|
||||
}
|
||||
|
||||
// Get latest version from npm registry
|
||||
try {
|
||||
const result = await this.shell.execSilent(`npm view ${pm} version 2>/dev/null`);
|
||||
if (result.exitCode === 0 && result.stdout.trim()) {
|
||||
latest = result.stdout.trim();
|
||||
}
|
||||
} catch {
|
||||
// Keep as null
|
||||
}
|
||||
|
||||
return { current, latest };
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user