Skip to content

Commit

Permalink
Update mksnapshot for 3-0-x
Browse files Browse the repository at this point in the history
Add support for generating needed v8_context_snapshot.bin
  • Loading branch information
John Kleinschmidt committed Dec 4, 2018
1 parent ff3aa3a commit ca1b18b
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 29 deletions.
6 changes: 5 additions & 1 deletion README.md
Expand Up @@ -22,8 +22,12 @@ an `electron-mksnapshot` dependency of `~2.0.0` in your `package.json` file.

```sh
npm install --save-dev electron-mksnapshot
mksnapshot --help
mksnapshot.js file.js (--output_dir OUTPUT_DIR).
```
Running mksnapshot.js will generate both a snapshot_blob.bin and v8_context_snapshot.bin files which
are needed to use custom snapshots in Electron.
If an output directory isn't specified, the current directory will be used.
(Additional mksnapshot args except for --startup_blob are supported, run mksnapshot --help to see options)

## Custom Mirror

Expand Down
107 changes: 89 additions & 18 deletions mksnapshot.js
@@ -1,30 +1,101 @@
#!/usr/bin/env node

var ChildProcess = require('child_process')
var path = require('path')
const fs = require('fs')
const { spawnSync } = require('child_process')
const path = require('path')
const temp = require('temp').track()
const workingDir = temp.mkdirSync('mksnapshot-workdir')

