Skip to content

Commit 2f00481

Browse files
committed
fix: installer now uses local binary from extracted archive
1 parent 52971d7 commit 2f00481

File tree

1 file changed

+98
-27
lines changed

1 file changed

+98
-27
lines changed

cmd/install/main.go

Lines changed: 98 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -186,31 +186,45 @@ func installBinary() {
186186
home, _ := os.UserHomeDir()
187187
var binDir string
188188
if runtime.GOOS == "windows" {
189-
binDir = filepath.Join(home, "go", "bin")
189+
binDir = filepath.Join(home, ".local", "share", "ragcode", "bin")
190190
} else {
191-
binDir = filepath.Join(home, ".local", "bin")
191+
binDir = filepath.Join(home, ".local", "share", "ragcode", "bin")
192192
}
193193
if err := os.MkdirAll(binDir, 0755); err != nil {
194194
fail(fmt.Sprintf("Could not create bin directory: %v", err))
195195
}
196196

197-
outputBin := filepath.Join(binDir, "rag-code-mcp")
197+
binaryName := "rag-code-mcp"
198198
if runtime.GOOS == "windows" {
199-
outputBin += ".exe"
199+
binaryName += ".exe"
200200
}
201+
outputBin := filepath.Join(binDir, binaryName)
201202

202-
// Try downloading pre‑built binary first
203-
if downloadBinary(outputBin) {
204-
success("Binary downloaded successfully")
203+
// Option 1: Check if binary exists in current directory (from extracted archive)
204+
if _, err := os.Stat(binaryName); err == nil {
205+
log(fmt.Sprintf("Found %s in current directory, copying to %s...", binaryName, binDir))
206+
if err := copyFile(binaryName, outputBin); err != nil {
207+
fail(fmt.Sprintf("Failed to copy binary: %v", err))
208+
}
209+
if err := os.Chmod(outputBin, 0755); err != nil {
210+
warn(fmt.Sprintf("Could not set executable flag: %v", err))
211+
}
212+
success("Binary installed successfully")
213+
addToPath(binDir)
214+
return
215+
}
216+
217+
// Option 2: Try downloading pre-built archive
218+
if downloadAndExtractBinary(outputBin) {
219+
success("Binary downloaded and installed successfully")
205220
addToPath(binDir)
206221
return
207222
}
208223

209-
// Fallback: build locally if source is present
224+
// Option 3: Fallback to local build if source is present
210225
warn("Download failed – attempting local build from source.")
211-
// Verify source exists
212226
if _, err := os.Stat("./cmd/rag-code-mcp"); err != nil {
213-
fail("Release not found and source code not available. Run installer from repository or create a GitHub release.")
227+
fail("Binary not found. Please download the release archive from:\nhttps://github.com/doITmagic/rag-code-mcp/releases/latest")
214228
}
215229
cmd := exec.Command("go", "build", "-o", outputBin, "./cmd/rag-code-mcp")
216230
cmd.Stdout = os.Stdout
@@ -223,44 +237,101 @@ func installBinary() {
223237
addToPath(binDir)
224238
}
225239

226-
// downloadBinary fetches the installer binary from the latest GitHub release.
227-
func downloadBinary(dest string) bool {
228-
var binaryName string
240+
// copyFile copies a file from src to dst
241+
func copyFile(src, dst string) error {
242+
sourceFile, err := os.Open(src)
243+
if err != nil {
244+
return err
245+
}
246+
defer sourceFile.Close()
247+
248+
destFile, err := os.Create(dst)
249+
if err != nil {
250+
return err
251+
}
252+
defer destFile.Close()
253+
254+
_, err = io.Copy(destFile, sourceFile)
255+
return err
256+
}
257+
258+
// downloadAndExtractBinary fetches the release archive and extracts the binary.
259+
func downloadAndExtractBinary(dest string) bool {
260+
var archiveName string
261+
arch := runtime.GOARCH
229262
switch runtime.GOOS {
230263
case "linux":
231-
binaryName = "ragcode-installer-linux"
264+
archiveName = fmt.Sprintf("rag-code-mcp_linux_%s.tar.gz", arch)
232265
case "darwin":
233-
binaryName = "ragcode-installer-darwin"
266+
archiveName = fmt.Sprintf("rag-code-mcp_darwin_%s.tar.gz", arch)
234267
case "windows":
235-
binaryName = "ragcode-installer-windows.exe"
268+
archiveName = fmt.Sprintf("rag-code-mcp_windows_%s.zip", arch)
236269
default:
237270
return false
238271
}
239-
url := fmt.Sprintf("https://github.com/doITmagic/rag-code-mcp/releases/latest/download/%s", binaryName)
272+
url := fmt.Sprintf("https://github.com/doITmagic/rag-code-mcp/releases/latest/download/%s", archiveName)
240273
log(fmt.Sprintf("Downloading from %s...", url))
274+
241275
resp, err := http.Get(url)
242-
if err != nil || resp.StatusCode != 200 {
243-
if resp != nil && resp.StatusCode == 404 {
276+
if err != nil {
277+
warn(fmt.Sprintf("Failed to download: %v", err))
278+
return false
279+
}
280+
defer resp.Body.Close()
281+
282+
if resp.StatusCode != 200 {
283+
if resp.StatusCode == 404 {
244284
warn("Release not found (404). Skipping download.")
245285
} else {
246-
warn(fmt.Sprintf("Failed to download binary: %v (status %d)", err, resp.StatusCode))
286+
warn(fmt.Sprintf("Download failed with status %d", resp.StatusCode))
247287
}
248288
return false
249289
}
250-
defer resp.Body.Close()
251-
out, err := os.Create(dest)
290+
291+
// Create temp file for archive
292+
tmpFile, err := os.CreateTemp("", "ragcode-*.tar.gz")
293+
if err != nil {
294+
warn(fmt.Sprintf("Could not create temp file: %v", err))
295+
return false
296+
}
297+
defer os.Remove(tmpFile.Name())
298+
defer tmpFile.Close()
299+
300+
if _, err := io.Copy(tmpFile, resp.Body); err != nil {
301+
warn(fmt.Sprintf("Error downloading archive: %v", err))
302+
return false
303+
}
304+
tmpFile.Close()
305+
306+
// Extract binary from archive
307+
binaryName := "rag-code-mcp"
308+
if runtime.GOOS == "windows" {
309+
binaryName += ".exe"
310+
}
311+
312+
if runtime.GOOS == "windows" {
313+
// Handle zip for Windows
314+
warn("Windows archive extraction not yet implemented")
315+
return false
316+
}
317+
318+
// Extract tar.gz
319+
cmd := exec.Command("tar", "-xzf", tmpFile.Name(), "-O", binaryName)
320+
outFile, err := os.Create(dest)
252321
if err != nil {
253-
warn(fmt.Sprintf("Could not create file %s: %v", dest, err))
322+
warn(fmt.Sprintf("Could not create destination file: %v", err))
254323
return false
255324
}
256-
defer out.Close()
257-
if _, err := io.Copy(out, resp.Body); err != nil {
258-
warn(fmt.Sprintf("Error writing binary: %v", err))
325+
defer outFile.Close()
326+
cmd.Stdout = outFile
327+
328+
if err := cmd.Run(); err != nil {
329+
warn(fmt.Sprintf("Failed to extract binary: %v", err))
259330
return false
260331
}
332+
261333
if err := os.Chmod(dest, 0755); err != nil {
262334
warn(fmt.Sprintf("Could not set executable flag: %v", err))
263-
return false
264335
}
265336
return true
266337
}

0 commit comments

Comments
 (0)