mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-02-19 23:25:51 -05:00
This commit modifies the daemon startup logic to check if the daemon is already running before attempting to build it. If the daemon is active, the build process is skipped, and the existing instance is used. This change improves efficiency by avoiding unnecessary builds and enhances the user experience during development. Additionally, the build process logging has been retained for clarity when a build is performed.
202 lines
6.3 KiB
TypeScript
Executable File
202 lines
6.3 KiB
TypeScript
Executable File
#!/usr/bin/env bun
|
|
|
|
/**
|
|
* Development script that:
|
|
* 1. Builds the daemon (dev profile)
|
|
* 2. Starts the daemon
|
|
* 3. Waits for it to be ready
|
|
* 4. Starts Vite dev server
|
|
* 5. Cleans up daemon on exit
|
|
*/
|
|
|
|
import { spawn } from "child_process";
|
|
import { existsSync, unlinkSync } from "fs";
|
|
import { join, resolve, dirname } from "path";
|
|
import { homedir, platform } from "os";
|
|
import { fileURLToPath } from "url";
|
|
|
|
// Get script directory
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = dirname(__filename);
|
|
|
|
// Detect Platform
|
|
const IS_WIN = platform() === "win32";
|
|
|
|
// Paths relative to this script (apps/tauri/scripts/)
|
|
// Script is at: PROJECT_ROOT/apps/tauri/scripts/
|
|
// So PROJECT_ROOT is: ../../../
|
|
const PROJECT_ROOT = resolve(__dirname, "../../../");
|
|
|
|
// FIX: Add .exe extension if on Windows
|
|
const BIN_NAME = IS_WIN ? "sd-daemon.exe" : "sd-daemon";
|
|
const DAEMON_BIN = join(PROJECT_ROOT, "target/debug", BIN_NAME);
|
|
|
|
const DAEMON_PORT = 6969;
|
|
const DAEMON_ADDR = `127.0.0.1:${DAEMON_PORT}`;
|
|
|
|
// Fix Data Directory for Windows (Optional but recommended)
|
|
const DATA_DIR = IS_WIN
|
|
? join(homedir(), "AppData/Roaming/spacedrive")
|
|
: join(homedir(), "Library/Application Support/spacedrive");
|
|
|
|
let daemonProcess: any = null;
|
|
let viteProcess: any = null;
|
|
let startedDaemon = false;
|
|
|
|
// Cleanup function
|
|
function cleanup() {
|
|
console.log("\nCleaning up...");
|
|
|
|
if (viteProcess) {
|
|
console.log("Stopping Vite...");
|
|
viteProcess.kill();
|
|
}
|
|
|
|
if (daemonProcess && startedDaemon) {
|
|
console.log("Stopping daemon (started by us)...");
|
|
daemonProcess.kill();
|
|
} else if (!startedDaemon) {
|
|
console.log("Leaving existing daemon running...");
|
|
}
|
|
|
|
process.exit(0);
|
|
}
|
|
|
|
// Handle signals
|
|
process.on("SIGINT", cleanup);
|
|
process.on("SIGTERM", cleanup);
|
|
|
|
async function main() {
|
|
// Check if daemon is already running by trying to connect to TCP port
|
|
let daemonAlreadyRunning = false;
|
|
console.log(`Checking if daemon is running on ${DAEMON_ADDR}...`);
|
|
try {
|
|
const { connect } = await import("net");
|
|
await new Promise<void>((resolve, reject) => {
|
|
const client = connect(DAEMON_PORT, "127.0.0.1");
|
|
client.on("connect", () => {
|
|
daemonAlreadyRunning = true;
|
|
client.end();
|
|
resolve();
|
|
});
|
|
client.on("error", () => {
|
|
reject();
|
|
});
|
|
setTimeout(() => reject(), 1000);
|
|
});
|
|
} catch (e) {
|
|
// Connection failed, daemon not running
|
|
daemonAlreadyRunning = false;
|
|
}
|
|
|
|
if (daemonAlreadyRunning) {
|
|
console.log("Daemon already running, skipping build and using existing instance");
|
|
startedDaemon = false;
|
|
} else {
|
|
console.log("Building daemon (dev profile)...");
|
|
console.log("Project root:", PROJECT_ROOT);
|
|
console.log("Daemon binary:", DAEMON_BIN);
|
|
|
|
// Build daemon
|
|
// On Windows, the binary target name is still just "sd-daemon" (Cargo handles the .exe)
|
|
const build = spawn("cargo", ["build", "--bin", "sd-daemon"], {
|
|
cwd: PROJECT_ROOT,
|
|
stdio: "inherit",
|
|
shell: IS_WIN, // shell: true is often needed on Windows for spawn to work correctly
|
|
});
|
|
|
|
await new Promise<void>((resolve, reject) => {
|
|
build.on("exit", (code) => {
|
|
if (code === 0) {
|
|
resolve();
|
|
} else {
|
|
reject(new Error(`Daemon build failed with code ${code}`));
|
|
}
|
|
});
|
|
});
|
|
|
|
console.log("Daemon built successfully");
|
|
// Start daemon
|
|
console.log("Starting daemon...");
|
|
startedDaemon = true;
|
|
|
|
// Verify binary exists
|
|
if (!existsSync(DAEMON_BIN)) {
|
|
throw new Error(`Daemon binary not found at: ${DAEMON_BIN}`);
|
|
}
|
|
|
|
const depsLibPath = join(PROJECT_ROOT, "apps/.deps/lib");
|
|
const depsBinPath = join(PROJECT_ROOT, "apps/.deps/bin");
|
|
|
|
daemonProcess = spawn(DAEMON_BIN, ["--data-dir", DATA_DIR], {
|
|
cwd: PROJECT_ROOT,
|
|
stdio: ["ignore", "pipe", "pipe"],
|
|
env: {
|
|
...process.env,
|
|
// macOS library path
|
|
DYLD_LIBRARY_PATH: depsLibPath,
|
|
// Windows: Add DLLs directory to PATH
|
|
PATH: IS_WIN
|
|
? `${depsBinPath};${process.env.PATH || ""}`
|
|
: process.env.PATH,
|
|
},
|
|
});
|
|
|
|
// Log daemon output
|
|
daemonProcess.stdout.on("data", (data: Buffer) => {
|
|
const lines = data.toString().trim().split("\n");
|
|
for (const line of lines) {
|
|
console.log(`[daemon] ${line}`);
|
|
}
|
|
});
|
|
|
|
daemonProcess.stderr.on("data", (data: Buffer) => {
|
|
const lines = data.toString().trim().split("\n");
|
|
for (const line of lines) {
|
|
console.log(`[daemon] ${line}`);
|
|
}
|
|
});
|
|
|
|
// Wait for daemon to be ready
|
|
console.log("Waiting for daemon to be ready...");
|
|
for (let i = 0; i < 30; i++) {
|
|
try {
|
|
const { connect } = await import("net");
|
|
await new Promise<void>((resolve, reject) => {
|
|
const client = connect(DAEMON_PORT, "127.0.0.1");
|
|
client.on("connect", () => {
|
|
client.end();
|
|
resolve();
|
|
});
|
|
client.on("error", reject);
|
|
setTimeout(() => reject(), 500);
|
|
});
|
|
console.log(`Daemon ready at ${DAEMON_ADDR}`);
|
|
break;
|
|
} catch (e) {
|
|
if (i === 29) {
|
|
throw new Error("Daemon failed to start (connection not available)");
|
|
}
|
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Start Vite
|
|
console.log("Starting Vite dev server...");
|
|
|
|
// Use 'bun' explicitly, with shell true for Windows compatibility
|
|
viteProcess = spawn("bun", ["run", "dev"], {
|
|
stdio: "inherit",
|
|
shell: IS_WIN,
|
|
});
|
|
|
|
// Keep running
|
|
await new Promise(() => {});
|
|
}
|
|
|
|
main().catch((error) => {
|
|
console.error("Error:", error);
|
|
cleanup();
|
|
process.exit(1);
|
|
}); |