Compare commits

..

5 Commits

Author SHA1 Message Date
calebboyd ff612d610e feat(fs): add option to restore all but internal filesystem methods 2019-04-08 22:14:27 -05:00
calebboyd 448f4270ea fix: set entrypoint correctly when outside a tty 2019-04-08 16:23:21 -05:00
calebboyd c9c9b5a0a3 fix: mount vfs relative to execPath instead of cwd 2019-04-08 11:10:33 -05:00
calebboyd d2756a5f75 fix: load implicit input if stdin is empty without a tty 2019-04-04 23:54:06 -05:00
calebboyd 255f3887c7 chore: remove unused methods 2019-04-04 19:37:30 -05:00
8 changed files with 89 additions and 59 deletions
+1
View File
@@ -1,6 +1,7 @@
.DS_Store .DS_Store
temp/ temp/
coverage coverage
nexe
node_modules node_modules
*.log *.log
*.exe *.exe
+31 -19
View File
@@ -1,6 +1,6 @@
{ {
"name": "nexe", "name": "nexe",
"version": "3.0.2", "version": "3.1.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@@ -183,9 +183,9 @@
} }
}, },
"@types/semver": { "@types/semver": {
"version": "5.5.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-6.0.0.tgz",
"integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==", "integrity": "sha512-OO0srjOGH99a4LUN2its3+r6CBYcplhJ466yLqs+zvAWgphCpS8hYZEZ797tRDP/QKcqTdb/YCN6ifASoAWkrQ==",
"dev": true "dev": true
}, },
"@types/tough-cookie": { "@types/tough-cookie": {
@@ -710,9 +710,9 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
}, },
"commander": { "commander": {
"version": "2.19.0", "version": "2.20.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
"integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
"dev": true "dev": true
}, },
"component-emitter": { "component-emitter": {
@@ -1526,13 +1526,13 @@
} }
}, },
"globby": { "globby": {
"version": "9.1.0", "version": "9.2.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-9.1.0.tgz", "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz",
"integrity": "sha512-VtYjhHr7ncls724Of5W6Kaahz0ag7dB4G62/2HsN+xEKG6SrPzM1AJMerGxQTwJGnN9reeyxdvXbuZYpfssCvg==", "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==",
"requires": { "requires": {
"@types/glob": "^7.1.1", "@types/glob": "^7.1.1",
"array-union": "^1.0.2", "array-union": "^1.0.2",
"dir-glob": "^2.2.1", "dir-glob": "^2.2.2",
"fast-glob": "^2.2.6", "fast-glob": "^2.2.6",
"glob": "^7.1.3", "glob": "^7.1.3",
"ignore": "^4.0.3", "ignore": "^4.0.3",
@@ -2463,15 +2463,15 @@
} }
}, },
"ora": { "ora": {
"version": "3.2.0", "version": "3.4.0",
"resolved": "https://registry.npmjs.org/ora/-/ora-3.2.0.tgz", "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz",
"integrity": "sha512-XHMZA5WieCbtg+tu0uPF8CjvwQdNzKCX6BVh3N6GFsEXH40mTk5dsw/ya1lBTUGJslcEFJFQ8cBhOgkkZXQtMA==", "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==",
"requires": { "requires": {
"chalk": "^2.4.2", "chalk": "^2.4.2",
"cli-cursor": "^2.1.0", "cli-cursor": "^2.1.0",
"cli-spinners": "^2.0.0", "cli-spinners": "^2.0.0",
"log-symbols": "^2.2.0", "log-symbols": "^2.2.0",
"strip-ansi": "^5.0.0", "strip-ansi": "^5.2.0",
"wcwidth": "^1.0.1" "wcwidth": "^1.0.1"
} }
}, },
@@ -3255,9 +3255,9 @@
"dev": true "dev": true
}, },
"tslint": { "tslint": {
"version": "5.14.0", "version": "5.15.0",
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.14.0.tgz", "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.15.0.tgz",
"integrity": "sha512-IUla/ieHVnB8Le7LdQFRGlVJid2T/gaJe5VkjzRVSRR6pA2ODYrnfR1hmxi+5+au9l50jBwpbBL34txgv4NnTQ==", "integrity": "sha512-6bIEujKR21/3nyeoX2uBnE8s+tMXCQXhqMmaIPJpHmXJoBJPTLcI7/VHRtUwMhnLVdwLqqY3zmd8Dxqa5CVdJA==",
"dev": true, "dev": true,
"requires": { "requires": {
"babel-code-frame": "^6.22.0", "babel-code-frame": "^6.22.0",
@@ -3266,13 +3266,25 @@
"commander": "^2.12.1", "commander": "^2.12.1",
"diff": "^3.2.0", "diff": "^3.2.0",
"glob": "^7.1.1", "glob": "^7.1.1",
"js-yaml": "^3.7.0", "js-yaml": "^3.13.0",
"minimatch": "^3.0.4", "minimatch": "^3.0.4",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"resolve": "^1.3.2", "resolve": "^1.3.2",
"semver": "^5.3.0", "semver": "^5.3.0",
"tslib": "^1.8.0", "tslib": "^1.8.0",
"tsutils": "^2.29.0" "tsutils": "^2.29.0"
},
"dependencies": {
"js-yaml": {
"version": "3.13.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.0.tgz",
"integrity": "sha512-pZZoSxcCYco+DIKBTimr67J6Hy+EYGZDY/HCWC+iAEA9h1ByhMXAIVUXMcMFpOCxQ/xjXmPI2MkDL5HRm5eFrQ==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
}
}
} }
}, },
"tslint-config-prettier": { "tslint-config-prettier": {
+5 -5
View File
@@ -2,7 +2,7 @@
"name": "nexe", "name": "nexe",
"description": "Create a single executable out of your Node.js application", "description": "Create a single executable out of your Node.js application",
"license": "MIT", "license": "MIT",
"version": "3.0.2", "version": "3.1.0",
"contributors": [ "contributors": [
"Craig Condon <craig.j.condon@gmail.com> (http://crcn.io)", "Craig Condon <craig.j.condon@gmail.com> (http://crcn.io)",
"Jared Allard <jaredallard@outlook.com>", "Jared Allard <jaredallard@outlook.com>",
@@ -39,12 +39,12 @@
"chalk": "^2.4.2", "chalk": "^2.4.2",
"cherow": "1.6.9", "cherow": "1.6.9",
"download": "^7.1.0", "download": "^7.1.0",
"globby": "^9.1.0", "globby": "^9.2.0",
"got": "^9.6.0", "got": "^9.6.0",
"minimist": "^1.2.0", "minimist": "^1.2.0",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"multistream": "^2.1.1", "multistream": "^2.1.1",
"ora": "^3.2.0", "ora": "^3.4.0",
"pify": "^4.0.1", "pify": "^4.0.1",
"resolve-dependencies": "^2.2.2", "resolve-dependencies": "^2.2.2",
"rimraf": "^2.6.3" "rimraf": "^2.6.3"
@@ -62,13 +62,13 @@
"@types/ora": "^3.2.0", "@types/ora": "^3.2.0",
"@types/pify": "3.0.2", "@types/pify": "3.0.2",
"@types/rimraf": "2.0.2", "@types/rimraf": "2.0.2",
"@types/semver": "^5.5.0", "@types/semver": "^6.0.0",
"chai": "^4.2.0", "chai": "^4.2.0",
"execa": "^1.0.0", "execa": "^1.0.0",
"mocha": "^6.0.2", "mocha": "^6.0.2",
"prettier": "^1.16.4", "prettier": "^1.16.4",
"ts-node": "^8.0.3", "ts-node": "^8.0.3",
"tslint": "^5.14.0", "tslint": "^5.15.0",
"tslint-config-prettier": "^1.18.0", "tslint-config-prettier": "^1.18.0",
"tslint-plugin-prettier": "^2.0.1", "tslint-plugin-prettier": "^2.0.1",
"typescript": "^3.4.1" "typescript": "^3.4.1"
+19 -22
View File
@@ -13,38 +13,24 @@ export interface NexeBinary {
} }
let originalFsMethods: any = null let originalFsMethods: any = null
let nexeBinary: NexeBinary | null = null let lazyRestoreFs = () => {}
function restoreFs(fs: any = require('fs')): NexeBinary | false {
if (!nexeBinary) {
return false
}
const source = nexeBinary
Object.assign(fs, originalFsMethods)
nexeBinary = originalFsMethods = null
return source
}
function shimFs(binary: NexeBinary, fs: any = require('fs')) { function shimFs(binary: NexeBinary, fs: any = require('fs')) {
if (originalFsMethods !== null) { if (originalFsMethods !== null) {
return return
} }
originalFsMethods = Object.assign({}, fs) originalFsMethods = Object.assign({}, fs)
nexeBinary = binary const { blobPath, resources: manifest } = binary,
const { blobPath, resources: manifest } = binary { resourceStart, stat } = binary.layout,
const { resourceStart, stat } = binary.layout directories: { [key: string]: { [key: string]: boolean } } = {},
const directories: { [key: string]: { [key: string]: boolean } } = {},
notAFile = '!@#$%^&*', notAFile = '!@#$%^&*',
isWin = process.platform.startsWith('win'), isWin = process.platform.startsWith('win'),
isString = (x: any): x is string => typeof x === 'string' || x instanceof String, isString = (x: any): x is string => typeof x === 'string' || x instanceof String,
isNotFile = () => false,
isNotDirectory = isNotFile,
isFile = () => true,
noop = () => {}, noop = () => {},
isDirectory = isFile, path = require('path'),
path = require('path') baseDir = path.dirname(process.execPath)
let log = (text: string) => true let log = (_: string) => true
if ((process.env.DEBUG || '').toLowerCase().includes('nexe:require')) { if ((process.env.DEBUG || '').toLowerCase().includes('nexe:require')) {
log = (text: string) => process.stderr.write('[nexe] - ' + text + '\n') log = (text: string) => process.stderr.write('[nexe] - ' + text + '\n')
} }
@@ -56,7 +42,7 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
if (!isString(filepath)) { if (!isString(filepath)) {
return notAFile return notAFile
} }
let key = path.resolve(filepath) let key = path.resolve(baseDir, filepath)
if (isWin && key.substr(1, 2) === ':\\') { if (isWin && key.substr(1, 2) === ':\\') {
key = key[0].toUpperCase() + key.substr(1) key = key[0].toUpperCase() + key.substr(1)
@@ -333,7 +319,18 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
} }
} }
Object.assign(fs, nfs) Object.assign(fs, nfs)
lazyRestoreFs = () => {
Object.keys(nfs).forEach(key => {
fs[key] = originalFsMethods[key]
})
lazyRestoreFs = () => {}
}
return true return true
} }
function restoreFs() {
lazyRestoreFs()
}
export { shimFs, restoreFs } export { shimFs, restoreFs }
+2
View File
@@ -23,6 +23,7 @@ export interface NexeOptions {
name: string name: string
asset: string asset: string
cwd: string cwd: string
fs: boolean | string[]
flags: string[] flags: string[]
configure: string[] configure: string[]
vcBuild: string[] vcBuild: string[]
@@ -59,6 +60,7 @@ export interface NexeOptions {
const defaults = { const defaults = {
flags: [], flags: [],
cwd: process.cwd(), cwd: process.cwd(),
fs: true,
configure: [], configure: [],
mangle: true, mangle: true,
make: [], make: [],
+14 -5
View File
@@ -1,7 +1,7 @@
import { NexeCompiler, NexeError } from '../compiler' import { NexeCompiler, NexeError } from '../compiler'
import { resolve, relative } from 'path' import { resolve, relative } from 'path'
import { each } from '@calebboyd/semaphore' import { each } from '@calebboyd/semaphore'
import resolveFiles from 'resolve-dependencies' import resolveFiles, { resolveFileNameSync } from 'resolve-dependencies'
import { dequote, STDIN_FLAG } from '../util' import { dequote, STDIN_FLAG } from '../util'
import { Readable } from 'stream' import { Readable } from 'stream'
@@ -16,12 +16,13 @@ function getStdIn(stdin: Readable): Promise<string> {
out += current out += current
} }
}) })
.on('end', () => resolve(out)) .on('end', () => resolve(out.trim()))
}) })
} }
export default async function bundle(compiler: NexeCompiler, next: any) { export default async function bundle(compiler: NexeCompiler, next: any) {
const { bundle, cwd, input } = compiler.options const { bundle, cwd, input: inputPath } = compiler.options
let input = inputPath
compiler.entrypoint = './' + relative(cwd, input) compiler.entrypoint = './' + relative(cwd, input)
compiler.startup = ';require("module").runMain();' compiler.startup = ';require("module").runMain();'
@@ -35,14 +36,22 @@ export default async function bundle(compiler: NexeCompiler, next: any) {
code = await require(bundle).createBundle(compiler.options) code = await require(bundle).createBundle(compiler.options)
} }
if (input === STDIN_FLAG) { if (input === STDIN_FLAG && (code = code || dequote(await getStdIn(process.stdin)))) {
compiler.stdinUsed = true compiler.stdinUsed = true
compiler.entrypoint = './__nexe_stdin.js' compiler.entrypoint = './__nexe_stdin.js'
code = code || dequote(await getStdIn(process.stdin))
await compiler.addResource(resolve(cwd, compiler.entrypoint), code) await compiler.addResource(resolve(cwd, compiler.entrypoint), code)
return next() return next()
} }
if (input === STDIN_FLAG) {
const maybeInput = resolveFileNameSync(cwd, '.')
if (!maybeInput || !maybeInput.absPath) {
throw new NexeError('No valid input detected')
}
input = maybeInput.absPath
compiler.entrypoint = './' + relative(cwd, input)
}
const { files, warnings } = await resolveFiles( const { files, warnings } = await resolveFiles(
input, input,
...Object.keys(compiler.bundle.index).filter(x => x.endsWith('.js')), ...Object.keys(compiler.bundle.index).filter(x => x.endsWith('.js')),
+9 -6
View File
@@ -1,4 +1,4 @@
import { dirname, normalize, relative } from 'path' import { dirname, normalize, relative, resolve } from 'path'
import { createWriteStream, chmodSync, statSync } from 'fs' import { createWriteStream, chmodSync, statSync } from 'fs'
import { NexeCompiler } from '../compiler' import { NexeCompiler } from '../compiler'
import { NexeTarget } from '../target' import { NexeTarget } from '../target'
@@ -24,18 +24,21 @@ export default async function cli(compiler: NexeCompiler, next: () => Promise<vo
mkdirp.sync(dirname(output)) mkdirp.sync(dirname(output))
return new Promise((resolve, reject) => { return new Promise((res, rej) => {
const step = log.step('Writing result to file') const step = log.step('Writing result to file')
deliverable deliverable
.pipe(createWriteStream(output)) .pipe(createWriteStream(output))
.on('error', reject) .on('error', rej)
.once('close', (e: Error) => { .once('close', (e: Error) => {
if (e) { if (e) {
reject(e) rej(e)
} else if (compiler.output) { } else if (compiler.output) {
const output = compiler.output, const output = compiler.output,
mode = statSync(output).mode | 0o111, mode = statSync(output).mode | 0o111,
inputFileLogOutput = relative(process.cwd(), compiler.options.input), inputFileLogOutput = relative(
process.cwd(),
resolve(compiler.options.cwd, compiler.entrypoint || compiler.options.input)
),
outputFileLogOutput = relative(process.cwd(), output) outputFileLogOutput = relative(process.cwd(), output)
chmodSync(output, mode.toString(8).slice(-3)) chmodSync(output, mode.toString(8).slice(-3))
@@ -48,7 +51,7 @@ export default async function cli(compiler: NexeCompiler, next: () => Promise<vo
: inputFileLogOutput : inputFileLogOutput
}' written to: ${outputFileLogOutput}` }' written to: ${outputFileLogOutput}`
) )
resolve(compiler.quit()) res(compiler.quit())
} }
}) })
}) })
+8 -2
View File
@@ -6,7 +6,9 @@ export default function(compiler: NexeCompiler, next: () => Promise<void>) {
wrap( wrap(
`process.__nexe = ${JSON.stringify(compiler.binaryConfiguration)};\n` + `process.__nexe = ${JSON.stringify(compiler.binaryConfiguration)};\n` +
'{{replace:lib/fs/patch.js}}' + '{{replace:lib/fs/patch.js}}' +
'\nshimFs(process.__nexe)' '\nshimFs(process.__nexe)' +
`\n${compiler.options.fs ? '' : 'restoreFs()'}`
//TODO support only restoring specific methods
) )
) )
compiler.shims.push( compiler.shims.push(
@@ -22,7 +24,11 @@ export default function(compiler: NexeCompiler, next: () => Promise<void>) {
compiler.shims.push( compiler.shims.push(
wrap(` wrap(`
if (!process.send) { if (!process.send) {
process.argv.splice(1,0, require.resolve(${JSON.stringify(compiler.entrypoint)})) const path = require('path')
const entry = path.resolve(path.dirname(process.execPath),${JSON.stringify(
compiler.entrypoint
)})
process.argv.splice(1,0, entry)
} }
`) `)
) )