]> git.immae.eu Git - github/fretlink/node-dhall-json-bin.git/blame - preinstall.js
Merge pull request #3 from cyrilfretlink/yaml-to-dhall-upper-bound
[github/fretlink/node-dhall-json-bin.git] / preinstall.js
CommitLineData
a4e6dec5
CS
1"use strict";
2
03aaa7d3
CS
3const fs = require("fs");
4const path = require("path");
5
a4e6dec5 6const { https } = require("follow-redirects");
6337a3be 7const semver = require("semver");
a4e6dec5
CS
8const tar = require("tar");
9const unbz2 = require("unbzip2-stream");
03aaa7d3 10const unzipper = require("unzipper");
a4e6dec5
CS
11
12const pkg = require("./package.json");
03aaa7d3 13const bindir = path.join(__dirname, "bin");
a4e6dec5 14
38da8e9a
CS
15const formatVersionKey = name =>
16 `${name}-version`;
17const toSnakeCase = name =>
18 name.replace(/-/g, '_');
19const formatNpmCfgVar = name =>
20 toSnakeCase(name.toLowerCase());
21const formatEnvVar = name =>
22 toSnakeCase(name.toUpperCase());
23const prefixNpmCfgKey = key =>
24 `${pkg.name}:${key}`;
a4e6dec5 25
38da8e9a
CS
26const readVersionWith = (lookup, discard = () => {}) => name => {
27 const key = formatVersionKey(name);
28 const version = lookup(key);
29 return version ? {
30 get version() { return String(version).trim() },
31 discard() { discard(key, version) },
32 orElse(alt) { alt.discard(); return this }
33 } : {
34 get version() {
35 throw new Error(`Missing \`${name}\` version! You can provide it as a \`${prefixNpmCfgKey(key)}\` npm configuration parameter or as a \`${formatEnvVar(key)}\` environment variable.`);
36 },
37 discard() {},
38 orElse(alt) { return alt }
39 };
40};
a4e6dec5 41
38da8e9a
CS
42const readPkgVersion = readVersionWith(key => pkg[key]);
43const readCfgVersion = readVersionWith(key => {
44 return process.env[`npm_config_${formatNpmCfgVar(pkg.name)}_${formatNpmCfgVar(key)}`];
45}, (key, version) => {
46 console.warn(`Ignoring \`${prefixNpmCfgKey(key)}\` npm configuration parameter (${version}).`);
47});
48const readEnvVersion = readVersionWith(key => {
49 return process.env[formatEnvVar(key)];
50}, (key, version) => {
51 console.warn(`Ignoring \`${formatEnvVar(key)}\` environment variable (${version}).`);
52});
53
54const readVersion = name =>
55 readPkgVersion(name)
56 .orElse(readEnvVersion(name))
57 .orElse(readCfgVersion(name))
58 .version;
59
60const dhallVersion = readVersion("dhall");
61const dhallJsonVersion = readVersion("dhall-json");
17386afd 62
41d2f5f5 63const isLesserThan = (version, upperBound) =>
17386afd 64 semver.valid(version) && semver.lt(version, upperBound);
41d2f5f5
CS
65const isGreaterThan = (version, lowerBound) =>
66 semver.valid(version) && semver.gt(version, lowerBound);
17386afd 67
41d2f5f5 68if (isLesserThan(dhallJsonVersion, "1.2.8")) {
6337a3be
CS
69 throw new Error(`This release of the \`${pkg.name}\` npm package installs \`json-to-dhall\`, which isn’t provided by \`dhall-json@<1.2.8\`.`);
70}
41d2f5f5
CS
71if (isLesserThan(dhallJsonVersion, "1.3.0") || isGreaterThan(dhallJsonVersion, "1.5.0")) {
72 throw new Error(`This release of the \`${pkg.name}\` npm package installs \`yaml-to-dhall\`, which isn’t provided by \`dhall-json@<1.3.0 >1.5.0\`.`);
17386afd 73}
a4e6dec5
CS
74
75const release = `https://github.com/dhall-lang/dhall-haskell/releases/download/${dhallVersion}/dhall-json-${dhallJsonVersion}`;
76
03aaa7d3
CS
77const get = (archive, callback) => {
78 const url = `${release}-${archive}`;
79 return https.get(url, res => {
80 if (res.statusCode >= 400) throw new Error(`Error fetching ${url}: ${res.statusMessage}`);
81 return callback(res);
82 });
83};
84
85if (process.platform === "win32") {
86 get("x86_64-windows.zip", res =>
87 res.pipe(unzipper.Extract({ path: bindir }))
88 );
89} else {
045515b2
CS
90 const isDarwin = process.platform === 'darwin';
91
41d2f5f5 92 if (isDarwin && isLesserThan(dhallJsonVersion, "1.4.0")) {
045515b2
CS
93 throw new Error(`Static macOS binaries aren’t provided by \`dhall-json@<1.4.0\`.`);
94 }
95
96 get(`x86_64-${isDarwin ? 'macos' : 'linux'}.tar.bz2`, res =>
03aaa7d3
CS
97 res.pipe(unbz2()).pipe(tar.x({ C: __dirname }).on("finish", () => {
98 fs.readdir(bindir, (err, names) => {
99 if (err) throw err;
100 for (const name of names) {
101 fs.rename(path.join(bindir, name), path.join(bindir, name + ".exe"), err => {
102 if (err) throw err;
103 });
104 }
105 });
106 }))
107 );
108}