cskit-cli 1.0.27 → 1.0.28
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.
- package/package.json +1 -1
- package/src/commands/init.js +83 -30
package/package.json
CHANGED
package/src/commands/init.js
CHANGED
|
@@ -67,6 +67,7 @@ class Timeline {
|
|
|
67
67
|
this.currentStep = -1;
|
|
68
68
|
this.lastLineCount = 0;
|
|
69
69
|
this.isFirstRender = true;
|
|
70
|
+
this.isPaused = false;
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
addStep(name) {
|
|
@@ -103,15 +104,28 @@ class Timeline {
|
|
|
103
104
|
|
|
104
105
|
// Call before any external output (prompts, logs, etc.)
|
|
105
106
|
pause() {
|
|
107
|
+
// Don't update in-place after external output - just continue below
|
|
106
108
|
this.lastLineCount = 0;
|
|
109
|
+
this.isPaused = true;
|
|
107
110
|
}
|
|
108
111
|
|
|
109
112
|
// Re-render timeline after external output
|
|
110
113
|
resume() {
|
|
114
|
+
if (this.isPaused) {
|
|
115
|
+
// Print separator and continue fresh (no in-place update)
|
|
116
|
+
console.log(chalk.dim(' ─'.repeat(20)));
|
|
117
|
+
this.isPaused = false;
|
|
118
|
+
}
|
|
111
119
|
this.isFirstRender = true;
|
|
112
120
|
this.render();
|
|
113
121
|
}
|
|
114
122
|
|
|
123
|
+
// Print final summary (no in-place update)
|
|
124
|
+
printSummary() {
|
|
125
|
+
this.lastLineCount = 0; // Disable in-place update
|
|
126
|
+
this.render();
|
|
127
|
+
}
|
|
128
|
+
|
|
115
129
|
render() {
|
|
116
130
|
// Build output lines
|
|
117
131
|
const lines = [];
|
|
@@ -125,22 +139,25 @@ class Timeline {
|
|
|
125
139
|
|
|
126
140
|
lines.push(` ${symbol} ${num} ${name}${msg}`);
|
|
127
141
|
|
|
128
|
-
// Show children (
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
142
|
+
// Show children only for active or done steps (not pending)
|
|
143
|
+
if (step.status !== 'pending') {
|
|
144
|
+
for (let j = 0; j < step.children.length; j++) {
|
|
145
|
+
const child = step.children[j];
|
|
146
|
+
const isLast = j === step.children.length - 1;
|
|
147
|
+
const branch = isLast ? SYMBOLS.branchLast : SYMBOLS.branch;
|
|
148
|
+
const prefix = child.type === 'new' ? chalk.green('+') :
|
|
149
|
+
child.type === 'update' ? chalk.blue('~') :
|
|
150
|
+
child.type === 'skip' ? chalk.yellow('!') :
|
|
151
|
+
child.type === 'delete' ? chalk.red('-') :
|
|
152
|
+
chalk.dim('•');
|
|
153
|
+
lines.push(` ${SYMBOLS.indent}${branch} ${prefix} ${child.text}`);
|
|
154
|
+
}
|
|
139
155
|
}
|
|
140
156
|
}
|
|
141
157
|
|
|
142
158
|
// Clear previous output (move cursor up and clear lines)
|
|
143
|
-
|
|
159
|
+
// Only do in-place update when not paused and have previous output
|
|
160
|
+
if (!this.isFirstRender && this.lastLineCount > 0 && !this.isPaused) {
|
|
144
161
|
// Move cursor up and clear each line
|
|
145
162
|
process.stdout.write(`\x1b[${this.lastLineCount}A`);
|
|
146
163
|
for (let i = 0; i < this.lastLineCount; i++) {
|
|
@@ -360,20 +377,54 @@ async function installPackages(libPythonDir, packages, timeline, stepIndex, pyth
|
|
|
360
377
|
}
|
|
361
378
|
}
|
|
362
379
|
|
|
363
|
-
//
|
|
380
|
+
// Get currently installed packages (to avoid reinstalling)
|
|
381
|
+
let installedPkgs = new Set();
|
|
382
|
+
try {
|
|
383
|
+
const freeze = execSync(`"${pipPath}" freeze`, { stdio: 'pipe' }).toString();
|
|
384
|
+
freeze.split('\n').forEach(line => {
|
|
385
|
+
const match = line.match(/^([^=]+)==/);
|
|
386
|
+
if (match) installedPkgs.add(match[1].toLowerCase());
|
|
387
|
+
});
|
|
388
|
+
} catch {}
|
|
389
|
+
|
|
390
|
+
// Install/update packages
|
|
364
391
|
let success = true;
|
|
392
|
+
let installed = 0, skipped = 0, failed = 0;
|
|
393
|
+
|
|
365
394
|
for (const pkg of packages) {
|
|
395
|
+
const pkgName = pkg.name.toLowerCase();
|
|
366
396
|
const pkgSpec = pkg.required || pkg.name;
|
|
397
|
+
|
|
398
|
+
// Check if already installed (skip unless it's an update)
|
|
399
|
+
if (installedPkgs.has(pkgName) && !pkg.current) {
|
|
400
|
+
timeline.addChild(stepIndex, `${pkg.name} (already installed)`, 'info');
|
|
401
|
+
skipped++;
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
404
|
+
|
|
367
405
|
try {
|
|
368
|
-
execSync(`"${pipPath}" install "${pkgSpec}" -q`, {
|
|
406
|
+
execSync(`"${pipPath}" install "${pkgSpec}" -q --upgrade`, {
|
|
369
407
|
stdio: 'pipe',
|
|
370
408
|
cwd: libPythonDir,
|
|
371
409
|
timeout: 120000
|
|
372
410
|
});
|
|
373
|
-
|
|
411
|
+
if (pkg.current) {
|
|
412
|
+
timeline.addChild(stepIndex, `${pkg.name} (${pkg.current} → updated)`, 'update');
|
|
413
|
+
} else {
|
|
414
|
+
timeline.addChild(stepIndex, `${pkg.name}`, 'new');
|
|
415
|
+
}
|
|
416
|
+
installed++;
|
|
374
417
|
} catch (error) {
|
|
375
|
-
|
|
376
|
-
|
|
418
|
+
// Check if it was actually installed despite error
|
|
419
|
+
try {
|
|
420
|
+
const check = execSync(`"${pipPath}" show ${pkgName}`, { stdio: 'pipe' });
|
|
421
|
+
timeline.addChild(stepIndex, `${pkg.name} (already installed)`, 'info');
|
|
422
|
+
skipped++;
|
|
423
|
+
} catch {
|
|
424
|
+
timeline.addChild(stepIndex, `${pkg.name} (failed)`, 'skip');
|
|
425
|
+
failed++;
|
|
426
|
+
success = false;
|
|
427
|
+
}
|
|
377
428
|
}
|
|
378
429
|
}
|
|
379
430
|
|
|
@@ -639,45 +690,47 @@ async function initCommand(options) {
|
|
|
639
690
|
|
|
640
691
|
const pkgStatus = checkPythonPackages(libPythonDir);
|
|
641
692
|
|
|
693
|
+
// Show Python version in timeline
|
|
694
|
+
timeline.addChild(6, `Python ${pythonCmd === 'python3' ? pythonInfo.version : '3.x'} (${pythonCmd})`, 'update');
|
|
695
|
+
|
|
696
|
+
// Show already installed count
|
|
642
697
|
if (pkgStatus.installed.length > 0) {
|
|
643
|
-
|
|
644
|
-
for (const pkg of pkgStatus.installed.slice(0, 5)) {
|
|
645
|
-
console.log(chalk.dim(` ✓ ${pkg.name} (${pkg.version})`));
|
|
646
|
-
}
|
|
647
|
-
if (pkgStatus.installed.length > 5) {
|
|
648
|
-
console.log(chalk.dim(` ... and ${pkgStatus.installed.length - 5} more\n`));
|
|
649
|
-
}
|
|
698
|
+
timeline.addChild(6, `${pkgStatus.installed.length} packages already installed`, 'info');
|
|
650
699
|
}
|
|
651
700
|
|
|
652
701
|
const allToInstall = [...pkgStatus.toInstall, ...pkgStatus.toUpdate];
|
|
653
702
|
|
|
654
703
|
if (allToInstall.length === 0) {
|
|
655
|
-
timeline.complete(6,
|
|
704
|
+
timeline.complete(6, `${pkgStatus.installed.length} packages ready`);
|
|
656
705
|
return;
|
|
657
706
|
}
|
|
658
707
|
|
|
708
|
+
// Show what needs to be installed/updated
|
|
659
709
|
console.log(chalk.cyan('\n Packages to install/update:\n'));
|
|
660
|
-
for (const pkg of allToInstall) {
|
|
710
|
+
for (const pkg of allToInstall.slice(0, 10)) {
|
|
661
711
|
if (pkg.current) {
|
|
662
|
-
console.log(` ${pkg.name}: ${pkg.current} → ${pkg.required}`);
|
|
712
|
+
console.log(` ~ ${pkg.name}: ${pkg.current} → ${pkg.required}`);
|
|
663
713
|
} else {
|
|
664
|
-
console.log(` ${pkg.name}: ${pkg.required || 'latest'}`);
|
|
714
|
+
console.log(` + ${pkg.name}: ${pkg.required || 'latest'}`);
|
|
665
715
|
}
|
|
666
716
|
}
|
|
717
|
+
if (allToInstall.length > 10) {
|
|
718
|
+
console.log(chalk.dim(` ... and ${allToInstall.length - 10} more`));
|
|
719
|
+
}
|
|
667
720
|
console.log('');
|
|
668
721
|
|
|
669
722
|
timeline.pause();
|
|
670
723
|
const { confirmPkgs } = await inquirer.prompt([{
|
|
671
724
|
type: 'confirm',
|
|
672
725
|
name: 'confirmPkgs',
|
|
673
|
-
message: `Install ${allToInstall.length} packages?`,
|
|
726
|
+
message: `Install/update ${allToInstall.length} packages?`,
|
|
674
727
|
default: true
|
|
675
728
|
}]);
|
|
676
729
|
timeline.resume();
|
|
677
730
|
|
|
678
731
|
if (confirmPkgs) {
|
|
679
732
|
await installPackages(libPythonDir, allToInstall, timeline, 6, pythonCmd);
|
|
680
|
-
timeline.complete(6, `${allToInstall.length} packages`);
|
|
733
|
+
timeline.complete(6, `${pkgStatus.installed.length + allToInstall.length} packages`);
|
|
681
734
|
} else {
|
|
682
735
|
timeline.skip(6, 'User skipped');
|
|
683
736
|
}
|