feat: targets
This commit is contained in:
+14
-4
@@ -1,4 +1,4 @@
|
||||
import { normalize, join } from 'path'
|
||||
import { dirname, normalize, join } from 'path'
|
||||
import { Buffer } from 'buffer'
|
||||
import { createHash } from 'crypto'
|
||||
import { createReadStream } from 'fs'
|
||||
@@ -8,6 +8,7 @@ import { Logger } from './logger'
|
||||
import { readFileAsync, writeFileAsync, pathExistsAsync, dequote, isWindows } from './util'
|
||||
import { NexeOptions, nexeVersion } from './options'
|
||||
import { NexeTarget } from './target'
|
||||
import { getLatestGitRelease, storeAsset } from './releases'
|
||||
|
||||
const isBsd = Boolean(~process.platform.indexOf('bsd'))
|
||||
const make = isWindows ? 'vcbuild.bat' : isBsd ? 'gmake' : 'make'
|
||||
@@ -133,8 +134,17 @@ export class NexeCompiler {
|
||||
return createReadStream(this._getNodeExecutableLocation())
|
||||
}
|
||||
|
||||
private _fetchPrebuiltBinaryAsync() {
|
||||
return this._buildAsync()
|
||||
private async _fetchPrebuiltBinaryAsync(target: NexeTarget) {
|
||||
const githubRelease = await getLatestGitRelease()
|
||||
const assetName = target.toString()
|
||||
const asset = githubRelease.assets.find(x => x.name === assetName)
|
||||
|
||||
if (!asset) {
|
||||
throw new Error(`${assetName} not available, create one using --build`)
|
||||
}
|
||||
const filename = this._getNodeExecutableLocation(target)
|
||||
await storeAsset(asset, dirname(filename))
|
||||
return createReadStream(filename)
|
||||
}
|
||||
|
||||
private _generateHeader() {
|
||||
@@ -161,7 +171,7 @@ export class NexeCompiler {
|
||||
const header = this._generateHeader()
|
||||
|
||||
if (target && !binary) {
|
||||
binary = await this._fetchPrebuiltBinaryAsync()
|
||||
binary = await this._fetchPrebuiltBinaryAsync(target)
|
||||
}
|
||||
|
||||
if (!binary) {
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ const defaults = {
|
||||
vcBuild: isWindows ? ['nosign', 'release', process.arch] : [],
|
||||
enableNodeCli: false,
|
||||
compress: false,
|
||||
build: true,
|
||||
build: false,
|
||||
bundle: true,
|
||||
patches: []
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import got = require('got')
|
||||
import download = require('download')
|
||||
import {
|
||||
NodePlatform,
|
||||
NodeArch,
|
||||
platforms,
|
||||
architectures,
|
||||
NexeTarget,
|
||||
getTarget,
|
||||
targetsEqual
|
||||
} from './target'
|
||||
export { NexeTarget }
|
||||
|
||||
export interface GitAsset {
|
||||
name: string
|
||||
url: string
|
||||
browser_download_url: string
|
||||
}
|
||||
|
||||
export interface GitRelease {
|
||||
tag_name: string
|
||||
assets_url: string
|
||||
upload_url: string
|
||||
assets: GitAsset[]
|
||||
}
|
||||
|
||||
interface NodeRelease {
|
||||
version: string
|
||||
}
|
||||
|
||||
async function getJson<T>(url: string) {
|
||||
return JSON.parse((await got(url)).body) as T
|
||||
}
|
||||
|
||||
//TODO only build the latest of each major...?
|
||||
function isBuildableVersion(version: string) {
|
||||
const major = +version.split('.')[0]
|
||||
return !~[0, 1, 2, 3, 4, 5, 7].indexOf(major) || version === '4.8.4'
|
||||
}
|
||||
|
||||
export function getLatestGitRelease() {
|
||||
return getJson<GitRelease>('https://api.github.com/repos/nexe/nexe/releases/latest')
|
||||
}
|
||||
|
||||
export async function storeAsset(asset: GitAsset, dest: string) {
|
||||
await download(asset.browser_download_url, dest)
|
||||
}
|
||||
|
||||
export async function getUnBuiltReleases() {
|
||||
const nodeReleases = await getJson<NodeRelease[]>(
|
||||
'https://nodejs.org/download/release/index.json'
|
||||
)
|
||||
const existingVersions = (await getLatestGitRelease()).assets.map(x => getTarget(x.name))
|
||||
|
||||
const versionMap: { [key: string]: true } = {}
|
||||
return nodeReleases
|
||||
.reduce((versions: NexeTarget[], { version }) => {
|
||||
version = version.replace('v', '').trim()
|
||||
if (!isBuildableVersion(version) || versionMap[version]) {
|
||||
return versions
|
||||
}
|
||||
versionMap[version] = true
|
||||
platforms.forEach(platform => {
|
||||
architectures.forEach(arch => {
|
||||
if (arch === 'x86' && platform === 'mac') return
|
||||
versions.push(getTarget({ platform, arch, version }))
|
||||
})
|
||||
})
|
||||
return versions
|
||||
}, [])
|
||||
.filter(x => !existingVersions.some(t => targetsEqual(t, x)))
|
||||
}
|
||||
+10
-6
@@ -1,12 +1,12 @@
|
||||
import download = require('download')
|
||||
import { isDirectoryAsync } from '../util'
|
||||
import { pathExistsAsync } from '../util'
|
||||
import { LogStep } from '../logger'
|
||||
import { IncomingMessage } from 'http'
|
||||
import { NexeCompiler } from '../compiler'
|
||||
|
||||
function fetchNodeSourceAsync(cwd: string, url: string, step: LogStep, options = {}) {
|
||||
function fetchNodeSourceAsync(dest: string, url: string, step: LogStep, options = {}) {
|
||||
const setText = (p: number) => step.modify(`Downloading Node: ${p.toFixed()}%...`)
|
||||
return download(url, cwd, Object.assign(options, { extract: true, strip: 1 }))
|
||||
return download(url, dest, Object.assign(options, { extract: true, strip: 1 }))
|
||||
.on('response', (res: IncomingMessage) => {
|
||||
const total = +res.headers['content-length']!
|
||||
let current = 0
|
||||
@@ -18,7 +18,7 @@ function fetchNodeSourceAsync(cwd: string, url: string, step: LogStep, options =
|
||||
}
|
||||
})
|
||||
})
|
||||
.then(() => step.log(`Node source extracted to: ${cwd}`))
|
||||
.then(() => step.log(`Node source extracted to: ${dest}`))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -31,10 +31,14 @@ export default async function downloadNode(compiler: NexeCompiler, next: () => P
|
||||
const { version, sourceUrl, downloadOptions } = compiler.options
|
||||
const url = sourceUrl || `https://nodejs.org/dist/v${version}/node-v${version}.tar.gz`
|
||||
const step = log.step(`Downloading Node.js source from: ${url}`)
|
||||
if (await isDirectoryAsync(src)) {
|
||||
if (await pathExistsAsync(src)) {
|
||||
step.log('Source already downloaded')
|
||||
return next()
|
||||
}
|
||||
|
||||
return fetchNodeSourceAsync(src, url, step, downloadOptions).then(next)
|
||||
if (compiler.options.build) {
|
||||
await fetchNodeSourceAsync(src, url, step, downloadOptions).then(next)
|
||||
}
|
||||
|
||||
return next()
|
||||
}
|
||||
|
||||
Vendored
+5
-1
@@ -1,6 +1,10 @@
|
||||
declare module 'got' {
|
||||
interface GotFn {
|
||||
(url: string, options?: any): Promise<{ body: string }>
|
||||
stream(url: string, optoins?: any): any
|
||||
}
|
||||
function got(url: string, options?: any): Promise<{ body: string }>
|
||||
export = got
|
||||
export = got as GotFn
|
||||
}
|
||||
declare module 'download' {
|
||||
import { Duplex } from 'stream'
|
||||
|
||||
Reference in New Issue
Block a user