Compare commits

...

12 Commits

Author SHA1 Message Date
calebboyd 1e54736fec fix: serialize shims/resources in upstream step
closes #677
2019-10-09 12:20:53 -05:00
calebboyd 4112bd7b3e fix: multistream export cast 2019-10-09 10:54:52 -05:00
calebboyd 5ec04f5791 chore: update buildable versions 2019-10-09 09:42:19 -05:00
Nathan Poirier 098a746e0d fix: support fs.stat options (#665) 2019-09-18 14:22:24 -05:00
Jared Allard cc2c5e31fc feat: use github issues/pr templates v2 (#663) 2019-08-22 13:51:43 -05:00
Caleb Boyd fe26b540de fix: arm arch mapping (#662) 2019-08-22 10:52:24 -05:00
bruce-one a143c470fb fix: support NODE_OPTIONS in newer node versions (#660)
And use `$&` for code simplification.
2019-08-22 09:44:03 -05:00
calebboyd eb887363de fix(build): fix ci task execa types 2019-08-06 14:57:24 -05:00
calebboyd de9894cf47 feat: variable import resolution
BREAKING: node 6 is no longer supported
2019-07-31 16:15:37 -05:00
dependabot[bot] 2e2d381969 build(deps): bump lodash from 4.17.11 to 4.17.14 (#651) 2019-07-15 10:36:54 -05:00
calebboyd 7d0f435bef chore: pipeline troubleshooting 2019-07-11 15:09:34 -05:00
calebboyd efd3dfc35a fix: windows build 10.16 2019-06-25 15:32:32 -05:00
19 changed files with 566 additions and 1443 deletions
+23
View File
@@ -0,0 +1,23 @@
---
name: Bug Report
about: Report a bug encountered while running Nexe
labels: bug
---
<!-- Please use this template while reporting a bug and provide as much info as possible. Not doing so may result in your bug not being addressed in a timely manner. Thanks!
-->
**What happened**:
**What you expected to happen**:
**How to reproduce it (as minimally and precisely as possible)**:
**Anything else we need to know?**:
**Environment**:
- Platform(OS/Version):
- Host Node Version:
- Target Node Version:
- Nexe version:
- Python Version:
+11
View File
@@ -0,0 +1,11 @@
---
name: Feature Request
about: Suggest an feature request
labels: feature
---
<!-- Please only use this template for submitting feature requests -->
**What would you like to be added**:
**Why is this needed**:
+11
View File
@@ -0,0 +1,11 @@
**What this PR does / why we need it**:
**Which issue(s) this PR fixes**:
<!--
*Automatically closes linked issue when PR is merged.
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
_If PR is about `failing-tests or flakes`, please post the related issues/tests in a comment and do not use `Fixes`_*
-->
Fixes #
**Special notes for your reviewer**:
+11 -3
View File
@@ -50,11 +50,19 @@ jobs:
- script: choco install visualcpp-build-tools --version 14.0.25420.1 -fy && npm config set msvs_version 2015 - script: choco install visualcpp-build-tools --version 14.0.25420.1 -fy && npm config set msvs_version 2015
condition: contains(variables['Agent.JobName'], 'windows_2015') condition: contains(variables['Agent.JobName'], 'windows_2015')
displayName: Install Windows build dependencies displayName: Install Windows build dependencies
- script: choco install nasm -fy
displayName: Install Windows Assembler (NASM)
condition: contains(variables['Agent.JobName'], 'windows')
- script: npm install && npm run ci:build - script: npm install && npm run ci:build
displayName: Build Nexe displayName: Build Nexe
env: env:
GITHUB_TOKEN: $(PersonalGithubToken) GITHUB_TOKEN: $(PersonalGithubToken)
NEXE_VERBOSE: $(NEXE_VERBOSE) NEXE_VERBOSE: $(NEXE_VERBOSE)
condition: not(contains(variables['Agent.JobName'], 'windows'))
- powershell: |
iex (new-object net.webclient).downloadstring('https://get.scoop.sh')
scoop install nasm
npm install
npm run ci:build
displayName: Build Nexe (Windows)
condition: contains(variables['Agent.JobName'], 'windows')
env:
GITHUB_TOKEN: $(PersonalGithubToken)
NEXE_VERBOSE: $(NEXE_VERBOSE)
-19
View File
@@ -1,19 +0,0 @@
<!-- If you need help or think you have found a bug, please help us with your issue by entering the following information (otherwise you can delete this text): -->
**Is this a BUG or a FEATURE REQUEST?:**
**What happened:**
**What you expected to happen:**
**How to reproduce it (as minimally and precisely as possible):**
**Anything else we need to know?:**
**Environment**
- Platform(OS/Version):
- Host Node Version:
- Target Node Version:
- Nexe version:
- Python Version:
+422 -1356
View File
File diff suppressed because it is too large Load Diff
+14 -14
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.3.1", "version": "4.0.0-beta.3",
"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,22 +39,22 @@
"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.2.0", "globby": "^10.0.1",
"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": "^4.0.0",
"ora": "^3.4.0", "ora": "^3.4.0",
"pify": "^4.0.1", "pify": "^4.0.1",
"resolve-dependencies": "^2.2.3", "resolve-dependencies": "^3.0.2",
"rimraf": "^2.6.3" "rimraf": "^3.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/chai": "^4.1.7", "@types/chai": "^4.2.3",
"@types/download": "^6.2.4", "@types/download": "^6.2.4",
"@types/execa": "^0.9.0", "@types/execa": "^2.0.0",
"@types/globby": "^9.1.0", "@types/globby": "^9.1.0",
"@types/got": "^9.6.0", "@types/got": "^9.6.7",
"@types/minimist": "^1.2.0", "@types/minimist": "^1.2.0",
"@types/mkdirp": "^0.5.2", "@types/mkdirp": "^0.5.2",
"@types/mocha": "^5.2.7", "@types/mocha": "^5.2.7",
@@ -62,15 +62,15 @@
"@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": "^6.0.0", "@types/semver": "^6.0.2",
"chai": "^4.2.0", "chai": "^4.2.0",
"execa": "^1.0.0", "execa": "^2.1.0",
"mocha": "^6.1.4", "mocha": "^6.2.1",
"prettier": "^1.18.2", "prettier": "^1.18.2",
"ts-node": "^8.3.0", "ts-node": "^8.4.1",
"tslint": "^5.17.0", "tslint": "^5.20.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.5.2" "typescript": "^3.6.3"
} }
} }
+5 -5
View File
@@ -15,7 +15,7 @@ import {
} from './util' } from './util'
import { NexeOptions, version } from './options' import { NexeOptions, version } from './options'
import { NexeTarget } from './target' import { NexeTarget } from './target'
import combineStreams = require('multistream') import MultiStream = require('multistream')
import { Bundle, toStream } from './fs/bundle' import { Bundle, toStream } from './fs/bundle'
const isBsd = Boolean(~process.platform.indexOf('bsd')) const isBsd = Boolean(~process.platform.indexOf('bsd'))
@@ -136,8 +136,8 @@ export class NexeCompiler {
} }
@bound @bound
addResource(file: string, content?: Buffer | string) { addResource(absoluteFileName: string, content?: Buffer | string) {
return this.bundle.addResource(file, content) return this.bundle.addResource(absoluteFileName, content)
} }
get binaryConfiguration() { get binaryConfiguration() {
@@ -237,7 +237,7 @@ export class NexeCompiler {
} }
private _configureAsync() { private _configureAsync() {
if (isWindows && semverGt(this.target.version, '11.999')) { if (isWindows && semverGt(this.target.version, '10.15.99')) {
return Promise.resolve() return Promise.resolve()
} }
return this._runBuildCommandAsync(this.env.PYTHON || 'python', [ return this._runBuildCommandAsync(this.env.PYTHON || 'python', [
@@ -309,7 +309,7 @@ export class NexeCompiler {
const lengths = Buffer.from(Array(16)) const lengths = Buffer.from(Array(16))
lengths.writeDoubleLE(codeSize, 0) lengths.writeDoubleLE(codeSize, 0)
lengths.writeDoubleLE(this.bundle.blobSize, 8) lengths.writeDoubleLE(this.bundle.blobSize, 8)
return combineStreams([ return new (MultiStream as any)([
binary, binary,
toStream(startup), toStream(startup),
this.bundle.toStream(), this.bundle.toStream(),
+8 -5
View File
@@ -1,7 +1,7 @@
import { stat as getStat, Stats, createReadStream } from 'fs' import { stat as getStat, Stats, createReadStream } from 'fs'
import { relative } from 'path' import { relative } from 'path'
import { Readable } from 'stream' import { Readable } from 'stream'
import combineStreams = require('multistream') import MultiStream = require('multistream')
const stat = (file: string): Promise<Stats> => { const stat = (file: string): Promise<Stats> => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@@ -14,9 +14,12 @@ function makeRelative(cwd: string, path: string) {
} }
export function toStream(content: Buffer | string) { export function toStream(content: Buffer | string) {
const readable = new Readable({ read() {} }) const readable = new Readable({
readable.push(content) read() {
readable.push(null) this.push(content)
this.push(null)
}
})
return readable return readable
} }
@@ -61,7 +64,7 @@ export class Bundle {
} }
toStream() { toStream() {
return combineStreams(this.streams) return new (MultiStream as any)(this.streams)
} }
toJSON() { toJSON() {
+28 -9
View File
@@ -75,21 +75,34 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
} }
} }
const createStat = function(extensions: any) { let BigInt: Function
return Object.assign(new fs.Stats(), binary.layout.stat, statTime(), extensions) try {
BigInt = eval('BigInt')
} catch (ignored) {}
const createStat = function(extensions: any, options: any) {
const stat = Object.assign(new fs.Stats(), binary.layout.stat, statTime(), extensions)
if (options && options.bigint && BigInt) {
for (const k in stat) {
if (Object.prototype.hasOwnProperty.call(stat, k) && typeof stat[k] === 'number') {
stat[k] = BigInt(stat[k])
}
}
}
return stat
} }
const ownStat = function(filepath: any) { const ownStat = function(filepath: any, options: any) {
setupManifest() setupManifest()
const key = getKey(filepath) const key = getKey(filepath)
if (directories[key]) { if (directories[key]) {
let mode = binary.layout.stat.mode let mode = binary.layout.stat.mode
mode |= fs.constants.S_IFDIR mode |= fs.constants.S_IFDIR
mode &= ~fs.constants.S_IFREG mode &= ~fs.constants.S_IFREG
return createStat({ mode, size: 0 }) return createStat({ mode, size: 0 }, options)
} }
if (manifest[key]) { if (manifest[key]) {
return createStat({ size: manifest[key][1] }) return createStat({ size: manifest[key][1] }, options)
} }
} }
@@ -250,15 +263,21 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
originalFsMethods.closeSync(fd) originalFsMethods.closeSync(fd)
return encoding ? result.toString(encoding) : result return encoding ? result.toString(encoding) : result
}, },
statSync: function statSync(filepath: string | Buffer) { statSync: function statSync(filepath: string | Buffer, options: any) {
const stat = ownStat(filepath) const stat = ownStat(filepath, options)
if (stat) { if (stat) {
return stat return stat
} }
return originalFsMethods.statSync.apply(fs, arguments) return originalFsMethods.statSync.apply(fs, arguments)
}, },
stat: function stat(filepath: string | Buffer, callback: any) { stat: function stat(filepath: string | Buffer, options: any, callback: any) {
const stat = ownStat(filepath) let stat: any
if (typeof options === 'function') {
callback = options
stat = ownStat(filepath, null)
} else {
stat = ownStat(filepath, options)
}
if (stat) { if (stat) {
process.nextTick(() => { process.nextTick(() => {
callback(null, stat) callback(null, stat)
+4 -4
View File
@@ -5,7 +5,7 @@ import { basename, extname, join, isAbsolute, resolve } from 'path'
import { getTarget, NexeTarget } from './target' import { getTarget, NexeTarget } from './target'
import { EOL, homedir } from 'os' import { EOL, homedir } from 'os'
import chalk from 'chalk' import chalk from 'chalk'
import { resolveFileNameSync } from 'resolve-dependencies' import { resolveSync } from 'resolve-dependencies'
const caw = require('caw') const caw = require('caw')
const c = process.platform === 'win32' ? chalk.constructor({ enabled: false }) : chalk const c = process.platform === 'win32' ? chalk.constructor({ enabled: false }) : chalk
@@ -208,17 +208,17 @@ export function resolveEntry(
} }
if (input) { if (input) {
const inputPath = padRelative(input) const inputPath = padRelative(input)
result = resolveFileNameSync(cwd, inputPath) result = resolveSync(cwd, inputPath)
} }
if (isEntryFile(maybeEntry) && (!result || !result.absPath)) { if (isEntryFile(maybeEntry) && (!result || !result.absPath)) {
const inputPath = padRelative(maybeEntry) const inputPath = padRelative(maybeEntry)
result = resolveFileNameSync(cwd, inputPath) result = resolveSync(cwd, inputPath)
} }
if (!process.stdin.isTTY && (!result || !result.absPath) && bundle === defaults.bundle) { if (!process.stdin.isTTY && (!result || !result.absPath) && bundle === defaults.bundle) {
return STDIN_FLAG return STDIN_FLAG
} }
if (!result || !result.absPath) { if (!result || !result.absPath) {
result = resolveFileNameSync(cwd, '.') result = resolveSync(cwd, '.')
} }
if (!result.absPath) { if (!result.absPath) {
throw new NexeError(`Entry file "${input || ''}" not found!`) throw new NexeError(`Entry file "${input || ''}" not found!`)
+2 -6
View File
@@ -7,13 +7,9 @@ export default async function disableNodeCli(compiler: NexeCompiler, next: () =>
} }
if (semverGt(compiler.target.version, '11.6.0')) { if (semverGt(compiler.target.version, '11.6.0')) {
await compiler.replaceInFileAsync( await compiler.replaceInFileAsync('src/node.cc', /(?<!int )ProcessGlobalArgs\(argv/g, '0;//$&')
'src/node.cc',
/(?<!int )ProcessGlobalArgs\(/g,
'0;//ProcessGlobalArgs('
)
} else if (semverGt(compiler.target.version, '10.9')) { } else if (semverGt(compiler.target.version, '10.9')) {
await compiler.replaceInFileAsync('src/node.cc', /(?<!void )ProcessArgv\(/g, '//ProcessArgv(') await compiler.replaceInFileAsync('src/node.cc', /(?<!void )ProcessArgv\(argv/g, '//$&')
} else if (semverGt(compiler.target.version, '9.999')) { } else if (semverGt(compiler.target.version, '9.999')) {
await compiler.replaceInFileAsync( await compiler.replaceInFileAsync(
'src/node.cc', 'src/node.cc',
+8 -3
View File
@@ -2,7 +2,7 @@ import got = require('got')
import { platforms, architectures, NexeTarget, getTarget, targetsEqual } from './target' import { platforms, architectures, NexeTarget, getTarget, targetsEqual } from './target'
export { NexeTarget } export { NexeTarget }
const versionsToSkip = [0, 1, 2, 3, 4, 5, 7, 9, 11] const versionsToSkip = [0, 1, 2, 3, 4, 5, 7, 9, 11, 13, 15, 17, 19, 21, 22]
export interface GitAsset { export interface GitAsset {
name: string name: string
url: string url: string
@@ -25,8 +25,13 @@ async function getJson<T>(url: string, options?: any) {
} }
function isBuildableVersion(version: string) { function isBuildableVersion(version: string) {
const major = Number(version.split('.')[0]) if (version === '12.11.0') {
return !versionsToSkip.includes(major) || version === '4.8.4' return false
}
if (version === '4.9.1') {
return true
}
return !versionsToSkip.includes(Number(version.split('.')[0]))
} }
export function getLatestGitRelease(options?: any) { export function getLatestGitRelease(options?: any) {
+3 -3
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, { resolveFileNameSync } from 'resolve-dependencies' import resolveFiles, { resolveSync } from 'resolve-dependencies'
import { dequote, STDIN_FLAG, semverGt } from '../util' import { dequote, STDIN_FLAG, semverGt } from '../util'
import { Readable } from 'stream' import { Readable } from 'stream'
@@ -54,7 +54,7 @@ export default async function bundle(compiler: NexeCompiler, next: any) {
} }
if (input === STDIN_FLAG) { if (input === STDIN_FLAG) {
const maybeInput = resolveFileNameSync(cwd, '.') const maybeInput = resolveSync(cwd, '.')
if (!maybeInput || !maybeInput.absPath) { if (!maybeInput || !maybeInput.absPath) {
throw new NexeError('No valid input detected') throw new NexeError('No valid input detected')
} }
@@ -65,7 +65,7 @@ export default async function bundle(compiler: NexeCompiler, next: any) {
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')),
{ cwd, expand: true, loadContent: false } { cwd, expand: 'variable', loadContent: false }
) )
if ( if (
+1 -1
View File
@@ -1,5 +1,5 @@
import { isDirectoryAsync, each } from '../util' import { isDirectoryAsync, each } from '../util'
import globs from 'globby' import * as globs from 'globby'
import { NexeCompiler } from '../compiler' import { NexeCompiler } from '../compiler'
export default async function resource(compiler: NexeCompiler, next: () => Promise<any>) { export default async function resource(compiler: NexeCompiler, next: () => Promise<any>) {
+3 -3
View File
@@ -1,7 +1,9 @@
import { NexeCompiler } from '../compiler' import { NexeCompiler } from '../compiler'
import { wrap } from '../util' import { wrap } from '../util'
export default function(compiler: NexeCompiler, next: () => Promise<void>) { export default async function(compiler: NexeCompiler, next: () => Promise<void>) {
await next()
compiler.shims.push( compiler.shims.push(
wrap( wrap(
`process.__nexe = ${JSON.stringify(compiler.binaryConfiguration)};\n` + `process.__nexe = ${JSON.stringify(compiler.binaryConfiguration)};\n` +
@@ -32,6 +34,4 @@ export default function(compiler: NexeCompiler, next: () => Promise<void>) {
} }
`) `)
) )
return next()
} }
+7 -7
View File
@@ -1,8 +1,8 @@
export type NodePlatform = 'windows' | 'mac' | 'alpine' | 'linux' export type NodePlatform = 'windows' | 'mac' | 'alpine' | 'linux'
export type NodeArch = 'x86' | 'x64' | 'arm7l' | 'arm6l' | 'arm64' export type NodeArch = 'x86' | 'x64' | 'arm' | 'arm64'
const platforms: NodePlatform[] = ['windows', 'mac', 'alpine', 'linux'], const platforms: NodePlatform[] = ['windows', 'mac', 'alpine', 'linux'],
architectures: NodeArch[] = ['x86', 'x64', 'arm7l', 'arm6l', 'arm64'] architectures: NodeArch[] = ['x86', 'x64', 'arm', 'arm64']
export { platforms, architectures } export { platforms, architectures }
@@ -26,12 +26,12 @@ const prettyPlatform: { [key: string]: NodePlatform } = {
const prettyArch: { [key: string]: NodeArch } = { const prettyArch: { [key: string]: NodeArch } = {
x86: 'x86', x86: 'x86',
arm6: 'arm6l', arm6: 'arm',
arm64: 'arm64', arm64: 'arm64',
arm6l: 'arm6l', arm6l: 'arm',
arm: 'arm7l', arm: 'arm',
arm7: 'arm7l', arm7: 'arm',
arm7l: 'arm7l', arm7l: 'arm',
amd64: 'x64', amd64: 'x64',
ia32: 'x86', ia32: 'x86',
x32: 'x86', x32: 'x86',
+1 -1
View File
@@ -4,7 +4,7 @@ import { runDockerBuild } from './docker'
import { getTarget, targetsEqual, NexeTarget } from '../lib/target' import { getTarget, targetsEqual, NexeTarget } from '../lib/target'
import { pathExistsAsync, readFileAsync, execFileAsync, semverGt } from '../lib/util' import { pathExistsAsync, readFileAsync, execFileAsync, semverGt } from '../lib/util'
import got = require('got') import got = require('got')
import { cpus } from 'os'; import { cpus } from 'os'
const env = process.env, const env = process.env,
isPullRequest = env.BUILD_REASON === 'PullRequest', isPullRequest = env.BUILD_REASON === 'PullRequest',
+4 -4
View File
@@ -46,10 +46,10 @@ export async function runDockerBuild(target: NexeTarget) {
let output: any = [] let output: any = []
try { try {
output.push(await execa.shell(`docker build -t nexe-docker .`)) output.push(await execa(`docker build -t nexe-docker .`, { shell: true }))
output.push(await execa.shell(`docker run -d --name nexe nexe-docker sh`)) output.push(await execa(`docker run -d --name nexe nexe-docker sh`, { shell: true }))
output.push(await execa.shell(`docker cp nexe:/out out`)) output.push(await execa(`docker cp nexe:/out out`, { shell: true }))
output.push(await execa.shell(`docker rm nexe`)) output.push(await execa(`docker rm nexe`, { shell: true }))
} catch (e) { } catch (e) {
console.log('Error running docker') console.log('Error running docker')
appendFileSync(outFilename, e.message) appendFileSync(outFilename, e.message)