forked from nodejs/node-core-utils
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: merge update-v8 in the project (nodejs#235)
* feat: merge update-v8 in the project * move to git-node
- Loading branch information
1 parent
67bc061
commit 969987b
Showing
15 changed files
with
1,652 additions
and
195 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
'use strict'; | ||
|
||
const path = require('path'); | ||
|
||
const execa = require('execa'); | ||
const logSymbols = require('log-symbols'); | ||
|
||
const updateV8 = require('../../lib/update-v8'); | ||
const constants = require('../../lib/update-v8/constants'); | ||
const common = require('../../lib/update-v8/common'); | ||
|
||
module.exports = { | ||
command: 'v8 [major|minor|backport]', | ||
describe: 'Update or patch the V8 engine', | ||
builder: (yargs) => { | ||
yargs | ||
.command({ | ||
command: 'major', | ||
desc: 'Do a major upgrade. Replaces the whole deps/v8 directory', | ||
handler: main, | ||
builder: (yargs) => { | ||
yargs.option('branch', { | ||
describe: 'Branch of the V8 repository to use for the upgrade', | ||
default: 'lkgr' | ||
}); | ||
} | ||
}) | ||
.command({ | ||
command: 'minor', | ||
desc: 'Do a minor patch of the current V8 version', | ||
handler: main | ||
}) | ||
.command({ | ||
command: 'backport <sha>', | ||
desc: 'Backport a single commit from the V8 repository', | ||
handler: main, | ||
builder: (yargs) => { | ||
yargs.option('bump', { | ||
describe: 'Bump V8 embedder version number or patch version', | ||
default: true | ||
}); | ||
} | ||
}) | ||
.demandCommand(1, 'Please provide a valid command') | ||
.option('node-dir', { | ||
describe: 'Directory of a Node.js clone', | ||
default: process.cwd() | ||
}) | ||
.option('base-dir', { | ||
describe: 'Directory where V8 should be cloned', | ||
default: constants.defaultBaseDir | ||
}) | ||
.option('verbose', { | ||
describe: 'Enable verbose output', | ||
boolean: true, | ||
default: false | ||
}); | ||
}, | ||
handler: main | ||
}; | ||
|
||
function main(argv) { | ||
const options = Object.assign({}, argv); | ||
options.nodeDir = path.resolve(options.nodeDir); | ||
options.baseDir = path.resolve(options.baseDir); | ||
options.v8CloneDir = path.join(options.baseDir, 'v8'); | ||
|
||
options.execGitNode = function execGitNode(...args) { | ||
return execa('git', args, { cwd: options.nodeDir }); | ||
}; | ||
options.execGitV8 = function execGitV8(...args) { | ||
return execa('git', args, { cwd: options.v8CloneDir }); | ||
}; | ||
|
||
Promise.resolve() | ||
.then(async() => { | ||
await common.checkCwd(options); | ||
const kind = argv._[0]; | ||
options[kind] = true; | ||
switch (kind) { | ||
case 'minor': | ||
return updateV8.minor(options); | ||
case 'major': | ||
return updateV8.major(options); | ||
case 'backport': | ||
return updateV8.backport(options); | ||
} | ||
}) | ||
.catch((err) => { | ||
console.error( | ||
logSymbols.error, | ||
options.verbose ? err.stack : err.message | ||
); | ||
process.exitCode = 1; | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
'use strict'; | ||
|
||
const path = require('path'); | ||
|
||
const execa = require('execa'); | ||
const fs = require('fs-extra'); | ||
const Listr = require('listr'); | ||
|
||
const common = require('./common'); | ||
|
||
exports.doBackport = function doBackport(options) { | ||
const todo = [common.getCurrentV8Version(), generatePatch(), applyPatch()]; | ||
if (options.bump !== false) { | ||
if (options.nodeMajorVersion < 9) { | ||
todo.push(incrementV8Version()); | ||
} else { | ||
todo.push(incrementEmbedderVersion()); | ||
} | ||
} | ||
return { | ||
title: 'V8 commit backport', | ||
task: () => { | ||
return new Listr(todo); | ||
} | ||
}; | ||
}; | ||
|
||
exports.commitBackport = function commitBackport() { | ||
return { | ||
title: 'Commit patch', | ||
task: async(ctx) => { | ||
const messageTitle = `deps: cherry-pick ${ctx.sha.substring( | ||
0, | ||
7 | ||
)} from upstream V8`; | ||
const indentedMessage = ctx.message.replace(/\n/g, '\n '); | ||
const messageBody = | ||
'Original commit message:\n\n' + | ||
` ${indentedMessage}\n\n` + | ||
`Refs: https://github.com/v8/v8/commit/${ctx.sha}`; | ||
|
||
await ctx.execGitNode('add', 'deps/v8'); | ||
await ctx.execGitNode('commit', '-m', messageTitle, '-m', messageBody); | ||
} | ||
}; | ||
}; | ||
|
||
function generatePatch() { | ||
return { | ||
title: 'Generate patch', | ||
task: async(ctx) => { | ||
const sha = ctx.sha; | ||
if (!sha || sha.length !== 40) { | ||
throw new Error( | ||
'--sha option is required and must be 40 characters long' | ||
); | ||
} | ||
try { | ||
const [patch, message] = await Promise.all([ | ||
ctx.execGitV8('format-patch', '--stdout', `${sha}^..${sha}`), | ||
ctx.execGitV8('log', '--format=%B', '-n', '1', sha) | ||
]); | ||
ctx.patch = patch.stdout; | ||
ctx.message = message.stdout; | ||
} catch (e) { | ||
throw new Error(e.stderr); | ||
} | ||
} | ||
}; | ||
} | ||
|
||
function applyPatch() { | ||
return { | ||
title: 'Apply patch to deps/v8', | ||
task: async(ctx) => { | ||
const patch = ctx.patch; | ||
try { | ||
await execa('git', ['apply', '-3', '--directory=deps/v8'], { | ||
cwd: ctx.nodeDir, | ||
input: patch | ||
}); | ||
} catch (e) { | ||
const file = path.join(ctx.nodeDir, `${ctx.sha}.diff`); | ||
await fs.writeFile(file, ctx.patch); | ||
throw new Error( | ||
`Could not apply patch.\n${e}\nDiff was stored in ${file}` | ||
); | ||
} | ||
} | ||
}; | ||
} | ||
|
||
function incrementV8Version() { | ||
return { | ||
title: 'Increment V8 version', | ||
task: async(ctx) => { | ||
const incremented = ctx.currentVersion[3] + 1; | ||
const versionHPath = `${ctx.nodeDir}/deps/v8/include/v8-version.h`; | ||
let versionH = await fs.readFile(versionHPath, 'utf8'); | ||
versionH = versionH.replace( | ||
/V8_PATCH_LEVEL (\d+)/, | ||
`V8_PATCH_LEVEL ${incremented}` | ||
); | ||
await fs.writeFile(versionHPath, versionH); | ||
} | ||
}; | ||
} | ||
|
||
const embedderRegex = /'v8_embedder_string': '-node\.(\d+)'/; | ||
function incrementEmbedderVersion() { | ||
return { | ||
title: 'Increment embedder version number', | ||
task: async(ctx) => { | ||
const commonGypiPath = path.join(ctx.nodeDir, 'common.gypi'); | ||
const commonGypi = await fs.readFile(commonGypiPath, 'utf8'); | ||
const embedderValue = parseInt(embedderRegex.exec(commonGypi)[1], 10); | ||
const embedderString = `'v8_embedder_string': '-node.${embedderValue + | ||
1}'`; | ||
await fs.writeFile( | ||
commonGypiPath, | ||
commonGypi.replace(embedderRegex, embedderString) | ||
); | ||
await ctx.execGitNode('add', 'common.gypi'); | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
'use strict'; | ||
|
||
const util = require('./util'); | ||
|
||
module.exports = function() { | ||
return { | ||
title: 'Commit V8 update', | ||
task: async(ctx) => { | ||
const newV8Version = util.getNodeV8Version(ctx.nodeDir).join('.'); | ||
await ctx.execGitNode('add', 'deps/v8'); | ||
const moreArgs = []; | ||
let message; | ||
if (ctx.minor) { | ||
const prev = ctx.currentVersion.join('.'); | ||
const next = ctx.latestVersion.join('.'); | ||
moreArgs.push( | ||
'-m', | ||
`Refs: https://github.com/v8/v8/compare/${prev}...${next}` | ||
); | ||
message = `deps: patch V8 to ${newV8Version}`; | ||
} else { | ||
message = `deps: update V8 to ${newV8Version}`; | ||
} | ||
await ctx.execGitNode('commit', '-m', message, ...moreArgs); | ||
}, | ||
skip: (ctx) => ctx.skipped | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
'use strict'; | ||
|
||
const path = require('path'); | ||
|
||
const fs = require('fs-extra'); | ||
|
||
const util = require('./util'); | ||
|
||
exports.getCurrentV8Version = function getCurrentV8Version() { | ||
return { | ||
title: 'Get current V8 version', | ||
task: (ctx) => { | ||
ctx.currentVersion = util.getNodeV8Version(ctx.nodeDir); | ||
} | ||
}; | ||
}; | ||
|
||
exports.checkCwd = async function checkCwd(ctx) { | ||
let isNode = false; | ||
try { | ||
const nodeVersion = await fs.readFile( | ||
path.join(ctx.nodeDir, 'src/node_version.h') | ||
); | ||
const match = /#define NODE_MAJOR_VERSION (\d+)/.exec(nodeVersion); | ||
if (match) { | ||
isNode = true; | ||
ctx.nodeMajorVersion = parseInt(match[1], 10); | ||
} | ||
} catch (e) { | ||
// ignore | ||
} | ||
if (!isNode) { | ||
throw new Error( | ||
'This does not seem to be the Node.js repository.\n' + | ||
`node-dir: ${ctx.nodeDir}` | ||
); | ||
} | ||
}; |
Oops, something went wrong.