Skip to content

Commit 8639ff2

Browse files
committed
fix: 打包流程修改
1 parent 6954eec commit 8639ff2

File tree

2 files changed

+144
-6
lines changed

2 files changed

+144
-6
lines changed

src/python/rag.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def initialize_storage(storage_path: str):
4343
print(f"已从 {kb_file} 加载知识库,共 {len(knowledge_base)} 条记录")
4444
else:
4545
knowledge_base = []
46-
print(f"创建新的知识库,将保存到 {kb_file}")
46+
print(f"创建新的记忆库,将保存到 {kb_file}")
4747

4848
storage_initialized = True
4949

@@ -138,4 +138,4 @@ def embed(text: str):
138138
finally:
139139
# 确保程序退出前保存数据
140140
save_to_storage(args.storage_path)
141-
print("服务关闭,数据已保存")
141+
print("记忆服务关闭,数据已保存")

src/ragService.ts

Lines changed: 142 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
// src/ragService.ts
2-
import { ChildProcess, execSync, exec, spawn } from 'child_process';
1+
import { ChildProcess, execSync, exec, spawn } from 'child_process';
32
import * as vscode from 'vscode';
43
import * as path from 'path';
54
import * as fs from 'fs/promises';
65
import * as net from 'net';
76
import * as os from 'os';
7+
import * as https from 'https';
8+
import * as crypto from 'crypto';
89

