feat(core): Initial project scaffold and implementation: Deno CLI, ISO tooling, cloud-init generation, packaging and installer scripts
This commit is contained in:
144
scripts/install-binary.js
Normal file
144
scripts/install-binary.js
Normal file
@@ -0,0 +1,144 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* npm postinstall script
|
||||
* Downloads the correct binary for the current platform
|
||||
*/
|
||||
|
||||
import { createWriteStream, chmodSync, existsSync, mkdirSync } from 'fs';
|
||||
import { dirname, join } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { get as httpsGet } from 'https';
|
||||
import { get as httpGet } from 'http';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
const rootDir = join(__dirname, '..');
|
||||
|
||||
const REPO_URL = 'https://code.foss.global/serve.zone/isocreator';
|
||||
const VERSION = '1.0.0'; // Will be updated automatically
|
||||
|
||||
// Detect platform and architecture
|
||||
const platformMap = {
|
||||
darwin: 'macos',
|
||||
linux: 'linux',
|
||||
win32: 'windows',
|
||||
};
|
||||
|
||||
const archMap = {
|
||||
x64: 'x64',
|
||||
arm64: 'arm64',
|
||||
};
|
||||
|
||||
const platform = platformMap[process.platform];
|
||||
const arch = archMap[process.arch];
|
||||
|
||||
if (!platform || !arch) {
|
||||
console.error(`❌ Unsupported platform: ${process.platform}-${process.arch}`);
|
||||
console.error('Supported platforms: linux-x64, linux-arm64, darwin-x64, darwin-arm64, win32-x64');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const ext = platform === 'windows' ? '.exe' : '';
|
||||
const binaryName = `isocreator-${platform}-${arch}${ext}`;
|
||||
const binaryDir = join(rootDir, 'dist', 'binaries');
|
||||
const binaryPath = join(binaryDir, binaryName);
|
||||
|
||||
// Create directory if it doesn't exist
|
||||
if (!existsSync(binaryDir)) {
|
||||
mkdirSync(binaryDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Try release URL first, fallback to raw branch
|
||||
const urls = [
|
||||
`${REPO_URL}/releases/download/v${VERSION}/${binaryName}`,
|
||||
`${REPO_URL}/raw/branch/main/dist/binaries/${binaryName}`,
|
||||
];
|
||||
|
||||
console.log(`📦 Installing isocreator for ${platform}-${arch}...`);
|
||||
|
||||
function downloadFile(url, attempt = 1) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const protocol = url.startsWith('https') ? httpsGet : httpGet;
|
||||
|
||||
console.log(`⬇️ Downloading from: ${url}`);
|
||||
|
||||
protocol(url, { timeout: 30000 }, (response) => {
|
||||
// Handle redirects
|
||||
if (response.statusCode === 301 || response.statusCode === 302) {
|
||||
const redirectUrl = response.headers.location;
|
||||
console.log(`↪️ Redirecting to: ${redirectUrl}`);
|
||||
return downloadFile(redirectUrl, attempt).then(resolve).catch(reject);
|
||||
}
|
||||
|
||||
if (response.statusCode !== 200) {
|
||||
console.warn(`⚠️ Failed to download (HTTP ${response.statusCode})`);
|
||||
|
||||
if (attempt < urls.length) {
|
||||
console.log(`🔄 Trying fallback URL (${attempt + 1}/${urls.length})...`);
|
||||
return downloadFile(urls[attempt], attempt + 1).then(resolve).catch(reject);
|
||||
}
|
||||
|
||||
return reject(new Error(`Failed to download binary from all sources`));
|
||||
}
|
||||
|
||||
const file = createWriteStream(binaryPath);
|
||||
const totalBytes = parseInt(response.headers['content-length'], 10);
|
||||
let downloadedBytes = 0;
|
||||
|
||||
response.on('data', (chunk) => {
|
||||
downloadedBytes += chunk.length;
|
||||
if (totalBytes) {
|
||||
const percent = ((downloadedBytes / totalBytes) * 100).toFixed(1);
|
||||
process.stdout.write(`\r📥 Progress: ${percent}%`);
|
||||
}
|
||||
});
|
||||
|
||||
response.pipe(file);
|
||||
|
||||
file.on('finish', () => {
|
||||
file.close();
|
||||
console.log('\n✅ Download complete!');
|
||||
|
||||
// Make executable on Unix-like systems
|
||||
if (platform !== 'windows') {
|
||||
try {
|
||||
chmodSync(binaryPath, 0o755);
|
||||
console.log('✅ Binary made executable');
|
||||
} catch (err) {
|
||||
console.warn('⚠️ Failed to make binary executable:', err.message);
|
||||
}
|
||||
}
|
||||
|
||||
resolve();
|
||||
});
|
||||
|
||||
file.on('error', (err) => {
|
||||
file.close();
|
||||
reject(err);
|
||||
});
|
||||
}).on('error', (err) => {
|
||||
if (attempt < urls.length) {
|
||||
console.warn(`⚠️ Download failed:`, err.message);
|
||||
console.log(`🔄 Trying fallback URL (${attempt + 1}/${urls.length})...`);
|
||||
downloadFile(urls[attempt], attempt + 1).then(resolve).catch(reject);
|
||||
} else {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Start download
|
||||
downloadFile(urls[0], 1)
|
||||
.then(() => {
|
||||
console.log('🎉 isocreator installed successfully!');
|
||||
console.log(`\n💡 Try running: isocreator --help`);
|
||||
process.exit(0);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('\n❌ Installation failed:', err.message);
|
||||
console.error('\nYou can try manual installation:');
|
||||
console.error(` curl -sSL ${REPO_URL}/raw/branch/main/install.sh | sudo bash`);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user