package-installer-cli 1.2.0 ā 1.3.1
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 +127 -84
- data/dist/commands/analyze.js +45 -37
- data/dist/commands/cache.js +141 -6
- data/dist/commands/check.js +121 -72
- data/dist/commands/clean.js +232 -93
- data/dist/commands/clone.js +65 -44
- data/dist/commands/create.js +76 -53
- data/dist/commands/deploy.js +28 -22
- data/dist/commands/doctor.js +26 -28
- data/dist/commands/env.js +44 -32
- data/dist/commands/update.js +598 -113
- data/dist/commands/upgrade-cli.js +30 -24
- data/dist/index.js +61 -16
- data/dist/utils/banner.js +3 -3
- data/dist/utils/cacheManager.js +57 -124
- data/dist/utils/dependencyInstaller.js +0 -2
- data/dist/utils/featureInstaller.js +404 -122
- data/dist/utils/helpFormatter.js +117 -0
- data/dist/utils/pathResolver.js +34 -72
- data/dist/utils/utils.js +20 -5
- metadata +3 -2
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standardized Help Formatter for Package Installer CLI
|
|
3
|
+
* Creates consistent, beautiful help displays for all commands
|
|
4
|
+
*/
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import gradient from 'gradient-string';
|
|
7
|
+
import boxen from 'boxen';
|
|
8
|
+
import { getPackageVersion } from './utils.js';
|
|
9
|
+
/**
|
|
10
|
+
* Create standardized help display for commands
|
|
11
|
+
*/
|
|
12
|
+
export function createStandardHelp(config) {
|
|
13
|
+
const version = getPackageVersion();
|
|
14
|
+
const piGradient = gradient(['#00c6ff', '#0072ff']);
|
|
15
|
+
const headerGradient = gradient(['#4facfe', '#00f2fe']);
|
|
16
|
+
let helpContent = '';
|
|
17
|
+
// Header
|
|
18
|
+
helpContent += headerGradient(`${config.emoji} Package Installer CLI - ${config.commandName} Command`) + '\n\n';
|
|
19
|
+
// Description
|
|
20
|
+
helpContent += chalk.white(config.description) + '\n\n';
|
|
21
|
+
// Usage
|
|
22
|
+
helpContent += chalk.cyan('Usage:') + '\n';
|
|
23
|
+
config.usage.forEach(usage => {
|
|
24
|
+
helpContent += chalk.white(` ${piGradient('pi')} ${usage}`) + '\n';
|
|
25
|
+
});
|
|
26
|
+
helpContent += '\n';
|
|
27
|
+
// Options
|
|
28
|
+
helpContent += chalk.cyan('Options:') + '\n';
|
|
29
|
+
// Check if help flag already exists
|
|
30
|
+
const hasHelpFlag = config.options && config.options.some(option => option.flag.includes('-h') || option.flag.includes('--help'));
|
|
31
|
+
// Add custom options first
|
|
32
|
+
if (config.options && config.options.length > 0) {
|
|
33
|
+
config.options.forEach(option => {
|
|
34
|
+
helpContent += chalk.gray(` ${option.flag.padEnd(20)} ${option.description}`) + '\n';
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
// Add the global help flag only if it doesn't already exist
|
|
38
|
+
if (!hasHelpFlag) {
|
|
39
|
+
helpContent += chalk.gray(` -h, --help`.padEnd(20) + ' Show this help message') + '\n';
|
|
40
|
+
}
|
|
41
|
+
helpContent += '\n';
|
|
42
|
+
// Examples
|
|
43
|
+
if (config.examples && config.examples.length > 0) {
|
|
44
|
+
helpContent += chalk.cyan('Examples:') + '\n';
|
|
45
|
+
config.examples.forEach(example => {
|
|
46
|
+
// Check if command already starts with 'pi', if not add it
|
|
47
|
+
const command = example.command.startsWith('pi ') ? example.command : `pi ${example.command}`;
|
|
48
|
+
const formattedCommand = command.replace(/^pi /, `${piGradient('pi')} `);
|
|
49
|
+
helpContent += chalk.gray(` ${formattedCommand.padEnd(35)} # ${example.description}`) + '\n';
|
|
50
|
+
});
|
|
51
|
+
helpContent += '\n';
|
|
52
|
+
}
|
|
53
|
+
// Additional sections
|
|
54
|
+
if (config.additionalSections && config.additionalSections.length > 0) {
|
|
55
|
+
config.additionalSections.forEach(section => {
|
|
56
|
+
helpContent += chalk.hex('#00d2d3')(`š” ${section.title}:`) + '\n';
|
|
57
|
+
section.items.forEach(item => {
|
|
58
|
+
helpContent += chalk.hex('#95afc0')(` ⢠${item}`) + '\n';
|
|
59
|
+
});
|
|
60
|
+
helpContent += '\n';
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
// Tips
|
|
64
|
+
if (config.tips && config.tips.length > 0) {
|
|
65
|
+
config.tips.forEach(tip => {
|
|
66
|
+
helpContent += chalk.yellow(`š” Tip: ${tip}`) + '\n';
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
// Version footer
|
|
70
|
+
helpContent += chalk.hex('#636e72')(`\nš¦ Package Installer CLI v${version} ⢠Fast ⢠Smart ⢠Feature-Rich`);
|
|
71
|
+
console.log('\n' + boxen(helpContent, {
|
|
72
|
+
padding: 1,
|
|
73
|
+
borderStyle: 'round',
|
|
74
|
+
borderColor: 'cyan',
|
|
75
|
+
backgroundColor: '#0a0a0a'
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Quick help display for commands with minimal options
|
|
80
|
+
*/
|
|
81
|
+
export function createQuickHelp(commandName, emoji, description, usage, options) {
|
|
82
|
+
const piGradient = gradient(['#00c6ff', '#0072ff']);
|
|
83
|
+
const headerGradient = gradient(['#4facfe', '#00f2fe']);
|
|
84
|
+
let helpContent = headerGradient(`${emoji} ${commandName.toUpperCase()} COMMAND HELP`) + '\n\n';
|
|
85
|
+
helpContent += chalk.white(description) + '\n\n';
|
|
86
|
+
helpContent += chalk.cyan('Usage:') + '\n';
|
|
87
|
+
helpContent += chalk.white(` ${piGradient('pi')} ${usage}`) + '\n\n';
|
|
88
|
+
if (options.length > 0) {
|
|
89
|
+
helpContent += chalk.cyan('Options:') + '\n';
|
|
90
|
+
options.forEach(option => {
|
|
91
|
+
helpContent += chalk.gray(` ${option}`) + '\n';
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
console.log('\n' + boxen(helpContent, {
|
|
95
|
+
padding: 1,
|
|
96
|
+
borderStyle: 'round',
|
|
97
|
+
borderColor: 'cyan',
|
|
98
|
+
backgroundColor: '#0a0a0a'
|
|
99
|
+
}));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Create error help display
|
|
103
|
+
*/
|
|
104
|
+
export function createErrorHelp(commandName, error, suggestion) {
|
|
105
|
+
let helpContent = chalk.red(`ā ${commandName.toUpperCase()} ERROR`) + '\n\n';
|
|
106
|
+
helpContent += chalk.white(error) + '\n';
|
|
107
|
+
if (suggestion) {
|
|
108
|
+
helpContent += '\n' + chalk.yellow(`š” Suggestion: ${suggestion}`) + '\n';
|
|
109
|
+
}
|
|
110
|
+
helpContent += '\n' + chalk.gray(`Run: `) + chalk.cyan(`pi ${commandName} --help`) + chalk.gray(` for more information`);
|
|
111
|
+
console.log('\n' + boxen(helpContent, {
|
|
112
|
+
padding: 1,
|
|
113
|
+
borderStyle: 'round',
|
|
114
|
+
borderColor: 'red',
|
|
115
|
+
backgroundColor: '#0a0a0a'
|
|
116
|
+
}));
|
|
117
|
+
}
|
data/dist/utils/pathResolver.js
CHANGED
|
@@ -25,7 +25,7 @@ export function getCliRootPath() {
|
|
|
25
25
|
if (fs.existsSync(packageJsonPath)) {
|
|
26
26
|
try {
|
|
27
27
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
28
|
-
if (packageNames.includes(packageJson.name)) {
|
|
28
|
+
if (packageNames.includes(packageJson.name) && fs.existsSync(path.join(currentDir, 'features'))) {
|
|
29
29
|
return currentDir;
|
|
30
30
|
}
|
|
31
31
|
}
|
|
@@ -49,77 +49,51 @@ export function getCliRootPath() {
|
|
|
49
49
|
// Continue to other methods
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
// Method 3:
|
|
52
|
+
// Method 3: Check current working directory (in case the CLI is run from the project root)
|
|
53
|
+
const cwdPath = process.cwd();
|
|
54
|
+
const workspacePackage = path.join(cwdPath, 'package.json');
|
|
55
|
+
if (fs.existsSync(workspacePackage) && fs.existsSync(path.join(cwdPath, 'features'))) {
|
|
56
|
+
try {
|
|
57
|
+
const packageJson = JSON.parse(fs.readFileSync(workspacePackage, 'utf-8'));
|
|
58
|
+
if (packageNames.includes(packageJson.name)) {
|
|
59
|
+
return cwdPath;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
// Continue to other methods
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Method 4: Try to resolve using require.resolve for npm installations
|
|
53
67
|
for (const packageName of packageNames) {
|
|
54
68
|
try {
|
|
55
69
|
const packageMainPath = require.resolve(`${packageName}/package.json`);
|
|
56
|
-
|
|
70
|
+
const resolvedRoot = path.dirname(packageMainPath);
|
|
71
|
+
if (fs.existsSync(path.join(resolvedRoot, 'features'))) {
|
|
72
|
+
return resolvedRoot;
|
|
73
|
+
}
|
|
57
74
|
}
|
|
58
75
|
catch (error) {
|
|
59
76
|
// Package not found in require cache, try next
|
|
60
77
|
}
|
|
61
78
|
}
|
|
62
|
-
// Method
|
|
79
|
+
// Method 5: Check common global installation paths for all package managers
|
|
63
80
|
const globalPaths = [];
|
|
81
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || '';
|
|
64
82
|
// npm global paths
|
|
65
83
|
globalPaths.push(
|
|
66
84
|
// Linux/macOS npm global paths
|
|
67
85
|
'/usr/local/lib/node_modules/@0xshariq/package-installer', '/usr/lib/node_modules/@0xshariq/package-installer',
|
|
68
86
|
// User-specific npm global paths
|
|
69
|
-
path.join(
|
|
87
|
+
path.join(homeDir, '.npm-global/lib/node_modules/@0xshariq/package-installer'), path.join(homeDir, '.npm/lib/node_modules/@0xshariq/package-installer'),
|
|
70
88
|
// Windows npm global paths
|
|
71
89
|
path.join(process.env.APPDATA || '', 'npm/node_modules/@0xshariq/package-installer'), path.join(process.env.ProgramFiles || '', 'nodejs/node_modules/@0xshariq/package-installer'));
|
|
72
|
-
//
|
|
73
|
-
if (process.env.HOME) {
|
|
74
|
-
globalPaths.push(
|
|
75
|
-
// Linux/macOS pip user install paths
|
|
76
|
-
path.join(process.env.HOME, '.local/lib/python*/site-packages/package-installer-cli'), path.join(process.env.HOME, '.local/bin/package-installer-cli'),
|
|
77
|
-
// System-wide pip install paths
|
|
78
|
-
'/usr/local/lib/python*/site-packages/package-installer-cli', '/usr/lib/python*/site-packages/package-installer-cli');
|
|
79
|
-
}
|
|
80
|
-
// RubyGems global paths
|
|
81
|
-
if (process.env.HOME) {
|
|
82
|
-
globalPaths.push(
|
|
83
|
-
// User gem installation paths
|
|
84
|
-
path.join(process.env.HOME, '.gem/ruby/*/gems/package-installer-cli-*'), path.join(process.env.HOME, '.local/share/gem/ruby/*/gems/package-installer-cli-*'),
|
|
85
|
-
// System gem installation paths
|
|
86
|
-
'/usr/local/lib/ruby/gems/*/gems/package-installer-cli-*', '/var/lib/gems/*/gems/package-installer-cli-*');
|
|
87
|
-
}
|
|
88
|
-
// Rust cargo global paths
|
|
89
|
-
if (process.env.HOME) {
|
|
90
|
-
globalPaths.push(path.join(process.env.HOME, '.cargo/bin/package-installer-cli'), path.join(process.env.HOME, '.cargo/registry/src/*/package-installer-cli-*'));
|
|
91
|
-
}
|
|
92
|
-
// Go global paths
|
|
93
|
-
const goPath = process.env.GOPATH || path.join(process.env.HOME || '', 'go');
|
|
94
|
-
globalPaths.push(path.join(goPath, 'bin/go_package_installer_cli'), path.join(goPath, 'bin/pi'), // In case the binary is named 'pi'
|
|
95
|
-
path.join(goPath, 'pkg/mod/github.com/0xshariq/go_package_installer_cli*'),
|
|
96
|
-
// Also check system-wide go installation paths
|
|
97
|
-
'/usr/local/bin/go_package_installer_cli', '/usr/local/bin/pi');
|
|
98
|
-
// Check all possible global paths
|
|
90
|
+
// Check all global paths
|
|
99
91
|
for (const globalPath of globalPaths) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
try {
|
|
103
|
-
const { execSync } = require('child_process');
|
|
104
|
-
const expandedPaths = execSync(`ls -d ${globalPath} 2>/dev/null || true`, { encoding: 'utf8' }).trim().split('\n').filter((p) => p);
|
|
105
|
-
for (const expandedPath of expandedPaths) {
|
|
106
|
-
if (fs.existsSync(expandedPath) && (fs.existsSync(path.join(expandedPath, 'features')) ||
|
|
107
|
-
fs.existsSync(path.join(path.dirname(expandedPath), 'features')))) {
|
|
108
|
-
return fs.existsSync(path.join(expandedPath, 'features')) ? expandedPath : path.dirname(expandedPath);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
catch (error) {
|
|
113
|
-
// Continue to next path
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
else {
|
|
117
|
-
if (fs.existsSync(globalPath) && fs.existsSync(path.join(globalPath, 'features'))) {
|
|
118
|
-
return globalPath;
|
|
119
|
-
}
|
|
92
|
+
if (fs.existsSync(globalPath) && fs.existsSync(path.join(globalPath, 'features'))) {
|
|
93
|
+
return globalPath;
|
|
120
94
|
}
|
|
121
95
|
}
|
|
122
|
-
// Method
|
|
96
|
+
// Method 6: Check if npm prefix is available and use it (for npm installations)
|
|
123
97
|
try {
|
|
124
98
|
const { execSync } = require('child_process');
|
|
125
99
|
const npmPrefix = execSync('npm config get prefix', { encoding: 'utf8' }).trim();
|
|
@@ -131,26 +105,14 @@ export function getCliRootPath() {
|
|
|
131
105
|
catch (error) {
|
|
132
106
|
// npm not available or command failed
|
|
133
107
|
}
|
|
134
|
-
// Method
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (whichResult) {
|
|
139
|
-
// Go up from binary location to find the package root
|
|
140
|
-
let binaryDir = path.dirname(whichResult);
|
|
141
|
-
while (binaryDir !== path.dirname(binaryDir)) {
|
|
142
|
-
if (fs.existsSync(path.join(binaryDir, 'features'))) {
|
|
143
|
-
return binaryDir;
|
|
144
|
-
}
|
|
145
|
-
binaryDir = path.dirname(binaryDir);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
catch (error) {
|
|
150
|
-
// which command failed or not available
|
|
108
|
+
// Method 7: Check relative to script location as last resort
|
|
109
|
+
const scriptRelativePath = path.resolve(__dirname, '../../');
|
|
110
|
+
if (fs.existsSync(path.join(scriptRelativePath, 'features'))) {
|
|
111
|
+
return scriptRelativePath;
|
|
151
112
|
}
|
|
152
|
-
// Final fallback: use the local development path
|
|
153
|
-
console.warn('ā ļø Could not resolve CLI root path, using fallback');
|
|
113
|
+
// Final fallback: use the local development path but warn user
|
|
114
|
+
console.warn('ā ļø Could not resolve CLI root path, using fallback. Some features may not work correctly.');
|
|
115
|
+
console.warn('š” Try running with npx for better compatibility: npx @0xshariq/package-installer');
|
|
154
116
|
return path.resolve(__dirname, '..', '..');
|
|
155
117
|
}
|
|
156
118
|
/**
|
data/dist/utils/utils.js
CHANGED
|
@@ -18,14 +18,29 @@ const __dirname = path.dirname(__filename);
|
|
|
18
18
|
*/
|
|
19
19
|
export function getPackageVersion() {
|
|
20
20
|
try {
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
// Try multiple paths to find package.json
|
|
22
|
+
const possiblePaths = [
|
|
23
|
+
getPackageJsonPath(),
|
|
24
|
+
path.resolve(process.cwd(), 'package.json'),
|
|
25
|
+
path.resolve(__dirname, '../../package.json'),
|
|
26
|
+
path.resolve(__dirname, '../../../package.json')
|
|
27
|
+
];
|
|
28
|
+
for (const packagePath of possiblePaths) {
|
|
29
|
+
if (fs.existsSync(packagePath)) {
|
|
30
|
+
const packageJsonContent = fs.readFileSync(packagePath, 'utf-8');
|
|
31
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
32
|
+
if (packageJson.version) {
|
|
33
|
+
return packageJson.version;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Fallback to hardcoded version as last resort
|
|
38
|
+
console.warn('Warning: Could not read version from package.json, using fallback version');
|
|
39
|
+
return '3.6.0';
|
|
25
40
|
}
|
|
26
41
|
catch (error) {
|
|
27
42
|
console.warn('Warning: Could not read version from package.json, using fallback version');
|
|
28
|
-
return '3.
|
|
43
|
+
return '3.6.0';
|
|
29
44
|
}
|
|
30
45
|
}
|
|
31
46
|
/**
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: package-installer-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- sharique
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-09-
|
|
11
|
+
date: 2025-09-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -103,6 +103,7 @@ files:
|
|
|
103
103
|
- dist/utils/dashboard.js
|
|
104
104
|
- dist/utils/dependencyInstaller.js
|
|
105
105
|
- dist/utils/featureInstaller.js
|
|
106
|
+
- dist/utils/helpFormatter.js
|
|
106
107
|
- dist/utils/historyManager.js
|
|
107
108
|
- dist/utils/languageConfig.js
|
|
108
109
|
- dist/utils/pathResolver.js
|