UNPKG

@dry-software/cmake-js

Version:

CMake.js - a Node.js native addon build tool

177 lines (163 loc) 4.54 kB
'use strict' const environment = require('./environment') const path = require('path') const urljoin = require('url-join') const fs = require('fs-extra') const CMLog = require('./cmLog') const TargetOptions = require('./targetOptions') const runtimePaths = require('./runtimePaths') const Downloader = require('./downloader') const os = require('os') function testSum(sums, sum, fPath) { const serverSum = sums.find(function (s) { return s.getPath === fPath }) if (serverSum && serverSum.sum === sum) { return } throw new Error("SHA sum of file '" + fPath + "' mismatch!") } class Dist { get internalPath() { const cacheDirectory = '.cmake-js' const runtimeArchDirectory = this.targetOptions.runtime + '-' + this.targetOptions.arch const runtimeVersionDirectory = 'v' + this.targetOptions.runtimeVersion return ( this.options.runtimeDirectory || path.join(os.homedir(), cacheDirectory, runtimeArchDirectory, runtimeVersionDirectory) ) } get externalPath() { return runtimePaths.get(this.targetOptions).externalPath } get downloaded() { let headers = false let libs = true let stat = getStat(this.internalPath) if (stat.isDirectory()) { if (this.headerOnly) { stat = getStat(path.join(this.internalPath, 'include/node/node.h')) headers = stat.isFile() } else { stat = getStat(path.join(this.internalPath, 'src/node.h')) if (stat.isFile()) { stat = getStat(path.join(this.internalPath, 'deps/v8/include/v8.h')) headers = stat.isFile() } } if (environment.isWin) { for (const libPath of this.winLibs) { stat = getStat(libPath) libs = libs && stat.isFile() } } } return headers && libs function getStat(path) { try { return fs.statSync(path) } catch (e) { return { isFile: () => false, isDirectory: () => false, } } } } get winLibs() { const libs = runtimePaths.get(this.targetOptions).winLibs const result = [] for (const lib of libs) { result.push(path.join(this.internalPath, lib.dir, lib.name)) } return result } get headerOnly() { return runtimePaths.get(this.targetOptions).headerOnly } constructor(options) { this.options = options || {} this.log = new CMLog(this.options) this.targetOptions = new TargetOptions(this.options) this.downloader = new Downloader(this.options) } async ensureDownloaded() { if (!this.downloaded) { await this.download() } } async download() { const log = this.log log.info('DIST', 'Downloading distribution files to: ' + this.internalPath) await fs.ensureDir(this.internalPath) const sums = await this._downloadShaSums() await Promise.all([this._downloadLibs(sums), this._downloadTar(sums)]) } async _downloadShaSums() { if (this.targetOptions.runtime === 'node') { const sumUrl = urljoin(this.externalPath, 'SHASUMS256.txt') const log = this.log log.http('DIST', '\t- ' + sumUrl) return (await this.downloader.downloadString(sumUrl)) .split('\n') .map(function (line) { const parts = line.split(/\s+/) return { getPath: parts[1], sum: parts[0], } }) .filter(function (i) { return i.getPath && i.sum }) } else { return null } } async _downloadTar(sums) { const log = this.log const self = this const tarLocalPath = runtimePaths.get(self.targetOptions).tarPath const tarUrl = urljoin(self.externalPath, tarLocalPath) log.http('DIST', '\t- ' + tarUrl) const sum = await this.downloader.downloadTgz(tarUrl, { hash: sums ? 'sha256' : null, cwd: self.internalPath, strip: 1, filter: function (entryPath) { if (entryPath === self.internalPath) { return true } const ext = path.extname(entryPath) return ext && ext.toLowerCase() === '.h' }, }) if (sums) { testSum(sums, sum, tarLocalPath) } } async _downloadLibs(sums) { const log = this.log const self = this if (!environment.isWin) { return } const paths = runtimePaths.get(self.targetOptions) for (const dirs of paths.winLibs) { const subDir = dirs.dir const fn = dirs.name const fPath = subDir ? urljoin(subDir, fn) : fn const libUrl = urljoin(self.externalPath, fPath) log.http('DIST', '\t- ' + libUrl) await fs.ensureDir(path.join(self.internalPath, subDir)) const sum = await this.downloader.downloadFile(libUrl, { path: path.join(self.internalPath, fPath), hash: sums ? 'sha256' : null, }) if (sums) { testSum(sums, sum, fPath) } } } } module.exports = Dist