package-installer-cli 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -1
- data/dist/commands/add.js +109 -75
- data/dist/commands/analyze.js +43 -35
- data/dist/commands/cache.js +142 -6
- data/dist/commands/check.js +119 -72
- data/dist/commands/clean.js +230 -92
- data/dist/commands/clone.js +66 -44
- data/dist/commands/create.js +74 -53
- data/dist/commands/deploy.js +30 -22
- data/dist/commands/doctor.js +27 -28
- data/dist/commands/env.js +44 -31
- data/dist/commands/update.js +599 -113
- data/dist/commands/upgrade-cli.js +32 -24
- data/dist/index.js +58 -15
- data/dist/utils/banner.js +1 -1
- data/dist/utils/cacheManager.js +57 -124
- data/dist/utils/dependencyInstaller.js +0 -2
- data/dist/utils/featureInstaller.js +394 -118
- data/dist/utils/helpFormatter.js +110 -0
- data/dist/utils/pathResolver.js +34 -72
- data/dist/utils/utils.js +20 -5
- metadata +3 -2
data/dist/commands/check.js
CHANGED
|
@@ -3,11 +3,11 @@ import { promisify } from 'util';
|
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import ora from 'ora';
|
|
5
5
|
import boxen from 'boxen';
|
|
6
|
-
import gradient from 'gradient-string';
|
|
7
6
|
import fs from 'fs-extra';
|
|
8
7
|
import path from 'path';
|
|
9
8
|
import semver from 'semver';
|
|
10
9
|
import https from 'https';
|
|
10
|
+
import { createStandardHelp } from '../utils/helpFormatter.js';
|
|
11
11
|
import { getSupportedLanguages, getLanguageConfig } from '../utils/languageConfig.js';
|
|
12
12
|
const execAsync = promisify(exec);
|
|
13
13
|
// Generate PROJECT_TYPES from shared language configuration with enhanced registry support
|
|
@@ -18,7 +18,6 @@ const PROJECT_TYPES = getSupportedLanguages().map(lang => {
|
|
|
18
18
|
let registryUrl;
|
|
19
19
|
let packageInfoUrl;
|
|
20
20
|
switch (lang) {
|
|
21
|
-
case 'nodejs':
|
|
22
21
|
case 'javascript':
|
|
23
22
|
case 'typescript':
|
|
24
23
|
registryUrl = 'https://registry.npmjs.org';
|
|
@@ -48,7 +47,8 @@ const PROJECT_TYPES = getSupportedLanguages().map(lang => {
|
|
|
48
47
|
const deps = {};
|
|
49
48
|
// Language-specific dependency parsing
|
|
50
49
|
switch (lang) {
|
|
51
|
-
case '
|
|
50
|
+
case 'javascript':
|
|
51
|
+
case 'typescript':
|
|
52
52
|
if (filename === 'package.json' || filename === 'package-lock.json' || filename === 'pnpm-lock.yml') {
|
|
53
53
|
return {
|
|
54
54
|
...content.dependencies,
|
|
@@ -104,14 +104,6 @@ const PROJECT_TYPES = getSupportedLanguages().map(lang => {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
break;
|
|
107
|
-
case 'php':
|
|
108
|
-
if (filename === 'composer.json') {
|
|
109
|
-
return {
|
|
110
|
-
...content.require,
|
|
111
|
-
...content['require-dev']
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
break;
|
|
115
107
|
case 'ruby':
|
|
116
108
|
if (filename === 'Gemfile') {
|
|
117
109
|
const lines = content.toString().split('\n');
|
|
@@ -159,16 +151,13 @@ const PROJECT_TYPES = getSupportedLanguages().map(lang => {
|
|
|
159
151
|
});
|
|
160
152
|
function getRegistryUrl(lang) {
|
|
161
153
|
switch (lang) {
|
|
162
|
-
case '
|
|
154
|
+
case 'javascript':
|
|
155
|
+
case 'typescript':
|
|
156
|
+
return 'https://registry.npmjs.org';
|
|
163
157
|
case 'rust': return 'https://crates.io/api/v1/crates';
|
|
164
158
|
case 'python': return 'https://pypi.org/pypi';
|
|
165
159
|
case 'go': return 'https://proxy.golang.org';
|
|
166
160
|
case 'ruby': return 'https://rubygems.org/api/v1/gems';
|
|
167
|
-
case 'php': return 'https://packagist.org/packages';
|
|
168
|
-
case 'java': return 'https://repo1.maven.org/maven2';
|
|
169
|
-
case 'csharp': return 'https://api.nuget.org/v3-flatcontainer';
|
|
170
|
-
case 'swift': return 'https://packagecatalog.com';
|
|
171
|
-
case 'dart': return 'https://pub.dev/api/packages';
|
|
172
161
|
default: return '';
|
|
173
162
|
}
|
|
174
163
|
}
|
|
@@ -191,7 +180,8 @@ async function fetchPackageFromRegistry(packageName, projectType) {
|
|
|
191
180
|
const parsed = JSON.parse(data);
|
|
192
181
|
// Handle different registry response formats
|
|
193
182
|
switch (projectType.name) {
|
|
194
|
-
case '
|
|
183
|
+
case 'JavaScript':
|
|
184
|
+
case 'Typescript':
|
|
195
185
|
resolve(parseNpmRegistryResponse(parsed, packageName));
|
|
196
186
|
break;
|
|
197
187
|
case 'Rust':
|
|
@@ -293,7 +283,8 @@ function parseGenericResponse(data, packageName) {
|
|
|
293
283
|
async function getLatestVersion(packageName, projectType) {
|
|
294
284
|
try {
|
|
295
285
|
switch (projectType.name) {
|
|
296
|
-
case '
|
|
286
|
+
case 'JavaScript':
|
|
287
|
+
case 'TypeScript':
|
|
297
288
|
const { stdout } = await execAsync(`npm view ${packageName} version`);
|
|
298
289
|
return stdout.trim();
|
|
299
290
|
case 'Rust':
|
|
@@ -380,33 +371,43 @@ async function getEnhancedPackageInfo(name, currentVersion, projectType) {
|
|
|
380
371
|
* Display help for check command
|
|
381
372
|
*/
|
|
382
373
|
export function showCheckHelp() {
|
|
383
|
-
const
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
374
|
+
const helpConfig = {
|
|
375
|
+
commandName: 'Check',
|
|
376
|
+
emoji: '🔍',
|
|
377
|
+
description: 'Check package versions in your project and get suggestions for updates.\nHelps you keep your dependencies up-to-date and secure.',
|
|
378
|
+
usage: [
|
|
379
|
+
'check [package-name] [options]',
|
|
380
|
+
'check [options]'
|
|
381
|
+
],
|
|
382
|
+
options: [
|
|
383
|
+
{ flag: '-h, --help', description: 'Display help for this command' },
|
|
384
|
+
{ flag: '-v, --verbose', description: 'Show detailed information for all packages' }
|
|
385
|
+
],
|
|
386
|
+
examples: [
|
|
387
|
+
{ command: 'check', description: 'Check all packages in current project' },
|
|
388
|
+
{ command: 'check --verbose', description: 'Check all packages with detailed info' },
|
|
389
|
+
{ command: 'check react', description: 'Check specific package version' },
|
|
390
|
+
{ command: 'check @types/node', description: 'Check scoped packages' },
|
|
391
|
+
{ command: 'check --help', description: 'Show this help message' }
|
|
392
|
+
],
|
|
393
|
+
additionalSections: [
|
|
394
|
+
{
|
|
395
|
+
title: 'Supported Package Managers',
|
|
396
|
+
items: [
|
|
397
|
+
'npm, pnpm, yarn (Node.js)',
|
|
398
|
+
'pip, pipenv, poetry (Python)',
|
|
399
|
+
'cargo (Rust)',
|
|
400
|
+
'go modules (Go)',
|
|
401
|
+
'composer (PHP)'
|
|
402
|
+
]
|
|
403
|
+
}
|
|
404
|
+
],
|
|
405
|
+
tips: [
|
|
406
|
+
'Use --verbose for detailed package information including security vulnerabilities',
|
|
407
|
+
'Check specific packages by name for targeted updates'
|
|
408
|
+
]
|
|
409
|
+
};
|
|
410
|
+
createStandardHelp(helpConfig);
|
|
410
411
|
}
|
|
411
412
|
export async function checkCommand(packageName, options) {
|
|
412
413
|
// Check for help flag
|
|
@@ -500,61 +501,100 @@ async function checkProjectPackages(verbose = false) {
|
|
|
500
501
|
}
|
|
501
502
|
async function detectProjectType() {
|
|
502
503
|
console.log(chalk.gray('🔍 Detecting project type...'));
|
|
504
|
+
// Priority order for detection - check most common files first
|
|
505
|
+
const priorityFiles = ['package.json', 'Cargo.toml', 'requirements.txt', 'composer.json', 'go.mod'];
|
|
506
|
+
// First pass: check priority files in current directory
|
|
507
|
+
for (const priorityFile of priorityFiles) {
|
|
508
|
+
const filePath = path.join(process.cwd(), priorityFile);
|
|
509
|
+
console.log(chalk.gray(` Checking priority file: ${filePath}`));
|
|
510
|
+
if (await fs.pathExists(filePath)) {
|
|
511
|
+
console.log(chalk.green(` ✅ Found: ${priorityFile}`));
|
|
512
|
+
// Find the project type that matches this file
|
|
513
|
+
const matchingType = PROJECT_TYPES.find(type => type.files.includes(priorityFile));
|
|
514
|
+
if (matchingType) {
|
|
515
|
+
console.log(chalk.green(` 📦 Detected: ${matchingType.name}`));
|
|
516
|
+
return matchingType;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
// Second pass: check all other files
|
|
503
521
|
for (const projectType of PROJECT_TYPES) {
|
|
504
522
|
console.log(chalk.gray(` Checking ${projectType.name}: ${projectType.files.join(', ')}`));
|
|
505
523
|
for (const file of projectType.files) {
|
|
524
|
+
if (priorityFiles.includes(file))
|
|
525
|
+
continue; // Already checked
|
|
506
526
|
// Check in current directory first
|
|
507
527
|
const filePath = path.join(process.cwd(), file);
|
|
508
|
-
console.log(chalk.gray(` Looking for: ${filePath}`));
|
|
509
528
|
if (await fs.pathExists(filePath)) {
|
|
510
|
-
console.log(chalk.green(`
|
|
529
|
+
console.log(chalk.green(` ✅ Found: ${file}`));
|
|
511
530
|
return projectType;
|
|
512
531
|
}
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
// Third pass: check subdirectories
|
|
535
|
+
try {
|
|
536
|
+
const currentDirContents = await fs.readdir(process.cwd());
|
|
537
|
+
for (const item of currentDirContents) {
|
|
538
|
+
const itemPath = path.join(process.cwd(), item);
|
|
539
|
+
const stats = await fs.stat(itemPath);
|
|
540
|
+
if (stats.isDirectory()) {
|
|
541
|
+
for (const priorityFile of priorityFiles) {
|
|
542
|
+
const configPath = path.join(itemPath, priorityFile);
|
|
543
|
+
if (await fs.pathExists(configPath)) {
|
|
544
|
+
console.log(chalk.green(` ✅ Found in subdirectory: ${item}/${priorityFile}`));
|
|
545
|
+
const matchingType = PROJECT_TYPES.find(type => type.files.includes(priorityFile));
|
|
546
|
+
if (matchingType)
|
|
547
|
+
return matchingType;
|
|
525
548
|
}
|
|
526
549
|
}
|
|
527
550
|
}
|
|
528
|
-
catch (error) {
|
|
529
|
-
// Ignore directory read errors
|
|
530
|
-
}
|
|
531
551
|
}
|
|
532
552
|
}
|
|
553
|
+
catch (error) {
|
|
554
|
+
console.log(chalk.yellow(' Warning: Could not read directory contents'));
|
|
555
|
+
}
|
|
533
556
|
console.log(chalk.yellow(' No project type detected'));
|
|
534
|
-
return
|
|
557
|
+
return null;
|
|
535
558
|
}
|
|
536
559
|
async function getDependenciesForProject(projectType) {
|
|
537
|
-
|
|
538
|
-
|
|
560
|
+
console.log(chalk.gray(`📋 Looking for dependencies in ${projectType.name} project...`));
|
|
561
|
+
// Priority order for dependency files
|
|
562
|
+
const priorityFiles = projectType.files.slice().sort((a, b) => {
|
|
563
|
+
const priority = ['package.json', 'Cargo.toml', 'requirements.txt', 'composer.json', 'go.mod'];
|
|
564
|
+
return priority.indexOf(a) - priority.indexOf(b);
|
|
565
|
+
});
|
|
566
|
+
// First check current directory with priority files
|
|
567
|
+
for (const file of priorityFiles) {
|
|
539
568
|
const filePath = path.join(process.cwd(), file);
|
|
569
|
+
console.log(chalk.gray(` Checking: ${filePath}`));
|
|
540
570
|
if (await fs.pathExists(filePath)) {
|
|
571
|
+
console.log(chalk.green(` ✅ Found: ${file}`));
|
|
541
572
|
try {
|
|
542
573
|
let content;
|
|
543
574
|
if (file.endsWith('.json')) {
|
|
544
575
|
content = await fs.readJson(filePath);
|
|
576
|
+
console.log(chalk.gray(` 📦 Loaded JSON config from ${file}`));
|
|
545
577
|
}
|
|
546
578
|
else if (file.endsWith('.toml')) {
|
|
547
579
|
// Simple TOML parser for basic cases
|
|
548
580
|
const tomlContent = await fs.readFile(filePath, 'utf-8');
|
|
549
581
|
content = parseSimpleToml(tomlContent);
|
|
582
|
+
console.log(chalk.gray(` 📦 Loaded TOML config from ${file}`));
|
|
550
583
|
}
|
|
551
584
|
else {
|
|
552
585
|
content = await fs.readFile(filePath, 'utf-8');
|
|
586
|
+
console.log(chalk.gray(` 📦 Loaded text config from ${file}`));
|
|
587
|
+
}
|
|
588
|
+
const dependencies = projectType.getDependencies(content, file);
|
|
589
|
+
const depCount = Object.keys(dependencies).length;
|
|
590
|
+
console.log(chalk.green(` 📊 Found ${depCount} dependencies`));
|
|
591
|
+
if (depCount > 0) {
|
|
592
|
+
console.log(chalk.gray(` Dependencies: ${Object.keys(dependencies).slice(0, 5).join(', ')}${depCount > 5 ? '...' : ''}`));
|
|
593
|
+
return dependencies;
|
|
553
594
|
}
|
|
554
|
-
return projectType.getDependencies(content, file);
|
|
555
595
|
}
|
|
556
596
|
catch (error) {
|
|
557
|
-
console.warn(
|
|
597
|
+
console.warn(chalk.yellow(` ⚠️ Could not parse ${file}: ${error}`));
|
|
558
598
|
}
|
|
559
599
|
}
|
|
560
600
|
}
|
|
@@ -565,9 +605,10 @@ async function getDependenciesForProject(projectType) {
|
|
|
565
605
|
const itemPath = path.join(process.cwd(), item);
|
|
566
606
|
const stats = await fs.stat(itemPath);
|
|
567
607
|
if (stats.isDirectory()) {
|
|
568
|
-
for (const file of
|
|
608
|
+
for (const file of priorityFiles) {
|
|
569
609
|
const configPath = path.join(itemPath, file);
|
|
570
610
|
if (await fs.pathExists(configPath)) {
|
|
611
|
+
console.log(chalk.green(` ✅ Found in subdirectory: ${item}/${file}`));
|
|
571
612
|
try {
|
|
572
613
|
let content;
|
|
573
614
|
if (file.endsWith('.json')) {
|
|
@@ -580,10 +621,15 @@ async function getDependenciesForProject(projectType) {
|
|
|
580
621
|
else {
|
|
581
622
|
content = await fs.readFile(configPath, 'utf-8');
|
|
582
623
|
}
|
|
583
|
-
|
|
624
|
+
const dependencies = projectType.getDependencies(content, file);
|
|
625
|
+
const depCount = Object.keys(dependencies).length;
|
|
626
|
+
if (depCount > 0) {
|
|
627
|
+
console.log(chalk.green(` 📊 Found ${depCount} dependencies in ${configPath}`));
|
|
628
|
+
return dependencies;
|
|
629
|
+
}
|
|
584
630
|
}
|
|
585
631
|
catch (error) {
|
|
586
|
-
console.warn(
|
|
632
|
+
console.warn(chalk.yellow(` ⚠️ Could not parse ${configPath}`));
|
|
587
633
|
}
|
|
588
634
|
}
|
|
589
635
|
}
|
|
@@ -591,8 +637,9 @@ async function getDependenciesForProject(projectType) {
|
|
|
591
637
|
}
|
|
592
638
|
}
|
|
593
639
|
catch (error) {
|
|
594
|
-
|
|
640
|
+
console.warn(chalk.yellow(' ⚠️ Could not read directory contents'));
|
|
595
641
|
}
|
|
642
|
+
console.log(chalk.yellow(' 📦 No dependencies found'));
|
|
596
643
|
return {};
|
|
597
644
|
}
|
|
598
645
|
function parseSimpleToml(content) {
|