Skip to content

Commit

Permalink
fix: consistent cwd usage
Browse files Browse the repository at this point in the history
  • Loading branch information
calebboyd committed Oct 6, 2017
1 parent 7710923 commit 4ec8a43
Show file tree
Hide file tree
Showing 16 changed files with 174 additions and 122 deletions.
8 changes: 4 additions & 4 deletions package.json
Expand Up @@ -2,18 +2,18 @@
"name": "nexe",
"description": "Create a single executable out of your Node.js application",
"license": "MIT",
"version": "2.0.0-rc.13",
"version": "2.0.0-rc.14",
"contributors": [
"Craig Condon <craig.j.condon@gmail.com> (http://crcn.io)",
"Jared Allard <jaredallard@outlook.com>",
"Caleb Boyd <caleb.boyd@hotmail.com>"
],
"scripts": {
"asset-compile": "ts-node tasks/asset-compile",
"prebuild": "rimraf lib && npm run lint",
"test": "mocha",
"fmt": "prettier --parser typescript --no-semi --print-width 100 --single-quote --write \"{src,plugins,tasks}/**/*.ts\"",
"prepublish": "npm test && npm run build",
"test": "mocha test/**/*.spec.ts",
"lint": "prettier --parser typescript --no-semi --print-width 100 --single-quote --write \"src/**/*.ts\"",
"prebuild": "rimraf lib && npm run fmt",
"build": "tsc --declaration",
"postbuild": "ts-node tasks/post-build"
},
Expand Down
19 changes: 9 additions & 10 deletions plugins/nexe-daemon/src/index.ts
Expand Up @@ -12,37 +12,36 @@ interface NexeDaemonOptions {
type DaemonOptions = NexeOptions & { daemon: { windows: NexeDaemonOptions } }

function renderWinswConfig(options: any) {
return '<configuration>\r\n' +
return (
'<configuration>\r\n' +
`${Object.keys(options).reduce((config: string, element: string) => {
return config += `<${element}>${options[element]}</${element}>\r\n`
return (config += `<${element}>${options[element]}</${element}>\r\n`)
}, '')}</configuration>\r\n`
)
}

export default function daemon (compiler: NexeCompiler<DaemonOptions>, next: () => Promise<void>) {
export default function daemon(compiler: NexeCompiler<DaemonOptions>, next: () => Promise<void>) {
if (compiler.target.platform !== 'windows') {
return next()
}
compiler.addResource(
'./nexe/plugin/daemon/winsw.exe',
readFileSync(require.resolve('../winsw.exe'))
)
)
const name = compiler.options.name,
options = compiler.options.daemon && compiler.options.daemon.windows || {},
options = (compiler.options.daemon && compiler.options.daemon.windows) || {},
defaults: NexeDaemonOptions = {
id: name,
name,
description: name,
executable: '%BASE%\\' + compiler.output
}
}

compiler.addResource(
'./nexe/plugin/daemon/winsw.xml',
Buffer.from(renderWinswConfig(Object.assign(defaults, options)))
)
compiler.addResource(
'./nexe/plugin/daemon/app.js',
Buffer.from(compiler.input)
)
compiler.addResource('./nexe/plugin/daemon/app.js', Buffer.from(compiler.input))
compiler.input = '{{replace:plugins/nexe-daemon/lib/nexe-daemon.js}}'

return next()
Expand Down
21 changes: 9 additions & 12 deletions plugins/nexe-daemon/src/nexe-daemon.ts
Expand Up @@ -4,7 +4,7 @@ import * as path from 'path'
import * as fs from 'fs'
import * as cp from 'child_process'

function mkdirp (r: string, t?: any): any {
function mkdirp(r: string, t?: any): any {
;(t = t || null), (r = path.resolve(r))
try {
fs.mkdirSync(r), (t = t || r)
Expand All @@ -31,23 +31,20 @@ if (~installIndex) {
const filename = path.join(directory, path.basename(process.execPath))
const readStream = fs.createReadStream(process.execPath)
const writeStream = fs.createWriteStream(filename)
const onError = function () {

const onError = function() {
readStream.removeAllListeners()
writeStream.removeAllListeners()
//TODO
}

readStream
.on('error', onError)
.pipe(writeStream)
.on('error', onError)
.on('close', () => {
const winsw = filename.replace('.exe', '-service.exe')
fs.writeFileSync(
winsw,
fs.readFileSync('./nexe/plugin/daemon/winsw.exe')
)
fs.writeFileSync(winsw, fs.readFileSync('./nexe/plugin/daemon/winsw.exe'))
fs.writeFileSync(
filename.replace('.exe', '-service.xml'),
fs.readFileSync('./nexe/plugin/daemon/winsw.xml')
Expand All @@ -56,14 +53,14 @@ if (~installIndex) {
})
}
} else {
console.log("DIRECTORY NOT FOUND")
console.log('DIRECTORY NOT FOUND')
require('./nexe/plugin/daemon/app.js')
}

function installService (filename: string) {
cp.exec(filename + ' install', (error) => {
function installService(filename: string) {
cp.exec(filename + ' install', error => {
if (error && !error.message.includes('already exists')) {
throw error
}
}
})
}
28 changes: 12 additions & 16 deletions src/compiler.ts
Expand Up @@ -45,10 +45,7 @@ export class NexeCompiler<T extends NexeOptions = NexeOptions> {
index: {},
bundle: Buffer.from('')
}
public output = isWindows
? `${(this.options.output || this.options.name).replace(/\.exe$/, '')}.exe`
: `${this.options.output || this.options.name}`

public output = this.options.output
private nodeSrcBinPath: string
constructor(public options: T) {
const { python } = (this.options = options)
Expand Down Expand Up @@ -196,18 +193,17 @@ export class NexeCompiler<T extends NexeOptions = NexeOptions> {
throw new Error(`${assetName} not available, create it using the --build flag`)
}
const filename = this.getNodeExecutableLocation(target)
await download(
asset.browser_download_url,
dirname(filename),
downloadOptions
).on('response', (res: IncomingMessage) => {
const total = +res.headers['content-length']!
let current = 0
res.on('data', data => {
current += data.length
this.compileStep.modify(`Downloading...${(current / total * 100).toFixed()}%`)
})
})
await download(asset.browser_download_url, dirname(filename), downloadOptions).on(
'response',
(res: IncomingMessage) => {
const total = +res.headers['content-length']!
let current = 0
res.on('data', data => {
current += data.length
this.compileStep.modify(`Downloading...${(current / total * 100).toFixed()}%`)
})
}
)
return createReadStream(filename)
}

Expand Down
4 changes: 2 additions & 2 deletions src/nexe.ts
@@ -1,7 +1,7 @@
import { compose, Middleware } from 'app-builder'
import resource from './steps/resource'
import { NexeCompiler } from './compiler'
import { argv, version, help, normalizeOptionsAsync, NexeOptions, NexePatch } from './options'
import { argv, version, help, normalizeOptions, NexeOptions, NexePatch } from './options'
import cli from './steps/cli'
import bundle from './steps/bundle'
import download from './steps/download'
Expand All @@ -15,7 +15,7 @@ async function compile(
compilerOptions?: Partial<NexeOptions>,
callback?: (err: Error | null) => void
) {
const options = await normalizeOptionsAsync(compilerOptions)
const options = normalizeOptions(compilerOptions)
const compiler = new NexeCompiler(options)
const build = compiler.options.build

Expand Down
46 changes: 26 additions & 20 deletions src/options.ts
@@ -1,9 +1,9 @@
import * as parseArgv from 'minimist'
import { NexeCompiler } from './compiler'
import { isWindows, padRight } from './util'
import { basename, extname, join, isAbsolute, relative, dirname } from 'path'
import { basename, extname, join, isAbsolute, relative, dirname, resolve } from 'path'
import { getTarget, NexeTarget } from './target'
import { EOL } from 'os'
import { EOL, homedir } from 'os'
import * as c from 'chalk'

export const version = '{{replace:0}}'
Expand Down Expand Up @@ -113,7 +113,7 @@ ${c.bold('nexe <entry-file> [options]')}
${c.underline.bold('Other options:')}
--bundle -- custom bundling module with 'createBundle' export
--temp -- temp file storage default './nexe'
--temp -- temp file storage default '~/.nexe'
--cwd -- set the current working directory for the command
--fake-argv -- fake argv[1] with entry file
--clean -- force download of sources
Expand Down Expand Up @@ -182,36 +182,38 @@ function extractName(options: NexeOptions) {
return name.replace(/\.exe$/, '')
}

function isEntryFile(filename: string) {
return filename && !isAbsolute(filename) && filename !== 'node' && /\.(tsx?|jsx?)$/.test(filename)
function isEntryFile(filename?: string): filename is string {
return Boolean(
filename && !isAbsolute(filename) && filename !== 'node' && /\.(tsx?|jsx?)$/.test(filename)
)
}

function findInput(input: string, cwd: string) {
const maybeInput = argv._.slice().pop() || ''
export function resolveEntry(input: string, cwd: string, maybeEntry?: string) {
if (input) {
return input
return resolve(cwd, input)
}
if (isEntryFile(maybeInput)) {
return maybeInput
if (isEntryFile(maybeEntry)) {
return resolve(cwd, maybeEntry)
}
if (!process.stdin.isTTY) {
return ''
}
try {
const main = require.resolve(cwd)
return './' + relative(cwd, main)
return require.resolve(cwd)
} catch (e) {
void e
throw new Error('No entry file found')
}
return ''
}

function normalizeOptionsAsync(input?: Partial<NexeOptions>): Promise<NexeOptions> {
function normalizeOptions(input?: Partial<NexeOptions>): NexeOptions {
const options = Object.assign({}, defaults, input) as NexeOptions
const opts = options as any

options.temp = options.temp || process.env.NEXE_TEMP || join(options.cwd, '.nexe')
options.input = findInput(options.input, options.cwd)
const cwd = (options.cwd = resolve(options.cwd))
options.temp = options.temp
? resolve(cwd, options.temp)
: process.env.NEXE_TEMP || join(homedir(), '.nexe')
const maybeEntry = input === argv ? argv._[argv._.length - 1] : undefined
options.input = resolveEntry(options.input, cwd, maybeEntry)
options.name = extractName(options)
options.loglevel = extractLogLevel(options)
options.flags = flatten(opts.flag, options.flags)
Expand All @@ -220,6 +222,10 @@ function normalizeOptionsAsync(input?: Partial<NexeOptions>): Promise<NexeOption
options.configure = flatten(options.configure)
options.resources = flatten(opts.resource, options.resources)
options.rc = options.rc || extractCliMap(/^rc-.*/, options)
options.output = isWindows
? `${(options.output || options.name).replace(/\.exe$/, '')}.exe`
: `${options.output || options.name}`
options.output = resolve(cwd, options.output)

if (!options.targets.length) {
options.targets.push(getTarget())
Expand Down Expand Up @@ -248,7 +254,7 @@ function normalizeOptionsAsync(input?: Partial<NexeOptions>): Promise<NexeOption
.filter(k => k !== 'rc')
.forEach(x => delete opts[x])

return Promise.resolve(options)
return options
}

export { argv, normalizeOptionsAsync, help }
export { argv, normalizeOptions, help }
14 changes: 8 additions & 6 deletions src/steps/bundle.ts
Expand Up @@ -16,17 +16,18 @@ function createBundle(options: NexeOptions) {
})
)
}
const cwd = options.cwd
const fuse = FuseBox.init({
cache: false,
log: Boolean(process.env.NEXE_BUNDLE_LOG) || false,
homeDir: options.cwd,
homeDir: cwd,
sourceMaps: false,
writeBundles: false,
output: '$name.js',
target: 'server',
plugins
})
const input = relative(options.cwd, options.input).replace(/\\/g, '/')
const input = relative(cwd, resolve(cwd, options.input)).replace(/\\/g, '/')
fuse.bundle(options.name).instructions(`> ${input}`)
return fuse.run().then((x: any) => {
let output = ''
Expand All @@ -36,8 +37,9 @@ function createBundle(options: NexeOptions) {
}

export default async function bundle(compiler: NexeCompiler, next: any) {
if (!compiler.options.bundle) {
compiler.input = await readFileAsync(compiler.options.input, 'utf-8')
const { bundle, cwd, empty, input } = compiler.options
if (!bundle) {
compiler.input = await readFileAsync(resolve(cwd, input), 'utf-8')
return next()
}

Expand All @@ -48,13 +50,13 @@ export default async function bundle(compiler: NexeCompiler, next: any) {

let producer = createBundle
if (typeof compiler.options.bundle === 'string') {
producer = require(resolve(compiler.options.cwd, compiler.options.bundle)).createBundle
producer = require(resolve(cwd, bundle)).createBundle
}

compiler.input = await producer(compiler.options)

if ('string' === typeof compiler.options.debugBundle) {
await writeFileAsync(compiler.options.debugBundle, compiler.input)
await writeFileAsync(resolve(cwd, compiler.options.debugBundle), compiler.input)
}

return next()
Expand Down
11 changes: 7 additions & 4 deletions src/steps/cli.ts
@@ -1,4 +1,4 @@
import { normalize } from 'path'
import { normalize, relative } from 'path'
import { Readable } from 'stream'
import { createWriteStream, chmodSync, statSync } from 'fs'
import { readFileAsync, dequote, isWindows } from '../util'
Expand Down Expand Up @@ -56,12 +56,15 @@ export default async function cli(compiler: NexeCompiler, next: () => Promise<vo
if (e) {
reject(e)
} else if (compiler.output) {
const mode = statSync(compiler.output).mode | 0o111
chmodSync(compiler.output, mode.toString(8).slice(-3))
const output = compiler.output
const mode = statSync(output).mode | 0o111
chmodSync(output, mode.toString(8).slice(-3))
const inputFile = relative(process.cwd(), compiler.options.input)
const outputFile = relative(process.cwd(), output)
step.log(
`Entry: '${stdInUsed
? compiler.options.empty ? '[empty]' : '[stdin]'
: compiler.options.input}' written to: ${compiler.output}`
: inputFile}' written to: ${outputFile}`
)
resolve(compiler.quit())
}
Expand Down

0 comments on commit 4ec8a43

Please sign in to comment.