var command = path.join(__dirname, 'bin', 'mksnapshot')
var args = process.argv.slice(2)
var options = {
cwd: process.cwd(),
/*
* Copy mksnapshot files to temporary working directory because
* v8_context_snapshot_generator expects to run everything from the same
* directory.
*/
function copyMksnapshotFiles (mksnapshotDir, workingDir) {
const mksnapshotFiles = fs.readdirSync(mksnapshotDir)
mksnapshotFiles.forEach(file => {
fs.copyFileSync(path.join(mksnapshotDir, file), path.join(workingDir, file))
})
}

function getBinaryPath (binary, binaryPath) {
if (process.platform === 'win32') {
return path.join(binaryPath, `${binary}.exe`)
} else {
return path.join(binaryPath, binary)
}
}

const args = process.argv.slice(2)
if (args.length === 0 || args.includes('--help')) {
console.log(`Usage: mksnapshot file.js (--output_dir OUTPUT_DIR). ` +
`Additional mksnapshot args except for --startup_blob are supported:`)
args.push('--help')
}
const outDirIdx = args.indexOf('--output_dir')
let outputDir = process.cwd()
let mksnapshotArgs = args
if (outDirIdx > -1) {
mksnapshotArgs = args.slice(0, outDirIdx)
if (args.length >= (outDirIdx + 2)) {
outputDir = args[(outDirIdx + 1)]
if (args.length > (outDirIdx + 2)) {
mksnapshotArgs = mksnapshotArgs.concat(args.slice(outDirIdx + 2))
}
} else {
console.log('Error! Output directory argument given but directory not specified.')
process.exit(1)
}
}
if (args.includes('--startup_blob')) {
console.log('--startup_blob argument not supported. Use --output_dir to specify where to output snapshot_blob.bin')
process.exit(1)
} else {
mksnapshotArgs = mksnapshotArgs.concat(['--startup_blob', 'snapshot_blob.bin'])
}
if (!mksnapshotArgs.includes('--turbo_instruction_scheduling')) {
mksnapshotArgs.push('--turbo_instruction_scheduling')
}

const mksnapshotDir = path.join(__dirname, 'bin')
copyMksnapshotFiles(mksnapshotDir, workingDir)

const options = {
cwd: workingDir,
env: process.env,
stdio: 'inherit'
}

var mksnapshotProcess = ChildProcess.spawn(command, args, options)
mksnapshotProcess.on('exit', function (code, signal) {
if (code == null && signal === 'SIGILL') {
const mksnapshotCommand = getBinaryPath('mksnapshot', workingDir)
const mksnapshotProcess = spawnSync(mksnapshotCommand, mksnapshotArgs, options)
if (mksnapshotProcess.status !== 0) {
let code = mksnapshotProcess.status
if (code == null && mksnapshotProcess.signal === 'SIGILL') {
code = 1
}
console.log('Error running mksnapshot.')
process.exit(code)
})

var killMksnapshot = function () {
try {
mksnapshotProcess.kill()
} catch (ignored) {
}
}
if (args.includes('--help')) {
process.exit(0)
}

fs.copyFileSync(path.join(workingDir, 'snapshot_blob.bin'),
path.join(outputDir, 'snapshot_blob.bin'))

process.on('exit', killMksnapshot)
process.on('SIGTERM', killMksnapshot)
const v8ContextGenCommand = getBinaryPath('v8_context_snapshot_generator', workingDir)
const v8ContextGenArgs = [
`--output_file=${path.join(outputDir, 'v8_context_snapshot.bin')}`
]

const v8ContextGenOptions = {
cwd: mksnapshotDir,
env: process.env,
stdio: 'inherit'
}
const v8ContextGenProcess = spawnSync(v8ContextGenCommand, v8ContextGenArgs, v8ContextGenOptions)
if (v8ContextGenProcess.status !== 0) {
console.log('Error running the v8 context snapshot generator.', v8ContextGenProcess)
process.exit(v8ContextGenProcess.status)
}
process.exit(0)
11 changes: 7 additions & 4 deletions package.json
@@ -1,6 +1,6 @@
{
"name": "electron-mksnapshot",
"version": "3.0.0-beta.1",
"version": "3.0.10",
"description": "Electron version of the mksnapshot binary",
"repository": "https://github.com/electron/mksnapshot",
"bin": {
Expand All @@ -13,16 +13,19 @@
"license": "MIT",
"dependencies": {
"electron-download": "^4.1.0",
"extract-zip": "^1.6.5"
"extract-zip": "^1.6.5",
"temp": "^0.8.3"
},
"devDependencies": {
"mocha": "^3.2.0",
"standard": "^8.6.0",
"temp": "^0.8.3"
"standard": "^8.6.0"
},
"standard": {
"ignore": [
"test/fixtures"
]
},
"engines" : {
"node" : ">=8.5.0"
}
}
19 changes: 13 additions & 6 deletions test/mksnapshot-test.js
Expand Up @@ -11,12 +11,14 @@ describe('mksnapshot binary', function () {
this.timeout(10000)

it('creates a snapshot for a valid file', function (done) {
var outputFile = path.join(temp.mkdirSync('mksnapshot-'), 'snapshot_blob.bin')
var tempDir = temp.mkdirSync('mksnapshot-')
var outputFile = path.join(tempDir, 'snapshot_blob.bin')
var v8ContextFile = path.join(tempDir, 'v8_context_snapshot.bin')
var args = [
path.join(__dirname, '..', 'mksnapshot.js'),
path.join(__dirname, 'fixtures', 'snapshot.js'),
'--startup_blob',
outputFile
'--output_dir',
tempDir
]
var mksnapshot = ChildProcess.spawn(process.execPath, args)

Expand All @@ -29,19 +31,22 @@ describe('mksnapshot binary', function () {
assert.equal(code, 0, 'Exit code is not zero')
assert.equal(output.indexOf('Loading script for embedding'), 0, output, 'Output is correct')
assert.equal(fs.existsSync(outputFile), true, 'Output file exists.')
assert.equal(fs.existsSync(v8ContextFile), true, 'V8 context file exists.')
done()
})

mksnapshot.on('error', done)
})

it('fails for invalid JavaScript files', function (done) {
var outputFile = path.join(temp.mkdirSync('mksnapshot-'), 'snapshot_blob.bin')
var tempDir = temp.mkdirSync('mksnapshot-')
var outputFile = path.join(tempDir, 'snapshot_blob.bin')
var v8ContextFile = path.join(tempDir, 'v8_context_snapshot.bin')
var args = [
path.join(__dirname, '..', 'mksnapshot.js'),
path.join(__dirname, 'fixtures', 'invalid.js'),
'--startup_blob',
outputFile
'--output_dir',
tempDir
]
var mksnapshot = ChildProcess.spawn(process.execPath, args)

Expand All @@ -50,10 +55,12 @@ describe('mksnapshot binary', function () {
mksnapshot.stderr.on('data', function (data) { output += data })

mksnapshot.on('close', function (code) {
console.log('Output is', output)
assert.equal(typeof code, 'number', 'Exit code is a number')
assert.notEqual(code, 0, 'Exit code is not zero')
assert.notEqual(output.indexOf('Fatal error'), -1, 'Output has fatal error')
assert.equal(fs.existsSync(outputFile), false, 'Output file does not exist.')
assert.equal(fs.existsSync(v8ContextFile), false, 'V8 context file does not exist.')
done()
})

Expand Down

0 comments on commit ca1b18b

Please sign in to comment.