package-installer-cli 1.1.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 -46
- data/dist/utils/featureInstaller.js +489 -153
- data/dist/utils/helpFormatter.js +110 -0
- data/dist/utils/languageConfig.js +167 -298
- data/dist/utils/pathResolver.js +34 -72
- data/dist/utils/templateResolver.js +3 -4
- data/dist/utils/utils.js +20 -5
- data/lib/package_installer_cli.rb +1 -1
- data/templates/django/django-full-stack-template/django-project-template/deployment/docker/build.sh +0 -0
- data/templates/django/django-full-stack-template/django-project-template/deployment/docker/manage.py +0 -0
- data/templates/django/django-full-stack-template/django-project-template/src/compile-locale.sh +0 -0
- data/templates/django/django-full-stack-template/django-project-template/src/compile-sass.sh +0 -0
- data/templates/django/django-full-stack-template/django-project-template/src/manage.py +0 -0
- data/templates/django/django-inertia-svelte-template/django-inertia-svelte-template-starter/manage.py +0 -0
- data/templates/flask/flask-cookiecutter-advance-template/cookiecutter-docker.sh +0 -0
- data/templates/flask/flask-cookiecutter-advance-template/{{cookiecutter.app_name}}/autoapp.py +0 -0
- data/templates/flask/flask-project-template/apply.sh +0 -0
- data/templates/react-native/typescript/template/android/gradlew +0 -0
- data/templates/ruby/rails_7_esbuild_hotwire_tailwindcss_starter/bin/bundle +0 -0
- data/templates/ruby/rails_7_esbuild_hotwire_tailwindcss_starter/bin/dev +0 -0
- data/templates/ruby/rails_7_esbuild_hotwire_tailwindcss_starter/bin/docker-entrypoint +0 -0
- data/templates/ruby/rails_7_esbuild_hotwire_tailwindcss_starter/bin/rails +0 -0
- data/templates/ruby/rails_7_esbuild_hotwire_tailwindcss_starter/bin/rake +0 -0
- data/templates/ruby/rails_7_esbuild_hotwire_tailwindcss_starter/bin/setup +0 -0
- data/templates/ruby/ruby-on-rails-apis-template/bin/bundle +0 -0
- data/templates/ruby/ruby-on-rails-apis-template/bin/rails +0 -0
- data/templates/ruby/ruby-on-rails-apis-template/bin/rake +0 -0
- data/templates/ruby/ruby-on-rails-apis-template/bin/setup +0 -0
- data/templates/ruby/ruby-on-rails-apis-template/bin/spring +0 -0
- data/templates/ruby/ruby-on-rails-apis-template/bin/update +0 -0
- data/templates/ruby/ruby-on-rails-boilerplate-template/bin/bundle +0 -0
- data/templates/ruby/ruby-on-rails-boilerplate-template/bin/dev +0 -0
- data/templates/ruby/ruby-on-rails-boilerplate-template/bin/importmap +0 -0
- data/templates/ruby/ruby-on-rails-boilerplate-template/bin/rails +0 -0
- data/templates/ruby/ruby-on-rails-boilerplate-template/bin/rake +0 -0
- data/templates/ruby/ruby-on-rails-boilerplate-template/bin/setup +0 -0
- metadata +6 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: de2baf8d0677e75c1471a523c2c8b581bde9c5187f0cecb4a5a4c79a6d03022a
|
|
4
|
+
data.tar.gz: c3e5ee669f095c1537ba2bf505367da009999c907b6814fb907e5b569eebcc2a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3f593de7edcf4ec3b60397cf4de415d7e2703debb4a49c7f85d1911d2c2c64b9c644e637d259187dd965d43b23906985795cb5ed5fbc5eece7bf6af45b33c4fb
|
|
7
|
+
data.tar.gz: c9f3538f2430caa503d7bbe21f52bd2592b689e80c1f08763b4afd2268a1cffd9ba4d1bd4dcf6a855aebacc0b2f59a1ca750ec296ad96aa57344b6cfdf40e043
|
data/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,7 @@ All notable changes to the Package Installer CLI Ruby gem will be documented in
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [1.
|
|
8
|
+
## [1.3.0] - 2025-09-23
|
|
9
9
|
|
|
10
10
|
### Updated
|
|
11
11
|
- Version bump to 1.1.0
|
data/dist/commands/add.js
CHANGED
|
@@ -4,9 +4,10 @@ import gradient from 'gradient-string';
|
|
|
4
4
|
import boxen from 'boxen';
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import fs from 'fs-extra';
|
|
7
|
+
import { createStandardHelp } from '../utils/helpFormatter.js';
|
|
7
8
|
import { addFeature, detectProjectStack, SUPPORTED_FEATURES } from '../utils/featureInstaller.js';
|
|
8
9
|
import { historyManager } from '../utils/historyManager.js';
|
|
9
|
-
import {
|
|
10
|
+
import { cacheProjectData } from '../utils/cacheManager.js';
|
|
10
11
|
import { getFeaturesJsonPath, getFeaturesPath } from '../utils/pathResolver.js';
|
|
11
12
|
/**
|
|
12
13
|
* Helper function to capitalize strings
|
|
@@ -15,14 +16,47 @@ function capitalize(str) {
|
|
|
15
16
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
16
17
|
}
|
|
17
18
|
/**
|
|
18
|
-
* Get features.json configuration
|
|
19
|
+
* Get features.json configuration with new jsonPath structure
|
|
19
20
|
*/
|
|
20
|
-
function getFeaturesConfig() {
|
|
21
|
+
async function getFeaturesConfig() {
|
|
21
22
|
try {
|
|
22
23
|
// Use the centralized path resolver
|
|
23
24
|
const featuresPath = getFeaturesJsonPath();
|
|
24
25
|
if (fs.existsSync(featuresPath)) {
|
|
25
|
-
|
|
26
|
+
const baseConfig = JSON.parse(fs.readFileSync(featuresPath, 'utf-8'));
|
|
27
|
+
const processedConfig = {};
|
|
28
|
+
// Process each feature to load individual JSON files
|
|
29
|
+
for (const [featureName, config] of Object.entries(baseConfig.features || baseConfig)) {
|
|
30
|
+
const featureConfig = config;
|
|
31
|
+
if (featureConfig.jsonPath) {
|
|
32
|
+
try {
|
|
33
|
+
// Load the individual feature JSON file
|
|
34
|
+
const individualFeaturePath = path.resolve(path.dirname(featuresPath), featureConfig.jsonPath);
|
|
35
|
+
if (fs.existsSync(individualFeaturePath)) {
|
|
36
|
+
const individualFeatureData = JSON.parse(fs.readFileSync(individualFeaturePath, 'utf-8'));
|
|
37
|
+
// Merge the base config with the individual feature data
|
|
38
|
+
processedConfig[featureName] = {
|
|
39
|
+
...featureConfig,
|
|
40
|
+
files: individualFeatureData.files || individualFeatureData,
|
|
41
|
+
...individualFeatureData
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.warn(chalk.yellow(`ā ļø Individual feature file not found: ${individualFeaturePath}`));
|
|
46
|
+
processedConfig[featureName] = featureConfig;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.warn(chalk.yellow(`ā ļø Could not load individual feature file for ${featureName}`));
|
|
51
|
+
processedConfig[featureName] = featureConfig;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// Legacy format
|
|
56
|
+
processedConfig[featureName] = featureConfig;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return { features: processedConfig };
|
|
26
60
|
}
|
|
27
61
|
console.warn(chalk.yellow(`ā ļø features.json not found at: ${featuresPath}`));
|
|
28
62
|
return { features: {} };
|
|
@@ -35,32 +69,32 @@ function getFeaturesConfig() {
|
|
|
35
69
|
/**
|
|
36
70
|
* Get available feature categories
|
|
37
71
|
*/
|
|
38
|
-
function getAvailableFeatures() {
|
|
39
|
-
const config = getFeaturesConfig();
|
|
40
|
-
return Object.keys(config);
|
|
72
|
+
export async function getAvailableFeatures() {
|
|
73
|
+
const config = await getFeaturesConfig();
|
|
74
|
+
return Object.keys(config.features || {});
|
|
41
75
|
}
|
|
42
76
|
/**
|
|
43
77
|
* Get sub-features for a category
|
|
44
78
|
*/
|
|
45
|
-
function getSubFeatures(category) {
|
|
46
|
-
const config = getFeaturesConfig();
|
|
47
|
-
const categoryConfig = config[category];
|
|
79
|
+
async function getSubFeatures(category) {
|
|
80
|
+
const config = await getFeaturesConfig();
|
|
81
|
+
const categoryConfig = config.features?.[category];
|
|
48
82
|
if (!categoryConfig || typeof categoryConfig !== 'object') {
|
|
49
83
|
return [];
|
|
50
84
|
}
|
|
51
|
-
return Object.keys(categoryConfig);
|
|
85
|
+
return Object.keys(categoryConfig.files || {});
|
|
52
86
|
}
|
|
53
87
|
/**
|
|
54
88
|
* List available features from features.json with descriptions
|
|
55
89
|
*/
|
|
56
|
-
function listAvailableFeatures() {
|
|
57
|
-
const featuresConfig = getFeaturesConfig();
|
|
90
|
+
async function listAvailableFeatures() {
|
|
91
|
+
const featuresConfig = await getFeaturesConfig();
|
|
58
92
|
if (!featuresConfig.features || Object.keys(featuresConfig.features).length === 0) {
|
|
59
93
|
console.log(chalk.yellow('ā ļø No features found in configuration'));
|
|
60
94
|
return;
|
|
61
95
|
}
|
|
62
96
|
const featuresData = Object.entries(featuresConfig.features).map(([key, config]) => {
|
|
63
|
-
const providers = Object.keys(config)
|
|
97
|
+
const providers = config.files ? Object.keys(config.files) : [];
|
|
64
98
|
const description = config.description || 'No description available';
|
|
65
99
|
const frameworks = config.supportedFrameworks ? config.supportedFrameworks.join(', ') : 'All frameworks';
|
|
66
100
|
return {
|
|
@@ -234,61 +268,60 @@ function showEnhancedSetupInstructions(feature, provider) {
|
|
|
234
268
|
/**
|
|
235
269
|
* Show help for add command
|
|
236
270
|
*/
|
|
237
|
-
export function showAddHelp() {
|
|
238
|
-
const
|
|
239
|
-
const featuresConfig = getFeaturesConfig();
|
|
271
|
+
export async function showAddHelp() {
|
|
272
|
+
const featuresConfig = await getFeaturesConfig();
|
|
240
273
|
const availableFeatures = Object.keys(featuresConfig.features || {});
|
|
241
|
-
|
|
242
|
-
'
|
|
243
|
-
'',
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
274
|
+
const helpConfig = {
|
|
275
|
+
commandName: 'Add',
|
|
276
|
+
emoji: 'ā',
|
|
277
|
+
description: 'Add new features to your project with automatic framework integration.\nSupports authentication, databases, AI, payments, AWS services, and more.',
|
|
278
|
+
usage: [
|
|
279
|
+
'add [options]',
|
|
280
|
+
'add <feature> [provider] [options]'
|
|
281
|
+
],
|
|
282
|
+
options: [
|
|
283
|
+
{ flag: '-l, --list', description: 'List all available features' },
|
|
284
|
+
{ flag: '-v, --verbose', description: 'Show detailed output' },
|
|
285
|
+
{ flag: '-h, --help', description: 'Show this help message' }
|
|
286
|
+
],
|
|
287
|
+
examples: [
|
|
288
|
+
{ command: 'add', description: 'Interactive feature selection' },
|
|
289
|
+
{ command: 'add auth', description: 'Show auth providers dropdown' },
|
|
290
|
+
{ command: 'add auth clerk', description: 'Add Clerk authentication' },
|
|
291
|
+
{ command: 'add aws ec2', description: 'Add AWS EC2 integration' },
|
|
292
|
+
{ command: 'add ai openai', description: 'Add OpenAI integration' },
|
|
293
|
+
{ command: 'add database postgres', description: 'Add PostgreSQL integration' },
|
|
294
|
+
{ command: 'add payment stripe', description: 'Add Stripe payment integration' },
|
|
295
|
+
{ command: 'add --list', description: 'List all available features' }
|
|
296
|
+
],
|
|
297
|
+
additionalSections: [
|
|
298
|
+
{
|
|
299
|
+
title: `Available Features (${availableFeatures.length})`,
|
|
300
|
+
items: availableFeatures.length > 0
|
|
301
|
+
? availableFeatures
|
|
302
|
+
: ['No features configured']
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
title: 'Supported Frameworks',
|
|
306
|
+
items: [
|
|
307
|
+
'Next.js - App Router & Pages Router',
|
|
308
|
+
'React - Create React App & Vite',
|
|
309
|
+
'Express.js - Node.js backend framework',
|
|
310
|
+
'NestJS - TypeScript backend framework',
|
|
311
|
+
'Vue.js - Vue 3 with Composition API',
|
|
312
|
+
'Angular - Angular 15+',
|
|
313
|
+
'Remix - Full-stack React framework'
|
|
314
|
+
]
|
|
315
|
+
}
|
|
316
|
+
],
|
|
317
|
+
tips: [
|
|
318
|
+
'Features are automatically configured for your framework',
|
|
319
|
+
'Environment variables are added to .env files',
|
|
320
|
+
'TypeScript and JavaScript are both supported',
|
|
321
|
+
'Use "pi add --list" to see detailed feature information'
|
|
322
|
+
]
|
|
323
|
+
};
|
|
324
|
+
createStandardHelp(helpConfig);
|
|
292
325
|
}
|
|
293
326
|
/**
|
|
294
327
|
* Main add command handler with enhanced syntax support
|
|
@@ -303,12 +336,12 @@ export async function addCommand(feature, provider, options = {}) {
|
|
|
303
336
|
try {
|
|
304
337
|
// Handle help flag
|
|
305
338
|
if (options.help || feature === '--help' || feature === '-h') {
|
|
306
|
-
showAddHelp();
|
|
339
|
+
await showAddHelp();
|
|
307
340
|
return;
|
|
308
341
|
}
|
|
309
342
|
// Handle list flag
|
|
310
343
|
if (options.list || feature === '--list' || feature === '-l') {
|
|
311
|
-
listAvailableFeatures();
|
|
344
|
+
await listAvailableFeatures();
|
|
312
345
|
return;
|
|
313
346
|
}
|
|
314
347
|
// Initialize history manager
|
|
@@ -330,7 +363,8 @@ export async function addCommand(feature, provider, options = {}) {
|
|
|
330
363
|
}
|
|
331
364
|
else {
|
|
332
365
|
// Standalone add command - detect framework from project files
|
|
333
|
-
|
|
366
|
+
// Get cached project info or detect it (simplified)
|
|
367
|
+
projectInfo = null; // Simplified - always detect fresh
|
|
334
368
|
if (!projectInfo) {
|
|
335
369
|
console.log(chalk.yellow('š Analyzing project structure...'));
|
|
336
370
|
projectInfo = await detectProjectStack(projectPath);
|
|
@@ -341,7 +375,7 @@ export async function addCommand(feature, provider, options = {}) {
|
|
|
341
375
|
const projectName = await fs.pathExists(packageJsonPath)
|
|
342
376
|
? (await fs.readJson(packageJsonPath)).name || path.basename(projectPath)
|
|
343
377
|
: path.basename(projectPath);
|
|
344
|
-
await cacheProjectData(projectPath, projectName, projectInfo.projectLanguage || 'unknown'
|
|
378
|
+
await cacheProjectData(projectPath, projectName, projectInfo.projectLanguage || 'unknown');
|
|
345
379
|
}
|
|
346
380
|
catch (error) {
|
|
347
381
|
console.warn(chalk.yellow('ā ļø Could not cache project info'));
|
|
@@ -375,8 +409,8 @@ export async function addCommand(feature, provider, options = {}) {
|
|
|
375
409
|
console.log(chalk.red('ā Features configuration not found'));
|
|
376
410
|
return;
|
|
377
411
|
}
|
|
378
|
-
const featuresConfig =
|
|
379
|
-
const availableFeatures = Object.keys(featuresConfig.features);
|
|
412
|
+
const featuresConfig = await getFeaturesConfig();
|
|
413
|
+
const availableFeatures = Object.keys(featuresConfig.features || {});
|
|
380
414
|
// Handle different command syntax cases
|
|
381
415
|
if (!feature) {
|
|
382
416
|
// Case 1: "pi add" - Show interactive dropdown for all features
|
|
@@ -511,7 +545,7 @@ export async function addCommand(feature, provider, options = {}) {
|
|
|
511
545
|
return;
|
|
512
546
|
}
|
|
513
547
|
// Get available sub-features/providers
|
|
514
|
-
const subFeatures = getSubFeatures(selectedFeature);
|
|
548
|
+
const subFeatures = await getSubFeatures(selectedFeature);
|
|
515
549
|
// If no provider specified and multiple providers available, show selection
|
|
516
550
|
if (!selectedProvider && subFeatures.length > 1) {
|
|
517
551
|
const providerChoices = subFeatures.map((subFeature) => {
|
data/dist/commands/analyze.js
CHANGED
|
@@ -7,46 +7,54 @@ import path from 'path';
|
|
|
7
7
|
import os from 'os';
|
|
8
8
|
import gradientString from 'gradient-string';
|
|
9
9
|
import boxen from 'boxen';
|
|
10
|
+
import { createStandardHelp } from '../utils/helpFormatter.js';
|
|
10
11
|
import { createBanner, displaySystemInfo, displaySuccessMessage } from '../utils/dashboard.js';
|
|
11
12
|
import { HistoryManager } from '../utils/historyManager.js';
|
|
12
13
|
/**
|
|
13
|
-
* Display help for analyze command
|
|
14
|
+
* Display help for analyze command using standardized format
|
|
14
15
|
*/
|
|
15
16
|
export function showAnalyzeHelp() {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
17
|
+
const helpConfig = {
|
|
18
|
+
commandName: 'Analyze',
|
|
19
|
+
emoji: 'š',
|
|
20
|
+
description: 'Display comprehensive CLI usage analytics and project dashboard.\nInteractive dashboard showing Package Installer CLI usage statistics, project analytics, recent activities, and development environment info.',
|
|
21
|
+
usage: [
|
|
22
|
+
'analyze [options]',
|
|
23
|
+
'stats [options] # alias'
|
|
24
|
+
],
|
|
25
|
+
options: [
|
|
26
|
+
{ flag: '--export', description: 'Export analytics data to JSON file' },
|
|
27
|
+
{ flag: '--reset', description: 'Reset analytics history' },
|
|
28
|
+
{ flag: '--detailed', description: 'Show detailed analytics breakdown' },
|
|
29
|
+
{ flag: '-h, --help', description: 'Show this help message' }
|
|
30
|
+
],
|
|
31
|
+
examples: [
|
|
32
|
+
{ command: 'analyze', description: 'Show complete analytics dashboard' },
|
|
33
|
+
{ command: 'analyze --detailed', description: 'Show detailed breakdown with more metrics' },
|
|
34
|
+
{ command: 'analyze --export', description: 'Export analytics data to JSON file' },
|
|
35
|
+
{ command: 'analyze --reset', description: 'Clear all analytics history' },
|
|
36
|
+
{ command: 'stats', description: 'Use alias command' }
|
|
37
|
+
],
|
|
38
|
+
additionalSections: [
|
|
39
|
+
{
|
|
40
|
+
title: 'Features',
|
|
41
|
+
items: [
|
|
42
|
+
'š Command Usage Stats - Frequency and trends of CLI commands',
|
|
43
|
+
'š Project Analytics - Created projects and framework breakdown',
|
|
44
|
+
'š Recent Activity - Last created/modified projects timeline',
|
|
45
|
+
'šÆ Feature Usage - Most used features and integrations',
|
|
46
|
+
'āļø Environment Info - Development environment overview',
|
|
47
|
+
'š Performance - CLI performance metrics and insights'
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
tips: [
|
|
52
|
+
'Analytics data is collected from ~/.package-installer-cli/history.json',
|
|
53
|
+
'Use --export to backup your analytics data',
|
|
54
|
+
'Use --reset to start fresh analytics tracking'
|
|
55
|
+
]
|
|
56
|
+
};
|
|
57
|
+
createStandardHelp(helpConfig);
|
|
50
58
|
}
|
|
51
59
|
/**
|
|
52
60
|
* Main analyze command function
|
data/dist/commands/cache.js
CHANGED
|
@@ -7,11 +7,98 @@ import fs from 'fs-extra';
|
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import os from 'os';
|
|
9
9
|
import ora from 'ora';
|
|
10
|
+
import { createStandardHelp } from '../utils/helpFormatter.js';
|
|
10
11
|
import { getDirectorySize, getCacheStats, getCacheStatus } from '../utils/cacheManager.js';
|
|
12
|
+
/**
|
|
13
|
+
* Display help for cache command
|
|
14
|
+
*/
|
|
15
|
+
export function showCacheHelp() {
|
|
16
|
+
const helpConfig = {
|
|
17
|
+
commandName: 'Cache',
|
|
18
|
+
emoji: 'šļø',
|
|
19
|
+
description: 'Manage CLI cache system for improved performance.\nAutomatically manages cached data for faster operations.',
|
|
20
|
+
usage: [
|
|
21
|
+
'cache [subcommand] [type]',
|
|
22
|
+
'cache [options]'
|
|
23
|
+
],
|
|
24
|
+
options: [
|
|
25
|
+
{ flag: '--stats', description: 'Show cache statistics' },
|
|
26
|
+
{ flag: '--clear [type]', description: 'Clear cache (optional type)' },
|
|
27
|
+
{ flag: '--info', description: 'Show cache information' },
|
|
28
|
+
{ flag: '--optimize', description: 'Optimize cache' },
|
|
29
|
+
{ flag: '--size', description: 'Show cache size only' },
|
|
30
|
+
{ flag: '-h, --help', description: 'Show this help message' }
|
|
31
|
+
],
|
|
32
|
+
examples: [
|
|
33
|
+
{ command: 'cache stats', description: 'Show cache statistics' },
|
|
34
|
+
{ command: 'cache --stats', description: 'Show cache statistics (flag)' },
|
|
35
|
+
{ command: 'cache clear', description: 'Clear all cache' },
|
|
36
|
+
{ command: 'cache clear projects', description: 'Clear specific cache type' },
|
|
37
|
+
{ command: 'cache info', description: 'Show cache information' },
|
|
38
|
+
{ command: 'cache optimize', description: 'Optimize cache performance' },
|
|
39
|
+
{ command: 'cache --size', description: 'Show cache size only' }
|
|
40
|
+
],
|
|
41
|
+
additionalSections: [
|
|
42
|
+
{
|
|
43
|
+
title: 'Subcommands',
|
|
44
|
+
items: [
|
|
45
|
+
'stats - Show cache statistics and usage info',
|
|
46
|
+
'clear [type] - Clear cache (all or specific type)',
|
|
47
|
+
'info - Show cache configuration and paths',
|
|
48
|
+
'optimize - Optimize cache performance'
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
title: 'Cache Types',
|
|
53
|
+
items: [
|
|
54
|
+
'projects - Project metadata and analysis',
|
|
55
|
+
'analysis - Analysis results and reports',
|
|
56
|
+
'packages - Package version information',
|
|
57
|
+
'templates - Template usage statistics',
|
|
58
|
+
'system - System environment information',
|
|
59
|
+
'all - Clear all cache types'
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
tips: [
|
|
64
|
+
'Cache improves CLI performance by storing frequently used data',
|
|
65
|
+
'Cache is automatically managed but you can manually optimize it',
|
|
66
|
+
'Use --size to check cache disk usage before clearing'
|
|
67
|
+
]
|
|
68
|
+
};
|
|
69
|
+
createStandardHelp(helpConfig);
|
|
70
|
+
}
|
|
11
71
|
/**
|
|
12
72
|
* Main cache command function
|
|
13
73
|
*/
|
|
14
|
-
export async function cacheCommand(subcommand, type) {
|
|
74
|
+
export async function cacheCommand(subcommand, type, options = {}) {
|
|
75
|
+
// Handle help flag
|
|
76
|
+
if (options.help || options['--help'] || options['-h'] || subcommand === '--help' || subcommand === '-h') {
|
|
77
|
+
showCacheHelp();
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
// Handle option flags
|
|
81
|
+
if (options.stats || subcommand === 'stats') {
|
|
82
|
+
await cacheStatsCommand();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (options.clear !== undefined || subcommand === 'clear') {
|
|
86
|
+
const clearType = options.clear || type;
|
|
87
|
+
await cacheClearCommand(clearType);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (options.info || subcommand === 'info') {
|
|
91
|
+
await cacheInfoCommand();
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (options.optimize || subcommand === 'optimize') {
|
|
95
|
+
await cacheOptimizeCommand();
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (options.size) {
|
|
99
|
+
await cacheSizeCommand();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
15
102
|
// Handle subcommands
|
|
16
103
|
if (subcommand === 'stats') {
|
|
17
104
|
await cacheStatsCommand();
|
|
@@ -27,26 +114,35 @@ export async function cacheCommand(subcommand, type) {
|
|
|
27
114
|
}
|
|
28
115
|
else {
|
|
29
116
|
// Default cache command - show help and quick stats
|
|
117
|
+
console.clear();
|
|
30
118
|
console.log(gradientString(['#00d2d3', '#0084ff'])('šļø Cache Manager\n'));
|
|
31
119
|
console.log(chalk.cyan('Available commands:'));
|
|
32
|
-
console.log(chalk.gray(' pi cache stats
|
|
33
|
-
console.log(chalk.gray(' pi cache clear
|
|
120
|
+
console.log(chalk.gray(' pi cache stats - Show cache statistics'));
|
|
121
|
+
console.log(chalk.gray(' pi cache clear - Clear all cache'));
|
|
34
122
|
console.log(chalk.gray(' pi cache clear <type> - Clear specific cache type'));
|
|
35
|
-
console.log(chalk.gray(' pi cache info
|
|
36
|
-
console.log(chalk.gray(' pi cache optimize
|
|
123
|
+
console.log(chalk.gray(' pi cache info - Show cache configuration'));
|
|
124
|
+
console.log(chalk.gray(' pi cache optimize - Optimize cache performance'));
|
|
125
|
+
console.log(chalk.gray(' pi cache --help - Show detailed help'));
|
|
37
126
|
console.log(chalk.cyan('\nCache types:'));
|
|
38
|
-
console.log(chalk.gray(' projects, templates, analysis, packages'));
|
|
127
|
+
console.log(chalk.gray(' projects, templates, analysis, packages, system, all'));
|
|
39
128
|
// Show quick stats
|
|
40
129
|
try {
|
|
41
130
|
const stats = getCacheStats();
|
|
42
131
|
console.log(chalk.cyan('\nQuick Stats:'));
|
|
43
132
|
console.log(chalk.gray(` Cached Projects: ${stats.projects?.length || 0}`));
|
|
44
133
|
console.log(chalk.gray(` Template Files: ${stats.templateFiles?.size || Object.keys(stats.templateFiles || {}).length || 0}`));
|
|
134
|
+
// Show cache size
|
|
135
|
+
const cacheDir = path.join(os.homedir(), '.pi-cache');
|
|
136
|
+
if (await fs.pathExists(cacheDir)) {
|
|
137
|
+
const size = await getDirectorySize(cacheDir);
|
|
138
|
+
console.log(chalk.gray(` Cache Size: ${(size / 1024 / 1024).toFixed(2)} MB`));
|
|
139
|
+
}
|
|
45
140
|
}
|
|
46
141
|
catch (error) {
|
|
47
142
|
console.log(chalk.yellow('\nā ļø Cache not initialized yet'));
|
|
48
143
|
}
|
|
49
144
|
console.log(chalk.green('\nā
Cache system ready'));
|
|
145
|
+
console.log(chalk.gray('š” Use --help for detailed options'));
|
|
50
146
|
}
|
|
51
147
|
}
|
|
52
148
|
/**
|
|
@@ -174,6 +270,46 @@ async function cacheInfoCommand() {
|
|
|
174
270
|
console.log(chalk.gray(' ⢠templateFiles - Cached template file contents'));
|
|
175
271
|
console.log(chalk.gray(' ⢠system - System environment info'));
|
|
176
272
|
}
|
|
273
|
+
/**
|
|
274
|
+
* Cache size subcommand
|
|
275
|
+
*/
|
|
276
|
+
async function cacheSizeCommand() {
|
|
277
|
+
console.log(gradientString(['#00d2d3', '#0084ff'])('\nš Cache Size Information\n'));
|
|
278
|
+
const spinner = ora('Calculating cache size...').start();
|
|
279
|
+
try {
|
|
280
|
+
const cacheDir = path.join(os.homedir(), '.pi-cache');
|
|
281
|
+
if (!await fs.pathExists(cacheDir)) {
|
|
282
|
+
spinner.warn('Cache directory not found');
|
|
283
|
+
console.log(chalk.yellow('ā ļø Cache has not been initialized yet'));
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const totalSize = await getDirectorySize(cacheDir);
|
|
287
|
+
const cacheFile = path.join(cacheDir, 'cache.json');
|
|
288
|
+
spinner.succeed('Cache size calculated');
|
|
289
|
+
console.log(chalk.cyan('š Cache Size Breakdown:'));
|
|
290
|
+
console.log(chalk.gray(` Total Cache Size: ${(totalSize / 1024 / 1024).toFixed(2)} MB`));
|
|
291
|
+
if (await fs.pathExists(cacheFile)) {
|
|
292
|
+
const cacheFileStats = await fs.stat(cacheFile);
|
|
293
|
+
console.log(chalk.gray(` Cache Data File: ${(cacheFileStats.size / 1024).toFixed(2)} KB`));
|
|
294
|
+
}
|
|
295
|
+
// Show cache efficiency
|
|
296
|
+
if (totalSize > 50 * 1024 * 1024) { // 50MB
|
|
297
|
+
console.log(chalk.yellow('\nā ļø Cache is quite large (>50MB)'));
|
|
298
|
+
console.log(chalk.gray('š” Consider running "pi cache optimize" or "pi cache clear"'));
|
|
299
|
+
}
|
|
300
|
+
else if (totalSize > 10 * 1024 * 1024) { // 10MB
|
|
301
|
+
console.log(chalk.cyan('\nš” Cache size is reasonable'));
|
|
302
|
+
console.log(chalk.gray('Consider optimizing if performance is slow'));
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
console.log(chalk.green('\nā
Cache size is optimal'));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
catch (error) {
|
|
309
|
+
spinner.fail('Failed to calculate cache size');
|
|
310
|
+
console.error(chalk.red(`ā Error: ${error.message}`));
|
|
311
|
+
}
|
|
312
|
+
}
|
|
177
313
|
/**
|
|
178
314
|
* Cache optimize subcommand
|
|
179
315
|
*/
|