refactor: addResource compiler method

This commit is contained in:
calebboyd
2017-09-19 00:54:20 -05:00
parent dbcff4c7d2
commit 4f2b1c51d5
13 changed files with 151 additions and 102 deletions
+1
View File
@@ -4,6 +4,7 @@ coverage
node_modules
*.log
*.exe
!winsw.exe
.idea
.nexe
lib
+1
View File
@@ -0,0 +1 @@
package-lock=false
+38 -55
View File
@@ -1,6 +1,6 @@
{
"name": "nexe",
"version": "2.0.0-rc.5",
"version": "2.0.0-rc.6",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -146,12 +146,6 @@
"json-stable-stringify": "1.0.1"
}
},
"amdefine": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
"optional": true
},
"ansi": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz",
@@ -532,9 +526,9 @@
"integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
},
"content-type": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz",
"integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0="
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
},
"cookie": {
"version": "0.3.1",
@@ -770,7 +764,7 @@
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
"requires": {
"iconv-lite": "0.4.18"
"iconv-lite": "0.4.19"
}
},
"end-of-stream": {
@@ -792,37 +786,26 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"escodegen": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz",
"integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=",
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz",
"integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==",
"requires": {
"esprima": "2.7.3",
"estraverse": "1.9.3",
"esprima": "3.1.3",
"estraverse": "4.2.0",
"esutils": "2.0.2",
"optionator": "0.8.2",
"source-map": "0.2.0"
},
"dependencies": {
"source-map": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
"integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
"optional": true,
"requires": {
"amdefine": "1.0.1"
}
}
"source-map": "0.5.7"
}
},
"esprima": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
"integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE="
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
"integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM="
},
"estraverse": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
"integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q="
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM="
},
"esutils": {
"version": "2.0.2",
@@ -830,9 +813,9 @@
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
},
"etag": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.0.tgz",
"integrity": "sha1-b2Ma7zNtbEY2K1F2QETOIWvjwFE="
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"exec-sh": {
"version": "0.2.1",
@@ -866,20 +849,20 @@
"accepts": "1.3.4",
"array-flatten": "1.1.1",
"content-disposition": "0.5.2",
"content-type": "1.0.2",
"content-type": "1.0.4",
"cookie": "0.3.1",
"cookie-signature": "1.0.6",
"debug": "2.6.8",
"depd": "1.1.1",
"encodeurl": "1.0.1",
"escape-html": "1.0.3",
"etag": "1.8.0",
"etag": "1.8.1",
"finalhandler": "1.0.4",
"fresh": "0.5.0",
"merge-descriptors": "1.0.1",
"methods": "1.1.2",
"on-finished": "2.3.0",
"parseurl": "1.3.1",
"parseurl": "1.3.2",
"path-to-regexp": "0.1.7",
"proxy-addr": "1.1.5",
"qs": "6.5.0",
@@ -920,7 +903,7 @@
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.4.tgz",
"integrity": "sha1-HtkZnanL/i7y96MbL96LDRI2iXI=",
"requires": {
"iconv-lite": "0.4.18",
"iconv-lite": "0.4.19",
"jschardet": "1.5.1",
"tmp": "0.0.31"
}
@@ -1022,7 +1005,7 @@
"encodeurl": "1.0.1",
"escape-html": "1.0.3",
"on-finished": "2.3.0",
"parseurl": "1.3.1",
"parseurl": "1.3.2",
"statuses": "1.3.1",
"unpipe": "1.0.0"
}
@@ -1064,9 +1047,9 @@
}
},
"forwarded": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz",
"integrity": "sha1-Ge+YdMSuHCl7zweP3mOgm2aoQ2M="
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.1.tgz",
"integrity": "sha1-ik4wxkCwU5U5mjVJxzAldygEiWE="
},
"fresh": {
"version": "0.5.0",
@@ -1102,7 +1085,7 @@
"base64-js": "1.2.1",
"chokidar": "1.7.0",
"concat-with-sourcemaps": "1.0.4",
"escodegen": "1.8.1",
"escodegen": "1.9.0",
"express": "4.15.4",
"fliplog": "0.3.13",
"fs-extra": "2.1.2",
@@ -1333,9 +1316,9 @@
}
},
"iconv-lite": {
"version": "0.4.18",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz",
"integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA=="
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
},
"ieee754": {
"version": "1.1.8",
@@ -2139,9 +2122,9 @@
}
},
"parseurl": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz",
"integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY="
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
"integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
},
"path-is-absolute": {
"version": "1.0.1",
@@ -2280,7 +2263,7 @@
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz",
"integrity": "sha1-ccDuOxAt4/IC87ZPYI0XP8uhqRg=",
"requires": {
"forwarded": "0.1.0",
"forwarded": "0.1.1",
"ipaddr.js": "1.4.0"
}
},
@@ -2507,7 +2490,7 @@
"destroy": "1.0.4",
"encodeurl": "1.0.1",
"escape-html": "1.0.3",
"etag": "1.8.0",
"etag": "1.8.1",
"fresh": "0.5.0",
"http-errors": "1.6.2",
"mime": "1.3.4",
@@ -2524,7 +2507,7 @@
"requires": {
"encodeurl": "1.0.1",
"escape-html": "1.0.3",
"parseurl": "1.3.1",
"parseurl": "1.3.2",
"send": "0.15.4"
}
},
+1
View File
@@ -0,0 +1 @@
package-lock=false
+5
View File
@@ -0,0 +1,5 @@
import { NexeCompiler } from 'nexe'
export default function daemon (compiler: NexeCompiler ) {
compiler.addResource('')
}
+12
View File
@@ -0,0 +1,12 @@
{
"name": "nexe-daemon",
"version": "1.0.0",
"description": "Plugin for nexe to create installable services",
"main": "index.js",
"scripts": {},
"author": "Caleb Boyd",
"license": "MIT",
"devDependencies": {
"nexe": "^2.0.0-rc.6"
}
}
@@ -0,0 +1,6 @@
<configuration>
<id>{{id}}</id>
<name>{{name}}</name>
<description>{{description}}</description>
<executable>%BASE%\{{executable}}.exe</executable>
</configuration>
Binary file not shown.
+54 -32
View File
@@ -5,7 +5,7 @@ import { createReadStream } from 'fs'
import { Readable } from 'stream'
import { spawn } from 'child_process'
import { Logger } from './logger'
import { readFileAsync, writeFileAsync, pathExistsAsync, dequote, isWindows } from './util'
import { readFileAsync, writeFileAsync, pathExistsAsync, dequote, isWindows, bound } from './util'
import { NexeOptions, nexeVersion } from './options'
import { NexeTarget } from './target'
import download = require('download')
@@ -34,19 +34,16 @@ export class NexeCompiler {
public log = new Logger(this.options.loglevel)
public src: string
public files: NexeFile[] = []
public shims: string[] = []
public input: string
public bundledInput?: string
public output: string | null
public targets: NexeTarget[]
public target: NexeTarget
public resources: { bundle: string; index: { [key: string]: number[] } } = {
public resources: { bundle: Buffer; index: { [key: string]: number[] } } = {
index: {},
bundle: ''
bundle: Buffer.from('')
}
public readFileAsync: (file: string) => Promise<NexeFile>
public writeFileAsync: (file: string, contents: Buffer | string) => Promise<void>
public replaceInFileAsync: (file: string, replacer: any, replaceValue: string) => Promise<void>
public setFileContentsAsync: (file: string, contents: string | Buffer) => Promise<void>
private nodeSrcBinPath: string
constructor(public options: NexeOptions) {
@@ -65,32 +62,50 @@ export class NexeCompiler {
this.env.PYTHON = python
}
}
}
this.readFileAsync = async (file: string) => {
let cachedFile = this.files.find(x => normalize(x.filename) === normalize(file))
if (!cachedFile) {
const absPath = join(this.src, file)
cachedFile = {
absPath,
filename: file,
contents: await readFileAsync(absPath, 'utf-8').catch(x => {
if (x.code === 'ENOENT') return ''
throw x
})
}
this.files.push(cachedFile)
@bound
addResource(file: string, contents: Buffer) {
const { resources } = this
resources.index[file] = [resources.bundle.byteLength, contents.byteLength]
resources.bundle = Buffer.concat([resources.bundle, contents])
}
@bound
async readFileAsync(file: string) {
this.assertBuild()
let cachedFile = this.files.find(x => normalize(x.filename) === normalize(file))
if (!cachedFile) {
const absPath = join(this.src, file)
cachedFile = {
absPath,
filename: file,
contents: await readFileAsync(absPath, 'utf-8').catch(x => {
if (x.code === 'ENOENT') return ''
throw x
})
}
return cachedFile
}
this.writeFileAsync = (file, contents) => writeFileAsync(join(this.src, file), contents)
this.replaceInFileAsync = async (file, replace: string | RegExp, value: string) => {
const entry = await this.readFileAsync(file)
entry.contents = entry.contents.replace(replace, value)
}
this.setFileContentsAsync = async (file: string, contents: string) => {
const entry = await this.readFileAsync(file)
entry.contents = contents
this.files.push(cachedFile)
}
return cachedFile
}
@bound
writeFileAsync(file: string, contents: string | Buffer) {
this.assertBuild()
return writeFileAsync(join(this.src, file), contents)
}
@bound
async replaceInFileAsync(file: string, replace: string | RegExp, value: string) {
const entry = await this.readFileAsync(file)
entry.contents = entry.contents.replace(replace, value)
}
@bound
async setFileContentsAsync(file: string, contents: string) {
const entry = await this.readFileAsync(file)
entry.contents = contents
}
quit() {
@@ -99,6 +114,12 @@ export class NexeCompiler {
return this.log.flush()
}
assertBuild() {
if (!this.options.build) {
throw new Error('This feature is only available with `--build`')
}
}
public getNodeExecutableLocation(target?: NexeTarget) {
if (target) {
return join(this.options.temp, target.toString())
@@ -217,12 +238,13 @@ export class NexeCompiler {
artifact.push(chunk)
})
binary.on('close', () => {
const content = this._serializeHeader(header) + this.input
const content = this._serializeHeader(header) + this.shims.join(';') + ';' + this.input
artifact.push(content)
artifact.push(this.resources.bundle)
const lengths = Buffer.from(Array(16))
lengths.writeDoubleLE(Buffer.byteLength(content), 0)
lengths.writeDoubleLE(Buffer.byteLength(this.resources.bundle), 8)
lengths.writeDoubleLE(this.resources.bundle.byteLength, 8)
artifact.push(Buffer.concat([Buffer.from('<nexe~~sentinel>'), lengths]))
artifact.push(null)
})
+13 -6
View File
@@ -148,10 +148,6 @@ function tryResolveMainFileName(cwd: string) {
filename = basename(file).replace(extname(file), '')
} catch (_) {}
if (filename === 'index' && basename(cwd)) {
return basename(cwd)
}
return filename ? filename : 'nexe_' + Date.now()
}
@@ -162,12 +158,23 @@ function extractLogLevel(options: NexeOptions) {
return 'info'
}
function isName(name: string) {
return name && name !== 'index'
}
function extractName(options: NexeOptions) {
let name = options.name
if (!name && typeof options.input === 'string') {
if (!isName(name) && typeof options.input === 'string') {
name = basename(options.input).replace(extname(options.input), '')
}
name = name === 'index' ? tryResolveMainFileName(options.cwd) : name
if (!isName(name)) {
name = tryResolveMainFileName(options.cwd)
}
if (!isName(name) && basename(options.cwd)) {
name = basename(options.cwd)
}
return name.replace(/\.exe$/, '')
}
+2 -9
View File
@@ -18,15 +18,8 @@ export default async function resource(compiler: NexeCompiler, next: () => Promi
count++
step.log(`Including file: ${file}`)
const contents = await readFileAsync(file)
const commentSafeContents = contents.toString('base64')
resources.index[file] = [
Buffer.byteLength(resources.bundle),
Buffer.byteLength(commentSafeContents)
]
resources.bundle += commentSafeContents
compiler.addResource(file, contents)
})
step.log(
`Included ${count} file(s). ${(Buffer.byteLength(resources.bundle) / 1e6).toFixed(3)} MB`
)
step.log(`Included ${count} file(s). ${(resources.bundle.byteLength / 1e6).toFixed(3)} MB`)
return next()
}
+17
View File
@@ -26,6 +26,22 @@ function padRight(str: string, l: number) {
return (str + ' '.repeat(l)).substr(0, l)
}
const bound: MethodDecorator = function bound<T>(
target: Object,
propertyKey: string,
descriptor: TypedPropertyDescriptor<T>
) {
const configurable = true
return {
configurable,
get(this: T) {
const value = (descriptor.value as any).bind(this)
Object.defineProperty(this, propertyKey, { configurable, value, writable: true })
return value
}
}
}
function dequote(input: string) {
input = input.trim()
const singleQuote = input.startsWith("'") && input.endsWith("'")
@@ -62,6 +78,7 @@ function isDirectoryAsync(path: string) {
export {
dequote,
padRight,
bound,
isWindows,
rimrafAsync,
statAsync,
+1
View File
@@ -1,6 +1,7 @@
{
"compilerOptions": {
"target":"es5",
"experimentalDecorators": true,
"lib": ["es2017"],
"module": "commonjs",
"outDir": "./lib",