UNPKG

@medflyt/test-db-service

Version:

Developer tool to instantly provision test PostgreSQL databases from a template

140 lines 5.46 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.runBinariesJarFileProcess = void 0; const AdmZip = require("adm-zip"); const fs = require("fs"); const promises_1 = require("fs/promises"); const makeDir = require("make-dir"); const path = require("path"); const promisify_child_process_1 = require("promisify-child-process"); const request = require("request"); const tempDir_1 = require("./DownloadUtils/tempDir"); function getBinariesDownloadJarUrl(platform, cpuArch, postgresVersion) { return `https://repo1.maven.org/maven2/io/zonky/test/postgres/embedded-postgres-binaries-${platform}-${cpuArch}/${postgresVersion}/embedded-postgres-binaries-${platform}-${cpuArch}-${postgresVersion}.jar`; } async function runBinariesJarFileProcess(appName, platform, cpuArch, postgresVersion, targetDir) { const url = getBinariesDownloadJarUrl(platform, cpuArch, postgresVersion); const exists = await checkIfLinkExists(url); if (!exists) { throw new Error(`Binary Download of PostgreSQL version ${postgresVersion} not available for ${platform}`); } await makeDir(path.dirname(targetDir)); const extractDir = await promises_1.mkdtemp(targetDir + "-tmp-"); await withTempExtractPostgresTo(appName, url, targetDir, extractDir); } exports.runBinariesJarFileProcess = runBinariesJarFileProcess; async function withTempExtractPostgresTo(appName, url, targetDir, extractDir) { await tempDir_1.withTempDir(appName, async (tmpDir) => { const jarFilePath = path.join(tmpDir, "tmp.jar"); await downloadFileWithRetry(url, jarFilePath); await makeDir(extractDir); console.log("extracting to", extractDir); const jarFile = new AdmZip(jarFilePath); const txzFile = jarFile .getEntries() .find((f) => f.entryName.endsWith(".txz")); if (txzFile === undefined) { throw new Error("No txz file found in jar"); } jarFile.extractEntryTo(txzFile, tmpDir, false, true); const txzFilePath = path.join(tmpDir, txzFile.name); if (url.endsWith(".zip")) { await new Promise((resolve, reject) => { const zip = new AdmZip(txzFilePath); zip.extractAllToAsync(extractDir, true, (err) => { // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/consistent-type-assertions if (err) { reject(err); return; } resolve(); }); }); } else { // Not clear on why this doesn't work. // await tar.x({ // f: txzFilePath, // C: extractDir // }); const result = await promisify_child_process_1.spawn("tar", ["xf", txzFilePath, "-C", extractDir], { stdio: "inherit", encoding: "utf8" }); if (result.code !== 0) { throw new Error(`Failed to extract txz file: ${result.stderr}`); } } try { await new Promise((resolve, reject) => { fs.rename(extractDir, targetDir, (err) => { // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/consistent-type-assertions if (err !== null) { reject(err); return; } resolve(); }); }); } catch (err) { if (err.code === "ENOTEMPTY") { // The target directory already exists. We can ignore, because // it means that some concurrent process was racing us to // install it and finished before us console.log(`Target directory already exists (created by a concurrent process)`); // Cleanup after ourselves: await tempDir_1.rimrafIgnoreErrors(extractDir); } else { throw err; } } }); } async function checkIfLinkExists(url) { try { await request(url, { method: "HEAD" }); return true; } catch (err) { return false; } } function downloadFile(url, filePath) { return new Promise((resolve, reject) => { const stream = request(url).pipe(fs.createWriteStream(filePath)); stream.on("finish", () => { resolve(); }); stream.on("error", (err) => { reject(err); }); }); } async function downloadFileWithRetry(url, filePath) { const MAX_RETRIES = 10; let retryCount = 0; while (true) { try { console.log("Downloading:", url); const result = await downloadFile(url, filePath); return result; } catch (err) { retryCount++; if (retryCount === MAX_RETRIES) { throw err; } console.log("Error downloading:", url); console.log(); console.log(err); console.log(); console.log("Sleeping..."); await delay(10000); } } } function delay(millis) { return new Promise((resolve, _reject) => { setTimeout(resolve, millis); }); } //# sourceMappingURL=download_postgres.js.map