feat: targets

This commit is contained in:
calebboyd
2017-08-31 08:46:50 -05:00
parent 9e5ab3e099
commit 7d0cdd7a50
8 changed files with 104 additions and 76 deletions
+14 -4
View File
@@ -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
View File
@@ -61,7 +61,7 @@ const defaults = {
vcBuild: isWindows ? ['nosign', 'release', process.arch] : [],
enableNodeCli: false,
compress: false,
build: true,
build: false,
bundle: true,
patches: []
}
+72
View File
@@ -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
View File
@@ -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()
}
+5 -1
View File
@@ -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'
+1 -1
View File
@@ -2,7 +2,7 @@ import { compile } from '../src/nexe'
import {
getUnBuiltReleases,
getLatestGitRelease
} from './releases'
} from '../src/releases'
import * as ci from './ci'
import { getTarget } from '../src/target'
import { pathExistsAsync, statAsync, readFileAsync, execFileAsync } from '../src/util'
+1 -1
View File
@@ -1,4 +1,4 @@
import { NexeTarget } from './releases'
import { NexeTarget } from '../src/releases'
import got = require('got')
import * as assert from 'assert'
const { env } = process
-62
View File
@@ -1,62 +0,0 @@
import got = require('got')
import {
NodePlatform,
NodeArch,
platforms,
architectures,
NexeTarget,
getTarget,
targetsEqual,
} from '../src/target'
export { NexeTarget }
export interface GitRelease {
tag_name: string
assets_url: string
upload_url: string
assets: Array<{ name: string }>
}
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 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))
)
}