Files
hapi/cli/scripts/unpack-tools.ts

116 lines
3.5 KiB
TypeScript

import { chmodSync, existsSync, mkdirSync, readdirSync, statSync } from 'node:fs';
import { dirname, join, resolve } from 'node:path';
import { arch, platform } from 'node:os';
import { fileURLToPath } from 'node:url';
import * as tar from 'tar';
export function getPlatformDir(): string {
const platformName = platform();
const archName = arch();
if (platformName === 'darwin') {
if (archName === 'arm64') return 'arm64-darwin';
if (archName === 'x64') return 'x64-darwin';
} else if (platformName === 'linux') {
if (archName === 'arm64') return 'arm64-linux';
if (archName === 'x64') return 'x64-linux';
} else if (platformName === 'win32') {
if (archName === 'x64') return 'x64-win32';
}
throw new Error(`Unsupported platform: ${archName}-${platformName}`);
}
export function getToolsDir(): string {
const scriptDir = dirname(fileURLToPath(import.meta.url));
return resolve(scriptDir, '..', 'tools');
}
function areToolsUnpacked(toolsDir: string): boolean {
const unpackedPath = join(toolsDir, 'unpacked');
if (!existsSync(unpackedPath)) {
return false;
}
const isWin = platform() === 'win32';
const difftBinary = isWin ? 'difft.exe' : 'difft';
const rgBinary = isWin ? 'rg.exe' : 'rg';
const expectedFiles = [
join(unpackedPath, difftBinary),
join(unpackedPath, rgBinary)
];
return expectedFiles.every((file) => existsSync(file));
}
function unpackArchive(archivePath: string, destDir: string): void {
if (!existsSync(destDir)) {
mkdirSync(destDir, { recursive: true });
}
tar.extract({
file: archivePath,
cwd: destDir,
sync: true,
gzip: true,
preserveMode: true,
preserveOwner: false
});
}
export function unpackTools(): { success: true; alreadyUnpacked: boolean } {
const platformDir = getPlatformDir();
const toolsDir = getToolsDir();
const archivesDir = join(toolsDir, 'archives');
const unpackedPath = join(toolsDir, 'unpacked');
if (areToolsUnpacked(toolsDir)) {
console.log(`Tools already unpacked for ${platformDir}`);
return { success: true, alreadyUnpacked: true };
}
console.log(`Unpacking tools for ${platformDir}...`);
if (!existsSync(unpackedPath)) {
mkdirSync(unpackedPath, { recursive: true });
}
const archives = [
`difftastic-${platformDir}.tar.gz`,
`ripgrep-${platformDir}.tar.gz`
];
for (const archiveName of archives) {
const archivePath = join(archivesDir, archiveName);
if (!existsSync(archivePath)) {
throw new Error(`Archive not found: ${archivePath}`);
}
unpackArchive(archivePath, unpackedPath);
}
if (platform() !== 'win32') {
const files = readdirSync(unpackedPath);
for (const file of files) {
const filePath = join(unpackedPath, file);
const stats = statSync(filePath);
if (stats.isFile() && !file.endsWith('.node')) {
chmodSync(filePath, 0o755);
}
}
}
console.log(`Tools unpacked successfully to ${unpackedPath}`);
return { success: true, alreadyUnpacked: false };
}
if (import.meta.main) {
try {
unpackTools();
process.exit(0);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
console.error('Failed to unpack tools:', message);
process.exit(1);
}
}