@iflow-ai/iflow-cli 0.2.1 → 0.2.2
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
|
@@ -9,6 +9,7 @@ import { join, dirname, resolve } from 'path';
|
|
|
9
9
|
import { fileURLToPath } from 'url';
|
|
10
10
|
import os from 'os';
|
|
11
11
|
import https from 'https';
|
|
12
|
+
import http from 'http'; // 添加HTTP模块导入
|
|
12
13
|
import { createHash } from 'crypto';
|
|
13
14
|
import { pipeline } from 'stream/promises';
|
|
14
15
|
import { Extract } from 'unzipper';
|
|
@@ -17,8 +18,20 @@ import { Extract } from 'unzipper';
|
|
|
17
18
|
const PLUGIN_URL = 'https://cloud.iflow.cn/iflow-cli/iflow-idea-0.0.1.zip';
|
|
18
19
|
const PLUGIN_DIR_NAME = 'iflow-idea';
|
|
19
20
|
const TEMP_DIR_NAME = 'tstar-cli-idea-plugin';
|
|
20
|
-
const LOG_PREFIX = '[
|
|
21
|
-
|
|
21
|
+
const LOG_PREFIX = '[JetBrains Extension]';
|
|
22
|
+
// 扩展支持的JetBrains IDE产品
|
|
23
|
+
const IDE_PATTERNS = [
|
|
24
|
+
'IntelliJIdea', 'IdeaIC', // IntelliJ IDEA
|
|
25
|
+
'PyCharm', 'PyCharmCE', // PyCharm
|
|
26
|
+
'GoLand', // GoLand
|
|
27
|
+
'WebStorm', // WebStorm
|
|
28
|
+
'PhpStorm', // PhpStorm
|
|
29
|
+
'CLion', // CLion
|
|
30
|
+
'RubyMine', // RubyMine
|
|
31
|
+
'DataGrip', // DataGrip
|
|
32
|
+
'Rider', // Rider
|
|
33
|
+
'AndroidStudio' // Android Studio
|
|
34
|
+
];
|
|
22
35
|
|
|
23
36
|
// 获取当前脚本的目录
|
|
24
37
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -45,8 +58,8 @@ function isExecutable(filePath) {
|
|
|
45
58
|
}
|
|
46
59
|
}
|
|
47
60
|
|
|
48
|
-
// 获取
|
|
49
|
-
function
|
|
61
|
+
// 获取 JetBrains IDE 插件目录的跨平台函数
|
|
62
|
+
function getJetBrainsPluginsDirectory() {
|
|
50
63
|
const platform = os.platform();
|
|
51
64
|
const homedir = os.homedir();
|
|
52
65
|
|
|
@@ -62,23 +75,24 @@ function getIdeaPluginsDirectory() {
|
|
|
62
75
|
}
|
|
63
76
|
}
|
|
64
77
|
|
|
65
|
-
// 查找最新版本的
|
|
66
|
-
function
|
|
67
|
-
const jetbrainsDir =
|
|
78
|
+
// 查找最新版本的 JetBrains IDE 目录
|
|
79
|
+
function findLatestJetBrainsDirectories() {
|
|
80
|
+
const jetbrainsDir = getJetBrainsPluginsDirectory();
|
|
68
81
|
|
|
69
82
|
if (!existsSync(jetbrainsDir)) {
|
|
70
83
|
console.warn(`${LOG_PREFIX} JetBrains directory not found:`, jetbrainsDir);
|
|
71
|
-
return
|
|
84
|
+
return [];
|
|
72
85
|
}
|
|
73
86
|
|
|
74
87
|
try {
|
|
88
|
+
// 获取所有匹配的IDE目录,并按修改时间排序
|
|
75
89
|
const dirs = readdirSync(jetbrainsDir)
|
|
76
|
-
.filter(dir =>
|
|
90
|
+
.filter(dir => IDE_PATTERNS.some(pattern => dir.startsWith(pattern)))
|
|
77
91
|
.map(dir => {
|
|
78
92
|
const fullPath = join(jetbrainsDir, dir);
|
|
79
93
|
try {
|
|
80
94
|
const stats = statSync(fullPath);
|
|
81
|
-
return { path: fullPath, mtime: stats.mtime };
|
|
95
|
+
return { path: fullPath, mtime: stats.mtime, name: dir };
|
|
82
96
|
} catch (error) {
|
|
83
97
|
console.warn(`${LOG_PREFIX} Cannot access directory ${fullPath}:`, error.message);
|
|
84
98
|
return null;
|
|
@@ -88,14 +102,23 @@ function findLatestIdeaDirectory() {
|
|
|
88
102
|
.sort((a, b) => b.mtime - a.mtime);
|
|
89
103
|
|
|
90
104
|
if (dirs.length === 0) {
|
|
91
|
-
console.warn(`${LOG_PREFIX} No
|
|
92
|
-
return
|
|
105
|
+
console.warn(`${LOG_PREFIX} No JetBrains IDE installation found`);
|
|
106
|
+
return [];
|
|
93
107
|
}
|
|
94
108
|
|
|
95
|
-
|
|
109
|
+
// 按IDE类型分组,每种IDE只保留最新版本
|
|
110
|
+
const latestByType = {};
|
|
111
|
+
dirs.forEach(dir => {
|
|
112
|
+
const ideType = IDE_PATTERNS.find(pattern => dir.name.startsWith(pattern));
|
|
113
|
+
if (ideType && !latestByType[ideType]) {
|
|
114
|
+
latestByType[ideType] = dir;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
return Object.values(latestByType);
|
|
96
119
|
} catch (error) {
|
|
97
|
-
console.error(`${LOG_PREFIX} Error finding
|
|
98
|
-
return
|
|
120
|
+
console.error(`${LOG_PREFIX} Error finding JetBrains IDE directories:`, error.message);
|
|
121
|
+
return [];
|
|
99
122
|
}
|
|
100
123
|
}
|
|
101
124
|
|
|
@@ -104,7 +127,10 @@ async function downloadPlugin(url, destPath) {
|
|
|
104
127
|
return new Promise((resolve, reject) => {
|
|
105
128
|
const file = createWriteStream(destPath);
|
|
106
129
|
|
|
107
|
-
|
|
130
|
+
// 根据URL协议选择适当的模块
|
|
131
|
+
const protocol = url.startsWith('https:') ? https : http;
|
|
132
|
+
|
|
133
|
+
protocol.get(url, (response) => {
|
|
108
134
|
if (response.statusCode !== 200) {
|
|
109
135
|
reject(new Error(`Failed to download plugin: ${response.statusCode}`));
|
|
110
136
|
return;
|
|
@@ -145,41 +171,16 @@ async function extractPlugin(zipFilePath, destDir) {
|
|
|
145
171
|
});
|
|
146
172
|
}
|
|
147
173
|
|
|
148
|
-
// 安装
|
|
149
|
-
async function
|
|
174
|
+
// 安装 JetBrains IDE 插件
|
|
175
|
+
async function installJetBrainsExtension() {
|
|
150
176
|
try {
|
|
151
|
-
//
|
|
152
|
-
const
|
|
153
|
-
if (
|
|
154
|
-
console.warn(`${LOG_PREFIX} Could not find
|
|
177
|
+
// 查找所有支持的 JetBrains IDE 目录
|
|
178
|
+
const ideDirs = findLatestJetBrainsDirectories();
|
|
179
|
+
if (ideDirs.length === 0) {
|
|
180
|
+
console.warn(`${LOG_PREFIX} Could not find any JetBrains IDE installation, skipping plugin installation`);
|
|
155
181
|
return;
|
|
156
182
|
}
|
|
157
183
|
|
|
158
|
-
console.info(`${LOG_PREFIX} Found IntelliJ IDEA at: ${ideaDir}`);
|
|
159
|
-
|
|
160
|
-
// 创建插件目录路径
|
|
161
|
-
const pluginsDir = join(ideaDir, 'plugins');
|
|
162
|
-
if (!existsSync(pluginsDir)) {
|
|
163
|
-
try {
|
|
164
|
-
mkdirSync(pluginsDir, { recursive: true });
|
|
165
|
-
} catch (error) {
|
|
166
|
-
console.error(`${LOG_PREFIX} Failed to create plugins directory: ${pluginsDir}`, error.message);
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// 检查并删除已存在的插件目录
|
|
172
|
-
const existingPluginDir = join(pluginsDir, PLUGIN_DIR_NAME);
|
|
173
|
-
if (existsSync(existingPluginDir)) {
|
|
174
|
-
try {
|
|
175
|
-
console.info(`${LOG_PREFIX} Removing existing plugin directory: ${existingPluginDir}`);
|
|
176
|
-
rmSync(existingPluginDir, { recursive: true, force: true });
|
|
177
|
-
} catch (error) {
|
|
178
|
-
console.error(`${LOG_PREFIX} Failed to remove existing plugin directory: ${existingPluginDir}`, error.message);
|
|
179
|
-
// 继续安装,即使删除失败
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
184
|
// 创建临时下载目录
|
|
184
185
|
const tempDir = join(os.tmpdir(), TEMP_DIR_NAME);
|
|
185
186
|
if (!existsSync(tempDir)) {
|
|
@@ -206,13 +207,44 @@ async function installIdeaExtension() {
|
|
|
206
207
|
const fileHash = await calculateFileHash(pluginFilePath);
|
|
207
208
|
console.info(`${LOG_PREFIX} Plugin file hash: ${fileHash}`);
|
|
208
209
|
|
|
209
|
-
//
|
|
210
|
-
|
|
210
|
+
// 为每个找到的IDE安装插件
|
|
211
|
+
for (const ideDir of ideDirs) {
|
|
212
|
+
console.info(`${LOG_PREFIX} Found JetBrains IDE at: ${ideDir.path}`);
|
|
213
|
+
|
|
214
|
+
// 创建插件目录路径
|
|
215
|
+
const pluginsDir = join(ideDir.path, 'plugins');
|
|
216
|
+
if (!existsSync(pluginsDir)) {
|
|
217
|
+
try {
|
|
218
|
+
mkdirSync(pluginsDir, { recursive: true });
|
|
219
|
+
} catch (error) {
|
|
220
|
+
console.error(`${LOG_PREFIX} Failed to create plugins directory: ${pluginsDir}`, error.message);
|
|
221
|
+
continue; // 跳过此IDE,继续下一个
|
|
222
|
+
}
|
|
223
|
+
}
|
|
211
224
|
|
|
212
|
-
|
|
213
|
-
|
|
225
|
+
// 检查并删除已存在的插件目录
|
|
226
|
+
const existingPluginDir = join(pluginsDir, PLUGIN_DIR_NAME);
|
|
227
|
+
if (existsSync(existingPluginDir)) {
|
|
228
|
+
try {
|
|
229
|
+
console.info(`${LOG_PREFIX} Removing existing plugin directory: ${existingPluginDir}`);
|
|
230
|
+
rmSync(existingPluginDir, { recursive: true, force: true });
|
|
231
|
+
} catch (error) {
|
|
232
|
+
console.error(`${LOG_PREFIX} Failed to remove existing plugin directory: ${existingPluginDir}`, error.message);
|
|
233
|
+
// 继续安装,即使删除失败
|
|
234
|
+
}
|
|
235
|
+
}
|
|
214
236
|
|
|
215
|
-
|
|
237
|
+
// 解压插件到插件目录
|
|
238
|
+
console.info(`${LOG_PREFIX} Extracting plugin to: ${pluginsDir}`);
|
|
239
|
+
|
|
240
|
+
try {
|
|
241
|
+
// 直接解压到插件目录,不创建额外的子目录
|
|
242
|
+
await extractPlugin(pluginFilePath, pluginsDir);
|
|
243
|
+
console.info(`${LOG_PREFIX} ✅ Plugin installed successfully to: ${pluginsDir}`);
|
|
244
|
+
} catch (error) {
|
|
245
|
+
console.error(`${LOG_PREFIX} Failed to install plugin for ${ideDir.name}:`, error.message);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
216
248
|
|
|
217
249
|
// 清理临时文件
|
|
218
250
|
try {
|
|
@@ -226,14 +258,14 @@ async function installIdeaExtension() {
|
|
|
226
258
|
console.debug(`${LOG_PREFIX} Stack trace:`, error.stack);
|
|
227
259
|
}
|
|
228
260
|
} catch (error) {
|
|
229
|
-
console.error(`${LOG_PREFIX} Unexpected error during
|
|
261
|
+
console.error(`${LOG_PREFIX} Unexpected error during JetBrains extension installation:`, error.message);
|
|
230
262
|
console.debug(`${LOG_PREFIX} Stack trace:`, error.stack);
|
|
231
263
|
}
|
|
232
264
|
}
|
|
233
265
|
|
|
234
266
|
// 只在非 CI 环境执行
|
|
235
267
|
if (!process.env.CI) {
|
|
236
|
-
|
|
268
|
+
installJetBrainsExtension().catch(error => {
|
|
237
269
|
console.error(`${LOG_PREFIX} Installation failed:`, error.message);
|
|
238
270
|
});
|
|
239
271
|
}
|