910
// Define a variable to store the extension path
1011
let EXTENSION_PATH: string = '';
@@ -60,6 +61,53 @@ class RagService {
6061
if (this.state.status !== 'stopped') { return; }
6162

6263
try {
64+
if (!isDevMode) {
65+
const exePath = getPythonScriptPath(EXTENSION_PATH);
66+
const distPath = path.dirname(exePath);
67+
await fs.mkdir(distPath, { recursive: true });
68+
69+
let shouldDownload = false;
70+
71+
// Check if rag.exe exists
72+
try {
73+
await fs.access(exePath, fs.constants.F_OK);
74+
75+
// Download MD5 from GitHub
76+
const remoteMd5 = await this.downloadText('https://github.com/yefansky/CodeReDesign/releases/download/latest/md5.txt');
77+
78+
// Calculate local rag.exe MD5
79+
const localMd5 = await this.calculateFileMd5(exePath);
80+
81+
// Compare MD5s
82+
if (remoteMd5.trim().toLowerCase() !== localMd5.toLowerCase()) {
83+
shouldDownload = true;
84+
vscode.window.showInformationMessage('rag.exe MD5 mismatch, downloading new version...');
85+
}
86+
} catch (err) {
87+
// rag.exe doesn't exist
88+
shouldDownload = true;
89+
vscode.window.showInformationMessage('rag.exe not found, downloading...');
90+
}
91+
92+
if (shouldDownload) {
93+
// Kill any running rag.exe process
94+
await this.killRagExeProcess();
95+
96+
// Download new rag.exe
97+
await this.downloadFile(
98+
'https://github.com/yefansky/CodeReDesign/releases/download/latest/rag.exe',
99+
exePath
100+
);
101+
102+
// Verify downloaded file's MD5
103+
const newMd5 = await this.calculateFileMd5(exePath);
104+
const remoteMd5 = await this.downloadText('https://github.com/yefansky/CodeReDesign/releases/download/latest/md5.txt');
105+
if (newMd5.toLowerCase() !== remoteMd5.trim().toLowerCase()) {
106+
throw new Error('Downloaded rag.exe MD5 verification failed');
107+
}
108+
}
109+
}
110+
63111
//await this.acquireLock();
64112
await this.ensurePortAvailable();
65113

@@ -74,6 +122,94 @@ class RagService {
74122
}
75123
}
76124

125+
private async downloadText(url: string): Promise<string> {
126+
return new Promise((resolve, reject) => {
127+
https.get(url, (res) => {
128+
let data = '';
129+
res.on('data', (chunk) => { data += chunk; });
130+
res.on('end', () => {
131+
if (res.statusCode !== 200) {
132+
reject(new Error(`Failed to download text from ${url}: Status ${res.statusCode}`));
133+
} else {
134+
resolve(data);
135+
}
136+
});
137+
}).on('error', (err) => {
138+
reject(new Error(`Failed to download text from ${url}: ${err.message}`));
139+
});
140+
});
141+
}
142+
143+
private async downloadFile(url: string, dest: string): Promise<void> {
144+
return new Promise((resolve, reject) => {
145+
const file = require('fs').createWriteStream(dest);
146+
https.get(url, (res) => {
147+
if (res.statusCode !== 200) {
148+
reject(new Error(`Failed to download file from ${url}: Status ${res.statusCode}`));
149+
return;
150+
}
151+
res.pipe(file);
152+
file.on('finish', () => {
153+
file.close();
154+
resolve();
155+
});
156+
}).on('error', (err) => {
157+
require('fs').unlink(dest, () => {}); // Clean up partial download
158+
reject(new Error(`Failed to download file from ${url}: ${err.message}`));
159+
});
160+
});
161+
}
162+
163+
private async calculateFileMd5(filePath: string): Promise<string> {
164+
const fileBuffer = await fs.readFile(filePath);
165+
return crypto.createHash('md5').update(fileBuffer).digest('hex');
166+
}
167+
168+
private async killRagExeProcess(): Promise<void> {
169+
if (process.platform !== 'win32') {
170+
return; // Only implemented for Windows as rag.exe is Windows-specific
171+
}
172+
173+
return new Promise((resolve, reject) => {
174+
try {
175+
const command = `tasklist | findstr "rag.exe"`;
176+
exec(command, { shell: 'cmd.exe', encoding: 'utf8' }, (error, stdout) => {
177+
if (error && !stdout) {
178+
console.log('No rag.exe process found');
179+
return resolve();
180+
}
181+
182+
const pids = stdout
183+
.trim()
184+
.split('\n')
185+
.map(line => {
186+
const parts = line.trim().split(/\s+/);
187+
return parts[1]; // PID is in the second column
188+
})
189+
.filter(pid => pid && /^\d+$/.test(pid));
190+
191+
if (pids.length === 0) {
192+
console.log('No valid rag.exe PIDs found');
193+
return resolve();
194+
}
195+
196+
console.log(`Terminating rag.exe PIDs: ${pids.join(', ')}`);
197+
const killCommand = `taskkill /F /PID ${pids.join(' ')}`;
198+
exec(killCommand, { shell: 'cmd.exe' }, (killError) => {
199+
if (killError) {
200+
console.error(`Failed to terminate rag.exe processes: ${killError.message}`);
201+
return reject(new Error(`Failed to terminate rag.exe processes: ${killError.message}`));
202+
}
203+
resolve();
204+
});
205+
});
206+
} catch (err) {
207+
console.error(`Error killing rag.exe process: ${(err as Error).message}`);
208+
reject(new Error(`Failed to kill rag.exe process: ${(err as Error).message}`));
209+
}
210+
});
211+
}
212+
77213
public async stop(): Promise<void> {
78214
if (this.state.process) {
79215
this.state.process.kill('SIGTERM');
@@ -284,8 +420,10 @@ class RagService {
284420
const scriptPath = getPythonScriptPath(EXTENSION_PATH);
285421
const isExe = scriptPath.endsWith('.exe');
286422

287-
if (!fs.access(scriptPath)) {
288-
throw new Error(`Script or executable not found: ${scriptPath}`);
423+
try {
424+
fs.access(scriptPath, fs.constants.X_OK);
425+
} catch (err) {
426+
throw new Error(`Script or executable not found or not executable: ${scriptPath}`);
289427
}
290428

291429
if (isExe) {

0 commit comments

Comments
 (0)