Compare commits
81 Commits
v3.0.0-beta.0
...
v3.3.2
| Author | SHA1 | Date | |
|---|---|---|---|
| cf23147c9c | |||
| 9c1d67b2e6 | |||
| 93e0a021d3 | |||
| 021f50d50f | |||
| bf5ff7d9bd | |||
| 86c3acedb1 | |||
| ecb3d41a97 | |||
| 1eb44797d0 | |||
| 1023b72513 | |||
| 0cf436c9a7 | |||
| 77f49eb07a | |||
| 9bc98bf597 | |||
| 7e9a05675c | |||
| e62d728624 | |||
| a0c8d31f03 | |||
| 472b98d839 | |||
| 9ae6ed8ae8 | |||
| a0c648bc8b | |||
| 463595f502 | |||
| be4ab09745 | |||
| a6ad034336 | |||
| 0afbe3b732 | |||
| 0865fda5ef | |||
| 7bfdc39700 | |||
| 9486399cec | |||
| 75bf6a3dc4 | |||
| 0dca0745ee | |||
| 6fc2ed9519 | |||
| 448f4270ea | |||
| c9c9b5a0a3 | |||
| d2756a5f75 | |||
| 255f3887c7 | |||
| 75ae41b7b9 | |||
| 3692c142fb | |||
| af2e381ed4 | |||
| 44393a22da | |||
| 57a08d2cfd | |||
| 6825cef609 | |||
| b3c2d2e764 | |||
| d73325ba35 | |||
| 6e3cadbe22 | |||
| de42dd94ad | |||
| 37192e4ca8 | |||
| c5cdbd9380 | |||
| b022cd525d | |||
| 72d9dfebf6 | |||
| 8849ac0c0c | |||
| 8ad6641278 | |||
| 1a75bdb058 | |||
| 12c77a34fd | |||
| c76edb7c0b | |||
| 09d7093295 | |||
| 3a091f45bd | |||
| 9575c0811b | |||
| ab6b540e23 | |||
| dcea374922 | |||
| b3b6c6b936 | |||
| 058c34ee8a | |||
| 9750c70873 | |||
| 7bc3a83667 | |||
| aa93ab6516 | |||
| c681a62566 | |||
| 2ea0f897d5 | |||
| cfa3036694 | |||
| c3ba3ec872 | |||
| 142338ede6 | |||
| e3f1d6fc74 | |||
| 0db8122f8f | |||
| 129c2f86a0 | |||
| db766e2832 | |||
| e6a416cc4f | |||
| 35f4811826 | |||
| 891ac0ab2a | |||
| 18bbf24456 | |||
| 689160e833 | |||
| bd3ae2e80a | |||
| 0447d8004c | |||
| 11be5a2573 | |||
| 664dc6a11b | |||
| 4a7bfd99b6 | |||
| a3af96eae8 |
@@ -1,8 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
export NVS_HOME="$HOME/.nvs"
|
|
||||||
. "$NVS_HOME/nvs.sh" install && nvs link lts && nvs use default
|
|
||||||
|
|
||||||
set -e -x
|
|
||||||
|
|
||||||
yarn run asset-compile
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
version: 2
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
macos:
|
|
||||||
xcode: "9.0"
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- restore_cache:
|
|
||||||
keys:
|
|
||||||
- package-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }}
|
|
||||||
- package- # Fallback for the latest package.json cache
|
|
||||||
- run:
|
|
||||||
name: setup
|
|
||||||
command: .circleci/setup.sh
|
|
||||||
- save_cache:
|
|
||||||
key: package-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }}
|
|
||||||
paths:
|
|
||||||
- node_modules
|
|
||||||
- run:
|
|
||||||
name: build
|
|
||||||
command: .circleci/build.sh
|
|
||||||
|
|
||||||
workflows:
|
|
||||||
version: 2
|
|
||||||
test:
|
|
||||||
jobs:
|
|
||||||
- build
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "setting up node to use latest lts"
|
|
||||||
|
|
||||||
export NVS_HOME="$HOME/.nvs"
|
|
||||||
git clone --depth=1 https://github.com/jasongin/nvs "$NVS_HOME"
|
|
||||||
. "$NVS_HOME/nvs.sh" install
|
|
||||||
nvs add lts && nvs link lts nvs use default
|
|
||||||
npm install -g yarn
|
|
||||||
yarn
|
|
||||||
+1
-2
@@ -4,6 +4,5 @@ end_of_line = lf
|
|||||||
charset = utf-8
|
charset = utf-8
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
#https://github.com/Microsoft/vscode/issues/23983#event-1087502108
|
trim_trailing_whitespace = true
|
||||||
#trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
temp/
|
temp/
|
||||||
coverage
|
coverage
|
||||||
|
nexe
|
||||||
node_modules
|
node_modules
|
||||||
*.log
|
*.log
|
||||||
*.exe
|
*.exe
|
||||||
|
|||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
language: node_js
|
|
||||||
node_js:
|
|
||||||
- '6'
|
|
||||||
before_install:
|
|
||||||
- sudo apt-get -qq update
|
|
||||||
- sudo apt-get install -y g++-multilib
|
|
||||||
node_js:
|
|
||||||
- '8'
|
|
||||||
script: npm run asset-compile
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- secure: LyC6djYqPfPKz5gHILES9JmSRxQ+ntKOcoaZNM5WID0+gogUoXZBhcmmtvq9RnMpFZN3pYujY6LB5iy7QS2seGjg+feyewNKI30yIK6N9ulJyZZKmrJVDdRx4wvl8YVTkttjcJFkanDGa6zRvFfFDKx/iIdcWLEpnqR/WO1ppf8=
|
|
||||||
notifications:
|
|
||||||
email: false
|
|
||||||
Vendored
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"recommendations": [ "eg2.tslint" ]
|
"recommendations": [ "ms-vscode.vscode-typescript-tslint-plugin" ]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
<p align="center"><img src="https://cloud.githubusercontent.com/assets/2391349/23598327/a17bb68a-01ee-11e7-8f55-88a5fc96e997.png" /></p>
|
<p align="center"><img src="https://cloud.githubusercontent.com/assets/2391349/23598327/a17bb68a-01ee-11e7-8f55-88a5fc96e997.png" /></p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://circleci.com/gh/nexe/nexe"><img src="https://img.shields.io/circleci/project/nexe/nexe.svg" alt="Build Status"></a>
|
<a href="https://dev.azure.com/nexe-ci/Nexe/_build?definitionId=1"><img src="https://img.shields.io/azure-devops/build/nexe-ci/nexe/1/master.svg" alt="Build Status"></a>
|
||||||
<a href="https://www.npmjs.com/package/nexe"><img src="https://img.shields.io/npm/dt/nexe.svg" alt="Downloads"></a>
|
<a href="https://www.npmjs.com/package/nexe"><img src="https://img.shields.io/npm/dt/nexe.svg" alt="Downloads"></a>
|
||||||
<a href="https://www.npmjs.com/package/nexe"><img src="https://img.shields.io/npm/v/nexe.svg" alt="Version"></a>
|
<a href="https://www.npmjs.com/package/nexe"><img src="https://img.shields.io/npm/v/nexe.svg" alt="Version"></a>
|
||||||
<a href="https://www.npmjs.com/package/nexe"><img src="https://img.shields.io/npm/l/nexe.svg" alt="License"></a>
|
<a href="https://www.npmjs.com/package/nexe"><img src="https://img.shields.io/npm/l/nexe.svg" alt="License"></a>
|
||||||
<a href="https://gitter.im/nexe/nexe?utm_source=badge&utm_medium=badge"><img src="https://badges.gitter.im/nexe/nexe.svg"></a>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center"><code>npm i nexe -g</code></p>
|
<p align="center"><code>npm i nexe -g</code></p>
|
||||||
@@ -40,8 +39,7 @@ For more CLI options see: `nexe --help`
|
|||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
- `nexe server.js -r public/**/*.html`
|
- `nexe server.js -r "public/**/*.html"`
|
||||||
- `nexe my-bundle.js --no-bundle -o app.exe`
|
|
||||||
- `nexe --build`
|
- `nexe --build`
|
||||||
- `nexe -t x86-8.0.0`
|
- `nexe -t x86-8.0.0`
|
||||||
|
|
||||||
@@ -88,14 +86,14 @@ compile({
|
|||||||
- Output executable file path
|
- Output executable file path
|
||||||
- default: same as `name` with an OS specific extension.
|
- default: same as `name` with an OS specific extension.
|
||||||
- #### `target: string | object`
|
- #### `target: string | object`
|
||||||
- An object or string describing platform-arch-version. e.g. `'windows-ia32-6.10.3'`
|
- An object or string describing platform-arch-version. e.g. `'windows-ia32-10.13.0'`
|
||||||
- each segment is optional, and will be merged with the current environment
|
- each segment is optional, and will be merged with the current environment
|
||||||
- Examples: ([full list](https://github.com/nexe/nexe/releases))
|
- Examples: ([full list](https://github.com/nexe/nexe/releases))
|
||||||
- `'win32-x86-8.6.0`
|
- `'win32-x86-10.13.0`
|
||||||
- `{ platform: 'alpine' }`
|
- `{ platform: 'alpine' }`
|
||||||
- `darwin-8.6.0`
|
- `darwin-10.13.0`
|
||||||
- `linux-x64`
|
- `linux-x64`
|
||||||
- `macos-8.4.0`
|
- `macos-10.13.0`
|
||||||
|
|
||||||
See [test/target.spec.ts](test/target.spec.ts)
|
See [test/target.spec.ts](test/target.spec.ts)
|
||||||
- If the [`build`](#build-boolean) flag is set, the platform portion of the target is ignored.
|
- If the [`build`](#build-boolean) flag is set, the platform portion of the target is ignored.
|
||||||
@@ -113,8 +111,15 @@ compile({
|
|||||||
- #### `cwd: string`
|
- #### `cwd: string`
|
||||||
- Directory nexe will operate on as though it is the cwd
|
- Directory nexe will operate on as though it is the cwd
|
||||||
- default: process.cwd()
|
- default: process.cwd()
|
||||||
|
- #### `mangle: boolean`
|
||||||
|
- If set to false, nexe will not include the virtual filesystem (your application and resources) on the output.
|
||||||
|
- This will cause the output to error as an "Invalid Binary" unless a userland patch alters the contents of lib/_third_party_main.js in the nodejs source.
|
||||||
|
- default: true
|
||||||
- #### `build: boolean`
|
- #### `build: boolean`
|
||||||
- Build node from source, passing this flag tells nexe to download and build from source. Subsequently using this flag will cause nexe to use the previously built binary. To rebuild, first add [`--clean`](#clean-boolean)
|
- Build node from source, passing this flag tells nexe to download and build from source. Subsequently using this flag will cause nexe to use the previously built binary. To rebuild, first add [`--clean`](#clean-boolean)
|
||||||
|
- #### `asset: string`
|
||||||
|
- Provide a pre-built nexe binary asset, this can either be an http or https URL or a file path.
|
||||||
|
- default: `null`
|
||||||
- #### `python: string`
|
- #### `python: string`
|
||||||
- On Linux this is the path pointing to your python2 executable
|
- On Linux this is the path pointing to your python2 executable
|
||||||
- On Windows this is the directory where `python` can be accessed
|
- On Windows this is the directory where `python` can be accessed
|
||||||
@@ -128,10 +133,11 @@ compile({
|
|||||||
- Example: `['--with-dtrace', '--dest-cpu=x64']`
|
- Example: `['--with-dtrace', '--dest-cpu=x64']`
|
||||||
- default: `[]`
|
- default: `[]`
|
||||||
- #### `make: string[]`
|
- #### `make: string[]`
|
||||||
- Array of arguments for the node build make step, on windows this step recieves options for vcBuild.bat
|
- Array of arguments for the node build make step
|
||||||
- default: `[]` or `['nosign', 'release']` for non windows systems
|
- default: `[]`
|
||||||
- #### `vcBuild: string[]`
|
- #### `vcBuild: string[]`
|
||||||
- Alias for `make` option
|
- Options for windows build
|
||||||
|
- default: `['nosign', 'release']`
|
||||||
- #### `snapshot: string`
|
- #### `snapshot: string`
|
||||||
- path to a file to be used as the warmup snapshot for the build
|
- path to a file to be used as the warmup snapshot for the build
|
||||||
- default: `null`
|
- default: `null`
|
||||||
@@ -142,12 +148,12 @@ compile({
|
|||||||
- #### `temp: string`
|
- #### `temp: string`
|
||||||
- Path to use for storing nexe's build files
|
- Path to use for storing nexe's build files
|
||||||
- Override in the env with `NEXE_TEMP`
|
- Override in the env with `NEXE_TEMP`
|
||||||
- default: `./.nexe` in the cwd
|
- default: `~/.nexe`
|
||||||
- #### `ico: string`
|
- #### `ico: string`
|
||||||
- Path to a user provided icon to be used (Windows only). Requires `--build` to be set.
|
- Path to a user provided icon to be used (Windows only). Requires `--build` to be set.
|
||||||
- #### `rc: object`
|
- #### `rc: object`
|
||||||
- Settings for patching the [node.rc](https://github.com/nodejs/node/blob/master/src/res/node.rc) configuration file (Windows only).
|
- Settings for patching the [node.rc](https://github.com/nodejs/node/blob/master/src/res/node.rc) configuration file (Windows only).
|
||||||
- Example:
|
- Example (keys may vary depending on the version. Reference the file linked above):
|
||||||
```javascript
|
```javascript
|
||||||
{
|
{
|
||||||
CompanyName: "ACME Corp",
|
CompanyName: "ACME Corp",
|
||||||
@@ -165,7 +171,7 @@ compile({
|
|||||||
variable will still be processed. NODE_OPTIONS support can be disabled with the `--without-node-options` configure flag.
|
variable will still be processed. NODE_OPTIONS support can be disabled with the `--without-node-options` configure flag.
|
||||||
- default: `false`
|
- default: `false`
|
||||||
- #### `fakeArgv: boolean`
|
- #### `fakeArgv: boolean`
|
||||||
- fake the entry point file name (`process.argv[1]`). If nexe was used with stdin this will be `'[stdin]'`.
|
- fake the entry point file name (`process.argv[1]`). If nexe was used with stdin this will be `'[stdin]'`.
|
||||||
- #### `ghToken: string`
|
- #### `ghToken: string`
|
||||||
- Provide a Github Token for accessing nexe releases
|
- Provide a Github Token for accessing nexe releases
|
||||||
- This is usually needed in CI environments
|
- This is usually needed in CI environments
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
image:
|
|
||||||
- Visual Studio 2017
|
|
||||||
- Visual Studio 2015
|
|
||||||
environment:
|
|
||||||
CIRCLE_TOKEN:
|
|
||||||
secure: TQKcepXmTzCNt4+tUBtYpwEQkdSPwFr9A8ugtoMhNbKu/SW1WM1EpjEu6kYXxpQ4
|
|
||||||
TRAVIS_TOKEN:
|
|
||||||
secure: tR7HXYv3x97q90uvPrjUxKZh7R1+uqKct0HdEcqTbsg=
|
|
||||||
GITHUB_TOKEN:
|
|
||||||
secure: 3wuEGJsppSKFvdwhp3jprUA9Zkc3WINlc/9oFXjhAR6J05lYMXP7Fl7lXTKpkGZx
|
|
||||||
install:
|
|
||||||
- ps: Install-Product node 8
|
|
||||||
- curl -L -o nasm.exe https://www.nasm.us/pub/nasm/releasebuilds/2.13.03/win64/nasm-2.13.03-installer-x64.exe
|
|
||||||
- start /wait nasm.exe /S
|
|
||||||
- ps: $env:path="C:\Program Files\nasm;$($env:path)"
|
|
||||||
- npm i
|
|
||||||
build: off
|
|
||||||
test: off
|
|
||||||
build_script:
|
|
||||||
- npm run asset-compile
|
|
||||||
artifacts:
|
|
||||||
- path: $(HOMEPATH)\.nexe\**\node.exe
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
schedules:
|
||||||
|
- cron: "0 8 * * *"
|
||||||
|
displayName: "Daily Build 1"
|
||||||
|
always: true
|
||||||
|
branches:
|
||||||
|
include:
|
||||||
|
- master
|
||||||
|
- cron: "0 13 * * *"
|
||||||
|
displayName: "Daily Build 2"
|
||||||
|
always: true
|
||||||
|
branches:
|
||||||
|
include:
|
||||||
|
- master
|
||||||
|
- cron: "0 19 * * *"
|
||||||
|
displayName: "Daily Build 3"
|
||||||
|
always: true
|
||||||
|
branches:
|
||||||
|
include:
|
||||||
|
- master
|
||||||
|
jobs:
|
||||||
|
- job: BaseBuild
|
||||||
|
timeoutInMinutes: 180
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
linux:
|
||||||
|
imageName: 'ubuntu-16.04'
|
||||||
|
mac:
|
||||||
|
imageName: 'macos-10.13'
|
||||||
|
windows_2017:
|
||||||
|
imageName: 'vs2017-win2016'
|
||||||
|
windows_2015:
|
||||||
|
imageName: 'vs2017-win2016'
|
||||||
|
alpine:
|
||||||
|
imageName: 'ubuntu-16.04'
|
||||||
|
pool:
|
||||||
|
vmImage: $(imageName)
|
||||||
|
steps:
|
||||||
|
- task: UsePythonVersion@0
|
||||||
|
displayName: Setup Python
|
||||||
|
inputs:
|
||||||
|
versionSpec: '2.7'
|
||||||
|
architecture: 'x64'
|
||||||
|
- task: NodeTool@0
|
||||||
|
displayName: Install Node
|
||||||
|
inputs:
|
||||||
|
versionSpec: '10.x'
|
||||||
|
- script: sudo apt-get update && sudo apt-get install -y libc6-dev-i386 gcc-multilib g++-multilib
|
||||||
|
condition: contains(variables['Agent.JobName'], 'linux')
|
||||||
|
displayName: Install Linux build dependencies
|
||||||
|
- 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)
|
||||||
@@ -10,7 +10,20 @@ if (require.main === module) {
|
|||||||
process.stderr.write(showHelp ? options.help : options.version + eol)
|
process.stderr.write(showHelp ? options.help : options.version + eol)
|
||||||
} else {
|
} else {
|
||||||
const nexe = require('./lib/nexe')
|
const nexe = require('./lib/nexe')
|
||||||
nexe.compile(argv).catch(() => {
|
nexe.compile(argv).catch((error) => {
|
||||||
|
const NexeError = require('./lib/compiler').NexeError
|
||||||
|
const chalk = require('chalk')
|
||||||
|
const isSilent = Boolean(argv.silent === true || argv.loglevel === 'silent')
|
||||||
|
if (!isSilent) {
|
||||||
|
if (error instanceof NexeError) {
|
||||||
|
process.stderr.write(eol + chalk.red('Error: ') + error.message + eol
|
||||||
|
+ eol + 'See nexe -h for usage..' + eol + eol
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
process.stderr.write(error.stack + eol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+907
-340
File diff suppressed because it is too large
Load Diff
+25
-24
@@ -2,14 +2,14 @@
|
|||||||
"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.0-beta.0",
|
"version": "3.3.2",
|
||||||
"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>",
|
||||||
"Caleb Boyd <caleb.boyd@hotmail.com>"
|
"Caleb Boyd <caleb.boyd@hotmail.com>"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"asset-compile": "ts-node tasks/asset-compile",
|
"ci:build": "ts-node tasks/build",
|
||||||
"test": "mocha",
|
"test": "mocha",
|
||||||
"lint": "tslint \"{src,plugins,tasks}/**/*.ts\" --fix",
|
"lint": "tslint \"{src,plugins,tasks}/**/*.ts\" --fix",
|
||||||
"prepare": "npm run lint && npm run build && npm test",
|
"prepare": "npm run lint && npm run build && npm test",
|
||||||
@@ -36,40 +36,41 @@
|
|||||||
"@calebboyd/semaphore": "^1.3.1",
|
"@calebboyd/semaphore": "^1.3.1",
|
||||||
"app-builder": "^5.2.0",
|
"app-builder": "^5.2.0",
|
||||||
"caw": "^2.0.1",
|
"caw": "^2.0.1",
|
||||||
"chalk": "^2.4.1",
|
"chalk": "^2.4.2",
|
||||||
"cherow": "^1.6.8",
|
"cherow": "1.6.9",
|
||||||
"download": "^7.1.0",
|
"download": "^7.1.0",
|
||||||
"globby": "^8.0.1",
|
"globby": "^9.2.0",
|
||||||
"got": "^9.2.2",
|
"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.0.0",
|
"ora": "^3.4.0",
|
||||||
"pify": "^4.0.0",
|
"pify": "^4.0.1",
|
||||||
"resolve-dependencies": "^2.1.1",
|
"resolve-dependencies": "^2.2.3",
|
||||||
"rimraf": "^2.6.2"
|
"rimraf": "^2.6.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/chai": "^4.1.5",
|
"@types/chai": "^4.1.7",
|
||||||
|
"@types/download": "^6.2.4",
|
||||||
"@types/execa": "^0.9.0",
|
"@types/execa": "^0.9.0",
|
||||||
"@types/globby": "^8.0.0",
|
"@types/globby": "^9.1.0",
|
||||||
"@types/got": "^8.3.4",
|
"@types/got": "^9.6.0",
|
||||||
"@types/minimist": "^1.2.0",
|
"@types/minimist": "^1.2.0",
|
||||||
"@types/mkdirp": "^0.5.2",
|
"@types/mkdirp": "^0.5.2",
|
||||||
"@types/mocha": "^5.2.5",
|
"@types/mocha": "^5.2.7",
|
||||||
"@types/multistream": "^2.1.1",
|
"@types/multistream": "^2.1.1",
|
||||||
"@types/ora": "^1.3.4",
|
"@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.1.2",
|
"chai": "^4.2.0",
|
||||||
"execa": "^1.0.0",
|
"execa": "^1.0.0",
|
||||||
"mocha": "^5.2.0",
|
"mocha": "^6.1.4",
|
||||||
"prettier": "^1.14.3",
|
"prettier": "^1.18.2",
|
||||||
"ts-node": "^7.0.1",
|
"ts-node": "^8.3.0",
|
||||||
"tslint": "^5.11.0",
|
"tslint": "^5.17.0",
|
||||||
"tslint-config-prettier": "^1.15.0",
|
"tslint-config-prettier": "^1.18.0",
|
||||||
"tslint-plugin-prettier": "^2.0.0",
|
"tslint-plugin-prettier": "^2.0.1",
|
||||||
"typescript": "^3.0.3"
|
"typescript": "^3.5.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+111
-52
@@ -1,15 +1,20 @@
|
|||||||
import { delimiter, dirname, normalize, join } from 'path'
|
import { delimiter, resolve, normalize, join } from 'path'
|
||||||
import { Buffer } from 'buffer'
|
import { Buffer } from 'buffer'
|
||||||
import { createReadStream } from 'fs'
|
import { createReadStream, ReadStream } from 'fs'
|
||||||
import { Readable, Stream } from 'stream'
|
|
||||||
import { spawn } from 'child_process'
|
import { spawn } from 'child_process'
|
||||||
import { Logger, LogStep } from './logger'
|
import { Logger, LogStep } from './logger'
|
||||||
import { readFileAsync, writeFileAsync, pathExistsAsync, dequote, isWindows, bound } from './util'
|
import {
|
||||||
|
readFileAsync,
|
||||||
|
writeFileAsync,
|
||||||
|
pathExistsAsync,
|
||||||
|
statAsync,
|
||||||
|
dequote,
|
||||||
|
isWindows,
|
||||||
|
bound,
|
||||||
|
semverGt
|
||||||
|
} from './util'
|
||||||
import { NexeOptions, version } from './options'
|
import { NexeOptions, version } from './options'
|
||||||
import { NexeTarget } from './target'
|
import { NexeTarget } from './target'
|
||||||
import download = require('download')
|
|
||||||
import { getLatestGitRelease } from './releases'
|
|
||||||
import { IncomingMessage } from 'http'
|
|
||||||
import combineStreams = require('multistream')
|
import combineStreams = require('multistream')
|
||||||
import { Bundle, toStream } from './fs/bundle'
|
import { Bundle, toStream } from './fs/bundle'
|
||||||
|
|
||||||
@@ -17,6 +22,8 @@ const isBsd = Boolean(~process.platform.indexOf('bsd'))
|
|||||||
const make = isWindows ? 'vcbuild.bat' : isBsd ? 'gmake' : 'make'
|
const make = isWindows ? 'vcbuild.bat' : isBsd ? 'gmake' : 'make'
|
||||||
const configure = isWindows ? 'configure' : './configure'
|
const configure = isWindows ? 'configure' : './configure'
|
||||||
|
|
||||||
|
type StringReplacer = (match: string) => string
|
||||||
|
|
||||||
export interface NexeFile {
|
export interface NexeFile {
|
||||||
filename: string
|
filename: string
|
||||||
absPath: string
|
absPath: string
|
||||||
@@ -25,28 +32,90 @@ export interface NexeFile {
|
|||||||
|
|
||||||
export { NexeOptions }
|
export { NexeOptions }
|
||||||
|
|
||||||
|
export class NexeError extends Error {
|
||||||
|
constructor(m: string) {
|
||||||
|
super(m)
|
||||||
|
Object.setPrototypeOf(this, NexeError.prototype)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class NexeCompiler {
|
export class NexeCompiler {
|
||||||
|
/**
|
||||||
|
* Epoch of when compilation started
|
||||||
|
*/
|
||||||
private start = Date.now()
|
private start = Date.now()
|
||||||
private env = { ...process.env }
|
|
||||||
private bundle: Bundle
|
|
||||||
private compileStep: LogStep | undefined
|
private compileStep: LogStep | undefined
|
||||||
public log = new Logger(this.options.loglevel)
|
public log = new Logger(this.options.loglevel)
|
||||||
|
/**
|
||||||
|
* Copy of process.env
|
||||||
|
*/
|
||||||
|
public env = { ...process.env }
|
||||||
|
/**
|
||||||
|
* Virtual FileSystem
|
||||||
|
*/
|
||||||
|
public bundle: Bundle
|
||||||
|
/**
|
||||||
|
* Root directory for the source of the current build
|
||||||
|
*/
|
||||||
public src: string
|
public src: string
|
||||||
|
/**
|
||||||
|
* In memory files that are being manipulated by the compiler
|
||||||
|
*/
|
||||||
public files: NexeFile[] = []
|
public files: NexeFile[] = []
|
||||||
|
/**
|
||||||
|
* Standalone pieces of code run before the application entrypoint
|
||||||
|
*/
|
||||||
public shims: string[] = []
|
public shims: string[] = []
|
||||||
|
/**
|
||||||
|
* The last shim (defaults to "require('module').runMain()")
|
||||||
|
*/
|
||||||
public startup: string = ''
|
public startup: string = ''
|
||||||
|
/**
|
||||||
|
* The main entrypoint filename for your application - eg. node mainFile.js
|
||||||
|
*/
|
||||||
public entrypoint: string | undefined
|
public entrypoint: string | undefined
|
||||||
public bundledInput?: string
|
/**
|
||||||
|
* Not used
|
||||||
|
*/
|
||||||
public targets: NexeTarget[]
|
public targets: NexeTarget[]
|
||||||
|
/**
|
||||||
|
* Current target of the compiler
|
||||||
|
*/
|
||||||
public target: NexeTarget
|
public target: NexeTarget
|
||||||
|
/**
|
||||||
|
* Output filename (-o myapp.exe)
|
||||||
|
*/
|
||||||
public output = this.options.output
|
public output = this.options.output
|
||||||
private nodeSrcBinPath: string
|
/**
|
||||||
|
* Flag to indicate whether or notstdin was used for input
|
||||||
|
*/
|
||||||
|
public stdinUsed = false
|
||||||
|
/**
|
||||||
|
* Path to the configure script
|
||||||
|
*/
|
||||||
|
public configureScript: string
|
||||||
|
/**
|
||||||
|
* The file path of node binary
|
||||||
|
*/
|
||||||
|
public nodeSrcBinPath: string
|
||||||
|
/**
|
||||||
|
* Remote asset path if available
|
||||||
|
*/
|
||||||
|
public remoteAsset: string
|
||||||
|
|
||||||
constructor(public options: NexeOptions) {
|
constructor(public options: NexeOptions) {
|
||||||
const { python } = (this.options = options)
|
const { python } = (this.options = options)
|
||||||
|
//SOMEDAY iterate over multiple targets with `--outDir`
|
||||||
this.targets = options.targets as NexeTarget[]
|
this.targets = options.targets as NexeTarget[]
|
||||||
this.target = this.targets[0]
|
this.target = this.targets[0]
|
||||||
|
if (options.asset && options.asset.startsWith('http')) {
|
||||||
|
this.remoteAsset = options.asset
|
||||||
|
} else {
|
||||||
|
this.remoteAsset =
|
||||||
|
'https://github.com/nexe/nexe/releases/download/v3.0.0/' + this.target.toString()
|
||||||
|
}
|
||||||
this.src = join(this.options.temp, this.target.version)
|
this.src = join(this.options.temp, this.target.version)
|
||||||
|
this.configureScript = configure + (semverGt(this.target.version, '10.10.0') ? '.py' : '')
|
||||||
this.nodeSrcBinPath = isWindows
|
this.nodeSrcBinPath = isWindows
|
||||||
? join(this.src, 'Release', 'node.exe')
|
? join(this.src, 'Release', 'node.exe')
|
||||||
: join(this.src, 'out', 'Release', 'node')
|
: join(this.src, 'out', 'Release', 'node')
|
||||||
@@ -105,9 +174,9 @@ export class NexeCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@bound
|
@bound
|
||||||
async replaceInFileAsync(file: string, replace: string | RegExp, value: string) {
|
async replaceInFileAsync(file: string, replace: string | RegExp, value: string | StringReplacer) {
|
||||||
const entry = await this.readFileAsync(file)
|
const entry = await this.readFileAsync(file)
|
||||||
entry.contents = entry.contents.replace(replace, value)
|
entry.contents = entry.contents.replace(replace, value as any)
|
||||||
}
|
}
|
||||||
|
|
||||||
@bound
|
@bound
|
||||||
@@ -116,19 +185,22 @@ export class NexeCompiler {
|
|||||||
entry.contents = contents
|
entry.contents = contents
|
||||||
}
|
}
|
||||||
|
|
||||||
quit() {
|
quit(error?: any) {
|
||||||
const time = Date.now() - this.start
|
const time = Date.now() - this.start
|
||||||
this.log.write(`Finished in ${time / 1000}s`)
|
this.log.write(`Finished in ${time / 1000}s`, error ? 'red' : 'green')
|
||||||
return this.log.flush()
|
return this.log.flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
assertBuild() {
|
assertBuild() {
|
||||||
if (!this.options.build) {
|
if (!this.options.build) {
|
||||||
throw new Error('This feature is only available with `--build`')
|
throw new NexeError('This feature is only available with `--build`')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getNodeExecutableLocation(target?: NexeTarget) {
|
public getNodeExecutableLocation(target?: NexeTarget) {
|
||||||
|
if (this.options.asset && !this.options.asset.startsWith('http')) {
|
||||||
|
return resolve(this.options.cwd, this.options.asset)
|
||||||
|
}
|
||||||
if (target) {
|
if (target) {
|
||||||
return join(this.options.temp, target.toString())
|
return join(this.options.temp, target.toString())
|
||||||
}
|
}
|
||||||
@@ -157,7 +229,7 @@ export class NexeCompiler {
|
|||||||
}
|
}
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
const error = `${command} ${args.join(' ')} exited with code: ${code}`
|
const error = `${command} ${args.join(' ')} exited with code: ${code}`
|
||||||
reject(new Error(error))
|
reject(new NexeError(error))
|
||||||
}
|
}
|
||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
@@ -165,13 +237,16 @@ export class NexeCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _configureAsync() {
|
private _configureAsync() {
|
||||||
|
if (isWindows && semverGt(this.target.version, '10.15.99')) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
return this._runBuildCommandAsync(this.env.PYTHON || 'python', [
|
return this._runBuildCommandAsync(this.env.PYTHON || 'python', [
|
||||||
configure,
|
this.configureScript,
|
||||||
...this.options.configure
|
...this.options.configure
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _buildAsync() {
|
public async build(): Promise<ReadStream> {
|
||||||
this.compileStep!.log(
|
this.compileStep!.log(
|
||||||
`Configuring node build${
|
`Configuring node build${
|
||||||
this.options.configure.length ? ': ' + this.options.configure : '...'
|
this.options.configure.length ? ': ' + this.options.configure : '...'
|
||||||
@@ -186,37 +261,24 @@ export class NexeCompiler {
|
|||||||
return createReadStream(this.getNodeExecutableLocation())
|
return createReadStream(this.getNodeExecutableLocation())
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _fetchPrebuiltBinaryAsync(target: NexeTarget) {
|
private async _shouldCompileBinaryAsync(
|
||||||
let downloadOptions = this.options.downloadOptions
|
binary: NodeJS.ReadableStream | null,
|
||||||
|
location: string | undefined
|
||||||
|
) {
|
||||||
|
//SOMEDAY combine make/configure/vcBuild/and modified times of included files
|
||||||
|
const { snapshot, build } = this.options
|
||||||
|
|
||||||
if (this.options.ghToken) {
|
if (!binary) {
|
||||||
downloadOptions = Object.assign({}, downloadOptions)
|
return true
|
||||||
downloadOptions.headers = Object.assign({}, downloadOptions.headers, {
|
|
||||||
Authorization: 'token ' + this.options.ghToken
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const githubRelease = await getLatestGitRelease(downloadOptions)
|
if (build && snapshot != null && (await pathExistsAsync(snapshot))) {
|
||||||
const assetName = target.toString()
|
const snapshotLastModified = (await statAsync(snapshot)).mtimeMs
|
||||||
const asset = githubRelease.assets.find(x => x.name === assetName)
|
const binaryLastModified = (await statAsync(location)).mtimeMs
|
||||||
|
return snapshotLastModified > binaryLastModified
|
||||||
if (!asset) {
|
|
||||||
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), this.options.downloadOptions).on(
|
return false
|
||||||
'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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async compileAsync(target: NexeTarget) {
|
async compileAsync(target: NexeTarget) {
|
||||||
@@ -224,15 +286,12 @@ export class NexeCompiler {
|
|||||||
const build = this.options.build
|
const build = this.options.build
|
||||||
const location = this.getNodeExecutableLocation(build ? undefined : target)
|
const location = this.getNodeExecutableLocation(build ? undefined : target)
|
||||||
let binary = (await pathExistsAsync(location)) ? createReadStream(location) : null
|
let binary = (await pathExistsAsync(location)) ? createReadStream(location) : null
|
||||||
if (!build && !binary) {
|
|
||||||
step.modify('Fetching prebuilt binary')
|
if (await this._shouldCompileBinaryAsync(binary, location)) {
|
||||||
binary = await this._fetchPrebuiltBinaryAsync(target)
|
binary = await this.build()
|
||||||
}
|
|
||||||
if (!binary) {
|
|
||||||
binary = await this._buildAsync()
|
|
||||||
step.log('Node binary compiled')
|
step.log('Node binary compiled')
|
||||||
}
|
}
|
||||||
return this._assembleDeliverable(binary)
|
return this._assembleDeliverable(binary!)
|
||||||
}
|
}
|
||||||
|
|
||||||
code() {
|
code() {
|
||||||
|
|||||||
Vendored
+18
-13
@@ -1,15 +1,20 @@
|
|||||||
const __nexe_patches = (process.nexe = { patches: {} }).patches
|
if (true) {
|
||||||
function __nexe_noop_patch(original, ...args) {
|
const __nexe_patches = (process.nexe = { patches: {} }).patches
|
||||||
return original.call(this, ...args)
|
const slice = [].slice
|
||||||
}
|
const __nexe_noop_patch = function (original) {
|
||||||
function __nexe_patch(obj, method, patch) {
|
const args = slice.call(arguments, 1)
|
||||||
const original = obj[method]
|
return original.apply(this, args)
|
||||||
if (!original) return
|
|
||||||
__nexe_patches[method] = patch
|
|
||||||
obj[method] = function( ...args) {
|
|
||||||
return __nexe_patches[method].call(this, original, ...args)
|
|
||||||
}
|
}
|
||||||
|
const __nexe_patch = function (obj, method, patch) {
|
||||||
|
const original = obj[method]
|
||||||
|
if (!original) return
|
||||||
|
__nexe_patches[method] = patch
|
||||||
|
obj[method] = function() {
|
||||||
|
const args = [original].concat(slice.call(arguments))
|
||||||
|
return __nexe_patches[method].apply(this, args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__nexe_patch((process).binding('fs'), 'internalModuleReadFile', __nexe_noop_patch)
|
||||||
|
__nexe_patch((process).binding('fs'), 'internalModuleReadJSON', __nexe_noop_patch)
|
||||||
|
__nexe_patch((process).binding('fs'), 'internalModuleStat', __nexe_noop_patch)
|
||||||
}
|
}
|
||||||
__nexe_patch((process).binding('fs'), 'internalModuleReadFile', __nexe_noop_patch)
|
|
||||||
__nexe_patch((process).binding('fs'), 'internalModuleReadJSON', __nexe_noop_patch)
|
|
||||||
__nexe_patch((process).binding('fs'), 'internalModuleStat', __nexe_noop_patch)
|
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ export class Bundle {
|
|||||||
|
|
||||||
async addResource(absoluteFileName: string, content?: Buffer | string) {
|
async addResource(absoluteFileName: string, content?: Buffer | string) {
|
||||||
let length = 0
|
let length = 0
|
||||||
if (content) {
|
if (content !== undefined) {
|
||||||
length = Buffer.byteLength(content)
|
length = Buffer.byteLength(content)
|
||||||
} else {
|
} else {
|
||||||
const stats = await stat(absoluteFileName)
|
const stats = await stat(absoluteFileName)
|
||||||
|
|||||||
+108
-74
@@ -13,52 +13,46 @@ 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 = '!@#$%^&*',
|
||||||
|
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) => {
|
let log = (_: string) => true
|
||||||
if ((process.env.DEBUG || '').toLowerCase().includes('nexe:require')) {
|
if ((process.env.DEBUG || '').toLowerCase().includes('nexe:require')) {
|
||||||
process.stderr.write('[nexe] - ' + text + '\n')
|
log = (text: string) => process.stderr.write('[nexe] - ' + text + '\n')
|
||||||
} else {
|
|
||||||
log = noop
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getKey = process.platform.startsWith('win')
|
const winPath = (key: string) => {
|
||||||
? function getKey(filepath: string): string {
|
if (isWin && key.substr(1, 2) === ':\\') {
|
||||||
let key = path.resolve(filepath)
|
key = key[0].toUpperCase() + key.substr(1)
|
||||||
if (key.substr(1, 2) === ':\\') {
|
}
|
||||||
key = key[0].toUpperCase() + key.substr(1)
|
return key
|
||||||
}
|
}
|
||||||
return key
|
|
||||||
}
|
const getKey = function getKey(filepath: string | Buffer | null): string {
|
||||||
: path.resolve
|
if (Buffer.isBuffer(filepath)) {
|
||||||
|
filepath = filepath.toString()
|
||||||
|
}
|
||||||
|
if (!isString(filepath)) {
|
||||||
|
return notAFile
|
||||||
|
}
|
||||||
|
let key = path.resolve(baseDir, filepath)
|
||||||
|
|
||||||
|
return winPath(key)
|
||||||
|
}
|
||||||
|
|
||||||
const statTime = function() {
|
const statTime = function() {
|
||||||
return {
|
return {
|
||||||
@@ -81,22 +75,21 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const createStat = function(directoryExtensions: any, fileExtensions?: any) {
|
const createStat = function(extensions: any) {
|
||||||
if (!fileExtensions) {
|
return Object.assign(new fs.Stats(), binary.layout.stat, statTime(), extensions)
|
||||||
return Object.assign({}, binary.layout.stat, directoryExtensions, { size: 0 }, statTime())
|
|
||||||
}
|
|
||||||
const size = directoryExtensions[1]
|
|
||||||
return Object.assign({}, binary.layout.stat, fileExtensions, { size }, statTime())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ownStat = function(filepath: string) {
|
const ownStat = function(filepath: any) {
|
||||||
setupManifest()
|
setupManifest()
|
||||||
const key = getKey(filepath)
|
const key = getKey(filepath)
|
||||||
if (directories[key]) {
|
if (directories[key]) {
|
||||||
return createStat({ isDirectory, isFile: isNotFile })
|
let mode = binary.layout.stat.mode
|
||||||
|
mode |= fs.constants.S_IFDIR
|
||||||
|
mode &= ~fs.constants.S_IFREG
|
||||||
|
return createStat({ mode, size: 0 })
|
||||||
}
|
}
|
||||||
if (manifest[key]) {
|
if (manifest[key]) {
|
||||||
return createStat(manifest[key], { isFile, isDirectory: isNotDirectory })
|
return createStat({ size: manifest[key][1] })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +106,7 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
|
|||||||
const entry = manifest[filepath]
|
const entry = manifest[filepath]
|
||||||
const absolutePath = getKey(filepath)
|
const absolutePath = getKey(filepath)
|
||||||
const longPath = makeLong(absolutePath)
|
const longPath = makeLong(absolutePath)
|
||||||
const normalizedPath = path.normalize(filepath)
|
const normalizedPath = winPath(path.normalize(filepath))
|
||||||
|
|
||||||
if (!manifest[absolutePath]) {
|
if (!manifest[absolutePath]) {
|
||||||
manifest[absolutePath] = entry
|
manifest[absolutePath] = entry
|
||||||
@@ -139,6 +132,8 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
|
|||||||
currentDir = path.dirname(currentDir)
|
currentDir = path.dirname(currentDir)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
;(manifest[notAFile] as any) = false
|
||||||
|
;(directories[notAFile] as any) = false
|
||||||
setupManifest = noop
|
setupManifest = noop
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,32 +158,26 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
|
|||||||
realpathSync: function realpathSync(filepath: any, options: any) {
|
realpathSync: function realpathSync(filepath: any, options: any) {
|
||||||
setupManifest()
|
setupManifest()
|
||||||
const key = getKey(filepath)
|
const key = getKey(filepath)
|
||||||
if (isString(filepath) && (manifest[filepath] || manifest[key])) {
|
if (manifest[key]) {
|
||||||
return filepath
|
return filepath
|
||||||
}
|
}
|
||||||
return originalFsMethods.realpathSync.call(fs, filepath, options)
|
return originalFsMethods.realpathSync.call(fs, filepath, options)
|
||||||
},
|
},
|
||||||
readdir: function readdir(filepath: string | Buffer, options: any, callback: any) {
|
readdir: function readdir(filepath: string | Buffer, options: any, callback: any) {
|
||||||
setupManifest()
|
setupManifest()
|
||||||
filepath = filepath.toString()
|
|
||||||
if ('function' === typeof options) {
|
|
||||||
callback = options
|
|
||||||
options = { encoding: 'utf8' }
|
|
||||||
}
|
|
||||||
const dir = directories[getKey(filepath)]
|
const dir = directories[getKey(filepath)]
|
||||||
if (dir) {
|
if (dir) {
|
||||||
process.nextTick(() => {
|
if ('function' === typeof options) {
|
||||||
//todo merge with original?
|
callback = options
|
||||||
callback(null, Object.keys(dir))
|
options = { encoding: 'utf8' }
|
||||||
})
|
}
|
||||||
|
process.nextTick(() => callback(null, Object.keys(dir)))
|
||||||
} else {
|
} else {
|
||||||
return originalFsMethods.readdir.apply(fs, arguments)
|
return originalFsMethods.readdir.apply(fs, arguments)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
readdirSync: function readdirSync(filepath: string | Buffer, options: any) {
|
readdirSync: function readdirSync(filepath: string | Buffer, options: any) {
|
||||||
setupManifest()
|
setupManifest()
|
||||||
filepath = filepath.toString()
|
|
||||||
const dir = directories[getKey(filepath)]
|
const dir = directories[getKey(filepath)]
|
||||||
if (dir) {
|
if (dir) {
|
||||||
return Object.keys(dir)
|
return Object.keys(dir)
|
||||||
@@ -198,8 +187,8 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
|
|||||||
|
|
||||||
readFile: function readFile(filepath: any, options: any, callback: any) {
|
readFile: function readFile(filepath: any, options: any, callback: any) {
|
||||||
setupManifest()
|
setupManifest()
|
||||||
const entry = manifest[filepath] || manifest[getKey(filepath)]
|
const entry = manifest[getKey(filepath)]
|
||||||
if (!entry || !isString(filepath)) {
|
if (!entry) {
|
||||||
return originalFsMethods.readFile.apply(fs, arguments)
|
return originalFsMethods.readFile.apply(fs, arguments)
|
||||||
}
|
}
|
||||||
const [offset, length] = entry
|
const [offset, length] = entry
|
||||||
@@ -207,19 +196,19 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
|
|||||||
const encoding = fileOpts(options).encoding
|
const encoding = fileOpts(options).encoding
|
||||||
callback = typeof options === 'function' ? options : callback
|
callback = typeof options === 'function' ? options : callback
|
||||||
|
|
||||||
fs.open(blobPath, 'r', function(err: Error, fd: number) {
|
originalFsMethods.open(blobPath, 'r', function(err: Error, fd: number) {
|
||||||
if (err) return callback(err, null)
|
if (err) return callback(err, null)
|
||||||
fs.read(fd, Buffer.alloc(length), 0, length, resourceOffset, function(
|
originalFsMethods.read(fd, Buffer.alloc(length), 0, length, resourceOffset, function(
|
||||||
error: Error,
|
error: Error,
|
||||||
bytesRead: number,
|
bytesRead: number,
|
||||||
result: Buffer
|
result: Buffer
|
||||||
) {
|
) {
|
||||||
if (error) {
|
if (error) {
|
||||||
return fs.close(fd, function() {
|
return originalFsMethods.close(fd, function() {
|
||||||
callback(error, null)
|
callback(error, null)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fs.close(fd, function(err: Error) {
|
originalFsMethods.close(fd, function(err: Error) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err, result)
|
return callback(err, result)
|
||||||
}
|
}
|
||||||
@@ -230,15 +219,15 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
|
|||||||
},
|
},
|
||||||
createReadStream: function createReadStream(filepath: any, options: any) {
|
createReadStream: function createReadStream(filepath: any, options: any) {
|
||||||
setupManifest()
|
setupManifest()
|
||||||
const entry = manifest[filepath] || manifest[getKey(filepath)]
|
const entry = manifest[getKey(filepath)]
|
||||||
if (!entry || !isString(filepath)) {
|
if (!entry) {
|
||||||
return originalFsMethods.createReadStream.apply(fs, arguments)
|
return originalFsMethods.createReadStream.apply(fs, arguments)
|
||||||
}
|
}
|
||||||
const [offset, length] = entry
|
const [offset, length] = entry
|
||||||
const resourceOffset = resourceStart + offset
|
const resourceOffset = resourceStart + offset
|
||||||
const opts = fileOpts(options)
|
const opts = fileOpts(options)
|
||||||
|
|
||||||
return fs.createReadStream(
|
return originalFsMethods.createReadStream(
|
||||||
blobPath,
|
blobPath,
|
||||||
Object.assign({}, opts, {
|
Object.assign({}, opts, {
|
||||||
start: resourceOffset,
|
start: resourceOffset,
|
||||||
@@ -248,29 +237,28 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
|
|||||||
},
|
},
|
||||||
readFileSync: function readFileSync(filepath: any, options: any) {
|
readFileSync: function readFileSync(filepath: any, options: any) {
|
||||||
setupManifest()
|
setupManifest()
|
||||||
|
const entry = manifest[getKey(filepath)]
|
||||||
const entry = manifest[filepath] || manifest[getKey(filepath)]
|
if (!entry) {
|
||||||
if (!entry || !isString(filepath)) {
|
|
||||||
return originalFsMethods.readFileSync.apply(fs, arguments)
|
return originalFsMethods.readFileSync.apply(fs, arguments)
|
||||||
}
|
}
|
||||||
const [offset, length] = entry
|
const [offset, length] = entry
|
||||||
const resourceOffset = resourceStart + offset
|
const resourceOffset = resourceStart + offset
|
||||||
const encoding = fileOpts(options).encoding
|
const encoding = fileOpts(options).encoding
|
||||||
const fd = fs.openSync(process.execPath, 'r')
|
const fd = originalFsMethods.openSync(process.execPath, 'r')
|
||||||
const result = Buffer.alloc(length)
|
const result = Buffer.alloc(length)
|
||||||
fs.readSync(fd, result, 0, length, resourceOffset)
|
originalFsMethods.readSync(fd, result, 0, length, resourceOffset)
|
||||||
fs.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) {
|
||||||
const stat = isString(filepath) && ownStat(filepath)
|
const stat = ownStat(filepath)
|
||||||
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, callback: any) {
|
||||||
const stat = isString(filepath) && ownStat(filepath)
|
const stat = ownStat(filepath)
|
||||||
if (stat) {
|
if (stat) {
|
||||||
process.nextTick(() => {
|
process.nextTick(() => {
|
||||||
callback(null, stat)
|
callback(null, stat)
|
||||||
@@ -301,6 +289,7 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
|
|||||||
log('read (miss) ' + filepath)
|
log('read (miss) ' + filepath)
|
||||||
return original.call(this, ...args)
|
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()
|
setupManifest()
|
||||||
const [filepath] = args
|
const [filepath] = args
|
||||||
@@ -333,8 +322,53 @@ function shimFs(binary: NexeBinary, fs: any = require('fs')) {
|
|||||||
process.nextTick(() => cb(exists))
|
process.nextTick(() => cb(exists))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof fs.copyFile === 'function') {
|
||||||
|
nfs.copyFile = function(filepath: string, dest: string, flags: number, callback: Function) {
|
||||||
|
setupManifest()
|
||||||
|
const entry = manifest[getKey(filepath)]
|
||||||
|
if (!entry) {
|
||||||
|
return originalFsMethods.copyFile.apply(fs, arguments)
|
||||||
|
}
|
||||||
|
if (typeof flags === 'function') {
|
||||||
|
callback = flags
|
||||||
|
flags = 0
|
||||||
|
}
|
||||||
|
nfs.readFile(filepath, (err: any, buffer: any) => {
|
||||||
|
if (err) {
|
||||||
|
return callback(err)
|
||||||
|
}
|
||||||
|
originalFsMethods.writeFile(dest, buffer, (err: any) => {
|
||||||
|
if (err) {
|
||||||
|
return callback(err)
|
||||||
|
}
|
||||||
|
callback(null)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
nfs.copyFileSync = function(filepath: string, dest: string) {
|
||||||
|
setupManifest()
|
||||||
|
const entry = manifest[getKey(filepath)]
|
||||||
|
if (!entry) {
|
||||||
|
return originalFsMethods.copyFileSync.apply(fs, arguments)
|
||||||
|
}
|
||||||
|
return originalFsMethods.writeFileSync(dest, nfs.readFileSync(filepath))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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
-2
@@ -1,5 +1,5 @@
|
|||||||
import colors = require('chalk')
|
import colors from 'chalk'
|
||||||
import ora = require('ora')
|
import ora from 'ora'
|
||||||
|
|
||||||
const frameLength = 120
|
const frameLength = 120
|
||||||
|
|
||||||
|
|||||||
+17
-19
@@ -1,6 +1,6 @@
|
|||||||
import { EOL } from 'os'
|
import { EOL } from 'os'
|
||||||
import { compose } from 'app-builder'
|
import { compose } from 'app-builder'
|
||||||
import { NexeCompiler } from './compiler'
|
import { NexeCompiler, NexeError } from './compiler'
|
||||||
import { normalizeOptions, NexeOptions, NexePatch } from './options'
|
import { normalizeOptions, NexeOptions, NexePatch } from './options'
|
||||||
import resource from './steps/resource'
|
import resource from './steps/resource'
|
||||||
import clean from './steps/clean'
|
import clean from './steps/clean'
|
||||||
@@ -15,31 +15,29 @@ async function compile(
|
|||||||
compilerOptions?: Partial<NexeOptions>,
|
compilerOptions?: Partial<NexeOptions>,
|
||||||
callback?: (err: Error | null) => void
|
callback?: (err: Error | null) => void
|
||||||
) {
|
) {
|
||||||
const options = normalizeOptions(compilerOptions)
|
let error = null,
|
||||||
const compiler = new NexeCompiler(options)
|
options: NexeOptions | null = null,
|
||||||
|
compiler: NexeCompiler | null = null
|
||||||
|
|
||||||
const nexe = compose(
|
|
||||||
clean,
|
|
||||||
resource,
|
|
||||||
cli,
|
|
||||||
bundle,
|
|
||||||
shim,
|
|
||||||
options.build ? [download, artifacts, ...patches, ...(options.patches as NexePatch[])] : [],
|
|
||||||
options.plugins as NexePatch[]
|
|
||||||
)
|
|
||||||
|
|
||||||
let error = null
|
|
||||||
try {
|
try {
|
||||||
await nexe(compiler)
|
options = normalizeOptions(compilerOptions)
|
||||||
|
compiler = new NexeCompiler(options)
|
||||||
|
await compose(
|
||||||
|
clean,
|
||||||
|
resource,
|
||||||
|
cli,
|
||||||
|
bundle,
|
||||||
|
shim,
|
||||||
|
download,
|
||||||
|
options.build ? [artifacts, ...patches, ...(options.patches as NexePatch[])] : [],
|
||||||
|
options.plugins as NexePatch[]
|
||||||
|
)(compiler)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error = e
|
error = e
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
if (compiler.options.loglevel !== 'silent' && error) {
|
compiler && compiler.quit(error)
|
||||||
process.stderr.write(EOL + error.message + EOL)
|
|
||||||
}
|
|
||||||
compiler.quit()
|
|
||||||
if (callback) return callback(error)
|
if (callback) return callback(error)
|
||||||
return Promise.reject(error)
|
return Promise.reject(error)
|
||||||
}
|
}
|
||||||
|
|||||||
+43
-35
@@ -1,6 +1,6 @@
|
|||||||
import * as parseArgv from 'minimist'
|
import * as parseArgv from 'minimist'
|
||||||
import { NexeCompiler } from './compiler'
|
import { NexeCompiler, NexeError } from './compiler'
|
||||||
import { isWindows } from './util'
|
import { isWindows, STDIN_FLAG } from './util'
|
||||||
import { basename, extname, join, isAbsolute, resolve } from 'path'
|
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'
|
||||||
@@ -21,7 +21,9 @@ export interface NexeOptions {
|
|||||||
output: string
|
output: string
|
||||||
targets: (string | NexeTarget)[]
|
targets: (string | NexeTarget)[]
|
||||||
name: string
|
name: string
|
||||||
|
asset: string
|
||||||
cwd: string
|
cwd: string
|
||||||
|
fs: boolean | string[]
|
||||||
flags: string[]
|
flags: string[]
|
||||||
configure: string[]
|
configure: string[]
|
||||||
vcBuild: string[]
|
vcBuild: string[]
|
||||||
@@ -35,11 +37,6 @@ export interface NexeOptions {
|
|||||||
patches: (string | NexePatch)[]
|
patches: (string | NexePatch)[]
|
||||||
plugins: (string | NexePatch)[]
|
plugins: (string | NexePatch)[]
|
||||||
native: any
|
native: any
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
* Use mangle: false instead
|
|
||||||
*/
|
|
||||||
empty: boolean
|
|
||||||
mangle: boolean
|
mangle: boolean
|
||||||
ghToken: string
|
ghToken: string
|
||||||
sourceUrl?: string
|
sourceUrl?: string
|
||||||
@@ -53,7 +50,6 @@ export interface NexeOptions {
|
|||||||
ico?: string
|
ico?: string
|
||||||
debugBundle?: boolean
|
debugBundle?: boolean
|
||||||
warmup?: string
|
warmup?: string
|
||||||
compress?: boolean
|
|
||||||
clean?: boolean
|
clean?: boolean
|
||||||
/**
|
/**
|
||||||
* Api Only
|
* Api Only
|
||||||
@@ -64,12 +60,13 @@ export interface NexeOptions {
|
|||||||
const defaults = {
|
const defaults = {
|
||||||
flags: [],
|
flags: [],
|
||||||
cwd: process.cwd(),
|
cwd: process.cwd(),
|
||||||
|
fs: true,
|
||||||
configure: [],
|
configure: [],
|
||||||
|
mangle: true,
|
||||||
make: [],
|
make: [],
|
||||||
targets: [],
|
targets: [],
|
||||||
vcBuild: isWindows ? ['nosign', 'release'] : [],
|
vcBuild: isWindows ? ['nosign', 'release'] : [],
|
||||||
enableNodeCli: false,
|
enableNodeCli: false,
|
||||||
compress: false,
|
|
||||||
build: false,
|
build: false,
|
||||||
bundle: true,
|
bundle: true,
|
||||||
patches: [],
|
patches: [],
|
||||||
@@ -83,7 +80,7 @@ const alias = {
|
|||||||
b: 'build',
|
b: 'build',
|
||||||
n: 'name',
|
n: 'name',
|
||||||
r: 'resource',
|
r: 'resource',
|
||||||
a: 'resource',
|
a: 'asset',
|
||||||
p: 'python',
|
p: 'python',
|
||||||
f: 'flag',
|
f: 'flag',
|
||||||
c: 'configure',
|
c: 'configure',
|
||||||
@@ -104,6 +101,7 @@ ${c.bold('nexe <entry-file> [options]')}
|
|||||||
-t --target -- node version description
|
-t --target -- node version description
|
||||||
-n --name -- main app module name
|
-n --name -- main app module name
|
||||||
-r --resource -- *embed files (glob) within the binary
|
-r --resource -- *embed files (glob) within the binary
|
||||||
|
-a --asset -- alternate asset path, file or url pointing to a base (nexe) binary
|
||||||
--plugin -- extend nexe runtime behavior
|
--plugin -- extend nexe runtime behavior
|
||||||
|
|
||||||
${c.underline.bold('Building from source:')}
|
${c.underline.bold('Building from source:')}
|
||||||
@@ -113,7 +111,8 @@ ${c.bold('nexe <entry-file> [options]')}
|
|||||||
-f --flag -- *v8 flags to include during compilation
|
-f --flag -- *v8 flags to include during compilation
|
||||||
-c --configure -- *arguments to the configure step
|
-c --configure -- *arguments to the configure step
|
||||||
-m --make -- *arguments to the make/build step
|
-m --make -- *arguments to the make/build step
|
||||||
--no-mangle -- used when generating base binaries, or when pathing _third_party_main manually.
|
--patch -- module with middleware default export for adding a build patch
|
||||||
|
--no-mangle -- used when generating base binaries, or when patching _third_party_main manually.
|
||||||
--snapshot -- path to a warmup snapshot
|
--snapshot -- path to a warmup snapshot
|
||||||
--ico -- file name for alternate icon file (windows)
|
--ico -- file name for alternate icon file (windows)
|
||||||
--rc-* -- populate rc file options (windows)
|
--rc-* -- populate rc file options (windows)
|
||||||
@@ -165,7 +164,7 @@ function extractLogLevel(options: NexeOptions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isName(name: string) {
|
function isName(name: string) {
|
||||||
return name && name !== 'index'
|
return name && name !== 'index' && name !== STDIN_FLAG
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractName(options: NexeOptions) {
|
function extractName(options: NexeOptions) {
|
||||||
@@ -194,11 +193,16 @@ function isEntryFile(filename?: string): filename is string {
|
|||||||
return Boolean(filename && !isAbsolute(filename))
|
return Boolean(filename && !isAbsolute(filename))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolveEntry(input: string, cwd: string, maybeEntry?: string) {
|
export function resolveEntry(
|
||||||
if (input === '-' || maybeEntry === '-') {
|
input: string,
|
||||||
return ''
|
cwd: string,
|
||||||
}
|
maybeEntry: string | undefined,
|
||||||
|
bundle: boolean | string
|
||||||
|
) {
|
||||||
let result = null
|
let result = null
|
||||||
|
if (input === '-' || maybeEntry === '-') {
|
||||||
|
return STDIN_FLAG
|
||||||
|
}
|
||||||
if (input && isAbsolute(input)) {
|
if (input && isAbsolute(input)) {
|
||||||
return input
|
return input
|
||||||
}
|
}
|
||||||
@@ -206,19 +210,19 @@ export function resolveEntry(input: string, cwd: string, maybeEntry?: string) {
|
|||||||
const inputPath = padRelative(input)
|
const inputPath = padRelative(input)
|
||||||
result = resolveFileNameSync(cwd, inputPath)
|
result = resolveFileNameSync(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 = resolveFileNameSync(cwd, inputPath)
|
||||||
}
|
}
|
||||||
if (!process.stdin.isTTY) {
|
if (!process.stdin.isTTY && (!result || !result.absPath) && bundle === defaults.bundle) {
|
||||||
return ''
|
return STDIN_FLAG
|
||||||
}
|
}
|
||||||
if (!result || !result.absPath) {
|
if (!result || !result.absPath) {
|
||||||
result = resolveFileNameSync(cwd, '.')
|
result = resolveFileNameSync(cwd, '.')
|
||||||
}
|
}
|
||||||
if (!result.absPath) throw new Error(`Entry file "${input}" not found!`)
|
if (!result.absPath) {
|
||||||
|
throw new NexeError(`Entry file "${input || ''}" not found!`)
|
||||||
|
}
|
||||||
return result.absPath
|
return result.absPath
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,8 +238,8 @@ function normalizeOptions(input?: Partial<NexeOptions>): NexeOptions {
|
|||||||
? resolve(cwd, options.temp)
|
? resolve(cwd, options.temp)
|
||||||
: process.env.NEXE_TEMP || join(homedir(), '.nexe')
|
: process.env.NEXE_TEMP || join(homedir(), '.nexe')
|
||||||
const maybeEntry = isCli(input) ? argv._[argv._.length - 1] : undefined
|
const maybeEntry = isCli(input) ? argv._[argv._.length - 1] : undefined
|
||||||
options.input = resolveEntry(options.input, cwd, maybeEntry)
|
options.input = resolveEntry(options.input, cwd, maybeEntry, options.bundle)
|
||||||
options.enableStdIn = isCli(input) && options.input === ''
|
options.enableStdIn = isCli(input) && options.input === STDIN_FLAG
|
||||||
options.name = extractName(options)
|
options.name = extractName(options)
|
||||||
options.loglevel = extractLogLevel(options)
|
options.loglevel = extractLogLevel(options)
|
||||||
options.flags = flatten(opts.flag, options.flags)
|
options.flags = flatten(opts.flag, options.flags)
|
||||||
@@ -244,7 +248,7 @@ function normalizeOptions(input?: Partial<NexeOptions>): NexeOptions {
|
|||||||
options.targets.push(getTarget())
|
options.targets.push(getTarget())
|
||||||
}
|
}
|
||||||
options.ghToken = options.ghToken || process.env.GITHUB_TOKEN || ''
|
options.ghToken = options.ghToken || process.env.GITHUB_TOKEN || ''
|
||||||
options.make = flatten(options.vcBuild, options.make)
|
options.make = flatten(isWindows ? options.vcBuild : options.make)
|
||||||
options.configure = flatten(options.configure)
|
options.configure = flatten(options.configure)
|
||||||
options.resources = flatten(opts.resource, options.resources)
|
options.resources = flatten(opts.resource, options.resources)
|
||||||
|
|
||||||
@@ -263,6 +267,21 @@ function normalizeOptions(input?: Partial<NexeOptions>): NexeOptions {
|
|||||||
: `${options.output || options.name}`
|
: `${options.output || options.name}`
|
||||||
options.output = resolve(cwd, options.output)
|
options.output = resolve(cwd, options.output)
|
||||||
|
|
||||||
|
const requireDefault = (x: string) => {
|
||||||
|
if (typeof x === 'string') {
|
||||||
|
return require(x).default
|
||||||
|
}
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
options.mangle = 'mangle' in opts ? opts.mangle : true
|
||||||
|
options.plugins = flatten(opts.plugin, options.plugins).map(requireDefault)
|
||||||
|
options.patches = flatten(opts.patch, options.patches).map(requireDefault)
|
||||||
|
|
||||||
|
if ((!options.mangle && !options.bundle) || options.patches.length) {
|
||||||
|
options.build = true
|
||||||
|
}
|
||||||
|
|
||||||
if (options.build) {
|
if (options.build) {
|
||||||
const { arch } = options.targets[0] as NexeTarget
|
const { arch } = options.targets[0] as NexeTarget
|
||||||
if (isWindows) {
|
if (isWindows) {
|
||||||
@@ -272,17 +291,6 @@ function normalizeOptions(input?: Partial<NexeOptions>): NexeOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const requireDefault = (x: string) => {
|
|
||||||
if (typeof x === 'string') {
|
|
||||||
return require(x).default
|
|
||||||
}
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
options.mangle = 'mangle' in opts ? opts.mangle : !opts.empty
|
|
||||||
options.plugins = flatten(opts.plugin, options.plugins).map(requireDefault)
|
|
||||||
options.patches = flatten(opts.patch, options.patches).map(requireDefault)
|
|
||||||
|
|
||||||
Object.keys(alias)
|
Object.keys(alias)
|
||||||
.filter(k => k !== 'rc')
|
.filter(k => k !== 'rc')
|
||||||
.forEach(x => delete opts[x])
|
.forEach(x => delete opts[x])
|
||||||
|
|||||||
@@ -1,17 +1,20 @@
|
|||||||
const fs = require('fs'),
|
const fs = require('fs'),
|
||||||
fd = fs.openSync(process.execPath, 'r'),
|
fd = fs.openSync(process.execPath, 'r'),
|
||||||
stat = fs.statSync(process.execPath),
|
stat = fs.statSync(process.execPath),
|
||||||
footer = Buffer.alloc(32, 0)
|
tailSize = Math.min(stat.size, 16000),
|
||||||
|
tailWindow = Buffer.from(Array(tailSize))
|
||||||
|
|
||||||
fs.readSync(fd, footer, 0, 32, stat.size - 32)
|
fs.readSync(fd, tailWindow, 0, tailSize, stat.size - tailSize)
|
||||||
|
|
||||||
if (!footer.slice(0, 16).equals(Buffer.from('<nexe~~sentinel>'))) {
|
const footerPosition = tailWindow.indexOf('<nexe~~sentinel>')
|
||||||
|
if (footerPosition == -1) {
|
||||||
throw 'Invalid Nexe binary'
|
throw 'Invalid Nexe binary'
|
||||||
}
|
}
|
||||||
|
|
||||||
const contentSize = footer.readDoubleLE(16),
|
const footer = tailWindow.slice(footerPosition, footerPosition + 32),
|
||||||
|
contentSize = footer.readDoubleLE(16),
|
||||||
resourceSize = footer.readDoubleLE(24),
|
resourceSize = footer.readDoubleLE(24),
|
||||||
contentStart = stat.size - 32 - resourceSize - contentSize,
|
contentStart = stat.size - tailSize + footerPosition - resourceSize - contentSize,
|
||||||
resourceStart = contentStart + contentSize
|
resourceStart = contentStart + contentSize
|
||||||
|
|
||||||
Object.defineProperty(
|
Object.defineProperty(
|
||||||
|
|||||||
@@ -1,20 +1,44 @@
|
|||||||
import { NexeCompiler } from '../compiler'
|
import { NexeCompiler } from '../compiler'
|
||||||
|
import { semverGt } from '../util'
|
||||||
|
|
||||||
export default async function disableNodeCli(compiler: NexeCompiler, next: () => Promise<void>) {
|
export default async function disableNodeCli(compiler: NexeCompiler, next: () => Promise<void>) {
|
||||||
if (compiler.options.enableNodeCli) {
|
if (compiler.options.enableNodeCli) {
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodeccMarker = 'argv[index][0] =='
|
if (semverGt(compiler.target.version, '11.6.0')) {
|
||||||
|
await compiler.replaceInFileAsync(
|
||||||
|
'src/node.cc',
|
||||||
|
/(?<!int )ProcessGlobalArgs\(/g,
|
||||||
|
'0;//ProcessGlobalArgs('
|
||||||
|
)
|
||||||
|
} else if (semverGt(compiler.target.version, '10.9')) {
|
||||||
|
await compiler.replaceInFileAsync('src/node.cc', /(?<!void )ProcessArgv\(/g, '//ProcessArgv(')
|
||||||
|
} else if (semverGt(compiler.target.version, '9.999')) {
|
||||||
|
await compiler.replaceInFileAsync(
|
||||||
|
'src/node.cc',
|
||||||
|
'int i = 1; i < v8_argc; i++',
|
||||||
|
'int i = v8_argc; i < v8_argc; i++'
|
||||||
|
)
|
||||||
|
let matches = 0
|
||||||
|
await compiler.replaceInFileAsync('src/node.cc', /v8_argc > 1/g, match => {
|
||||||
|
if (matches++) {
|
||||||
|
return 'false'
|
||||||
|
}
|
||||||
|
return match
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const nodeccMarker = 'argv[index][0] =='
|
||||||
|
|
||||||
await compiler.replaceInFileAsync(
|
await compiler.replaceInFileAsync(
|
||||||
'src/node.cc',
|
'src/node.cc',
|
||||||
`${nodeccMarker} '-'`,
|
`${nodeccMarker} '-'`,
|
||||||
// allow NODE_OPTIONS, introduced in 8.0
|
// allow NODE_OPTIONS, introduced in 8.0
|
||||||
parseInt(compiler.target.version.split('.')[0]) >= 8
|
semverGt(compiler.target.version, '7.99')
|
||||||
? `(${nodeccMarker} (is_env ? '-' : ']'))`
|
? `(${nodeccMarker} (is_env ? '-' : ']'))`
|
||||||
: `(${nodeccMarker} ']')`
|
: `(${nodeccMarker} ']')`
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import cli from './disable-node-cli'
|
|||||||
import flags from './flags'
|
import flags from './flags'
|
||||||
import ico from './ico'
|
import ico from './ico'
|
||||||
import rc from './node-rc'
|
import rc from './node-rc'
|
||||||
|
import snapshot from './snapshot'
|
||||||
|
|
||||||
const patches = [gyp, bootNexe, buildFixes, cli, flags, ico, rc]
|
const patches = [gyp, bootNexe, buildFixes, cli, flags, ico, rc, snapshot]
|
||||||
|
|
||||||
export default patches
|
export default patches
|
||||||
|
|||||||
+15
-7
@@ -1,18 +1,26 @@
|
|||||||
|
import { resolve } from 'path'
|
||||||
import { NexeCompiler } from '../compiler'
|
import { NexeCompiler } from '../compiler'
|
||||||
|
import { semverGt } from '../util'
|
||||||
|
|
||||||
export default async function snapshot(compiler: NexeCompiler, next: () => Promise<void>) {
|
export default async function(compiler: NexeCompiler, next: () => Promise<void>) {
|
||||||
const snapshotFile = compiler.options.snapshot
|
const { snapshot, warmup, cwd } = compiler.options
|
||||||
const warmupScript = compiler.options.warmup
|
|
||||||
|
|
||||||
if (!snapshotFile) {
|
if (!snapshot) {
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const variablePrefix = semverGt(compiler.target.version, '11.0.0') ? 'v8_' : ''
|
||||||
|
|
||||||
await compiler.replaceInFileAsync(
|
await compiler.replaceInFileAsync(
|
||||||
'configure',
|
compiler.configureScript,
|
||||||
'def configure_v8(o):',
|
'def configure_v8(o):',
|
||||||
`def configure_v8(o):\n o['variables']['embed_script'] = '${snapshotFile}'\n o['variables']['warmup_script'] = '${warmupScript ||
|
`def configure_v8(o):\n o['variables']['${variablePrefix}embed_script'] = r'${resolve(
|
||||||
snapshotFile}'`
|
cwd,
|
||||||
|
snapshot
|
||||||
|
)}'\n o['variables']['${variablePrefix}warmup_script'] = r'${resolve(
|
||||||
|
cwd,
|
||||||
|
warmup || snapshot
|
||||||
|
)}'`
|
||||||
)
|
)
|
||||||
|
|
||||||
return next()
|
return next()
|
||||||
|
|||||||
@@ -1,16 +1,6 @@
|
|||||||
import { NexeCompiler } from '../compiler'
|
import { NexeCompiler } from '../compiler'
|
||||||
import { parse } from 'cherow'
|
import { parse } from 'cherow'
|
||||||
|
import { wrap, semverGt } from '../util'
|
||||||
function semverGt(version: string, operand: string) {
|
|
||||||
const [cMajor, cMinor, cPatch] = version.split('.').map(Number)
|
|
||||||
const [major, minor, patch] = operand.split('.').map(Number)
|
|
||||||
|
|
||||||
return (
|
|
||||||
cMajor > major ||
|
|
||||||
(cMajor === major && cMinor > minor) ||
|
|
||||||
(cMajor === major && cMinor === minor && cPatch > patch)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function walkSome(node: any, visit: Function) {
|
function walkSome(node: any, visit: Function) {
|
||||||
if (!node || typeof node.type !== 'string' || node._visited) {
|
if (!node || typeof node.type !== 'string' || node._visited) {
|
||||||
@@ -39,6 +29,8 @@ export default async function main(compiler: NexeCompiler, next: () => Promise<v
|
|||||||
|
|
||||||
if (version.startsWith('4.')) {
|
if (version.startsWith('4.')) {
|
||||||
bootFile = 'src/node.js'
|
bootFile = 'src/node.js'
|
||||||
|
} else if (semverGt(version, '11.99')) {
|
||||||
|
bootFile = 'lib/internal/bootstrap/pre_execution.js'
|
||||||
} else if (semverGt(version, '9.10.1')) {
|
} else if (semverGt(version, '9.10.1')) {
|
||||||
bootFile = 'lib/internal/bootstrap/node.js'
|
bootFile = 'lib/internal/bootstrap/node.js'
|
||||||
}
|
}
|
||||||
@@ -63,12 +55,32 @@ export default async function main(compiler: NexeCompiler, next: () => Promise<v
|
|||||||
})
|
})
|
||||||
|
|
||||||
const fileLines = file.contents.split('\n')
|
const fileLines = file.contents.split('\n')
|
||||||
fileLines.splice(location.start.line, 0, '{{replace:lib/fs/bootstrap.js}}' + '\n')
|
fileLines.splice(
|
||||||
|
location.start.line,
|
||||||
|
0,
|
||||||
|
'{{replace:lib/fs/bootstrap.js}}' +
|
||||||
|
'\n' +
|
||||||
|
(semverGt(version, '11.99') ? 'expandArgv1 = false;\n' : '')
|
||||||
|
)
|
||||||
file.contents = fileLines.join('\n')
|
file.contents = fileLines.join('\n')
|
||||||
|
|
||||||
await compiler.setFileContentsAsync(
|
if (semverGt(version, '11.99')) {
|
||||||
'lib/_third_party_main.js',
|
await compiler.replaceInFileAsync(
|
||||||
'{{replace:lib/patches/boot-nexe.js}}'
|
bootFile,
|
||||||
)
|
'initializePolicy();',
|
||||||
|
'initializePolicy();\n' + wrap('{{replace:lib/patches/boot-nexe.js}}')
|
||||||
|
)
|
||||||
|
await compiler.replaceInFileAsync(
|
||||||
|
'src/node.cc',
|
||||||
|
'MaybeLocal<Value> StartMainThreadExecution(Environment* env) {',
|
||||||
|
'MaybeLocal<Value> StartMainThreadExecution(Environment* env) {\n' +
|
||||||
|
' return StartExecution(env, "internal/main/run_main_module");\n'
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
await compiler.setFileContentsAsync(
|
||||||
|
'lib/_third_party_main.js',
|
||||||
|
'{{replace:lib/patches/boot-nexe.js}}'
|
||||||
|
)
|
||||||
|
}
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -25,8 +25,8 @@ async function getJson<T>(url: string, options?: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isBuildableVersion(version: string) {
|
function isBuildableVersion(version: string) {
|
||||||
const major = +version.split('.')[0]
|
const major = Number(version.split('.')[0])
|
||||||
return !~versionsToSkip.indexOf(major) || version === '4.8.4'
|
return !versionsToSkip.includes(major) || version === '4.8.4'
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLatestGitRelease(options?: any) {
|
export function getLatestGitRelease(options?: any) {
|
||||||
@@ -50,7 +50,7 @@ export async function getUnBuiltReleases(options?: any) {
|
|||||||
platforms.forEach(platform => {
|
platforms.forEach(platform => {
|
||||||
architectures.forEach(arch => {
|
architectures.forEach(arch => {
|
||||||
if (arch === 'x86' && platform === 'mac') return
|
if (arch === 'x86' && platform === 'mac') return
|
||||||
if (arch === 'arm7l' && platform !== 'linux') return
|
if (arch.includes('arm')) return
|
||||||
versions.push(getTarget({ platform, arch, version }))
|
versions.push(getTarget({ platform, arch, version }))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+65
-6
@@ -1,20 +1,79 @@
|
|||||||
import { NexeCompiler } from '../compiler'
|
import { NexeCompiler, NexeError } from '../compiler'
|
||||||
import { resolve } 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, semverGt } from '../util'
|
||||||
|
import { Readable } from 'stream'
|
||||||
|
|
||||||
|
function getStdIn(stdin: Readable): Promise<string> {
|
||||||
|
let out = ''
|
||||||
|
return new Promise(resolve => {
|
||||||
|
stdin
|
||||||
|
.setEncoding('utf8')
|
||||||
|
.on('readable', () => {
|
||||||
|
let current
|
||||||
|
while ((current = stdin.read())) {
|
||||||
|
out += current
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on('end', () => resolve(out.trim()))
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!out.trim()) {
|
||||||
|
resolve(out.trim())
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
|
if (semverGt(compiler.target.version, '11.99')) {
|
||||||
|
compiler.startup = ''
|
||||||
|
} else {
|
||||||
|
compiler.startup = ';require("module").runMain();'
|
||||||
|
}
|
||||||
|
|
||||||
if (!bundle) {
|
if (!bundle) {
|
||||||
await compiler.addResource(resolve(cwd, input))
|
await compiler.addResource(resolve(cwd, input))
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!input) {
|
let code = ''
|
||||||
|
if (typeof bundle === 'string') {
|
||||||
|
code = await require(bundle).createBundle(compiler.options)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input === STDIN_FLAG && (code = code || dequote(await getStdIn(process.stdin)))) {
|
||||||
|
compiler.stdinUsed = true
|
||||||
|
compiler.entrypoint = './__nexe_stdin.js'
|
||||||
|
await compiler.addResource(resolve(cwd, compiler.entrypoint), code)
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|
||||||
const { files } = await resolveFiles(input, { cwd, expand: true, loadContent: false })
|
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(
|
||||||
|
input,
|
||||||
|
...Object.keys(compiler.bundle.index).filter(x => x.endsWith('.js')),
|
||||||
|
{ cwd, expand: true, loadContent: false }
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
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), {
|
await each(Object.keys(files), (filename: string) => compiler.addResource(filename), {
|
||||||
concurrency: 10
|
concurrency: 10
|
||||||
})
|
})
|
||||||
|
|||||||
+28
-46
@@ -1,24 +1,9 @@
|
|||||||
import { normalize, relative, resolve } from 'path'
|
import { dirname, normalize, relative, resolve } from 'path'
|
||||||
import { createWriteStream, chmodSync, statSync } from 'fs'
|
import { createWriteStream, chmodSync, statSync } from 'fs'
|
||||||
import { dequote } from '../util'
|
|
||||||
import { Readable } from 'stream'
|
|
||||||
import { NexeCompiler } from '../compiler'
|
import { NexeCompiler } from '../compiler'
|
||||||
import { NexeTarget } from '../target'
|
import { NexeTarget } from '../target'
|
||||||
|
import { STDIN_FLAG } from '../util'
|
||||||
function getStdIn(stdin: Readable): Promise<string> {
|
import mkdirp = require('mkdirp')
|
||||||
return new Promise(resolve => {
|
|
||||||
let out = ''
|
|
||||||
stdin
|
|
||||||
.setEncoding('utf8')
|
|
||||||
.on('readable', () => {
|
|
||||||
let current
|
|
||||||
while ((current = stdin.read())) {
|
|
||||||
out += current
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.on('end', () => resolve(out))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The "cli" step detects the appropriate input. If no input options are passed,
|
* The "cli" step detects the appropriate input. If no input options are passed,
|
||||||
@@ -26,51 +11,48 @@ function getStdIn(stdin: Readable): Promise<string> {
|
|||||||
* After all the build steps have run, the output (the executable) is written to a file or piped to stdout.
|
* After all the build steps have run, the output (the executable) is written to a file or piped to stdout.
|
||||||
*
|
*
|
||||||
* Configuration:
|
* Configuration:
|
||||||
* - compiler.options.input - file path to the input bundle.
|
|
||||||
* - fallbacks: stdin, package.json#main
|
|
||||||
* - compiler.options.output - file path to the output executable.
|
|
||||||
* - fallbacks: stdout, nexe_ + epoch + ext
|
|
||||||
*
|
*
|
||||||
* @param {*} compiler
|
* @param {*} compiler
|
||||||
* @param {*} next
|
* @param {*} next
|
||||||
*/
|
*/
|
||||||
export default async function cli(compiler: NexeCompiler, next: () => Promise<void>) {
|
export default async function cli(compiler: NexeCompiler, next: () => Promise<void>) {
|
||||||
const { log } = compiler
|
|
||||||
let stdInUsed = false
|
|
||||||
if (!process.stdin.isTTY && compiler.options.enableStdIn) {
|
|
||||||
stdInUsed = true
|
|
||||||
compiler.entrypoint = './__nexe_stdin.js'
|
|
||||||
const code = dequote(await getStdIn(process.stdin))
|
|
||||||
await compiler.addResource(resolve(compiler.options.cwd, compiler.entrypoint), code)
|
|
||||||
} else {
|
|
||||||
compiler.entrypoint = './' + relative(compiler.options.cwd, compiler.options.input)
|
|
||||||
}
|
|
||||||
compiler.startup = ';require("module").runMain();'
|
|
||||||
await next()
|
await next()
|
||||||
|
const { log } = compiler,
|
||||||
|
target = compiler.options.targets.shift() as NexeTarget,
|
||||||
|
deliverable = await compiler.compileAsync(target),
|
||||||
|
output = normalize(compiler.output!)
|
||||||
|
|
||||||
const target = compiler.options.targets.shift() as NexeTarget
|
mkdirp.sync(dirname(output))
|
||||||
const deliverable = await compiler.compileAsync(target)
|
|
||||||
|
|
||||||
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(normalize(compiler.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,
|
||||||
const mode = statSync(output).mode | 0o111
|
mode = statSync(output).mode | 0o111,
|
||||||
|
inputFileLogOutput = relative(
|
||||||
|
process.cwd(),
|
||||||
|
resolve(compiler.options.cwd, compiler.entrypoint || compiler.options.input)
|
||||||
|
),
|
||||||
|
outputFileLogOutput = relative(process.cwd(), output)
|
||||||
|
|
||||||
chmodSync(output, mode.toString(8).slice(-3))
|
chmodSync(output, mode.toString(8).slice(-3))
|
||||||
const inputFile = relative(process.cwd(), compiler.options.input)
|
|
||||||
const outputFile = relative(process.cwd(), output)
|
|
||||||
step.log(
|
step.log(
|
||||||
`Entry: '${
|
`Entry: '${
|
||||||
stdInUsed ? (compiler.options.mangle ? '[stdin]' : '[none]') : inputFile
|
compiler.stdinUsed
|
||||||
}' written to: ${outputFile}`
|
? compiler.options.mangle
|
||||||
|
? STDIN_FLAG
|
||||||
|
: '[none]'
|
||||||
|
: inputFileLogOutput
|
||||||
|
}' written to: ${outputFileLogOutput}`
|
||||||
)
|
)
|
||||||
resolve(compiler.quit())
|
compiler.quit()
|
||||||
|
res(output)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+42
-12
@@ -2,7 +2,8 @@ import download = require('download')
|
|||||||
import { pathExistsAsync } from '../util'
|
import { pathExistsAsync } from '../util'
|
||||||
import { LogStep } from '../logger'
|
import { LogStep } from '../logger'
|
||||||
import { IncomingMessage } from 'http'
|
import { IncomingMessage } from 'http'
|
||||||
import { NexeCompiler } from '../compiler'
|
import { NexeCompiler, NexeError } from '../compiler'
|
||||||
|
import { dirname } from 'path'
|
||||||
|
|
||||||
function fetchNodeSourceAsync(dest: string, url: string, step: LogStep, options = {}) {
|
function fetchNodeSourceAsync(dest: string, url: string, step: LogStep, options = {}) {
|
||||||
const setText = (p: number) => step.modify(`Downloading Node: ${p.toFixed()}%...`)
|
const setText = (p: number) => step.modify(`Downloading Node: ${p.toFixed()}%...`)
|
||||||
@@ -21,27 +22,56 @@ function fetchNodeSourceAsync(dest: string, url: string, step: LogStep, options
|
|||||||
.then(() => step.log(`Node source extracted to: ${dest}`))
|
.then(() => step.log(`Node source extracted to: ${dest}`))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchPrebuiltBinary(compiler: NexeCompiler, step: any) {
|
||||||
|
const { target, remoteAsset } = compiler,
|
||||||
|
filename = compiler.getNodeExecutableLocation(target)
|
||||||
|
|
||||||
|
try {
|
||||||
|
await download(remoteAsset, dirname(filename), compiler.options.downloadOptions).on(
|
||||||
|
'response',
|
||||||
|
(res: IncomingMessage) => {
|
||||||
|
const total = +res.headers['content-length']!
|
||||||
|
let current = 0
|
||||||
|
res.on('data', data => {
|
||||||
|
current += data.length
|
||||||
|
step!.modify(`Downloading...${((current / total) * 100).toFixed()}%`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} catch (e) {
|
||||||
|
if (e.statusCode === 404) {
|
||||||
|
throw new NexeError(`${remoteAsset} is not available, create it using the --build flag`)
|
||||||
|
} else {
|
||||||
|
throw new NexeError('Error downloading prebuilt binary: ' + e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Downloads the node source to the configured temporary directory
|
* Downloads the node source to the configured temporary directory
|
||||||
* @param {*} compiler
|
* @param {*} compiler
|
||||||
* @param {*} next
|
* @param {*} next
|
||||||
*/
|
*/
|
||||||
export default async function downloadNode(compiler: NexeCompiler, next: () => Promise<void>) {
|
export default async function downloadNode(compiler: NexeCompiler, next: () => Promise<void>) {
|
||||||
const {
|
const { src, log, target } = compiler,
|
||||||
src,
|
{ version } = target,
|
||||||
log,
|
{ sourceUrl, downloadOptions, build } = compiler.options,
|
||||||
targets: [{ version }]
|
url = sourceUrl || `https://nodejs.org/dist/v${version}/node-v${version}.tar.gz`,
|
||||||
} = compiler
|
step = log.step(
|
||||||
const { sourceUrl, downloadOptions } = compiler.options
|
`Downloading ${build ? '' : 'pre-built '}Node.js${build ? `source from: ${url}` : ''}`
|
||||||
const url = sourceUrl || `https://nodejs.org/dist/v${version}/node-v${version}.tar.gz`
|
),
|
||||||
const step = log.step(`Downloading Node.js source from: ${url}`)
|
exeLocation = compiler.getNodeExecutableLocation(build ? undefined : target),
|
||||||
if (await pathExistsAsync(src)) {
|
downloadExists = await pathExistsAsync(build ? src : exeLocation)
|
||||||
step.log('Source already downloaded')
|
|
||||||
|
if (downloadExists) {
|
||||||
|
step.log('Already downloaded...')
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compiler.options.build) {
|
if (build) {
|
||||||
await fetchNodeSourceAsync(src, url, step, downloadOptions)
|
await fetchNodeSourceAsync(src, url, step, downloadOptions)
|
||||||
|
} else {
|
||||||
|
await fetchPrebuiltBinary(compiler, step)
|
||||||
}
|
}
|
||||||
|
|
||||||
return next()
|
return next()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { isDirectoryAsync, each } from '../util'
|
import { isDirectoryAsync, each } from '../util'
|
||||||
import * as globs from 'globby'
|
import 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>) {
|
||||||
|
|||||||
+8
-2
@@ -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("${compiler.entrypoint}"))
|
const path = require('path')
|
||||||
|
const entry = path.resolve(path.dirname(process.execPath),${JSON.stringify(
|
||||||
|
compiler.entrypoint
|
||||||
|
)})
|
||||||
|
process.argv.splice(1,0, entry)
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
)
|
)
|
||||||
|
|||||||
+17
@@ -4,6 +4,7 @@ import pify = require('pify')
|
|||||||
import rimraf = require('rimraf')
|
import rimraf = require('rimraf')
|
||||||
|
|
||||||
const rimrafAsync = pify(rimraf)
|
const rimrafAsync = pify(rimraf)
|
||||||
|
export const STDIN_FLAG = '[stdin]'
|
||||||
|
|
||||||
export async function each<T>(
|
export async function each<T>(
|
||||||
list: T[] | Promise<T[]>,
|
list: T[] | Promise<T[]>,
|
||||||
@@ -80,10 +81,26 @@ function isDirectoryAsync(path: string) {
|
|||||||
.then(x => x.isDirectory())
|
.then(x => x.isDirectory())
|
||||||
.catch(falseOnEnoent)
|
.catch(falseOnEnoent)
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @param version See if this version is greather than the second one
|
||||||
|
* @param operand Version to compare against
|
||||||
|
*/
|
||||||
|
function semverGt(version: string, operand: string) {
|
||||||
|
const [cMajor, cMinor, cPatch] = version.split('.').map(Number)
|
||||||
|
let [major, minor, patch] = operand.split('.').map(Number)
|
||||||
|
if (!minor) minor = 0
|
||||||
|
if (!patch) patch = 0
|
||||||
|
return (
|
||||||
|
cMajor > major ||
|
||||||
|
(cMajor === major && cMinor > minor) ||
|
||||||
|
(cMajor === major && cMinor === minor && cPatch > patch)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
dequote,
|
dequote,
|
||||||
padRight,
|
padRight,
|
||||||
|
semverGt,
|
||||||
bound,
|
bound,
|
||||||
isWindows,
|
isWindows,
|
||||||
rimrafAsync,
|
rimrafAsync,
|
||||||
|
|||||||
@@ -1,99 +0,0 @@
|
|||||||
import * as nexe from '../lib/nexe'
|
|
||||||
import { getUnBuiltReleases, getLatestGitRelease } from '../lib/releases'
|
|
||||||
import * as ci from './ci'
|
|
||||||
import { runDockerBuild } from './docker'
|
|
||||||
import { getTarget } from '../lib/target'
|
|
||||||
import { pathExistsAsync, readFileAsync, execFileAsync } from '../lib/util'
|
|
||||||
import got = require('got')
|
|
||||||
|
|
||||||
const env = process.env,
|
|
||||||
branchName = env.CIRCLE_BRANCH || env.APPVEYOR_REPO_BRANCH || env.TRAVIS_BRANCH || '',
|
|
||||||
isScheduled = Boolean(env.APPVEYOR_SCHEDULED_BUILD || env.NEXE_TRIGGERED),
|
|
||||||
isWindows = Boolean(env.APPVEYOR),
|
|
||||||
isPullRequest =
|
|
||||||
Boolean(env.CIRCLE_PR_NUMBER) ||
|
|
||||||
Boolean(env.APPVEYOR_PULL_REQUEST_NUMBER) ||
|
|
||||||
Boolean(env.TRAVIS_PULL_REQUEST_BRANCH),
|
|
||||||
headers = {
|
|
||||||
Authorization: 'token ' + env.GITHUB_TOKEN,
|
|
||||||
'User-Agent': 'nexe (https://www.npmjs.com/package/nexe)'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (require.main === module) {
|
|
||||||
if (!isPullRequest) {
|
|
||||||
build().catch(x => {
|
|
||||||
console.error(x)
|
|
||||||
process.exit(1)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function build() {
|
|
||||||
if (isScheduled) {
|
|
||||||
const releases = await getUnBuiltReleases({ headers })
|
|
||||||
if (!releases.length) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const windowsBuild = releases.find(x => x.platform === 'windows')
|
|
||||||
const macBuild = releases.find(x => x.platform === 'mac')
|
|
||||||
const linuxOrAlpine = releases.find(x => x.platform === 'linux' || x.platform === 'alpine')
|
|
||||||
|
|
||||||
if (linuxOrAlpine) {
|
|
||||||
await ci.triggerDockerBuild(linuxOrAlpine, branchName)
|
|
||||||
}
|
|
||||||
if (macBuild) {
|
|
||||||
await ci.triggerMacBuild(macBuild, branchName)
|
|
||||||
}
|
|
||||||
if (windowsBuild) {
|
|
||||||
await ci.triggerWindowsBuild(windowsBuild)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (env.NEXE_VERSION) {
|
|
||||||
const target = getTarget(env.NEXE_VERSION),
|
|
||||||
output = isWindows ? './out.exe' : './out',
|
|
||||||
options = {
|
|
||||||
empty: true,
|
|
||||||
build: true,
|
|
||||||
target,
|
|
||||||
output
|
|
||||||
}
|
|
||||||
console.log('Building: ', target)
|
|
||||||
const stop = keepalive()
|
|
||||||
if (['arm7l', 'arm6l', 'arm64', 'alpine'].indexOf(target.platform)) {
|
|
||||||
await runDockerBuild(target)
|
|
||||||
} else {
|
|
||||||
await nexe.compile(options)
|
|
||||||
}
|
|
||||||
stop()
|
|
||||||
|
|
||||||
if (await pathExistsAsync(output)) {
|
|
||||||
await assertNexeBinary(output)
|
|
||||||
const gitRelease = await getLatestGitRelease({ headers })
|
|
||||||
await got(gitRelease.upload_url.split('{')[0], {
|
|
||||||
query: { name: target.toString() },
|
|
||||||
body: await readFileAsync(output),
|
|
||||||
headers: {
|
|
||||||
Authorization: 'token ' + env.GITHUB_TOKEN,
|
|
||||||
'Content-Type': 'application/octet-stream',
|
|
||||||
'User-Agent': 'nexe (https://www.npmjs.com/package/nexe)'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
console.log(target + ' uploaded.')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function keepalive() {
|
|
||||||
const keepalive = setInterval(() => console.log('Building...'), 300 * 1000)
|
|
||||||
return () => clearInterval(keepalive)
|
|
||||||
}
|
|
||||||
|
|
||||||
function assertNexeBinary(file: string) {
|
|
||||||
return execFileAsync(file).catch(e => {
|
|
||||||
if (e && e.stack && e.stack.includes('Invalid Nexe binary')) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
throw e
|
|
||||||
})
|
|
||||||
}
|
|
||||||
+116
@@ -0,0 +1,116 @@
|
|||||||
|
import * as nexe from '../lib/nexe'
|
||||||
|
import { getUnBuiltReleases, getLatestGitRelease } from '../lib/releases'
|
||||||
|
import { runDockerBuild } from './docker'
|
||||||
|
import { getTarget, targetsEqual, NexeTarget } from '../lib/target'
|
||||||
|
import { pathExistsAsync, readFileAsync, execFileAsync, semverGt } from '../lib/util'
|
||||||
|
import got = require('got')
|
||||||
|
import { cpus } from 'os'
|
||||||
|
|
||||||
|
const env = process.env,
|
||||||
|
isPullRequest = env.BUILD_REASON === 'PullRequest',
|
||||||
|
isWindows = process.platform === 'win32',
|
||||||
|
isLinux = process.platform === 'linux',
|
||||||
|
buildHost = env.AGENT_JOBNAME || (isWindows && 'windows_2017_2015') || '',
|
||||||
|
isMac = process.platform === 'darwin',
|
||||||
|
headers = {
|
||||||
|
Authorization: 'token ' + env.GITHUB_TOKEN,
|
||||||
|
'User-Agent': 'nexe (https://www.npmjs.com/package/nexe)'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (require.main === module) {
|
||||||
|
if (!isPullRequest) {
|
||||||
|
build().catch(x => {
|
||||||
|
console.error(x)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function build() {
|
||||||
|
const releases = await getUnBuiltReleases({ headers })
|
||||||
|
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')
|
||||||
|
|
||||||
|
let target: NexeTarget | undefined
|
||||||
|
|
||||||
|
if (env.NEXE_VERSION) target = getTarget(env.NEXE_VERSION)
|
||||||
|
else if (isWindows) target = windowsBuild
|
||||||
|
else if (isMac) target = macBuild
|
||||||
|
else if (isLinux) target = linux
|
||||||
|
if (buildHost.includes('alpine')) target = alpine
|
||||||
|
|
||||||
|
if (!target) {
|
||||||
|
return console.log('Nothing to build...')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isWindows && buildHost.includes('2017') && !semverGt(target.version, '9.99.99')) {
|
||||||
|
return console.log(`Not building ${target} on this host...`)
|
||||||
|
}
|
||||||
|
if (isWindows && buildHost.includes('2015') && semverGt(target.version, '9.99.99')) {
|
||||||
|
return console.log(`Not building ${target} on this host...`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const output = isWindows ? './out.exe' : './out',
|
||||||
|
options = {
|
||||||
|
mangle: false,
|
||||||
|
build: true,
|
||||||
|
verbose: Boolean(env.NEXE_VERBOSE!),
|
||||||
|
target,
|
||||||
|
make: ['-j' + cpus().length],
|
||||||
|
output
|
||||||
|
}
|
||||||
|
console.log('Building: ' + target + ' on ' + buildHost)
|
||||||
|
const stop = keepalive()
|
||||||
|
|
||||||
|
if (
|
||||||
|
[/*'arm7l', 'arm6l', 'arm64', */ 'alpine'].includes(target.platform) &&
|
||||||
|
buildHost.includes('alpine')
|
||||||
|
) {
|
||||||
|
await runDockerBuild(target)
|
||||||
|
} else {
|
||||||
|
await nexe.compile(options)
|
||||||
|
}
|
||||||
|
stop()
|
||||||
|
if (await pathExistsAsync(output)) {
|
||||||
|
await assertNexeBinary(output)
|
||||||
|
const gitRelease = await getLatestGitRelease({ headers }),
|
||||||
|
unbuiltReleases = await getUnBuiltReleases({ headers })
|
||||||
|
if (!unbuiltReleases.some(x => targetsEqual(x, target!))) {
|
||||||
|
console.log(`${target} already uploaded.`)
|
||||||
|
process.exit(0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await got(gitRelease.upload_url.split('{')[0], {
|
||||||
|
query: { name: target.toString() },
|
||||||
|
body: await readFileAsync(output),
|
||||||
|
headers: {
|
||||||
|
...headers,
|
||||||
|
'Content-Type': 'application/octet-stream'
|
||||||
|
}
|
||||||
|
}).catch(reason => {
|
||||||
|
console.log(reason && reason.response && reason.response.body)
|
||||||
|
throw reason
|
||||||
|
})
|
||||||
|
console.log(target + ' uploaded.')
|
||||||
|
process.exit(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function keepalive() {
|
||||||
|
const keepalive = setInterval(() => console.log('Building...'), 300 * 1000)
|
||||||
|
return () => clearInterval(keepalive)
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertNexeBinary(file: string) {
|
||||||
|
return execFileAsync(file).catch(e => {
|
||||||
|
if (e && e.stack && e.stack.includes('Invalid Nexe binary')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
throw e
|
||||||
|
})
|
||||||
|
}
|
||||||
-58
@@ -1,58 +0,0 @@
|
|||||||
import { NexeTarget } from '../lib/releases'
|
|
||||||
import got = require('got')
|
|
||||||
import * as assert from 'assert'
|
|
||||||
import { getTarget } from '../lib/target'
|
|
||||||
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
|
|
||||||
}`
|
|
||||||
return got(circle, {
|
|
||||||
json: true,
|
|
||||||
body: {
|
|
||||||
build_parameters: {
|
|
||||||
NEXE_VERSION: release.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function triggerDockerBuild(release: NexeTarget, branch: string) {
|
|
||||||
assert.ok(env.TRAVIS_TOKEN)
|
|
||||||
const travis = `https://api.travis-ci.org/repo/nexe%2Fnexe/requests`
|
|
||||||
return got(travis, {
|
|
||||||
json: true,
|
|
||||||
body: {
|
|
||||||
request: {
|
|
||||||
branch: branch,
|
|
||||||
config: {
|
|
||||||
merge_mode: 'deep_merge',
|
|
||||||
env: {
|
|
||||||
//use matrix so that secure global variable is merged
|
|
||||||
matrix: {
|
|
||||||
NEXE_VERSION: release.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
headers: {
|
|
||||||
'Travis-API-Version': '3',
|
|
||||||
Authorization: `token ${env.TRAVIS_TOKEN}`
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function triggerWindowsBuild(release: NexeTarget) {
|
|
||||||
const version = 'NEXE_VERSION' in env ? env.NEXE_VERSION!.trim() : release.toString()
|
|
||||||
if (getTarget(version).version.startsWith('10.')) {
|
|
||||||
if ((env.APPVEYOR_BUILD_WORKER_IMAGE || '').includes('2017')) {
|
|
||||||
env.NEXE_VERSION = version
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
env.NEXE_VERSION = version
|
|
||||||
}
|
|
||||||
return Promise.resolve()
|
|
||||||
}
|
|
||||||
+8
-7
@@ -1,6 +1,5 @@
|
|||||||
import { NexeTarget, architectures } from '../lib/target'
|
import { NexeTarget, architectures } from '../lib/target'
|
||||||
import { writeFileAsync, readFileAsync } from '../lib/util'
|
import { writeFileAsync, readFileAsync } from '../lib/util'
|
||||||
import { spawn } from 'child_process'
|
|
||||||
import got = require('got')
|
import got = require('got')
|
||||||
import execa = require('execa')
|
import execa = require('execa')
|
||||||
import { appendFileSync } from 'fs'
|
import { appendFileSync } from 'fs'
|
||||||
@@ -10,7 +9,7 @@ function alpine(target: NexeTarget) {
|
|||||||
FROM ${target.arch === 'x64' ? '' : 'i386/'}alpine:3.4
|
FROM ${target.arch === 'x64' ? '' : 'i386/'}alpine:3.4
|
||||||
RUN apk add --no-cache curl make gcc g++ binutils-gold python linux-headers paxctl libgcc libstdc++ git vim tar gzip wget
|
RUN apk add --no-cache curl make gcc g++ binutils-gold python linux-headers paxctl libgcc libstdc++ git vim tar gzip wget
|
||||||
ENV NODE_VERSION=${target.version}
|
ENV NODE_VERSION=${target.version}
|
||||||
ENV NEXE_VERSION=beta
|
ENV NEXE_VERSION=latest
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
|
|
||||||
RUN curl -sSL https://nodejs.org/dist/v\${NODE_VERSION}/node-v\${NODE_VERSION}.tar.gz | tar -xz && \
|
RUN curl -sSL https://nodejs.org/dist/v\${NODE_VERSION}/node-v\${NODE_VERSION}.tar.gz | tar -xz && \
|
||||||
@@ -21,19 +20,20 @@ RUN curl -sSL https://nodejs.org/dist/v\${NODE_VERSION}/node-v\${NODE_VERSION}.t
|
|||||||
paxctl -cm /usr/bin/node
|
paxctl -cm /usr/bin/node
|
||||||
|
|
||||||
RUN rm /nexe_temp/\${NODE_VERSION}/out/Release/node && \
|
RUN rm /nexe_temp/\${NODE_VERSION}/out/Release/node && \
|
||||||
npm install -g nexe@\${NEXE_VERSION} && \
|
npm install -g nexe@\${NEXE_VERSION}
|
||||||
nexe --build --empty --temp /nexe_temp -c="--fully-static" -o out
|
RUN echo "console.log('hello world')" >> index.js && \
|
||||||
|
nexe --build --no-mangle --temp /nexe_temp -c="--fully-static" -o out
|
||||||
`.trim()
|
`.trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
function arm(target: NexeTarget) {
|
function arm(target: NexeTarget) {
|
||||||
return `
|
return `
|
||||||
FROM hypriot/rpi-node
|
FROM hypriot/rpi-node
|
||||||
ENV NEXE_VERSION=beta
|
ENV NEXE_VERSION=latest
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
|
|
||||||
RUN yarn global add nexe@\${NEXE_VERSION} && \
|
RUN yarn global add nexe@\${NEXE_VERSION} && \
|
||||||
nexe --build --empty -o out -t ${target.version}
|
nexe --build --no-mangle -o out -t ${target.version}
|
||||||
`.trim()
|
`.trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +51,8 @@ export async function runDockerBuild(target: NexeTarget) {
|
|||||||
output.push(await execa.shell(`docker cp nexe:/out out`))
|
output.push(await execa.shell(`docker cp nexe:/out out`))
|
||||||
output.push(await execa.shell(`docker rm nexe`))
|
output.push(await execa.shell(`docker rm nexe`))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('Error running docker', e)
|
console.log('Error running docker')
|
||||||
|
appendFileSync(outFilename, e.message)
|
||||||
} finally {
|
} finally {
|
||||||
output.forEach((x: any) => {
|
output.forEach((x: any) => {
|
||||||
appendFileSync(outFilename, x.stderr)
|
appendFileSync(outFilename, x.stderr)
|
||||||
|
|||||||
@@ -10,9 +10,13 @@ describe('options', () => {
|
|||||||
const options = normalizeOptions()
|
const options = normalizeOptions()
|
||||||
expect(options.cwd).to.equal(process.cwd())
|
expect(options.cwd).to.equal(process.cwd())
|
||||||
})
|
})
|
||||||
it('should use the main module in a package directory', () => {
|
it('should use the main module in a package directory (if not in a TTY)', () => {
|
||||||
const options = normalizeOptions()
|
const options = normalizeOptions()
|
||||||
expect(options.input).to.equal(path.resolve('./index.js'))
|
if (!process.stdin.isTTY) {
|
||||||
|
expect(options.input).to.equal('[stdin]')
|
||||||
|
} else {
|
||||||
|
expect(options.input).to.equal(path.resolve('./index.js'))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
it('should resolve relative paths for input', () => {
|
it('should resolve relative paths for input', () => {
|
||||||
const options = normalizeOptions({ input: 'test/fixture/entry.js' })
|
const options = normalizeOptions({ input: 'test/fixture/entry.js' })
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
"target":"es5",
|
"target":"es5",
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"lib": ["es2017"],
|
"lib": ["es2018"],
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"outDir": "./lib",
|
"outDir": "./lib",
|
||||||
"strict": true
|
"strict": true
|
||||||
|
|||||||
Reference in New Issue
Block a user