From 1f35fe498ee9484b85d9fbf59825cd1f09291782 Mon Sep 17 00:00:00 2001 From: calebboyd Date: Sun, 30 Apr 2017 00:48:54 -0500 Subject: [PATCH] chore: switch to tar-fs for better stream support --- package.json | 5 ++++- src/artifacts.js | 3 ++- src/bundle.js | 24 ++++++++++++++++++++---- src/cli.js | 12 ++++++------ src/compiler.js | 12 +++++++----- src/download.js | 24 +++++++++++++++--------- src/nexe.js | 18 ++++++++---------- src/options.js | 11 ++++++----- src/patches/third-party-main.js | 17 +++++++++-------- src/util.js | 16 ++++++++++++---- 10 files changed, 89 insertions(+), 53 deletions(-) diff --git a/package.json b/package.json index bf6acf2..5cc6b7f 100644 --- a/package.json +++ b/package.json @@ -30,17 +30,20 @@ "app-builder": "^5.1.0", "bluebird": "^3.5.0", "chalk": "^1.1.3", + "html-loader": "^0.4.5", + "json-loader": "^0.5.4", "memory-fs": "^0.4.1", "minimist": "^1.2.0", "mkdirp": "^0.5.1", "request": "^2.81.0", "rimraf": "^2.6.1", - "tar": "^2.2.1", + "tar-fs": "^1.15.2", "webpack": "^2.3.3" }, "devDependencies": { "babel-cli": "^6.24.1", "babel-core": "^6.24.1", + "babel-loader": "^7.0.0", "babel-preset-env": "^1.3.3", "mocha": "^3.2.0", "standard": "^10.0.1" diff --git a/src/artifacts.js b/src/artifacts.js index 7aef25f..b7eeb28 100644 --- a/src/artifacts.js +++ b/src/artifacts.js @@ -1,9 +1,10 @@ import { join, dirname } from 'path' import { readdir, stat, unlink } from 'fs' import { readFileAsync, writeFileAsync } from './util' -import { promisify, map } from 'bluebird' +import Bluebird from 'bluebird' import mkdirp from 'mkdirp' +const { promisify, map } = Bluebird const mkdirpAsync = promisify(mkdirp) const statAsync = promisify(stat) const unlinkAsync = promisify(unlink) diff --git a/src/bundle.js b/src/bundle.js index 88bdfbb..4e43340 100644 --- a/src/bundle.js +++ b/src/bundle.js @@ -1,32 +1,48 @@ import Mfs from 'memory-fs' import webpack from 'webpack' import { fromCallback } from 'bluebird' -import { resolve, join, relative } from 'path' +import { resolveModule } from './util' +import { resolve, join } from 'path' +import module from 'module' +import 'json-loader' +import 'html-loader' const isObject = (x) => typeof x === 'object' const isString = (x) => typeof x === 'string' +function loadModule (path) { + console.log('loading module!!!!', path) + return module._load(path, module, false) +} + export default async function bundle (compiler, next) { let bundleConfig = compiler.options.bundle if (!bundleConfig) { return next() } - const input = compiler.options.input || require.resolve(process.cwd()) + const input = compiler.options.input || resolveModule(process.cwd()) const mfs = new Mfs() const path = resolve('nexe') const filename = 'virtual-bundle.js' if (isString(bundleConfig)) { - bundleConfig === require(relative(process.cwd(), bundleConfig)) + bundleConfig = loadModule(relative(process.cwd(), bundleConfig)) } else if (!isObject(bundleConfig)) { bundleConfig = { entry: resolve(input), target: 'node', - output: { path, filename } + module: { + rules: [ + { test: /\.html$/, use: 'html-loader' }, + { test: /\.json$/, use: 'json-loader' } + ] + } } } + bundleConfig.output = { path, filename } + const bundler = webpack(bundleConfig) bundler.outputFileSystem = mfs const stats = await fromCallback(cb => bundler.run(cb)) diff --git a/src/cli.js b/src/cli.js index 5604d99..ac17c60 100644 --- a/src/cli.js +++ b/src/cli.js @@ -1,12 +1,12 @@ import { normalize } from 'path' -import { Promise } from 'bluebird' +import Bluebird from 'bluebird' import { createWriteStream } from 'fs' -import { dequote, readFileAsync } from './util' +import { dequote, readFileAsync, resolveModule } from './util' const isWindows = process.platform === 'win32' function getStdIn () { - return new Promise((resolve) => { + return new Bluebird((resolve) => { const bundle = [] process.stdin.setEncoding('utf-8') process.stdin.on('data', x => bundle.push(x)) @@ -45,16 +45,16 @@ export default async function cli (compiler, next) { compiler.input = await readFileAsync(normalize(input)) } else if (!compiler.options.empty) { compiler.log.verbose('Resolving cwd as main module...') - compiler.input = await readFileAsync(require.resolve(process.cwd())) + compiler.input = await readFileAsync(resolveModule(process.cwd())) } if (!bundled) { await next() } - const deliverable = await compiler.getDeliverableAsync() + const deliverable = await compiler.compileAsync() - return new Promise((resolve, reject) => { + return new Bluebird((resolve, reject) => { deliverable.once('error', reject) if (!compiler.options.output && !process.stdout.isTTY) { diff --git a/src/compiler.js b/src/compiler.js index c3a12b3..9103c33 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -1,5 +1,5 @@ import { normalize, join } from 'path' -import { Promise } from 'bluebird' +import Bluebird from 'bluebird' import { createReadStream } from 'fs' import { spawn } from 'child_process' import * as logger from './logger' @@ -55,7 +55,7 @@ export class NexeCompiler { } _runBuildCommandAsync (command, args) { - return new Promise((resolve, reject) => { + return new Bluebird((resolve, reject) => { spawn(command, args, { cwd: this.src, env: this.env, @@ -73,12 +73,14 @@ export class NexeCompiler { ) } - async buildAsync () { + async _buildAsync () { await this._configureAsync() return this._runBuildCommandAsync(make, this.make) } - getDeliverableAsync () { - return Promise.resolve(createReadStream(this._deliverableLocation)) + compileAsync () { + return this._buildAsync().then(() => { + return createReadStream(this._deliverableLocation) + }) } } diff --git a/src/download.js b/src/download.js index 5267513..d5dc881 100644 --- a/src/download.js +++ b/src/download.js @@ -1,12 +1,12 @@ import { createGunzip as unZip } from 'zlib' -import { Extract as unTar } from 'tar' +import { extract as unTar } from 'tar-fs' import request from 'request' -import { Promise, promisify } from 'bluebird' +import Bluebird from 'bluebird' import { stat } from 'fs' import rimraf from 'rimraf' -const statAsync = promisify(stat) -const rimrafAsync = promisify(rimraf) +const statAsync = Bluebird.promisify(stat) +const rimrafAsync = Bluebird.promisify(rimraf) function progress (req, log, precision = 10) { const logged = {} @@ -26,16 +26,22 @@ function progress (req, log, precision = 10) { } function fetchNodeSource (path, url, log) { + const prefix = url.split('/').pop().replace('.tar.gz', '/') log.info('Downloading Node: ' + url) - return new Promise((resolve, reject) => { + return new Bluebird((resolve, reject) => { progress(request.get(url), (pc) => { - log.verbose(`Downloading Node: ${pc}%...`) + log.verbose(`Downloading and Extracting Node: ${pc}%...`) if (pc === 100) { - log.info('Extracting Node...') + log.info('Complete...') } }).on('error', reject) .pipe(unZip().on('error', reject)) - .pipe(unTar({ path, strip: 1 })) + .pipe(unTar(path, { + map (header) { + header.name = header.name.replace(prefix, '') + return header + } + })) .on('error', reject) .on('end', () => resolve(log.info('Extracted to: ' + path))) }) @@ -48,7 +54,7 @@ function cleanSrc (clean, src, log) { log.info('Source deleted.' + src) }) } - return Promise.resolve() + return Bluebird.resolve() } /** diff --git a/src/nexe.js b/src/nexe.js index 6fb4e37..1404f68 100644 --- a/src/nexe.js +++ b/src/nexe.js @@ -1,5 +1,6 @@ import { compose, PromiseConfig } from 'app-builder' import bundle from './bundle' +import resource from './resource' import { NexeCompiler } from './compiler' import { argv, normalizeOptionsAsync } from './options' import cli from './cli' @@ -7,11 +8,11 @@ import download from './download' import artifacts from './artifacts' import patches from './patches' import { EOL } from 'os' -import { longStackTraces, Promise } from 'bluebird' +import Bluebird from 'bluebird' import { error } from './logger' -PromiseConfig.constructor = Promise -longStackTraces() +PromiseConfig.constructor = Bluebird +Bluebird.longStackTraces() async function compile (compilerOptions, callback) { const options = await normalizeOptionsAsync(compilerOptions) @@ -22,22 +23,19 @@ async function compile (compilerOptions, callback) { ) const nexe = compose( + resource, bundle, cli, download, - async (_, next) => { - await next() - return compiler.buildAsync() - }, artifacts, patches, - compiler.options.patches + options.patches ) return nexe(compiler).asCallback(callback) } function isNexe (callback) { - return Promise.resolve(Boolean(process.__nexe)).asCallback(callback) + return Bluebird.resolve(Boolean(process.__nexe)).asCallback(callback) } export { @@ -46,7 +44,7 @@ export { compile } -if (require.main === module || process.__nexe) { +if (process.__nexe) { compile(argv) .catch((e) => { error(e.stack, () => process.exit(e.exitCode || 1)) diff --git a/src/options.js b/src/options.js index 0701746..bff7f23 100644 --- a/src/options.js +++ b/src/options.js @@ -1,6 +1,7 @@ import parseArgv from 'minimist' import { basename, extname, join } from 'path' -import { fromCallback, Promise } from 'bluebird' +import Bluebird from 'bluebird' +import { resolveModule } from './util' import { EOL } from 'os' function padRight (str, l) { @@ -81,20 +82,20 @@ function flattenFilter (...args) { * @param {*} options */ function extractCliMap (match, options) { - Object.keys(options).filter(x => match.test(x)) + return Object.keys(options).filter(x => match.test(x)) .reduce((map, option) => { const key = option.split('-')[1] map = map || {} map[key] = options[option] delete options[option] return map - }, null) + }, null) || {} } function tryResolveMainFileName () { let filename = 'nexe' try { - const file = require.resolve(process.cwd()) + const file = resolveModule(process.cwd()) filename = basename(file).replace(extname(file), '') } catch (_) {} @@ -119,7 +120,7 @@ function extractName (options) { function normalizeOptionsAsync (input) { if (argv.help || Boolean(argv._.find(x => x === 'version'))) { - return fromCallback(cb => process.stderr.write( + return Bluebird.fromCallback(cb => process.stderr.write( argv.help ? help : '2.0.0-beta.1' + EOL, () => cb(null, process.exit(1)) )) diff --git a/src/patches/third-party-main.js b/src/patches/third-party-main.js index fdbdd3d..eefb77b 100644 --- a/src/patches/third-party-main.js +++ b/src/patches/third-party-main.js @@ -1,19 +1,20 @@ export default async function main (compiler, next) { const mainFile = await compiler.readFileAsync('lib/_third_party_main.js') mainFile.contents = ` - Object.defineProperty(process, '__nexe', { - value: true, - enumerable: false, - writable: false, - configurable: false - }); - require("${compiler.options.name}"); +Object.defineProperty(process, '__nexe', { + value: true, + enumerable: false, + writable: false, + configurable: false +}); + +require("${compiler.options.name}"); `.trim() if (compiler.options.empty === true) { compiler.options.resources.length = 0 //eslint-disable-next-line - compiler.input = 'console.log(`nexe-${process.platform}-${process.arch}-${process.version}`)' + compiler.input = 'console.log(`nexe: ${process.platform}-${process.arch}-${process.version.slice(1)}`)' return next() } diff --git a/src/util.js b/src/util.js index 881c2b9..daad89b 100644 --- a/src/util.js +++ b/src/util.js @@ -1,5 +1,12 @@ import { readFile, writeFile } from 'fs' -import { promisify } from 'bluebird' +import Bluebird from 'bluebird' +import module from 'module' + +function resolveModule (path) { + const filename = module._resolveFilename(path, module) + console.log('resolving module ', path) + return filename +} function dequote (input) { input = input.trim() @@ -12,11 +19,12 @@ function dequote (input) { return input } -const readFileAsync = promisify(readFile) -const writeFileAsync = promisify(writeFile) +const readFileAsync = Bluebird.promisify(readFile) +const writeFileAsync = Bluebird.promisify(writeFile) export { readFileAsync, writeFileAsync, - dequote + dequote, + resolveModule }