Files
seedit/electron/before-pack.js
Tom (plebeius.eth) 0767774c86 Update before-pack.js
2025-05-21 14:53:50 +02:00

161 lines
5.9 KiB
JavaScript
Executable File

// download the ipfs binaries before building the electron clients
import fs from 'fs-extra';
import ProgressBar from 'progress';
import https from 'https';
import decompress from 'decompress';
import path from 'path';
import { fileURLToPath } from 'url';
const ipfsClientsPath = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'bin');
const ipfsClientWindowsPath = path.join(ipfsClientsPath, 'win');
const ipfsClientMacPath = path.join(ipfsClientsPath, 'mac');
const ipfsClientLinuxPath = path.join(ipfsClientsPath, 'linux');
// plebbit kubu download links https://github.com/plebbit/kubo/releases
// const ipfsClientVersion = '0.20.0'
// const ipfsClientWindowsUrl = `https://github.com/plebbit/kubo/releases/download/v${ipfsClientVersion}/ipfs-windows-amd64`
// const ipfsClientMacUrl = `https://github.com/plebbit/kubo/releases/download/v${ipfsClientVersion}/ipfs-darwin-amd64`
// const ipfsClientLinuxUrl = `https://github.com/plebbit/kubo/releases/download/v${ipfsClientVersion}/ipfs-linux-amd64`
// official kubo download links https://docs.ipfs.tech/install/command-line/#install-official-binary-distributions
const ipfsClientVersion = '0.32.1';
const ipfsClientWindowsUrl = `https://dist.ipfs.io/kubo/v${ipfsClientVersion}/kubo_v${ipfsClientVersion}_windows-amd64.zip`;
const ipfsClientMacUrl = `https://dist.ipfs.io/kubo/v${ipfsClientVersion}/kubo_v${ipfsClientVersion}_darwin-amd64.tar.gz`;
const ipfsClientLinuxUrl = `https://dist.ipfs.io/kubo/v${ipfsClientVersion}/kubo_v${ipfsClientVersion}_linux-amd64.tar.gz`;
const downloadWithProgress = (url) =>
new Promise((resolve, reject) => {
const split = url.split('/');
const fileName = split[split.length - 1];
const chunks = [];
const req = https.request(url);
req.on('error', (err) => {
console.error(`Error making request for ${url}:`, err);
reject(err);
});
req.on('response', (res) => {
res.on('error', (err) => {
console.error(`Error in response for ${url}:`, err);
reject(err);
});
// handle redirects
if (res.statusCode == 301 || res.statusCode === 302) {
resolve(downloadWithProgress(res.headers.location));
return;
}
const len = parseInt(res.headers['content-length'], 10);
console.log();
const bar = new ProgressBar(` ${fileName} [:bar] :rate/bps :percent :etas`, {
complete: '=',
incomplete: ' ',
width: 20,
total: len,
stream: process.stdout,
});
res.on('data', (chunk) => {
chunks.push(chunk);
bar.tick(chunk.length);
});
res.on('end', () => {
console.log('\n');
resolve(Buffer.concat(chunks));
});
});
req.end();
});
// add retry wrapper around downloadWithProgress to handle transient network errors
const downloadWithRetry = async (url, retries = 3) => {
for (let attempt = 1; attempt <= retries; attempt++) {
try {
return await downloadWithProgress(url);
} catch (err) {
console.warn(`Download attempt ${attempt} for ${url} failed:`, err);
if (attempt === retries) throw err;
// wait before retrying
await new Promise((res) => setTimeout(res, attempt * 1000));
}
}
};
// plebbit kubo downloads dont need to be extracted
const download = async (url, destinationPath) => {
let binName = 'ipfs';
if (destinationPath.endsWith('win')) {
binName += '.exe';
}
const binPath = path.join(destinationPath, binName);
// already downloaded, don't download again
if (fs.pathExistsSync(binPath)) {
return;
}
const split = url.split('/');
const fileName = split[split.length - 1];
const downloadPath = path.join(destinationPath, fileName);
const file = await downloadWithRetry(url);
fs.ensureDirSync(destinationPath);
await fs.writeFile(binPath, file);
};
// official kubo downloads need to be extracted
const downloadAndExtract = async (url, destinationPath) => {
let binName = 'ipfs';
if (destinationPath.endsWith('win')) {
binName += '.exe';
}
const binPath = path.join(destinationPath, binName);
if (fs.pathExistsSync(binPath)) {
return;
}
console.log(`Downloading IPFS client from ${url} to ${destinationPath}`);
const split = url.split('/');
const fileName = split[split.length - 1];
const downloadPath = path.join(destinationPath, fileName);
const file = await downloadWithRetry(url);
fs.ensureDirSync(destinationPath);
await fs.writeFile(downloadPath, file);
console.log(`Downloaded archive to ${downloadPath}`);
console.log(`Extracting ${downloadPath} to ${destinationPath}`);
try {
await decompress(downloadPath, destinationPath);
console.log('Decompression complete');
} catch (err) {
console.error('Error during decompression:', err);
throw err;
}
const extractedPath = path.join(destinationPath, 'kubo');
const extractedBinPath = path.join(extractedPath, binName);
console.log(`Moving binary from ${extractedBinPath} to ${binPath}`);
fs.moveSync(extractedBinPath, binPath);
console.log('Binary moved');
console.log('Cleaning up temporary files');
fs.removeSync(downloadPath);
console.log('Cleanup complete');
};
export const downloadIpfsClients = async () => {
const platform = process.platform;
console.log(`Starting IPFS client download for platform: ${platform}`);
switch (platform) {
case 'win32':
await downloadAndExtract(ipfsClientWindowsUrl, ipfsClientWindowsPath);
break;
case 'darwin':
await downloadAndExtract(ipfsClientMacUrl, ipfsClientMacPath);
break;
case 'linux':
await downloadAndExtract(ipfsClientLinuxUrl, ipfsClientLinuxPath);
break;
default:
console.warn(`Unknown platform: ${platform}, downloading all IPFS clients`);
await downloadAndExtract(ipfsClientWindowsUrl, ipfsClientWindowsPath);
await downloadAndExtract(ipfsClientMacUrl, ipfsClientMacPath);
await downloadAndExtract(ipfsClientLinuxUrl, ipfsClientLinuxPath);
}
};
export default async (context) => {
await downloadIpfsClients();
};