cskit-cli 1.0.11 → 1.0.13

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cskit-cli",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "description": "Content Suite Kit CLI - Download and manage CSK skills from private repository",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -110,17 +110,39 @@ async function setupPythonEnv(projectDir, spinner) {
110
110
  execSync(`"${pipPath}" install --upgrade pip -q`, { stdio: 'pipe', cwd: libPythonDir });
111
111
  } catch { /* ignore pip upgrade errors */ }
112
112
 
113
+ // Check which packages need installation
114
+ spinner.text = 'Checking installed packages...';
115
+ let installedPkgs = [];
116
+ try {
117
+ const freezeOutput = execSync(`"${pipPath}" freeze`, { stdio: 'pipe', cwd: libPythonDir });
118
+ installedPkgs = freezeOutput.toString().split('\n')
119
+ .map(line => line.split('==')[0].toLowerCase().trim())
120
+ .filter(Boolean);
121
+ } catch { /* ignore */ }
122
+
123
+ // Filter out already installed packages
124
+ const toInstall = requirements.filter(pkg => {
125
+ const pkgName = pkg.split(/[>=<\[]/)[0].toLowerCase();
126
+ return !installedPkgs.includes(pkgName);
127
+ });
128
+
129
+ if (toInstall.length === 0) {
130
+ spinner.succeed(`Python ready: ${requirements.length} packages already installed`);
131
+ return { success: true, version: pythonVersion };
132
+ }
133
+
113
134
  // Install packages one by one with progress
114
135
  spinner.stop();
115
- console.log(chalk.dim(`\n Installing ${requirements.length} packages:\n`));
136
+ const skipped = requirements.length - toInstall.length;
137
+ console.log(chalk.dim(`\n Installing ${toInstall.length} packages (${skipped} already installed):\n`));
116
138
 
117
139
  const installed = [];
118
140
  const failed = [];
119
141
 
120
- for (let i = 0; i < requirements.length; i++) {
121
- const pkg = requirements[i];
142
+ for (let i = 0; i < toInstall.length; i++) {
143
+ const pkg = toInstall[i];
122
144
  const pkgName = pkg.split(/[>=<\[]/)[0]; // Extract package name
123
- const progress = `[${i + 1}/${requirements.length}]`;
145
+ const progress = `[${i + 1}/${toInstall.length}]`;
124
146
 
125
147
  process.stdout.write(` ${chalk.dim(progress)} ${pkgName}... `);
126
148
 
@@ -143,11 +165,12 @@ async function setupPythonEnv(projectDir, spinner) {
143
165
  console.log('');
144
166
 
145
167
  // Summary
168
+ const totalOk = installed.length + skipped;
146
169
  if (failed.length === 0) {
147
- spinner.succeed(`Python ready: ${installed.length} packages (${pythonVersion})`);
170
+ spinner.succeed(`Python ready: ${totalOk} packages (${pythonVersion})`);
148
171
  return { success: true, version: pythonVersion };
149
- } else if (installed.length > 0) {
150
- spinner.warn(`Partial: ${installed.length} ok, ${failed.length} failed`);
172
+ } else if (installed.length > 0 || skipped > 0) {
173
+ spinner.warn(`Partial: ${totalOk} ok, ${failed.length} failed`);
151
174
  console.log(chalk.yellow(` Failed: ${failed.join(', ')}`));
152
175
  console.log(chalk.dim(` Run manually: ${pipPath} install <package>\n`));
153
176
  return { success: true, partial: true, version: pythonVersion, failed };