Compare commits

..

3 Commits

Author SHA1 Message Date
calebboyd 7c539db738 chore: bump resolve-dependencies 2020-06-26 10:26:53 -05:00
calebboyd ae51cc6b87 fix: set explicit release 2020-06-21 20:16:45 -05:00
calebboyd cf23147c9c fix: windows build 10.16 2019-06-24 15:57:54 -05:00
29 changed files with 1771 additions and 928 deletions
-23
View File
@@ -1,23 +0,0 @@
---
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
@@ -1,11 +0,0 @@
---
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
@@ -1,11 +0,0 @@
**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**:
+2 -1
View File
@@ -49,7 +49,8 @@ Additional files or resources can be added to the binary by passing `-r "glob/pa
## Compiling Node
By default `nexe` will attempt to download a pre-built executable. These are listed on the [Nexe V3 releases page](https://github.com/nexe/nexe/releases/tag/v3.0.0). The exact version you want may be unavailable or you may want to customize what is built. See `nexe --help` for a list of options available when passing the [`--build`](#build-boolean) option. You will also need to ensure your environment is setup to [build node](https://github.com/nodejs/node/blob/master/BUILDING.md). Note: the `python` binary in your path should be an acceptable version of python 2. eg. Systems that have python2 will need to create a [symlink](https://github.com/nexe/nexe/issues/354#issuecomment-319874486).
By default `nexe` will attempt to download a pre-built executable. However, It may be unavailable ([github releases](https://github.com/nexe/nexe/releases))
or you may want to customize what is built. See `nexe --help` for a list of options available when passing the [`--build`](#build-boolean) option. You will also need to ensure your environment is setup to [build node](https://github.com/nodejs/node/blob/master/BUILDING.md). Note: the `python` binary in your path should be an acceptable version of python 2. eg. Systems that have python2 will need to create a [symlink](https://github.com/nexe/nexe/issues/354#issuecomment-319874486).
## Node.js API
+4 -12
View File
@@ -19,7 +19,7 @@ schedules:
- master
jobs:
- job: BaseBuild
timeoutInMinutes: 360
timeoutInMinutes: 180
strategy:
matrix:
linux:
@@ -50,19 +50,11 @@ jobs:
- 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')
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
displayName: Build Nexe
env:
GITHUB_TOKEN: $(PersonalGithubToken)
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
@@ -0,0 +1,19 @@
<!-- 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:
+1558 -649
View File
File diff suppressed because it is too large Load Diff
+22 -22
View File
@@ -2,7 +2,7 @@
"name": "nexe",
"description": "Create a single executable out of your Node.js application",
"license": "MIT",
"version": "4.0.0-beta.6",
"version": "3.3.4",
"contributors": [
"Craig Condon <craig.j.condon@gmail.com> (http://crcn.io)",
"Jared Allard <jaredallard@outlook.com>",
@@ -34,43 +34,43 @@
},
"dependencies": {
"@calebboyd/semaphore": "^1.3.1",
"app-builder": "^6.2.2",
"app-builder": "^5.2.0",
"caw": "^2.0.1",
"chalk": "^2.4.2",
"cherow": "1.6.9",
"download": "^7.1.0",
"globby": "^10.0.1",
"globby": "^9.2.0",
"got": "^9.6.0",
"minimist": "^1.2.5",
"mkdirp": "^1.0.4",
"multistream": "^4.0.0",
"minimist": "^1.2.0",
"mkdirp": "^0.5.1",
"multistream": "^2.1.1",
"ora": "^3.4.0",
"pify": "^4.0.1",
"resolve-dependencies": "^4.0.0",
"rimraf": "^3.0.0"
"resolve-dependencies": "^4.2.2",
"rimraf": "^2.6.3"
},
"devDependencies": {
"@types/chai": "^4.2.11",
"@types/chai": "^4.1.7",
"@types/download": "^6.2.4",
"@types/execa": "^2.0.0",
"@types/execa": "^0.9.0",
"@types/globby": "^9.1.0",
"@types/got": "^9.6.10",
"@types/got": "^9.6.0",
"@types/minimist": "^1.2.0",
"@types/mkdirp": "^1.0.0",
"@types/mocha": "^7.0.2",
"@types/mkdirp": "^0.5.2",
"@types/mocha": "^5.2.7",
"@types/multistream": "^2.1.1",
"@types/ora": "^3.2.0",
"@types/pify": "3.0.2",
"@types/rimraf": "3.0.0",
"@types/semver": "^7.1.0",
"@types/rimraf": "2.0.2",
"@types/semver": "^6.0.0",
"chai": "^4.2.0",
"execa": "^4.0.0",
"mocha": "^7.1.1",
"prettier": "^2.0.5",
"ts-node": "^8.9.0",
"tslint": "^6.1.1",
"execa": "^1.0.0",
"mocha": "^6.1.4",
"prettier": "^1.18.2",
"ts-node": "^8.3.0",
"tslint": "^5.17.0",
"tslint-config-prettier": "^1.18.0",
"tslint-plugin-prettier": "^2.3.0",
"typescript": "^3.8.3"
"tslint-plugin-prettier": "^2.0.1",
"typescript": "^3.5.2"
}
}
+12 -12
View File
@@ -11,11 +11,11 @@ import {
dequote,
isWindows,
bound,
semverGt,
semverGt
} from './util'
import { NexeOptions, version } from './options'
import { NexeTarget } from './target'
import MultiStream = require('multistream')
import combineStreams = require('multistream')
import { Bundle, toStream } from './fs/bundle'
const isBsd = Boolean(~process.platform.indexOf('bsd'))
@@ -112,7 +112,7 @@ export class NexeCompiler {
this.remoteAsset = options.asset
} else {
this.remoteAsset =
'https://github.com/nexe/nexe/releases/download/v3.0.0/' + this.target.toString()
'https://github.com/nexe/nexe/releases/download/v3.3.3/' + this.target.toString()
}
this.src = join(this.options.temp, this.target.version)
this.configureScript = configure + (semverGt(this.target.version, '10.10.0') ? '.py' : '')
@@ -136,8 +136,8 @@ export class NexeCompiler {
}
@bound
addResource(absoluteFileName: string, content?: Buffer | string) {
return this.bundle.addResource(absoluteFileName, content)
addResource(file: string, content?: Buffer | string) {
return this.bundle.addResource(file, content)
}
get binaryConfiguration() {
@@ -151,16 +151,16 @@ export class NexeCompiler {
@bound
async readFileAsync(file: string) {
this.assertBuild()
let cachedFile = this.files.find((x) => normalize(x.filename) === normalize(file))
let cachedFile = this.files.find(x => normalize(x.filename) === normalize(file))
if (!cachedFile) {
const absPath = join(this.src, file)
cachedFile = {
absPath,
filename: file,
contents: await readFileAsync(absPath, 'utf-8').catch((x) => {
contents: await readFileAsync(absPath, 'utf-8').catch(x => {
if (x.code === 'ENOENT') return ''
throw x
}),
})
}
this.files.push(cachedFile)
}
@@ -215,7 +215,7 @@ export class NexeCompiler {
spawn(command, args, {
cwd: this.src,
env: this.env,
stdio: this.log.verbose ? 'inherit' : 'ignore',
stdio: this.log.verbose ? 'inherit' : 'ignore'
})
.once('error', (e: Error) => {
if (this.log.verbose) {
@@ -242,7 +242,7 @@ export class NexeCompiler {
}
return this._runBuildCommandAsync(this.env.PYTHON || 'python', [
this.configureScript,
...this.options.configure,
...this.options.configure
])
}
@@ -309,11 +309,11 @@ export class NexeCompiler {
const lengths = Buffer.from(Array(16))
lengths.writeDoubleLE(codeSize, 0)
lengths.writeDoubleLE(this.bundle.blobSize, 8)
return new (MultiStream as any)([
return combineStreams([
binary,
toStream(startup),
this.bundle.toStream(),
toStream(Buffer.concat([Buffer.from('<nexe~~sentinel>'), lengths])),
toStream(Buffer.concat([Buffer.from('<nexe~~sentinel>'), lengths]))
])
}
}
+5 -8
View File
@@ -1,7 +1,7 @@
import { stat as getStat, Stats, createReadStream } from 'fs'
import { relative } from 'path'
import { Readable } from 'stream'
import MultiStream = require('multistream')
import combineStreams = require('multistream')
const stat = (file: string): Promise<Stats> => {
return new Promise((resolve, reject) => {
@@ -14,12 +14,9 @@ function makeRelative(cwd: string, path: string) {
}
export function toStream(content: Buffer | string) {
const readable = new Readable({
read() {
this.push(content)
this.push(null)
},
})
const readable = new Readable({ read() {} })
readable.push(content)
readable.push(null)
return readable
}
@@ -64,7 +61,7 @@ export class Bundle {
}
toStream() {
return new (MultiStream as any)(this.streams)
return combineStreams(this.streams)
}
toJSON() {
+35 -63
View File
@@ -15,12 +15,6 @@ export interface NexeBinary {
let originalFsMethods: any = null
let lazyRestoreFs = () => {}
// optional Win32 file namespace prefix followed by drive letter and colon
const windowsFullPathRegex = /^(\\{2}\?\\)?([a-zA-Z]):/
const upcaseDriveLetter = (s: string): string =>
s.replace(windowsFullPathRegex, (_match, ns, drive) => `${ns || ''}${drive.toUpperCase()}:`)
function shimFs(binary: NexeBinary, fs: any = require('fs')) {
if (originalFsMethods !== null) {
return
@@ -34,21 +28,18 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
isString = (x: any): x is string => typeof x === 'string' || x instanceof String,
noop = () => {},
path = require('path'),
winPath: (key: string) => string = isWin ? upcaseDriveLetter : (s) => s,
baseDir = winPath(path.dirname(process.execPath))
baseDir = path.dirname(process.execPath)
let log = (_: string) => true
let loggedManifest = false
if ((process.env.DEBUG || '').toLowerCase().includes('nexe:require')) {
log = (text: string) => {
setupManifest()
if (!loggedManifest) {
process.stderr.write('[nexe] - MANIFEST' + JSON.stringify(manifest, null, 4) + '\n')
process.stderr.write('[nexe] - DIRECTORIES' + JSON.stringify(directories, null, 4) + '\n')
loggedManifest = true
}
return process.stderr.write('[nexe] - ' + text + '\n')
log = (text: string) => process.stderr.write('[nexe] - ' + text + '\n')
}
const winPath = (key: string) => {
if (isWin && key.substr(1, 2) === ':\\') {
key = key[0].toUpperCase() + key.substr(1)
}
return key
}
const getKey = function getKey(filepath: string | Buffer | null): string {
@@ -63,7 +54,7 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
return winPath(key)
}
const statTime = function () {
const statTime = function() {
return {
dev: 0,
ino: 0,
@@ -80,38 +71,25 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
ctime: new Date(stat.ctime),
ctimMs: stat.ctime.getTime(),
birthtime: new Date(stat.birthtime),
birthtimeMs: stat.birthtime.getTime(),
birthtimeMs: stat.birthtime.getTime()
}
}
let BigInt: Function
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 createStat = function(extensions: any) {
return Object.assign(new fs.Stats(), binary.layout.stat, statTime(), extensions)
}
const ownStat = function (filepath: any, options: any) {
const ownStat = function(filepath: any) {
setupManifest()
const key = getKey(filepath)
if (directories[key]) {
let mode = binary.layout.stat.mode
mode |= fs.constants.S_IFDIR
mode &= ~fs.constants.S_IFREG
return createStat({ mode, size: 0 }, options)
return createStat({ mode, size: 0 })
}
if (manifest[key]) {
return createStat({ size: manifest[key][1] }, options)
return createStat({ size: manifest[key][1] })
}
}
@@ -124,7 +102,7 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
}
let setupManifest = () => {
Object.keys(manifest).forEach((filepath) => {
Object.keys(manifest).forEach(filepath => {
const entry = manifest[filepath]
const absolutePath = getKey(filepath)
const longPath = makeLong(absolutePath)
@@ -218,19 +196,19 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
const encoding = fileOpts(options).encoding
callback = typeof options === 'function' ? options : callback
originalFsMethods.open(blobPath, 'r', function (err: Error, fd: number) {
originalFsMethods.open(blobPath, 'r', function(err: Error, fd: number) {
if (err) return callback(err, null)
originalFsMethods.read(fd, Buffer.alloc(length), 0, length, resourceOffset, function (
originalFsMethods.read(fd, Buffer.alloc(length), 0, length, resourceOffset, function(
error: Error,
bytesRead: number,
result: Buffer
) {
if (error) {
return originalFsMethods.close(fd, function () {
return originalFsMethods.close(fd, function() {
callback(error, null)
})
}
originalFsMethods.close(fd, function (err: Error) {
originalFsMethods.close(fd, function(err: Error) {
if (err) {
return callback(err, result)
}
@@ -253,7 +231,7 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
blobPath,
Object.assign({}, opts, {
start: resourceOffset,
end: resourceOffset + length - 1,
end: resourceOffset + length - 1
})
)
},
@@ -272,21 +250,15 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
originalFsMethods.closeSync(fd)
return encoding ? result.toString(encoding) : result
},
statSync: function statSync(filepath: string | Buffer, options: any) {
const stat = ownStat(filepath, options)
statSync: function statSync(filepath: string | Buffer) {
const stat = ownStat(filepath)
if (stat) {
return stat
}
return originalFsMethods.statSync.apply(fs, arguments)
},
stat: function stat(filepath: string | Buffer, options: any, callback: any) {
let stat: any
if (typeof options === 'function') {
callback = options
stat = ownStat(filepath, null)
} else {
stat = ownStat(filepath, options)
}
stat: function stat(filepath: string | Buffer, callback: any) {
const stat = ownStat(filepath)
if (stat) {
process.nextTick(() => {
callback(null, stat)
@@ -294,11 +266,11 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
} else {
return originalFsMethods.stat.apply(fs, arguments)
}
},
}
}
if (typeof fs.exists === 'function') {
nfs.exists = function (filepath: string, cb: Function) {
nfs.exists = function(filepath: string, cb: Function) {
cb = cb || noop
const exists = nfs.existsSync(filepath)
process.nextTick(() => cb(exists))
@@ -307,9 +279,9 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
const patches = (process as any).nexe.patches || {}
delete (process as any).nexe
patches.internalModuleReadFile = function (this: any, original: any, ...args: any[]) {
patches.internalModuleReadFile = function(this: any, original: any, ...args: any[]) {
const [filepath] = args
setupManifest()
const filepath = getKey(args[0])
if (manifest[filepath]) {
log('read (hit) ' + filepath)
return nfs.readFileSync(filepath, 'utf-8')
@@ -318,9 +290,9 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
return original.call(this, ...args)
}
patches.internalModuleReadJSON = patches.internalModuleReadFile
patches.internalModuleStat = function (this: any, original: any, ...args: any[]) {
patches.internalModuleStat = function(this: any, original: any, ...args: any[]) {
setupManifest()
const filepath = getKey(args[0])
const [filepath] = args
if (manifest[filepath]) {
log('stat (hit) ' + filepath + ' ' + 0)
return 0
@@ -341,7 +313,7 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
}
if (typeof fs.exists === 'function') {
nfs.exists = function (filepath: string, cb: Function) {
nfs.exists = function(filepath: string, cb: Function) {
cb = cb || noop
const exists = nfs.existsSync(filepath)
if (!exists) {
@@ -352,7 +324,7 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
}
if (typeof fs.copyFile === 'function') {
nfs.copyFile = function (filepath: string, dest: string, flags: number, callback: Function) {
nfs.copyFile = function(filepath: string, dest: string, flags: number, callback: Function) {
setupManifest()
const entry = manifest[getKey(filepath)]
if (!entry) {
@@ -374,7 +346,7 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
})
})
}
nfs.copyFileSync = function (filepath: string, dest: string) {
nfs.copyFileSync = function(filepath: string, dest: string) {
setupManifest()
const entry = manifest[getKey(filepath)]
if (!entry) {
@@ -387,7 +359,7 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
Object.assign(fs, nfs)
lazyRestoreFs = () => {
Object.keys(nfs).forEach((key) => {
Object.keys(nfs).forEach(key => {
fs[key] = originalFsMethods[key]
})
lazyRestoreFs = () => {}
+3 -3
View File
@@ -24,7 +24,7 @@ export class Logger {
this.ora = ora({
text: 'Starting...',
color: 'blue',
spinner: 'dots',
spinner: 'dots'
})
this.ora.stop()
}
@@ -35,7 +35,7 @@ export class Logger {
flush() {
!this.silent && this.ora.succeed()
return new Promise((resolve) => setTimeout(resolve, frameLength))
return new Promise(resolve => setTimeout(resolve, frameLength))
}
_write(update: string, color = 'green') {
@@ -66,7 +66,7 @@ export class Logger {
modify: this.modify,
log: this.verbose ? this.write : this.modify,
pause: () => this.ora.stopAndPersist(),
resume: () => this.ora.start(),
resume: () => this.ora.start()
} as LogStep
}
}
+15 -12
View File
@@ -70,7 +70,7 @@ const defaults = {
build: false,
bundle: true,
patches: [],
plugins: [],
plugins: []
}
const alias = {
i: 'input',
@@ -88,7 +88,7 @@ const alias = {
h: 'help',
l: 'loglevel',
'fake-argv': 'fakeArgv',
'gh-token': 'ghToken',
'gh-token': 'ghToken'
}
const argv = parseArgv(process.argv, { alias, default: { ...defaults } })
let help = `
@@ -133,7 +133,7 @@ ${c.bold('nexe <entry-file> [options]')}
help = EOL + help + EOL
function flatten(...args: any[]): string[] {
return ([] as string[]).concat(...args).filter((x) => x)
return ([] as string[]).concat(...args).filter(x => x)
}
/**
@@ -144,13 +144,16 @@ function flatten(...args: any[]): string[] {
*/
function extractCliMap(match: RegExp, options: any) {
return Object.keys(options)
.filter((x) => match.test(x))
.reduce((map: any, option: any) => {
const key = option.split('-')[1]
map[key] = options[option]
delete options[option]
return map
}, {} as any)
.filter(x => match.test(x))
.reduce(
(map: any, option: any) => {
const key = option.split('-')[1]
map[key] = options[option]
delete options[option]
return map
},
{} as any
)
}
function extractLogLevel(options: NexeOptions) {
@@ -289,8 +292,8 @@ function normalizeOptions(input?: Partial<NexeOptions>): NexeOptions {
}
Object.keys(alias)
.filter((k) => k !== 'rc')
.forEach((x) => delete opts[x])
.filter(k => k !== 'rc')
.forEach(x => delete opts[x])
return options
}
+6 -6
View File
@@ -20,13 +20,13 @@ const footer = tailWindow.slice(footerPosition, footerPosition + 32),
Object.defineProperty(
process,
'__nexe',
(function () {
(function() {
let nexeHeader: any = null
return {
get: function () {
get: function() {
return nexeHeader
},
set: function (value: any) {
set: function(value: any) {
if (nexeHeader) {
throw new Error('This property is readonly')
}
@@ -37,13 +37,13 @@ Object.defineProperty(
contentSize,
contentStart,
resourceSize,
resourceStart,
},
resourceStart
}
})
Object.freeze(nexeHeader)
},
enumerable: false,
configurable: false,
configurable: false
}
})()
)
+4 -4
View File
@@ -9,11 +9,11 @@ export default async function disableNodeCli(compiler: NexeCompiler, next: () =>
if (semverGt(compiler.target.version, '11.6.0')) {
await compiler.replaceInFileAsync(
'src/node.cc',
/(?<!int )ProcessGlobalArgs\(argv[^;]*;/gm,
'0;/*$&*/'
/(?<!int )ProcessGlobalArgs\(/g,
'0;//ProcessGlobalArgs('
)
} else if (semverGt(compiler.target.version, '10.9')) {
await compiler.replaceInFileAsync('src/node.cc', /(?<!void )ProcessArgv\(argv/g, '//$&')
await compiler.replaceInFileAsync('src/node.cc', /(?<!void )ProcessArgv\(/g, '//ProcessArgv(')
} else if (semverGt(compiler.target.version, '9.999')) {
await compiler.replaceInFileAsync(
'src/node.cc',
@@ -21,7 +21,7 @@ export default async function disableNodeCli(compiler: NexeCompiler, next: () =>
'int i = v8_argc; i < v8_argc; i++'
)
let matches = 0
await compiler.replaceInFileAsync('src/node.cc', /v8_argc > 1/g, (match) => {
await compiler.replaceInFileAsync('src/node.cc', /v8_argc > 1/g, match => {
if (matches++) {
return 'false'
}
+2 -2
View File
@@ -13,8 +13,8 @@ export default async function nodeGyp(
`
${nodeGypMarker}
${files
.filter((x) => x.filename.startsWith('lib'))
.map((x) => `'${x.filename}'`)
.filter(x => x.filename.startsWith('lib'))
.map(x => `'${x.filename}'`)
.toString()},
`.trim()
)
+2 -2
View File
@@ -8,7 +8,7 @@ export default async function nodeRc(compiler: NexeCompiler, next: () => Promise
const file = await compiler.readFileAsync('src/res/node.rc')
Object.keys(options).forEach((key) => {
Object.keys(options).forEach(key => {
let value = options[key]
const isVar = /^[A-Z_]+$/.test(value)
value = isVar ? value : `"${value}"`
@@ -17,7 +17,7 @@ export default async function nodeRc(compiler: NexeCompiler, next: () => Promise
`VALUE "${key}", ${value}`
)
})
;['PRODUCTVERSION', 'FILEVERSION'].forEach((x) => {
;['PRODUCTVERSION', 'FILEVERSION'].forEach(x => {
if (options[x]) {
file.contents = file.contents.replace(new RegExp(x + ' .*$', 'm'), `${x} ${options[x]}`)
}
+1 -1
View File
@@ -2,7 +2,7 @@ import { resolve } from 'path'
import { NexeCompiler } from '../compiler'
import { semverGt } from '../util'
export default async function (compiler: NexeCompiler, next: () => Promise<void>) {
export default async function(compiler: NexeCompiler, next: () => Promise<void>) {
const { snapshot, warmup, cwd } = compiler.options
if (!snapshot) {
+1 -6
View File
@@ -42,7 +42,7 @@ export default async function main(compiler: NexeCompiler, next: () => Promise<v
next: true,
globalReturn: true,
node: true,
skipShebang: true,
skipShebang: true
}),
location = { start: { line: 0 } }
@@ -70,11 +70,6 @@ export default async function main(compiler: NexeCompiler, next: () => Promise<v
'initializePolicy();',
'initializePolicy();\n' + wrap('{{replace:lib/patches/boot-nexe.js}}')
)
await compiler.replaceInFileAsync(
bootFile,
'assert(!CJSLoader.hasLoadedAnyUserCJSModule)',
'/*assert(!CJSLoader.hasLoadedAnyUserCJSModule)*/'
)
await compiler.replaceInFileAsync(
'src/node.cc',
'MaybeLocal<Value> StartMainThreadExecution(Environment* env) {',
+9 -11
View File
@@ -2,7 +2,7 @@ import got = require('got')
import { platforms, architectures, NexeTarget, getTarget, targetsEqual } from './target'
export { NexeTarget }
const versionsToSkip = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 17, 19, 21, 22]
const versionsToSkip = [0, 1, 2, 3, 4, 5, 7, 9, 11]
export interface GitAsset {
name: string
url: string
@@ -25,21 +25,19 @@ async function getJson<T>(url: string, options?: any) {
}
function isBuildableVersion(version: string) {
if (version === '12.11.0') {
return false
}
return !versionsToSkip.includes(Number(version.split('.')[0]))
const major = Number(version.split('.')[0])
return !versionsToSkip.includes(major) || version === '4.8.4'
}
export function getLatestGitRelease(options?: any) {
return getJson<GitRelease>('https://api.github.com/repos/nexe/nexe/releases/latest', options)
export function getV3GitRelease(options?: any) {
return getJson<GitRelease>('https://api.github.com/repos/nexe/nexe/releases/7567580/', options)
}
export async function getUnBuiltReleases(options?: any) {
const nodeReleases = await getJson<NodeRelease[]>(
'https://nodejs.org/download/release/index.json'
)
const existingVersions = (await getLatestGitRelease(options)).assets.map((x) => getTarget(x.name))
const existingVersions = (await getV3GitRelease(options)).assets.map(x => getTarget(x.name))
const versionMap: { [key: string]: true } = {}
return nodeReleases
@@ -49,8 +47,8 @@ export async function getUnBuiltReleases(options?: any) {
return versions
}
versionMap[version] = true
platforms.forEach((platform) => {
architectures.forEach((arch) => {
platforms.forEach(platform => {
architectures.forEach(arch => {
if (arch === 'x86' && platform === 'mac') return
if (arch.includes('arm')) return
versions.push(getTarget({ platform, arch, version }))
@@ -58,5 +56,5 @@ export async function getUnBuiltReleases(options?: any) {
})
return versions
}, [])
.filter((x) => !existingVersions.some((t) => targetsEqual(t, x)))
.filter(x => !existingVersions.some(t => targetsEqual(t, x)))
}
+13 -11
View File
@@ -1,27 +1,29 @@
import { join, dirname } from 'path'
import { promises } from 'fs'
import { readdir, unlink } from 'fs'
import { readFileAsync, writeFileAsync, isDirectoryAsync } from '../util'
import mkdirpAsync = require('mkdirp')
import * as mkdirp from 'mkdirp'
import { NexeCompiler } from '../compiler'
import pify = require('pify')
const unlinkAsync = promises.unlink
const readdirAsync = promises.readdir
const mkdirpAsync = pify(mkdirp)
const unlinkAsync = pify(unlink)
const readdirAsync = pify(readdir)
function readDirAsync(dir: string): Promise<string[]> {
return readdirAsync(dir).then((paths) => {
return readdirAsync(dir).then(paths => {
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) => {
).then(result => {
return [].concat(...(result as any))
})
})
}
function maybeReadFileContentsAsync(file: string) {
return readFileAsync(file, 'utf-8').catch((e) => {
return readFileAsync(file, 'utf-8').catch(e => {
if (e.code === 'ENOENT') {
return ''
}
@@ -45,16 +47,16 @@ export default async function artifacts(compiler: NexeCompiler, next: () => Prom
const tmpFiles = await readDirAsync(temp)
await Promise.all(
tmpFiles.map(async (path) => {
tmpFiles.map(async path => {
return compiler.writeFileAsync(path.replace(temp, ''), await readFileAsync(path, 'utf-8'))
})
)
await next()
await Promise.all(tmpFiles.map((x) => unlinkAsync(x)))
await Promise.all(tmpFiles.map(x => unlinkAsync(x)))
return Promise.all(
compiler.files.map(async (file) => {
compiler.files.map(async file => {
const sourceFile = join(src, file.filename)
const tempFile = join(temp, file.filename)
const fileContents = await maybeReadFileContentsAsync(sourceFile)
+5 -5
View File
@@ -7,7 +7,7 @@ import { Readable } from 'stream'
function getStdIn(stdin: Readable): Promise<string> {
let out = ''
return new Promise((resolve) => {
return new Promise(resolve => {
stdin
.setEncoding('utf8')
.on('readable', () => {
@@ -64,18 +64,18 @@ export default async function bundle(compiler: NexeCompiler, next: any) {
const { files, warnings } = await resolveFiles(
input,
...Object.keys(compiler.bundle.index).filter((x) => x.endsWith('.js')),
{ cwd, expand: 'variable', loadContent: false }
...Object.keys(compiler.bundle.index).filter(x => x.endsWith('.js')),
{ cwd, expand: 'all', loadContent: false }
)
if (
warnings.filter((x) => x.startsWith('Error parsing file') && !x.includes('node_modules')).length
warnings.filter(x => x.startsWith('Error parsing file') && !x.includes('node_modules')).length
) {
throw new NexeError('Parsing Error:\n' + warnings.join('\n'))
}
await each(Object.keys(files), (filename: string) => compiler.addResource(filename), {
concurrency: 10,
concurrency: 10
})
return next()
}
+2 -2
View File
@@ -11,7 +11,7 @@ function fetchNodeSourceAsync(dest: string, url: string, step: LogStep, options
.on('response', (res: IncomingMessage) => {
const total = +res.headers['content-length']!
let current = 0
res.on('data', (data) => {
res.on('data', data => {
current += data.length
setText((current / total) * 100)
if (current === total) {
@@ -32,7 +32,7 @@ async function fetchPrebuiltBinary(compiler: NexeCompiler, step: any) {
(res: IncomingMessage) => {
const total = +res.headers['content-length']!
let current = 0
res.on('data', (data) => {
res.on('data', data => {
current += data.length
step!.modify(`Downloading...${((current / total) * 100).toFixed()}%`)
})
+4 -9
View File
@@ -1,20 +1,15 @@
import { isDirectoryAsync, each } from '../util'
import * as globs from 'globby'
import globs from 'globby'
import { NexeCompiler } from '../compiler'
export default async function resource(compiler: NexeCompiler, next: () => Promise<any>) {
const { cwd, resources } = compiler.options
if (!resources.length) {
const { cwd } = compiler.options
if (!compiler.options.resources.length) {
return next()
}
const step = compiler.log.step('Bundling Resources...')
let count = 0
// workaround for https://github.com/sindresorhus/globby/issues/127
// and https://github.com/mrmlnc/fast-glob#pattern-syntax
const resourcesWithForwardSlashes = resources.map((r) => r.replace(/\\/g, '/'))
await each(globs(resourcesWithForwardSlashes, { cwd }), async (file) => {
await each(globs(compiler.options.resources, { cwd }), async file => {
if (await isDirectoryAsync(file)) {
return
}
+3 -3
View File
@@ -1,9 +1,7 @@
import { NexeCompiler } from '../compiler'
import { wrap } from '../util'
export default async function (compiler: NexeCompiler, next: () => Promise<void>) {
await next()
export default function(compiler: NexeCompiler, next: () => Promise<void>) {
compiler.shims.push(
wrap(
`process.__nexe = ${JSON.stringify(compiler.binaryConfiguration)};\n` +
@@ -34,4 +32,6 @@ export default async function (compiler: NexeCompiler, next: () => Promise<void>
}
`)
)
return next()
}
+10 -10
View File
@@ -1,8 +1,8 @@
export type NodePlatform = 'windows' | 'mac' | 'alpine' | 'linux'
export type NodeArch = 'x86' | 'x64' | 'arm' | 'arm64'
export type NodeArch = 'x86' | 'x64' | 'arm7l' | 'arm6l' | 'arm64'
const platforms: NodePlatform[] = ['windows', 'mac', 'alpine', 'linux'],
architectures: NodeArch[] = ['x86', 'x64', 'arm', 'arm64']
architectures: NodeArch[] = ['x86', 'x64', 'arm7l', 'arm6l', 'arm64']
export { platforms, architectures }
@@ -21,21 +21,21 @@ const prettyPlatform: { [key: string]: NodePlatform } = {
mac: 'mac',
linux: 'linux',
static: 'alpine',
alpine: 'alpine',
alpine: 'alpine'
}
const prettyArch: { [key: string]: NodeArch } = {
x86: 'x86',
arm6: 'arm',
arm6: 'arm6l',
arm64: 'arm64',
arm6l: 'arm',
arm: 'arm',
arm7: 'arm',
arm7l: 'arm',
arm6l: 'arm6l',
arm: 'arm7l',
arm7: 'arm7l',
arm7l: 'arm7l',
amd64: 'x64',
ia32: 'x86',
x32: 'x86',
x64: 'x64',
x64: 'x64'
}
function isVersion(x: string) {
@@ -80,7 +80,7 @@ export function getTarget(target: string | Partial<NexeTarget> = ''): NexeTarget
target
.toLowerCase()
.split('-')
.forEach((x) => {
.forEach(x => {
if (isVersion(x)) {
version = x.replace(/v/g, '')
}
+5 -5
View File
@@ -42,10 +42,10 @@ const bound: MethodDecorator = function bound<T>(
Object.defineProperty(this, propertyKey as string, {
configurable,
value,
writable: true,
writable: true
})
return value
},
}
}
}
@@ -72,13 +72,13 @@ const isWindows = process.platform === 'win32'
function pathExistsAsync(path: string) {
return statAsync(path)
.then((x) => true)
.then(x => true)
.catch(falseOnEnoent)
}
function isDirectoryAsync(path: string) {
return statAsync(path)
.then((x) => x.isDirectory())
.then(x => x.isDirectory())
.catch(falseOnEnoent)
}
/**
@@ -109,5 +109,5 @@ export {
readFileAsync,
pathExistsAsync,
isDirectoryAsync,
writeFileAsync,
writeFileAsync
}
+14 -14
View File
@@ -1,5 +1,5 @@
import * as nexe from '../lib/nexe'
import { getUnBuiltReleases, getLatestGitRelease } from '../lib/releases'
import { getUnBuiltReleases, getV3GitRelease } from '../lib/releases'
import { runDockerBuild } from './docker'
import { getTarget, targetsEqual, NexeTarget } from '../lib/target'
import { pathExistsAsync, readFileAsync, execFileAsync, semverGt } from '../lib/util'
@@ -14,12 +14,12 @@ const env = process.env,
isMac = process.platform === 'darwin',
headers = {
Authorization: 'token ' + env.GITHUB_TOKEN,
'User-Agent': 'nexe (https://www.npmjs.com/package/nexe)',
'User-Agent': 'nexe (https://www.npmjs.com/package/nexe)'
}
if (require.main === module) {
if (!isPullRequest) {
build().catch((x) => {
build().catch(x => {
console.error(x)
process.exit(1)
})
@@ -31,10 +31,10 @@ async function build() {
if (!releases.length) {
return
}
const windowsBuild = releases.find((x) => x.platform === 'windows'),
macBuild = releases.find((x) => x.platform === 'mac'),
linux = releases.find((x) => x.platform === 'linux'),
alpine = releases.find((x) => x.platform === 'alpine')
const windowsBuild = releases.find(x => x.platform === 'windows'),
macBuild = releases.find(x => x.platform === 'mac'),
linux = releases.find(x => x.platform === 'linux'),
alpine = releases.find(x => x.platform === 'alpine')
let target: NexeTarget | undefined
@@ -62,7 +62,7 @@ async function build() {
verbose: Boolean(env.NEXE_VERBOSE!),
target,
make: ['-j' + cpus().length],
output,
output
}
console.log('Building: ' + target + ' on ' + buildHost)
const stop = keepalive()
@@ -78,9 +78,9 @@ async function build() {
stop()
if (await pathExistsAsync(output)) {
await assertNexeBinary(output)
const gitRelease = await getLatestGitRelease({ headers }),
const gitRelease = await getV3GitRelease({ headers }),
unbuiltReleases = await getUnBuiltReleases({ headers })
if (!unbuiltReleases.some((x) => targetsEqual(x, target!))) {
if (!unbuiltReleases.some(x => targetsEqual(x, target!))) {
console.log(`${target} already uploaded.`)
process.exit(0)
return
@@ -90,9 +90,9 @@ async function build() {
body: await readFileAsync(output),
headers: {
...headers,
'Content-Type': 'application/octet-stream',
},
}).catch((reason) => {
'Content-Type': 'application/octet-stream'
}
}).catch(reason => {
console.log(reason && reason.response && reason.response.body)
throw reason
})
@@ -107,7 +107,7 @@ function keepalive() {
}
function assertNexeBinary(file: string) {
return execFileAsync(file).catch((e) => {
return execFileAsync(file).catch(e => {
if (e && e.stack && e.stack.includes('Invalid Nexe binary')) {
return
}
+15 -10
View File
@@ -46,10 +46,10 @@ export async function runDockerBuild(target: NexeTarget) {
let output: any = []
try {
output.push(await execa(`docker build -t nexe-docker .`, { shell: true }))
output.push(await execa(`docker run -d --name nexe nexe-docker sh`, { shell: true }))
output.push(await execa(`docker cp nexe:/out out`, { shell: true }))
output.push(await execa(`docker rm nexe`, { shell: true }))
output.push(await execa.shell(`docker build -t nexe-docker .`))
output.push(await execa.shell(`docker run -d --name nexe nexe-docker sh`))
output.push(await execa.shell(`docker cp nexe:/out out`))
output.push(await execa.shell(`docker rm nexe`))
} catch (e) {
console.log('Error running docker')
appendFileSync(outFilename, e.message)
@@ -58,11 +58,16 @@ export async function runDockerBuild(target: NexeTarget) {
appendFileSync(outFilename, x.stderr)
appendFileSync(outFilename, x.stdout)
})
await got(`https://transfer.sh/${Math.random().toString(36).substring(2)}.txt`, {
body: await readFileAsync(outFilename),
method: 'PUT',
})
.then((x) => console.log('Posted docker log: ', x.body))
.catch((e) => console.log('Error posting log', e))
await got(
`https://transfer.sh/${Math.random()
.toString(36)
.substring(2)}.txt`,
{
body: await readFileAsync(outFilename),
method: 'PUT'
}
)
.then(x => console.log('Posted docker log: ', x.body))
.catch(e => console.log('Error posting log', e))
}
}