Skip to content

Commit

Permalink
Version 4.2.0 (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
Eric Kim-Butler committed Oct 30, 2023
1 parent b1e43e9 commit 2ba0575
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 59 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Changelog

## [4.2.0](https://github.com/notarize/qlc/compare/4.1.0...4.2.0)

### Bugfixes

- Cleanly exit from NPM post-install script

### Chores

- Upgrade to Rust 1.73.0
- Upgrade dependencies (including security fix)

## [4.1.0](https://github.com/notarize/qlc/compare/4.0.0...4.1.0)

### Features
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "qlc"
version = "4.1.0"
version = "4.2.0"
authors = ["Eric Kim-Butler <eric.butler@notarize.com>"]
edition = "2021"
license = "MIT"
Expand Down
104 changes: 47 additions & 57 deletions pkg/npm/lib/postinstall.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
"use strict";

const os = require("os");
const fs = require("fs");
const { platform, arch } = require("os");
const { createWriteStream } = require("fs");
const { mkdir, unlink, chmod, readFile, access } = require("fs/promises");
const url = require("url");
const https = require("https");
const path = require("path");
const util = require("util");
const crypto = require("crypto");
const childProc = require("child_process");

const fsChmod = util.promisify(fs.chmod);
const fsUnlink = util.promisify(fs.unlink);
const fsExists = util.promisify(fs.exists);
const fsReadFile = util.promisify(fs.readFile);
const mkdir = util.promisify(fs.mkdir);
const { get: httpsGet } = require("https");
const { join } = require("path");
const { createHash } = require("crypto");
const { spawn } = require("child_process");

const {
version: VERSION,
checksumConfig: CHECKSUMS,
} = require("../package.json");
const BIN_PATH = path.join(__dirname, "../bin");
const BIN_PATH = join(__dirname, "../bin");

function getTarget() {
const id = `${os.platform()}-${os.arch()}`;
const id = `${platform()}-${arch()}`;
switch (id) {
case "darwin-x64":
return "x86_64-apple-darwin";
Expand All @@ -39,48 +33,45 @@ function getTarget() {

function download(fullUrl, dest) {
return new Promise((resolve, reject) => {
const outFile = fs.createWriteStream(dest);
const cleanup = (err) =>
fsUnlink(dest)
unlink(dest)
.catch(console.error)
.finally(() => {
reject(err);
});
const opts = {
...url.parse(fullUrl),
timeout: 20000,
headers: { Accept: "application/octet-stream" },
};
https
.get(opts, (response) => {
if (response.statusCode === 302) {
httpsGet(opts, (response) => {
switch (response.statusCode) {
case 200:
return response.pipe(createWriteStream(dest).on("finish", resolve));
case 302:
return download(response.headers.location, dest)
.then(resolve)
.catch(reject);
} else if (response.statusCode !== 200) {
default:
return cleanup(
new Error(`Download failed with ${response.statusCode}`)
new Error(`Download failed with ${response.statusCode}`),
);
}
response.pipe(outFile);
outFile.on("finish", () => {
resolve();
});
})
.on("error", cleanup);
}
})
.on("error", cleanup)
.end();
});
}

function untar(zipPath, destDir) {
return new Promise((resolve, reject) => {
const unzipProc = childProc.spawn("tar", ["xf", zipPath, "-C", destDir], {
stdio: "inherit",
});
unzipProc.on("error", reject);
unzipProc.on("close", (code) => {
return code === 0
? resolve()
: reject(new Error(`tar exited with ${code}`));
});
spawn("tar", ["xf", zipPath, "-C", destDir], { stdio: "inherit" })
.on("error", reject)
.on("close", (code) => {
return code === 0
? resolve()
: reject(new Error(`tar exited with ${code}`));
});
});
}

Expand All @@ -89,42 +80,41 @@ async function checksum(tarballPath, target) {
if (!expected) {
throw new Error(`Missing checksum for ${target}`);
}
const actual = crypto
.createHash("sha256")
.update(await fsReadFile(tarballPath))
const actual = createHash("sha256")
.update(await readFile(tarballPath))
.digest("hex");
if (expected !== actual) {
throw new Error(
`Checksum integrity check failed: expected ${expected}, got ${actual}`
`Checksum integrity check failed: expected ${expected}, got ${actual}`,
);
}
return actual;
}

async function main() {
const target = getTarget();
const fileName = `qlc-${VERSION}-${target}.tar.gz`;
const url = `https://github.com/notarize/qlc/releases/download/${VERSION}/${fileName}`;
const tarballFileName = `qlc-${VERSION}-${target}.tar.gz`;
const url = `https://github.com/notarize/qlc/releases/download/${VERSION}/${tarballFileName}`;
await Promise.all([
fsExists(BIN_PATH).then((exists) => {
return exists ? Promise.resolve() : mkdir(BIN_PATH);
}),
download(url, fileName),
access(BIN_PATH).catch(() => mkdir(BIN_PATH)),
download(url, tarballFileName),
]);
try {
await checksum(fileName, target);
await checksum(tarballFileName, target);
} catch (error) {
await fsUnlink(fileName);
await unlink(tarballFileName);
throw error;
}
await untar(fileName, BIN_PATH);
await untar(tarballFileName, BIN_PATH);
await Promise.all([
fsUnlink(fileName),
fsChmod(path.join(BIN_PATH, "qlc"), "755"),
unlink(tarballFileName),
chmod(join(BIN_PATH, "qlc"), "755"),
]);
}

main().catch((err) => {
console.error(`Unhandled error: ${err}`);
process.exit(1);
});
main()
.then(() => process.exit(0))
.catch((err) => {
console.error(`Unhandled error: ${err}`);
process.exit(1);
});

0 comments on commit 2ba0575

Please sign in to comment.