Compare commits

..

15 Commits

Author SHA1 Message Date
calebboyd 66afccc2e2 fix: order of operations #448 2018-02-16 22:26:42 -06:00
David Goemans 71e77052e5 docs: add note about --build required for --ico option 2018-02-07 11:54:26 -06:00
calebboyd eef430afb1 chore: update fuse-box 2018-02-05 20:22:23 -06:00
bruce-one 133d1919fa feat: allow setting NODE_OPTIONS. (#448) 2018-02-01 16:29:49 -06:00
calebboyd 9a81cc2fa2 fix: don't rely on got as a transient dependency
closes #439
2018-01-22 18:37:50 -06:00
Bryce Gibson a40d697542 feat: add createReadStream support for resources 2018-01-22 19:24:13 -05:00
calebboyd 02481f069c fix re-order shim 2018-01-04 13:44:01 -06:00
Andrew Razumovsky cb26021296 fix(rc): regex works to the end of the line (#437) 2017-12-21 22:47:30 -06:00
calebboyd 719804eb2f chore: bump dependencies 2017-12-02 12:52:59 -06:00
calebboyd 721b06f5d2 chore: bump rc 23 2017-11-29 15:52:53 -06:00
calebboyd c1896e13a3 feat: add proxy support (set environment variable HTTPS_PROXY) 2017-11-29 15:49:33 -06:00
calebboyd 931af404ae chore: bump rc 2017-11-26 09:10:04 -06:00
Tim f83298a0af fix(download): remove the ghToken for binary download
The github token is only needed for the API access and will confuse amazon S3 when it is passed to the download:

```
<?xml version="1.0" encoding="UTF-8"?>\n<Error><Code>InvalidArgument</Code><Message>Only one auth mechanism allowed; only the X-Amz-Algorithm query parameter, Signature query string parameter or the Authorization header should be specified</Message><ArgumentName>Authorization</ArgumentName><ArgumentValue>token herebesecrettoken</ArgumentValue><RequestId>7CCDB87CF1347C29</RequestId><HostId>xyyeVP5ImwDePFMXAZheNYLnXQBsVCka4U6KLWKCjynHNpQZxzfBdl4sRfUbORSul8c8YNwux8w=</HostId></Error>
```

Refs #425
2017-11-26 08:08:28 -07:00
calebboyd 717e825b17 chore: lint 2017-11-25 21:53:16 -06:00
calebboyd 5ac0afb0dd feat(options): add ability to pass a github token 2017-11-25 21:51:41 -06:00
18 changed files with 724 additions and 213 deletions
+1
View File
@@ -0,0 +1 @@
package-lock=false
+8 -2
View File
@@ -144,7 +144,7 @@ compile({
- Override in the env with `NEXE_TEMP`
- default: `./.nexe` in the cwd
- #### `ico: string`
- Path to a user provided icon to be used (Windows only).
- Path to a user provided icon to be used (Windows only). Requires `--build` to be set.
- #### `rc: object`
- Settings for patching the [node.rc](https://github.com/nodejs/node/blob/master/src/res/node.rc) configuration file (Windows only).
- Example:
@@ -160,10 +160,16 @@ compile({
- #### `clean: boolean`
- If included, nexe will remove temporary files for the accompanying configuration and exit
- #### `enableNodeCli: boolean`
- Enable the original Node CLI (will prevent application cli from working)
- Enable the original Node CLI (will prevent application cli from working).
- Node CLI arguments passed via the [NODE_OPTIONS](https://nodejs.org/api/cli.html#cli_node_options_options) environment
variable will still be processed. NODE_OPTIONS support can be disabled with the `--without-node-options` configure flag.
- default: `false`
- #### `fakeArgv: boolean`
- fake the entry point file name (`process.argv[1]`). If nexe was used with stdin this will be `'[stdin]'`.
- #### `ghToken: string`
- Provide a Github Token for accessing nexe releases
- This is usually needed in CI environments
- default: `process.env.GITHUB_TOKEN`
- #### `sourceUrl: string`
- Provide an alternate url for the node source code
- Note: temporary files will still be created for this under the specified version
+1 -3
View File
@@ -10,9 +10,7 @@ if (require.main === module) {
process.stderr.write(showHelp ? options.help : options.version + eol)
} else {
const nexe = require('./lib/nexe')
nexe.compile(argv).catch((e) => {
process.stderr.write(eol + e.stack)
})
nexe.compile(argv)
}
} else {
module.exports = require('./lib/nexe')
+6 -5
View File
@@ -2,7 +2,7 @@
"name": "nexe",
"description": "Create a single executable out of your Node.js application",
"license": "MIT",
"version": "2.0.0-rc.20",
"version": "2.0.0-rc.25",
"contributors": [
"Craig Condon <craig.j.condon@gmail.com> (http://crcn.io)",
"Jared Allard <jaredallard@outlook.com>",
@@ -36,10 +36,13 @@
},
"dependencies": {
"app-builder": "^5.1.0",
"typescript": "2.5.3",
"caw": "^2.0.1",
"chalk": "^1.1.3",
"download": "^6.2.0",
"fuse-box": "^2.3.4-beta.11",
"fuse-box": "^3.1.0",
"globby": "^6.1.0",
"got": "^8.0.3",
"minimist": "^1.2.0",
"mkdirp": "^0.5.1",
"ora": "^1.2.0",
@@ -60,10 +63,8 @@
"@types/rimraf": "0.0.28",
"chai": "^4.1.2",
"execa": "^0.8.0",
"got": "^7.1.0",
"mocha": "^3.5.0",
"prettier": "^1.6.1",
"ts-node": "3.3.0",
"typescript": "^2.4.1"
"ts-node": "3.3.0"
}
}
+18 -9
View File
@@ -166,9 +166,9 @@ export class NexeCompiler<T extends NexeOptions = NexeOptions> {
private async _buildAsync() {
this.compileStep.log(
`Configuring node build${this.options.configure.length
? ': ' + this.options.configure
: '...'}`
`Configuring node build${
this.options.configure.length ? ': ' + this.options.configure : '...'
}`
)
await this._configureAsync()
const buildOptions = this.options.make
@@ -180,11 +180,15 @@ export class NexeCompiler<T extends NexeOptions = NexeOptions> {
}
private async _fetchPrebuiltBinaryAsync(target: NexeTarget) {
const downloadOptions: any = {
headers: {
'User-Agent': 'nexe (https://www.npmjs.com/package/nexe)'
}
let downloadOptions = this.options.downloadOptions
if (this.options.ghToken) {
downloadOptions = Object.assign({}, downloadOptions)
downloadOptions.headers = Object.assign({}, downloadOptions.headers, {
Authorization: 'token ' + this.options.ghToken
})
}
const githubRelease = await getLatestGitRelease(downloadOptions)
const assetName = target.toString()
const asset = githubRelease.assets.find(x => x.name === assetName)
@@ -193,7 +197,8 @@ 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(
await download(asset.browser_download_url, dirname(filename), this.options.downloadOptions).on(
'response',
(res: IncomingMessage) => {
const total = +res.headers['content-length']!
@@ -240,6 +245,10 @@ export class NexeCompiler<T extends NexeOptions = NexeOptions> {
return this._assembleDeliverable(binary)
}
code() {
return [this.shims.join(''), this.input].join(';')
}
private _assembleDeliverable(binary: NodeJS.ReadableStream) {
if (this.options.empty) {
return binary
@@ -249,7 +258,7 @@ export class NexeCompiler<T extends NexeOptions = NexeOptions> {
artifact.push(chunk)
})
binary.on('close', () => {
const content = [this.shims.join(''), this.input].join(';')
const content = this.code()
artifact.push(content)
artifact.push(this.resources.bundle)
const lengths = Buffer.from(Array(16))
+25 -15
View File
@@ -1,15 +1,16 @@
import { EOL } from 'os'
import { compose, Middleware } from 'app-builder'
import resource from './steps/resource'
import { rimrafAsync } from './util'
import { NexeTarget } from './target'
import { NexeCompiler } from './compiler'
import { argv, version, help, normalizeOptions, NexeOptions, NexePatch } from './options'
import { normalizeOptions, NexeOptions, NexePatch } from './options'
import resource from './steps/resource'
import cli from './steps/cli'
import bundle from './steps/bundle'
import download from './steps/download'
import shim from './steps/shim'
import artifacts from './steps/artifacts'
import patches from './patches'
import { rimrafAsync } from './util'
import { NexeTarget } from './target'
async function compile(
compilerOptions?: Partial<NexeOptions>,
@@ -34,16 +35,25 @@ async function compile(
const buildSteps = build
? [download, artifacts, ...patches, ...(options.patches as NexePatch[])]
: []
const nexe = compose(resource, bundle, cli, buildSteps, shim, options.plugins as NexePatch[])
return callback
? void nexe(compiler).then(
() => callback && callback(null),
(e: Error) => {
if (callback) callback(e)
else throw e
}
)
: nexe(compiler)
const nexe = compose(resource, bundle, shim, cli, buildSteps, options.plugins as NexePatch[])
let error = null
try {
await nexe(compiler)
} catch (e) {
error = e
}
if (error) {
if (compiler.options.loglevel !== 'silent' && error) {
process.stderr.write(EOL + error.stack + EOL)
}
compiler.quit()
if (callback) return callback(error)
return Promise.reject(error)
}
if (callback) callback(null)
}
export { argv, compile, version, NexeCompiler, NexeOptions, help }
export { compile, NexeCompiler }
export { argv, version, NexeOptions, help } from './options'
+15 -1
View File
@@ -6,6 +6,8 @@ import { getTarget, NexeTarget } from './target'
import { EOL, homedir } from 'os'
import * as c from 'chalk'
const caw = require('caw')
export const version = '{{replace:0}}'
export interface NexePatch {
@@ -33,6 +35,7 @@ export interface NexeOptions {
plugins: (string | NexePatch)[]
native: any
empty: boolean
ghToken: string
sourceUrl?: string
enableStdIn?: boolean
python?: string
@@ -81,7 +84,8 @@ const alias = {
m: 'make',
h: 'help',
l: 'loglevel',
'fake-argv': 'fakeArgv'
'fake-argv': 'fakeArgv',
'gh-token': 'ghToken'
}
const argv = parseArgv(process.argv, { alias, default: { ...defaults, enableStdIn: true } })
const g = c.gray
@@ -221,9 +225,19 @@ function normalizeOptions(input?: Partial<NexeOptions>): NexeOptions {
if (!options.targets.length) {
options.targets.push(getTarget())
}
options.ghToken = options.ghToken || process.env.GITHUB_TOKEN || ''
options.make = flatten(options.vcBuild, options.make)
options.configure = flatten(options.configure)
options.resources = flatten(opts.resource, options.resources)
options.downloadOptions = options.downloadOptions || {}
options.downloadOptions.headers = options.downloadOptions.headers || {}
options.downloadOptions.headers['User-Agent'] = 'nexe (https://www.npmjs.com/package/nexe)'
options.downloadOptions.agent = process.env.HTTPS_PROXY
? caw(process.env.HTTPS_PROXY, { protocol: 'https' })
: options.downloadOptions.agent || require('https').globalAgent
options.downloadOptions.rejectUnauthorized = process.env.HTTPS_PROXY ? false : true
options.rc = options.rc || extractCliMap(/^rc-.*/, options)
options.output =
(options.targets[0] as NexeTarget).platform === 'windows'
+10 -2
View File
@@ -5,8 +5,16 @@ export default async function disableNodeCli(compiler: NexeCompiler, next: () =>
return next()
}
const nodeccMarker = "argv[index][0] == '-'"
const nodeccMarker = 'argv[index][0] =='
await compiler.replaceInFileAsync(
'src/node.cc',
`${nodeccMarker} '-'`,
// allow NODE_OPTIONS, introduced in 8.0
parseInt(compiler.target.version.split('.')[0]) >= 8
? `(${nodeccMarker} (is_env ? '-' : ']'))`
: `(${nodeccMarker} ']')`
)
await compiler.replaceInFileAsync('src/node.cc', nodeccMarker, nodeccMarker.replace('-', ']'))
return next()
}
+2 -2
View File
@@ -1,5 +1,5 @@
import gyp from './gyp'
import nexePatches from './third-party-main'
import bootNexe from './third-party-main'
import buildFixes from './build-fixes'
import cli from './disable-node-cli'
import flags from './flags'
@@ -7,6 +7,6 @@ import ico from './ico'
import rc from './node-rc'
import { NexeCompiler, NexeOptions } from '../compiler'
const patches = [gyp, nexePatches, buildFixes, cli, flags, ico, rc]
const patches = [gyp, bootNexe, buildFixes, cli, flags, ico, rc]
export default patches
+1 -1
View File
@@ -13,7 +13,7 @@ export default async function nodeRc(compiler: NexeCompiler, next: () => Promise
const isVar = /^[A-Z_]+$/.test(value)
value = isVar ? value : `"${value}"`
file.contents = file.contents.replace(
new RegExp(`VALUE "${key}",*`),
new RegExp(`VALUE "${key}",.*`),
`VALUE "${key}", ${value}`
)
})
+1 -1
View File
@@ -14,7 +14,7 @@ function readDirAsync(dir: string): Promise<string[]> {
return Promise.all(
paths.map((file: string) => {
const path = join(dir, file)
return isDirectoryAsync(path).then(x => (x ? readDirAsync(path) : path as any))
return isDirectoryAsync(path).then(x => (x ? readDirAsync(path) : (path as any)))
})
).then(result => {
return [].concat(...(result as any))
+3 -3
View File
@@ -10,7 +10,7 @@ function createBundle(options: NexeOptions) {
if (options.compress) {
plugins.push(
QuantumPlugin({
target: 'server',
target: 'server@esnext',
uglify: true,
bakeApiIntoBundle: options.name
})
@@ -24,7 +24,7 @@ function createBundle(options: NexeOptions) {
sourceMaps: false,
writeBundles: false,
output: '$name.js',
target: 'server',
target: 'server@esnext', //try not to transpile
plugins
})
const input = relative(cwd, resolve(cwd, options.input)).replace(/\\/g, '/')
@@ -49,7 +49,7 @@ export default async function bundle(compiler: NexeCompiler, next: any) {
}
let producer = createBundle
if (typeof compiler.options.bundle === 'string') {
if (typeof bundle === 'string') {
producer = require(resolve(cwd, bundle)).createBundle
}
+3 -3
View File
@@ -62,9 +62,9 @@ export default async function cli(compiler: NexeCompiler, next: () => Promise<vo
const inputFile = relative(process.cwd(), compiler.options.input)
const outputFile = relative(process.cwd(), output)
step.log(
`Entry: '${stdInUsed
? compiler.options.empty ? '[empty]' : '[stdin]'
: inputFile}' written to: ${outputFile}`
`Entry: '${
stdInUsed ? (compiler.options.empty ? '[empty]' : '[stdin]') : inputFile
}' written to: ${outputFile}`
)
resolve(compiler.quit())
}
+20 -1
View File
@@ -16,6 +16,7 @@ if (Object.keys(manifest).length) {
const fs = require('fs')
const originalReadFile = fs.readFile
const originalReadFileSync = fs.readFileSync
const originalCreateReadStream = fs.createReadStream
const originalReaddir = fs.readdir
const originalReaddirSync = fs.readdirSync
const originalStatSync = fs.statSync
@@ -53,7 +54,7 @@ if (Object.keys(manifest).length) {
}
const ownStat = function(path: string | Buffer) {
const key = resolve(path)
const key = resolve(path as string)
if (directories[key]) {
return createStat({ isDirectory, isFile: isNotFile })
}
@@ -139,6 +140,24 @@ if (Object.keys(manifest).length) {
})
})
},
createReadStream: function createReadStream(file: any, options: any) {
setupManifest()
const entry = manifest[file]
if (!entry || !isString(file)) {
return originalCreateReadStream.apply(fs, arguments)
}
const [offset, length] = entry
const resourceOffset = resourceStart + offset
const opts = !options ? {} : isString(options) ? { encoding: options } : options
return fs.createReadStream(
process.execPath,
Object.assign({}, opts, {
start: resourceOffset,
end: resourceOffset + length
})
)
},
readFileSync: function readFileSync(file: any, options: any) {
setupManifest()
const entry = manifest[file]
+1 -1
View File
@@ -65,7 +65,7 @@ export function targetsEqual(a: NexeTarget, b: NexeTarget) {
export function getTarget(target: string | Partial<NexeTarget> = ''): NexeTarget {
const currentArch = process.arch
let arch = currentArch in prettyArch ? prettyArch[process.arch] : process.arch as NodeArch,
let arch = currentArch in prettyArch ? prettyArch[process.arch] : (process.arch as NodeArch),
platform = prettyPlatform[process.platform],
version = process.version.slice(1)
+3 -1
View File
@@ -5,7 +5,9 @@ const { env } = process
export function triggerMacBuild(release: NexeTarget, branch: string) {
assert.ok(env.CIRCLE_TOKEN)
const circle = `https://circleci.com/api/v1.1/project/github/nexe/nexe/tree/${branch}?circle-token=${env.CIRCLE_TOKEN}`
const circle = `https://circleci.com/api/v1.1/project/github/nexe/nexe/tree/${branch}?circle-token=${
env.CIRCLE_TOKEN
}`
return got(circle, {
json: true,
body: {
+1 -1
View File
@@ -1,7 +1,7 @@
import { writeFileSync, readFileSync } from 'fs'
/**
* post build step to insert code files into code files.
* post build step to insert code files into code files.
* '{{replace:path/to/file}}' => "file contents"
* And the package.json version.
*/
+605 -162
View File
File diff suppressed because it is too large Load Diff