-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathpostinstall.js
executable file
·91 lines (77 loc) · 3.41 KB
/
postinstall.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/env node
const https = require('https')
, fs = require('fs')
, path = require('path')
, crypto = require('crypto')
, tar = require('tar')
const getUrl = (version, dist_name) => `https://github.com/bwt-dev/libbwt/releases/download/v${version}/${dist_name}.tar.gz`
const getDistName = (version, platform, variant) => `libbwt-${version}-${variant?variant+'-':''}${platform}`
if (!process.env.BWT_NO_DOWNLOAD) {
download(require('./package.json').version, process.env.BWT_VARIANT)
.catch(err => console.error(`[bwt] Failed! ${err}`))
}
// Fetch the shared library file from GitHub releases and verify its hash
async function download(version, variant=null) {
const { platform, libname } = getPlatform()
, dist_name = getDistName(version, platform, variant)
, release_url = getUrl(version, dist_name)
, temp_path = path.join(__dirname, `__${dist_name}__temp${Math.random()*99999|0}.tar.gz`)
, target = path.join(__dirname, libname)
, hash = getExpectedHash(dist_name)
if (fs.existsSync(target) && !process.env.BWT_FORCE && !process.env.BWT_VARIANT) {
console.error(`[bwt] Skipping download, ${target} found`)
return
}
console.log(`[bwt] Downloading ${dist_name} from ${release_url}`)
const actual_hash = await getFile(release_url, temp_path)
if (actual_hash != hash) {
throw new Error(`Hash mismatch for ${temp_path} downloaded from ${release_url}, expected ${hash}, found ${actual_hash}`)
}
console.log(`[bwt] Verified SHA256(${dist_name}.tar.gz) == ${hash}`)
await tar.extract({ file: temp_path, cwd: __dirname, strip: 1 }, [ `${dist_name}/${libname}` ])
console.log(`[bwt] Extracted to ${path.join(__dirname, libname)}`)
fs.unlinkSync(temp_path)
}
// Download the file while stream-hashing its contents
async function getFile(url, dest) {
return new Promise((resolve, reject) => {
const options = { headers: { 'user-agent': 'libbwt' } }
https.get(url, options, resp => {
if (resp.statusCode == 302) {
return getFile(resp.headers.location, dest).then(resolve, reject)
} else if (resp.statusCode != 200) {
return reject(new Error(`Invalid status code ${resp.statusCode} while downloading bwt`))
}
const hasher = crypto.createHash('sha256')
resp.on('data', d => hasher.update(d))
.pipe(fs.createWriteStream(dest)
.on('finish', () => resolve(hasher.digest('hex')))
.on('error', reject)
)
}).on('error', err => {
reject(`Error while downloading bwt: ${err}`)
})
})
}
// Read the expected sha256 hash out of the SHA256SUMS file
function getExpectedHash(dist_name) {
let line = fs.readFileSync(path.join(__dirname, 'LIBBWT-SHA256SUMS'))
.toString()
.split('\n')
.find(line => line.endsWith(` ${dist_name}.tar.gz`))
if (!line) throw new Error(`Cannot find ${dist_name} in LIBBWT-SHA256SUMS`)
return line.split(' ')[0]
}
function getPlatform() {
const libname = `libbwt.${{'linux': 'so', 'darwin': 'dylib', 'win32': 'dll'}[process.platform]}`
const arch = process.env.npm_config_arch || require('os').arch()
const platform = {
'x64-darwin': 'x86_64-osx'
, 'x64-win32': 'x86_64-windows'
, 'x64-linux': 'x86_64-linux'
, 'arm-linux': 'arm32v7-linux'
, 'arm64-linux': 'arm64v8-linux'
}[`${arch}-${process.platform}`]
if (!platform) throw new Error(`Unsuppported platform: ${arch}-${process.platform}`)
return { platform, libname }
}