cskit-cli 1.0.7 → 1.0.9
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 +58 -47
package/package.json
CHANGED
package/src/commands/init.js
CHANGED
|
@@ -92,60 +92,69 @@ async function setupPythonEnv(projectDir, spinner) {
|
|
|
92
92
|
execSync(`python3 -m venv "${venvPath}"`, { stdio: 'pipe', cwd: libPythonDir });
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
//
|
|
96
|
-
spinner.text = 'Installing Python packages...';
|
|
95
|
+
// Parse requirements.txt
|
|
97
96
|
const pipPath = path.join(venvPath, 'bin', 'pip');
|
|
97
|
+
const requirements = fs.readFileSync(requirementsFile, 'utf8')
|
|
98
|
+
.split('\n')
|
|
99
|
+
.map(line => line.trim())
|
|
100
|
+
.filter(line => line && !line.startsWith('#'));
|
|
98
101
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
stdio: 'pipe',
|
|
102
|
-
cwd: libPythonDir
|
|
103
|
-
});
|
|
104
|
-
spinner.succeed(`Python environment ready (${pythonVersion})`);
|
|
102
|
+
if (requirements.length === 0) {
|
|
103
|
+
spinner.succeed('No packages to install');
|
|
105
104
|
return { success: true, version: pythonVersion };
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Upgrade pip first (silent)
|
|
108
|
+
spinner.text = 'Upgrading pip...';
|
|
109
|
+
try {
|
|
110
|
+
execSync(`"${pipPath}" install --upgrade pip -q`, { stdio: 'pipe', cwd: libPythonDir });
|
|
111
|
+
} catch { /* ignore pip upgrade errors */ }
|
|
112
|
+
|
|
113
|
+
// Install packages one by one with progress
|
|
114
|
+
spinner.stop();
|
|
115
|
+
console.log(chalk.dim(`\n Installing ${requirements.length} packages:\n`));
|
|
116
|
+
|
|
117
|
+
const installed = [];
|
|
118
|
+
const failed = [];
|
|
119
|
+
|
|
120
|
+
for (let i = 0; i < requirements.length; i++) {
|
|
121
|
+
const pkg = requirements[i];
|
|
122
|
+
const pkgName = pkg.split(/[>=<\[]/)[0]; // Extract package name
|
|
123
|
+
const progress = `[${i + 1}/${requirements.length}]`;
|
|
124
|
+
|
|
125
|
+
process.stdout.write(` ${chalk.dim(progress)} ${pkgName}... `);
|
|
123
126
|
|
|
124
|
-
// Try installing without failed packages
|
|
125
|
-
spinner.text = 'Retrying with core packages...';
|
|
126
127
|
try {
|
|
127
|
-
execSync(`"${pipPath}" install
|
|
128
|
+
execSync(`"${pipPath}" install "${pkg}" -q`, {
|
|
128
129
|
stdio: 'pipe',
|
|
129
|
-
cwd: libPythonDir
|
|
130
|
+
cwd: libPythonDir,
|
|
131
|
+
timeout: 120000 // 2 min timeout per package
|
|
130
132
|
});
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
spinner.warn('Partial install - some optional packages failed');
|
|
139
|
-
console.log(chalk.dim(`\n Error: ${errorOutput.slice(0, 200)}...\n`));
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return { success: true, partial: true, version: pythonVersion, failed: failedPackages };
|
|
143
|
-
} catch {
|
|
144
|
-
spinner.fail('Python setup failed');
|
|
145
|
-
console.log(chalk.red(`\n ${errorOutput.slice(0, 500)}\n`));
|
|
146
|
-
return { success: false, error: errorOutput.slice(0, 200) };
|
|
133
|
+
console.log(chalk.green('✓'));
|
|
134
|
+
installed.push(pkgName);
|
|
135
|
+
} catch (err) {
|
|
136
|
+
console.log(chalk.red('✗'));
|
|
137
|
+
const errMsg = err.stderr ? err.stderr.toString().split('\n')[0] : err.message;
|
|
138
|
+
console.log(chalk.dim(` ${errMsg.slice(0, 60)}`));
|
|
139
|
+
failed.push(pkgName);
|
|
147
140
|
}
|
|
148
141
|
}
|
|
142
|
+
|
|
143
|
+
console.log('');
|
|
144
|
+
|
|
145
|
+
// Summary
|
|
146
|
+
if (failed.length === 0) {
|
|
147
|
+
spinner.succeed(`Python ready: ${installed.length} packages (${pythonVersion})`);
|
|
148
|
+
return { success: true, version: pythonVersion };
|
|
149
|
+
} else if (installed.length > 0) {
|
|
150
|
+
spinner.warn(`Partial: ${installed.length} ok, ${failed.length} failed`);
|
|
151
|
+
console.log(chalk.yellow(` Failed: ${failed.join(', ')}`));
|
|
152
|
+
console.log(chalk.dim(` Run manually: ${pipPath} install <package>\n`));
|
|
153
|
+
return { success: true, partial: true, version: pythonVersion, failed };
|
|
154
|
+
} else {
|
|
155
|
+
spinner.fail('All packages failed');
|
|
156
|
+
return { success: false, error: 'All packages failed to install' };
|
|
157
|
+
}
|
|
149
158
|
} catch (error) {
|
|
150
159
|
spinner.warn(`Python setup failed: ${error.message}`);
|
|
151
160
|
return { success: false, error: error.message };
|
|
@@ -241,11 +250,13 @@ async function initCommand(options) {
|
|
|
241
250
|
spinner.succeed(`Found ${releases.length} release(s)`);
|
|
242
251
|
}
|
|
243
252
|
|
|
244
|
-
// Version selection
|
|
253
|
+
// Version selection (show max 5 recent releases)
|
|
245
254
|
let selectedVersion = 'main';
|
|
255
|
+
const maxVersions = 5;
|
|
246
256
|
|
|
247
257
|
if (releases.length > 0 && !options.latest) {
|
|
248
|
-
const
|
|
258
|
+
const recentReleases = releases.slice(0, maxVersions);
|
|
259
|
+
const choices = recentReleases.map((r, i) => ({
|
|
249
260
|
name: `${r.tag}${i === 0 ? chalk.green(' (latest)') : ''} - ${formatDate(r.published)}`,
|
|
250
261
|
value: r.tag
|
|
251
262
|
}));
|