Compare commits

..

11 Commits

Author SHA1 Message Date
calebboyd 32033b6d15 fix: bring idepotent builds back 2020-06-27 06:46:13 -05:00
calebboyd bc1d579baa build: add more space for msbuild 2020-06-24 20:17:30 -05:00
calebboyd 6ffd47f1f1 chore: update macos build version 2020-06-24 09:55:56 -05:00
calebboyd c4e16fb6e0 chore: bump globby and fix ci node version 2020-06-24 09:52:27 -05:00
calebboyd ea6f1f0808 fix: update legacy v3 tag while v4 is beta 2020-06-22 14:59:44 -05:00
calebboyd c1055149ab chore: bump resolve dependnencies 2020-06-20 12:15:13 -05:00
calebboyd 79fffc358a chore: update resolve-dependencies 2020-06-20 08:39:39 -05:00
Bryce Gibson c8cf13a9dd Move nexe boot to support 12.18.0. 2020-06-04 07:43:26 -05:00
Aral Balkan 928b8134a7 fix: remove full stop from one line of help output for consistency 2020-05-08 17:42:03 -05:00
Aral Balkan 0a2e8dba00 fix: replace --asset option with --remote option (#760) 2020-05-08 17:42:03 -05:00
Aral Balkan 01c977bb3c feat: alternate nexe base binary remotes (--remote option) (#760) 2020-05-08 17:42:03 -05:00
14 changed files with 222 additions and 153 deletions
+3 -3
View File
@@ -49,7 +49,7 @@ Additional files or resources can be added to the binary by passing `-r "glob/pa
## Compiling Node
By default `nexe` will attempt to download a pre-built executable. These are listed on the [Nexe V3 releases page](https://github.com/nexe/nexe/releases/tag/v3.0.0). The exact version you want may be unavailable or you may want to customize what is built. See `nexe --help` for a list of options available when passing the [`--build`](#build-boolean) option. You will also need to ensure your environment is setup to [build node](https://github.com/nodejs/node/blob/master/BUILDING.md). Note: the `python` binary in your path should be an acceptable version of python 2. eg. Systems that have python2 will need to create a [symlink](https://github.com/nexe/nexe/issues/354#issuecomment-319874486).
By default `nexe` will attempt to download a pre-built executable. These are listed on the [Nexe V3 releases page](https://github.com/nexe/nexe/releases/tag/v3.3.3). The exact version you want may be unavailable or you may want to customize what is built. See `nexe --help` for a list of options available when passing the [`--build`](#build-boolean) option. You will also need to ensure your environment is setup to [build node](https://github.com/nodejs/node/blob/master/BUILDING.md). Note: the `python` binary in your path should be an acceptable version of python 2. eg. Systems that have python2 will need to create a [symlink](https://github.com/nexe/nexe/issues/354#issuecomment-319874486).
## Node.js API
@@ -116,8 +116,8 @@ compile({
- default: true
- #### `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)
- #### `asset: string`
- Provide a pre-built nexe binary asset, this can either be an http or https URL or a file path.
- #### `remote: string`
- Provide a custom remote location for fetching pre-built nexe binaries from. This can either be an HTTP or HTTPS URL or a file path.
- default: `null`
- #### `python: string`
- On Linux this is the path pointing to your python2 executable
+3 -2
View File
@@ -25,7 +25,7 @@ jobs:
linux:
imageName: 'ubuntu-16.04'
mac:
imageName: 'macos-10.13'
imageName: 'macos-10.15'
windows_2017:
imageName: 'vs2017-win2016'
windows_2015:
@@ -43,7 +43,7 @@ jobs:
- task: NodeTool@0
displayName: Install Node
inputs:
versionSpec: '10.x'
versionSpec: '12.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
@@ -55,6 +55,7 @@ jobs:
env:
GITHUB_TOKEN: $(PersonalGithubToken)
NEXE_VERBOSE: $(NEXE_VERBOSE)
msbuild_args: /3G
condition: not(contains(variables['Agent.JobName'], 'windows'))
- powershell: |
iex (new-object net.webclient).downloadstring('https://get.scoop.sh')
+73 -77
View File
@@ -1,6 +1,6 @@
{
"name": "nexe",
"version": "4.0.0-beta.6",
"version": "4.0.0-beta.11",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -41,25 +41,25 @@
"integrity": "sha512-17z9me12RgAEcMhIgR7f+BiXKbzwF9p1VraI69OxrUUSWGuSMOyOTEHQNVtMKuVrkEDVD0/Av5uiGZPBMYZljw=="
},
"@nodelib/fs.scandir": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.1.tgz",
"integrity": "sha512-NT/skIZjgotDSiXs0WqYhgcuBKhUMgfekCmCGtkUAiLqZdOnrdjmZr9wRl3ll64J9NF79uZ4fk16Dx0yMc/Xbg==",
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
"integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
"requires": {
"@nodelib/fs.stat": "2.0.1",
"@nodelib/fs.stat": "2.0.3",
"run-parallel": "^1.1.9"
}
},
"@nodelib/fs.stat": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.1.tgz",
"integrity": "sha512-+RqhBlLn6YRBGOIoVYthsG0J9dfpO79eJyN7BYBkZJtfqrBwf2KK+rD/M/yjZR6WBmIhAgOV7S60eCgaSWtbFw=="
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
"integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA=="
},
"@nodelib/fs.walk": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.2.tgz",
"integrity": "sha512-J/DR3+W12uCzAJkw7niXDcqcKBg6+5G5Q/ZpThpGNzAUz70eOR6RV4XnnSN01qHZiVl0eavoxJsBypQoKsV2QQ==",
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
"integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
"requires": {
"@nodelib/fs.scandir": "2.1.1",
"@nodelib/fs.scandir": "2.1.3",
"fastq": "^1.6.0"
}
},
@@ -116,7 +116,8 @@
"@types/events": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz",
"integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA=="
"integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==",
"dev": true
},
"@types/execa": {
"version": "2.0.0",
@@ -161,7 +162,8 @@
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA=="
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
"dev": true
},
"@types/minimist": {
"version": "1.2.0",
@@ -196,7 +198,8 @@
"@types/node": {
"version": "10.5.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.5.7.tgz",
"integrity": "sha512-VkKcfuitP+Nc/TaTFH0B8qNmn+6NbI6crLkQonbedViVz7O2w8QV/GERPlkJ4bg42VGHiEWa31CoTOPs1q6z1w=="
"integrity": "sha512-VkKcfuitP+Nc/TaTFH0B8qNmn+6NbI6crLkQonbedViVz7O2w8QV/GERPlkJ4bg42VGHiEWa31CoTOPs1q6z1w==",
"dev": true
},
"@types/ora": {
"version": "3.2.0",
@@ -881,9 +884,9 @@
}
},
"enhanced-resolve": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz",
"integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz",
"integrity": "sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ==",
"requires": {
"graceful-fs": "^4.1.2",
"memory-fs": "^0.5.0",
@@ -1022,16 +1025,23 @@
"dev": true
},
"fast-glob": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.0.4.tgz",
"integrity": "sha512-wkIbV6qg37xTJwqSsdnIphL1e+LaGz4AIQqr00mIubMaEhv1/HEmJ0uuCGZRNRUkZZmOB5mJKO0ZUTVq+SxMQg==",
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz",
"integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==",
"requires": {
"@nodelib/fs.stat": "^2.0.1",
"@nodelib/fs.walk": "^1.2.1",
"glob-parent": "^5.0.0",
"is-glob": "^4.0.1",
"merge2": "^1.2.3",
"micromatch": "^4.0.2"
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
"glob-parent": "^5.1.0",
"merge2": "^1.3.0",
"micromatch": "^4.0.2",
"picomatch": "^2.2.1"
},
"dependencies": {
"picomatch": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg=="
}
}
},
"fastq": {
@@ -1178,38 +1188,24 @@
}
},
"glob-parent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz",
"integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==",
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
"requires": {
"is-glob": "^4.0.1"
}
},
"globby": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz",
"integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==",
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz",
"integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==",
"requires": {
"@types/glob": "^7.1.1",
"array-union": "^2.1.0",
"dir-glob": "^3.0.1",
"fast-glob": "^3.0.3",
"glob": "^7.1.3",
"ignore": "^5.1.1",
"merge2": "^1.2.3",
"fast-glob": "^3.1.1",
"ignore": "^5.1.4",
"merge2": "^1.3.0",
"slash": "^3.0.0"
},
"dependencies": {
"@types/glob": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
"integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
"requires": {
"@types/events": "*",
"@types/minimatch": "*",
"@types/node": "*"
}
}
}
},
"got": {
@@ -1346,9 +1342,9 @@
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
},
"ignore": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.2.tgz",
"integrity": "sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ=="
"version": "5.1.8",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
"integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw=="
},
"inflight": {
"version": "1.0.6",
@@ -1599,14 +1595,14 @@
"dev": true
},
"merge2": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.4.tgz",
"integrity": "sha512-FYE8xI+6pjFOhokZu0We3S5NKCirLbCzSh2Usf3qEyr4X8U+0jNg9P8RZ4qz+V2UoECLVwSyzU3LxXBaLGtD3A=="
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="
},
"meriyah": {
"version": "1.9.12",
"resolved": "https://registry.npmjs.org/meriyah/-/meriyah-1.9.12.tgz",
"integrity": "sha512-EgnwghBfzhegstEg3GL17cyjXs/YZOzDGW4mDpiv+v4ZqZgfjNvjfjsAJ99IJMA3LyGvdC8nffZJRGX65FOqLQ=="
"version": "1.9.15",
"resolved": "https://registry.npmjs.org/meriyah/-/meriyah-1.9.15.tgz",
"integrity": "sha512-D4rT6XIYGqZab0EI/xbihUpwh0WbNRVQ35l2J/5QC2atxaI8h3KvA55DEJLBB/FRdaji7JwkNehfCRjCyjCjqw=="
},
"micromatch": {
"version": "4.0.2",
@@ -2099,14 +2095,14 @@
}
},
"resolve-dependencies": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-dependencies/-/resolve-dependencies-4.0.0.tgz",
"integrity": "sha512-M5d5+5HSsei7JB9fLMcVh4F3Gn1xwYbo4W+pWNFUpDpd1+foJ7ruLpEy3VzG4O6dmkOrL7blTfoy15hJyGQXOw==",
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/resolve-dependencies/-/resolve-dependencies-4.2.2.tgz",
"integrity": "sha512-jA5TjcYwz0MvPCdJz5NVHk68KYzVZ7+hSHEkaKaI31OLOpUGao5/u6Dvd9O3h9YF8QEMUY9EYJ7C1mdXDcQFgQ==",
"requires": {
"@calebboyd/async": "^1.4.0",
"enhanced-resolve": "^4.1.1",
"globby": "^11.0.0",
"meriyah": "^1.9.12"
"enhanced-resolve": "^4.2.0",
"globby": "^11.0.1",
"meriyah": "^1.9.15"
},
"dependencies": {
"@nodelib/fs.scandir": {
@@ -2133,9 +2129,9 @@
}
},
"fast-glob": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz",
"integrity": "sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A==",
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz",
"integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==",
"requires": {
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
@@ -2154,9 +2150,9 @@
}
},
"globby": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.0.tgz",
"integrity": "sha512-iuehFnR3xu5wBBtm4xi0dMe92Ob87ufyu/dHwpDYfbcpYpIbrO5OnS8M1vWvrBhSGEJ3/Ecj7gnX76P8YxpPEg==",
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz",
"integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==",
"requires": {
"array-union": "^2.1.0",
"dir-glob": "^3.0.1",
@@ -2167,14 +2163,14 @@
}
},
"ignore": {
"version": "5.1.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
"integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A=="
"version": "5.1.8",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
"integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw=="
},
"merge2": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz",
"integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw=="
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="
},
"picomatch": {
"version": "2.2.2",
+4 -4
View File
@@ -2,7 +2,7 @@
"name": "nexe",
"description": "Create a single executable out of your Node.js application",
"license": "MIT",
"version": "4.0.0-beta.6",
"version": "4.0.0-beta.11",
"contributors": [
"Craig Condon <craig.j.condon@gmail.com> (http://crcn.io)",
"Jared Allard <jaredallard@outlook.com>",
@@ -30,7 +30,7 @@
"nexe": "index.js"
},
"engines": {
"node": ">=6"
"node": ">=10"
},
"dependencies": {
"@calebboyd/semaphore": "^1.3.1",
@@ -39,14 +39,14 @@
"chalk": "^2.4.2",
"cherow": "1.6.9",
"download": "^7.1.0",
"globby": "^10.0.1",
"globby": "^11.0.1",
"got": "^9.6.0",
"minimist": "^1.2.5",
"mkdirp": "^1.0.4",
"multistream": "^4.0.0",
"ora": "^3.4.0",
"pify": "^4.0.1",
"resolve-dependencies": "^4.0.0",
"resolve-dependencies": "^4.2.2",
"rimraf": "^3.0.0"
},
"devDependencies": {
+22 -21
View File
@@ -12,6 +12,7 @@ import {
isWindows,
bound,
semverGt,
wrap,
} from './util'
import { NexeOptions, version } from './options'
import { NexeTarget } from './target'
@@ -108,12 +109,18 @@ export class NexeCompiler {
//SOMEDAY iterate over multiple targets with `--outDir`
this.targets = options.targets as NexeTarget[]
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()
if (
!(
options.remote.startsWith('http://') ||
options.remote.startsWith('https://') ||
options.remote.startsWith('file://')
)
) {
throw new NexeError(
`Invalid remote URI scheme (must be http, https, or file): ${options.remote}`
)
}
this.remoteAsset = options.remote + this.target.toString()
this.src = join(this.options.temp, this.target.version)
this.configureScript = configure + (semverGt(this.target.version, '10.10.0') ? '.py' : '')
this.nodeSrcBinPath = isWindows
@@ -140,14 +147,6 @@ export class NexeCompiler {
return this.bundle.addResource(absoluteFileName, content)
}
get binaryConfiguration() {
return { resources: this.bundle.index }
}
get resourceSize() {
return this.bundle.blobSize
}
@bound
async readFileAsync(file: string) {
this.assertBuild()
@@ -198,9 +197,6 @@ export class NexeCompiler {
}
public getNodeExecutableLocation(target?: NexeTarget) {
if (this.options.asset && !this.options.asset.startsWith('http')) {
return resolve(this.options.cwd, this.options.asset)
}
if (target) {
return join(this.options.temp, target.toString())
}
@@ -298,21 +294,26 @@ export class NexeCompiler {
return [this.shims.join(''), this.startup].join(';')
}
private _assembleDeliverable(binary: NodeJS.ReadableStream) {
private async _assembleDeliverable(binary: NodeJS.ReadableStream) {
if (!this.options.mangle) {
return binary
}
const bundle = await this.bundle.toStream()
this.shims.unshift(
wrap(`process.__nexe = ${JSON.stringify({ resources: this.bundle.fileIndex() })};\n`)
)
const startup = this.code(),
codeSize = Buffer.byteLength(startup)
codeSize = Buffer.byteLength(startup),
lengths = Buffer.from(Array(16))
const lengths = Buffer.from(Array(16))
lengths.writeDoubleLE(codeSize, 0)
lengths.writeDoubleLE(this.bundle.blobSize, 8)
lengths.writeDoubleLE(this.bundle.size, 8)
return new (MultiStream as any)([
binary,
toStream(startup),
this.bundle.toStream(),
bundle,
toStream(Buffer.concat([Buffer.from('<nexe~~sentinel>'), lengths])),
])
}
+67 -26
View File
@@ -1,12 +1,23 @@
import { stat as getStat, Stats, createReadStream } from 'fs'
import * as fs from 'fs'
import { promisify } from 'util'
import { relative } from 'path'
import { Readable } from 'stream'
import { each } from '@calebboyd/semaphore'
import MultiStream = require('multistream')
const stat = (file: string): Promise<Stats> => {
return new Promise((resolve, reject) => {
getStat(file, (err, stats) => (err ? reject(err) : resolve(stats)))
})
const { createReadStream } = fs,
lstat = promisify(fs.lstat),
realpath = promisify(fs.realpath),
stat = promisify(fs.stat)
export type MultiStreams = (Readable | (() => Readable))[]
function renderSortedObject(entries: [string, [number, number]][], streams: MultiStreams) {
return entries.sort().reduce((obj, [key, value]) => {
streams.push((value as any).stream)
;(value as any).stream = void 0
return Object.assign(obj, { [key]: value })
}, {})
}
function makeRelative(cwd: string, path: string) {
@@ -35,39 +46,69 @@ export interface BundleOptions {
}
export class Bundle {
size = 0
cwd: string
rendered = false
files: { [key: string]: string | Buffer | undefined } = {}
streams: MultiStreams = []
private index: { [relativeFilePath: string]: [number, number] } = {}
constructor({ cwd }: { cwd: string } = { cwd: process.cwd() }) {
this.cwd = cwd
}
cwd: string
blobSize: number = 0
index: { [relativeFilePath: string]: [number, number] } = {}
streams: (Readable | (() => Readable))[] = []
async addResource(absoluteFileName: string, content?: Buffer | string) {
addResource(absoluteFileName: string, content?: Buffer | string) {
this.files[absoluteFileName] = content
}
async addEntry(absoluteFileName: string, content?: Buffer | string) {
let length = 0
let linkpath = ''
if (content !== undefined) {
length = Buffer.byteLength(content)
} else {
const stats = await stat(absoluteFileName)
let stats = await lstat(absoluteFileName)
if (stats.isSymbolicLink()) {
linkpath = absoluteFileName
absoluteFileName = await realpath(linkpath)
stats = await stat(linkpath)
}
length = stats.size
}
const start = this.blobSize
this.blobSize += length
this.index[makeRelative(this.cwd, absoluteFileName)] = [start, length]
this.streams.push(() => (content ? toStream(content) : createReadStream(absoluteFileName)))
const name = makeRelative(this.cwd, absoluteFileName),
existing = this.index[name]
if (!existing) {
const start = this.size
this.size += length
this.index[name] = [start, length]
}
if (linkpath) {
const linkName = makeRelative(this.cwd, absoluteFileName)
this.index[linkName] = this.index[name]
}
if (!existing) {
;(this.index[name] as any).stream = () =>
content ? toStream(content) : createReadStream(absoluteFileName)
}
}
concat() {
throw new Error('Not Implemented')
}
toStream() {
return new (MultiStream as any)(this.streams)
}
toJSON() {
fileIndex() {
if (!this.rendered) {
throw new Error('Index not rendered must call toStream() first')
}
return this.index
}
async toStream() {
this.files
await each(
Object.keys(this.files),
(key: string) => {
return this.addEntry(key, this.files[key])
},
{ concurrency: 10 }
)
this.index = renderSortedObject(Object.entries(this.index), this.streams)
this.rendered = true
return new (MultiStream as any)(this.streams)
}
}
+8 -4
View File
@@ -21,7 +21,7 @@ export interface NexeOptions {
output: string
targets: (string | NexeTarget)[]
name: string
asset: string
remote: string
cwd: string
fs: boolean | string[]
flags: string[]
@@ -71,6 +71,7 @@ const defaults = {
bundle: true,
patches: [],
plugins: [],
remote: 'https://github.com/nexe/nexe/releases/download/v3.3.3/',
}
const alias = {
i: 'input',
@@ -80,7 +81,6 @@ const alias = {
b: 'build',
n: 'name',
r: 'resource',
a: 'asset',
p: 'python',
f: 'flag',
c: 'configure',
@@ -101,7 +101,7 @@ ${c.bold('nexe <entry-file> [options]')}
-t --target -- node version description
-n --name -- main app module name
-r --resource -- *embed files (glob) within the binary
-a --asset -- alternate asset path, file or url pointing to a base (nexe) binary
--remote -- alternate location (URL) to download pre-built base (nexe) binaries from
--plugin -- extend nexe runtime behavior
${c.underline.bold('Building from source:')}
@@ -112,7 +112,7 @@ ${c.bold('nexe <entry-file> [options]')}
-c --configure -- *arguments to the configure step
-m --make -- *arguments to the make/build step
--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.
--no-mangle -- used when generating base binaries, or when patching _third_party_main manually
--snapshot -- path to a warmup snapshot
--ico -- file name for alternate icon file (windows)
--rc-* -- populate rc file options (windows)
@@ -249,6 +249,10 @@ function normalizeOptions(input?: Partial<NexeOptions>): NexeOptions {
options.configure = flatten(options.configure)
options.resources = flatten(opts.resource, options.resources)
if (!options.remote.endsWith('/')) {
options.remote += '/'
}
options.downloadOptions = options.downloadOptions || {}
options.downloadOptions.headers = options.downloadOptions.headers || {}
options.downloadOptions.headers['User-Agent'] = 'nexe (https://www.npmjs.com/package/nexe)'
+13 -5
View File
@@ -65,11 +65,19 @@ export default async function main(compiler: NexeCompiler, next: () => Promise<v
file.contents = fileLines.join('\n')
if (semverGt(version, '11.99')) {
await compiler.replaceInFileAsync(
bootFile,
'initializePolicy();',
'initializePolicy();\n' + wrap('{{replace:lib/patches/boot-nexe.js}}')
)
if (semverGt(version, '12.17.99')) {
await compiler.replaceInFileAsync(
bootFile,
'initializeFrozenIntrinsics();',
'initializeFrozenIntrinsics();\n' + wrap('{{replace:lib/patches/boot-nexe.js}}')
)
} else {
await compiler.replaceInFileAsync(
bootFile,
'initializePolicy();',
'initializePolicy();\n' + wrap('{{replace:lib/patches/boot-nexe.js}}')
)
}
await compiler.replaceInFileAsync(
bootFile,
'assert(!CJSLoader.hasLoadedAnyUserCJSModule)',
+4 -3
View File
@@ -1,11 +1,12 @@
import { join, dirname } from 'path'
import { promises } from 'fs'
import * as fs from 'fs'
import { promisify } from 'util'
import { readFileAsync, writeFileAsync, isDirectoryAsync } from '../util'
import mkdirpAsync = require('mkdirp')
import { NexeCompiler } from '../compiler'
const unlinkAsync = promises.unlink
const readdirAsync = promises.readdir
const unlinkAsync = promisify(fs.unlink),
readdirAsync = promisify(fs.readdir)
function readDirAsync(dir: string): Promise<string[]> {
return readdirAsync(dir).then((paths) => {
+2 -4
View File
@@ -64,7 +64,7 @@ export default async function bundle(compiler: NexeCompiler, next: any) {
const { files, warnings } = await resolveFiles(
input,
...Object.keys(compiler.bundle.index).filter((x) => x.endsWith('.js')),
...Object.keys(compiler.bundle.files).filter((x) => x.endsWith('.js')),
{ cwd, expand: 'variable', loadContent: false }
)
@@ -74,8 +74,6 @@ export default async function bundle(compiler: NexeCompiler, next: any) {
throw new NexeError('Parsing Error:\n' + warnings.join('\n'))
}
await each(Object.keys(files), (filename: string) => compiler.addResource(filename), {
concurrency: 10,
})
Object.keys(files).forEach((x) => compiler.addResource(x))
return next()
}
+1 -1
View File
@@ -22,6 +22,6 @@ export default async function resource(compiler: NexeCompiler, next: () => Promi
step.log(`Including file: ${file}`)
await compiler.addResource(file)
})
step.log(`Included ${count} file(s). ${(compiler.resourceSize / 1e6).toFixed(3)} MB`)
step.log(`Included ${count} file(s)`)
return next()
}
+1 -2
View File
@@ -3,10 +3,9 @@ import { wrap } from '../util'
export default async function (compiler: NexeCompiler, next: () => Promise<void>) {
await next()
compiler.shims.push(
wrap(
`process.__nexe = ${JSON.stringify(compiler.binaryConfiguration)};\n` +
'' +
'{{replace:lib/fs/patch.js}}' +
'\nshimFs(process.__nexe)' +
`\n${compiler.options.fs ? '' : 'restoreFs()'}`
+1 -1
View File
@@ -6,7 +6,7 @@ import { appendFileSync } from 'fs'
function alpine(target: NexeTarget) {
return `
FROM ${target.arch === 'x64' ? '' : 'i386/'}alpine:3.4
FROM ${target.arch === 'x64' ? '' : 'i386/'}alpine:3.12
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 NEXE_VERSION=latest
+20
View File
@@ -39,6 +39,26 @@ describe('options', () => {
expect(options.output).to.equal(path.resolve(cwd, `abc${ext}`))
})
})
describe('remote', () => {
it('should use default remote', () => {
const options = normalizeOptions({})
expect(options.remote).to.equal('https://github.com/nexe/nexe/releases/download/v3.3.3/')
})
it('should append trailing slash to third-party remote if necessary', () => {
const options = normalizeOptions({
remote: 'https://sitejs.org/nexe'
})
expect(options.remote).to.equal('https://sitejs.org/nexe/')
})
it('should not append trailing slash to third-party remote that already has one', () => {
const options = normalizeOptions({
remote: 'https://sitejs.org/nexe/'
})
expect(options.remote).to.equal('https://sitejs.org/nexe/')
})
})
describe('output', () => {
it('should work', () => {
const options = normalizeOptions({