committed by
GitHub
parent
fcaf99ebf6
commit
1b1e186a15
222
scripts/setup-dev-environment.js
Normal file
222
scripts/setup-dev-environment.js
Normal file
@@ -0,0 +1,222 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const net = require("net");
|
||||
|
||||
const PORTS_FILE = path.join(__dirname, "..", ".dev-ports.json");
|
||||
const DEV_ASSETS_SEED = path.join(__dirname, "..", "dev_assets_seed");
|
||||
const DEV_ASSETS = path.join(__dirname, "..", "dev_assets");
|
||||
|
||||
/**
|
||||
* Check if a port is available
|
||||
*/
|
||||
function isPortAvailable(port) {
|
||||
return new Promise((resolve) => {
|
||||
const sock = net.createConnection({ port, host: "localhost" });
|
||||
sock.on("connect", () => {
|
||||
sock.destroy();
|
||||
resolve(false);
|
||||
});
|
||||
sock.on("error", () => resolve(true));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a free port starting from a given port
|
||||
*/
|
||||
async function findFreePort(startPort = 3000) {
|
||||
let port = startPort;
|
||||
while (!(await isPortAvailable(port))) {
|
||||
port++;
|
||||
if (port > 65535) {
|
||||
throw new Error("No available ports found");
|
||||
}
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load existing ports from file
|
||||
*/
|
||||
function loadPorts() {
|
||||
try {
|
||||
if (fs.existsSync(PORTS_FILE)) {
|
||||
const data = fs.readFileSync(PORTS_FILE, "utf8");
|
||||
return JSON.parse(data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("Failed to load existing ports:", error.message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save ports to file
|
||||
*/
|
||||
function savePorts(ports) {
|
||||
try {
|
||||
fs.writeFileSync(PORTS_FILE, JSON.stringify(ports, null, 2));
|
||||
} catch (error) {
|
||||
console.error("Failed to save ports:", error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that saved ports are still available
|
||||
*/
|
||||
async function verifyPorts(ports) {
|
||||
const frontendAvailable = await isPortAvailable(ports.frontend);
|
||||
const backendAvailable = await isPortAvailable(ports.backend);
|
||||
|
||||
if (process.argv[2] === "get" && (!frontendAvailable || !backendAvailable)) {
|
||||
console.log(
|
||||
`Port availability check failed: frontend:${ports.frontend}=${frontendAvailable}, backend:${ports.backend}=${backendAvailable}`
|
||||
);
|
||||
}
|
||||
|
||||
return frontendAvailable && backendAvailable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate ports for development
|
||||
*/
|
||||
async function allocatePorts() {
|
||||
// Try to load existing ports first
|
||||
const existingPorts = loadPorts();
|
||||
|
||||
if (existingPorts) {
|
||||
// Verify existing ports are still available
|
||||
if (await verifyPorts(existingPorts)) {
|
||||
if (process.argv[2] === "get") {
|
||||
console.log("Reusing existing dev ports:");
|
||||
console.log(`Frontend: ${existingPorts.frontend}`);
|
||||
console.log(`Backend: ${existingPorts.backend}`);
|
||||
}
|
||||
return existingPorts;
|
||||
} else {
|
||||
if (process.argv[2] === "get") {
|
||||
console.log(
|
||||
"Existing ports are no longer available, finding new ones..."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find new free ports
|
||||
const frontendPort = await findFreePort(3000);
|
||||
const backendPort = await findFreePort(frontendPort + 1);
|
||||
|
||||
const ports = {
|
||||
frontend: frontendPort,
|
||||
backend: backendPort,
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
|
||||
savePorts(ports);
|
||||
|
||||
if (process.argv[2] === "get") {
|
||||
console.log("Allocated new dev ports:");
|
||||
console.log(`Frontend: ${ports.frontend}`);
|
||||
console.log(`Backend: ${ports.backend}`);
|
||||
}
|
||||
|
||||
return ports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ports (allocate if needed)
|
||||
*/
|
||||
async function getPorts() {
|
||||
const ports = await allocatePorts();
|
||||
copyDevAssets();
|
||||
return ports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy dev_assets_seed to dev_assets
|
||||
*/
|
||||
function copyDevAssets() {
|
||||
try {
|
||||
if (!fs.existsSync(DEV_ASSETS)) {
|
||||
// Copy dev_assets_seed to dev_assets
|
||||
fs.cpSync(DEV_ASSETS_SEED, DEV_ASSETS, { recursive: true });
|
||||
|
||||
if (process.argv[2] === "get") {
|
||||
console.log("Copied dev_assets_seed to dev_assets");
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to copy dev assets:", error.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear saved ports
|
||||
*/
|
||||
function clearPorts() {
|
||||
try {
|
||||
if (fs.existsSync(PORTS_FILE)) {
|
||||
fs.unlinkSync(PORTS_FILE);
|
||||
console.log("Cleared saved dev ports");
|
||||
} else {
|
||||
console.log("No saved ports to clear");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to clear ports:", error.message);
|
||||
}
|
||||
}
|
||||
|
||||
// CLI interface
|
||||
if (require.main === module) {
|
||||
const command = process.argv[2];
|
||||
|
||||
switch (command) {
|
||||
case "get":
|
||||
getPorts()
|
||||
.then((ports) => {
|
||||
console.log(JSON.stringify(ports));
|
||||
})
|
||||
.catch(console.error);
|
||||
break;
|
||||
|
||||
case "clear":
|
||||
clearPorts();
|
||||
break;
|
||||
|
||||
case "frontend":
|
||||
getPorts()
|
||||
.then((ports) => {
|
||||
console.log(ports.frontend);
|
||||
})
|
||||
.catch(console.error);
|
||||
break;
|
||||
|
||||
case "backend":
|
||||
getPorts()
|
||||
.then((ports) => {
|
||||
console.log(ports.backend);
|
||||
})
|
||||
.catch(console.error);
|
||||
break;
|
||||
|
||||
default:
|
||||
console.log("Usage:");
|
||||
console.log(
|
||||
" node setup-dev-environment.js get - Setup dev environment (ports + assets)"
|
||||
);
|
||||
console.log(
|
||||
" node setup-dev-environment.js frontend - Get frontend port only"
|
||||
);
|
||||
console.log(
|
||||
" node setup-dev-environment.js backend - Get backend port only"
|
||||
);
|
||||
console.log(
|
||||
" node setup-dev-environment.js clear - Clear saved ports"
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { getPorts, clearPorts, findFreePort };
|
||||
Reference in New Issue
Block a user