Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 133
chore(git-node): avoid dealing with patch files for landing#486
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Uh oh!
There was an error while loading. Please reload this page.
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 |
|---|---|---|
| @@ -30,6 +30,7 @@ class LandingSession extends Session { | ||
| this.lint = lint; | ||
| this.autorebase = autorebase; | ||
| this.fixupAll = fixupAll; | ||
| this.expectedCommitShas = []; | ||
| } | ||
| get argv() { | ||
| @@ -44,6 +45,8 @@ class LandingSession extends Session { | ||
| async start(metadata) { | ||
| const { cli } = this; | ||
| this.startLanding(); | ||
| this.expectedCommitShas = | ||
| metadata.data.commits.map(({ commit }) => commit.oid); | ||
| const status = metadata.status ? 'should be ready' : 'is not ready'; | ||
| // NOTE(mmarchini): default answer is yes. If --yes is given, we need to be | ||
| // more careful though, and we change the default to the result of our | ||
| @@ -78,34 +81,46 @@ class LandingSession extends Session { | ||
| } | ||
| async downloadAndPatch() { | ||
| const { cli, req, repo, owner, prid } = this; | ||
| const { cli, repo, owner, prid, expectedCommitShas } = this; | ||
| // TODO(joyeecheung): restore previously downloaded patches | ||
| cli.startSpinner(`Downloading patch for ${prid}`); | ||
| const patch = await req.text( | ||
| `https://github.com/${owner}/${repo}/pull/${prid}.patch`); | ||
| this.savePatch(patch); | ||
| cli.stopSpinner(`Downloaded patch to ${this.patchPath}`); | ||
| await runAsync('git', [ | ||
| 'fetch', `https://github.com/${owner}/${repo}.git`, | ||
| `refs/pull/${prid}/merge`]); | ||
| // We fetched the commit that would result if we used `git merge`. | ||
| // ^1 and ^2 refer to the PR base and the PR head, respectively. | ||
| const [base, head] = await runAsync('git', | ||
| ['rev-parse', 'FETCH_HEAD^1', 'FETCH_HEAD^2'], | ||
| { captureStdout: 'lines' }); | ||
| const commitShas = await runAsync('git', | ||
| ['rev-list', `${base}..${head}`], | ||
| { captureStdout: 'lines' }); | ||
| cli.stopSpinner(`Fetched commits as ${shortSha(base)}..${shortSha(head)}`); | ||
| cli.separator(); | ||
| // TODO: check that patches downloaded match metadata.commits | ||
| const mismatchedCommits = [ | ||
| ...commitShas.filter((sha) => !expectedCommitShas.includes(sha)) | ||
| .map((sha) => `Unexpected commit ${sha}`), | ||
| ...expectedCommitShas.filter((sha) => !commitShas.includes(sha)) | ||
| .map((sha) => `Missing commit ${sha}`) | ||
| ].join('\n'); | ||
mmarchini marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| if (mismatchedCommits.length > 0) { | ||
| cli.error(`Mismatched commits:\n${mismatchedCommits}`); | ||
| process.exit(1); | ||
| } | ||
| const commitInfo = { base, head, shas: commitShas }; | ||
| this.saveCommitInfo(commitInfo); | ||
| try { | ||
| await forceRunAsync('git', ['am', this.patchPath], { | ||
| await forceRunAsync('git', ['cherry-pick', `${base}..${head}`], { | ||
mmarchini marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| ignoreFailure: false | ||
| }); | ||
| } catch (ex) { | ||
| const should3Way = await cli.prompt( | ||
| 'The normal `git am` failed. Do you want to retry with 3-way merge?'); | ||
| if (should3Way) { | ||
| await forceRunAsync('git', ['am', '--abort']); | ||
| await runAsync('git', [ | ||
| 'am', | ||
| '-3', | ||
| this.patchPath | ||
| ]); | ||
| } else { | ||
| cli.error('Failed to apply patches'); | ||
| process.exit(1); | ||
| } | ||
| await forceRunAsync('git', ['cherry-pick', '--abort']); | ||
| cli.error('Failed to apply patches'); | ||
| process.exit(1); | ||
| } | ||
| // Check for and maybe assign any unmarked deprecations in the codebase. | ||
| @@ -126,7 +141,7 @@ class LandingSession extends Session { | ||
| } | ||
| cli.ok('Patches applied'); | ||
| return patch; | ||
| return commitInfo; | ||
| } | ||
| getRebaseSuggestion(subjects) { | ||
| @@ -173,21 +188,13 @@ class LandingSession extends Session { | ||
| } | ||
| } | ||
| async tryCompleteLanding(patch) { | ||
| async tryCompleteLanding(commitInfo) { | ||
| const { cli } = this; | ||
| const subjects = await runAsync('git', | ||
| ['log', '--pretty=format:%s', `${commitInfo.base}..${commitInfo.head}`], | ||
| { captureStdout: 'lines' }); | ||
| const subjects = patch.match(/Subject: \[PATCH.*?\].*/g); | ||
| if (!subjects) { | ||
| cli.warn('Cannot get number of commits in the patch. ' + | ||
| 'It seems to be malformed'); | ||
| return; | ||
| } | ||
| // XXX(joyeecheung) we cannot guarantee that no one will put a subject | ||
| // line in the commit message but that seems unlikely (some deps update | ||
| // might do that). | ||
| if (subjects.length === 1) { | ||
| // assert(subjects[0].startsWith('Subject: [PATCH]')) | ||
| if (commitInfo.shas.length === 1) { | ||
| const shouldAmend = await cli.prompt( | ||
| 'There is only one commit in this PR.\n' + | ||
| 'do you want to amend the commit message?'); | ||
| @@ -247,7 +254,7 @@ class LandingSession extends Session { | ||
| } | ||
| await this.tryResetBranch(); | ||
| const patch = await this.downloadAndPatch(); | ||
| const commitInfo = await this.downloadAndPatch(); | ||
| const cleanLint = await this.validateLint(); | ||
| if (cleanLint === LINT_RESULTS.FAILED) { | ||
| @@ -280,7 +287,7 @@ class LandingSession extends Session { | ||
| this.startAmending(); | ||
| await this.tryCompleteLanding(patch); | ||
| await this.tryCompleteLanding(commitInfo); | ||
| } | ||
| async amend() { | ||
| @@ -407,13 +414,13 @@ class LandingSession extends Session { | ||
| } | ||
| if (this.isApplying()) { | ||
| // We're still resolving conflicts. | ||
| if (this.amInProgress()) { | ||
| cli.log('Looks like you are resolving a `git am` conflict'); | ||
| if (this.cherryPickInProgress()) { | ||
| cli.log('Looks like you are resolving a `git cherry-pick` conflict'); | ||
| cli.log('Please run `git status` for help'); | ||
| } else { | ||
| // Conflicts has been resolved - amend. | ||
| this.startAmending(); | ||
| return this.tryCompleteLanding(this.patch); | ||
| return this.tryCompleteLanding(this.commitInfo); | ||
| } | ||
| return; | ||
| } | ||
This file contains hidden or 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 |
|---|---|---|
| @@ -4,15 +4,24 @@ const { spawn, spawnSync } = require('child_process'); | ||
| const IGNORE = '__ignore__'; | ||
| function runAsyncBase(cmd, args, options = {}) { | ||
| function runAsyncBase(cmd, args, { | ||
| ignoreFailure = true, | ||
| spawnArgs, | ||
| captureStdout = false | ||
| } = {}) { | ||
| return new Promise((resolve, reject) => { | ||
| const child = spawn(cmd, args, Object.assign({ | ||
| cwd: process.cwd(), | ||
| stdio: 'inherit' | ||
| }, options.spawnArgs)); | ||
| stdio: captureStdout ? ['inherit', 'pipe', 'inherit'] : 'inherit' | ||
| }, spawnArgs)); | ||
| let stdout; | ||
| if (captureStdout) { | ||
| stdout = ''; | ||
| child.stdout.setEncoding('utf8'); | ||
| child.stdout.on('data', (chunk) => { stdout += chunk; }); | ||
| } | ||
| child.on('close', (code) => { | ||
| if (code !== 0) { | ||
| const { ignoreFailure = true } = options; | ||
| if (ignoreFailure) { | ||
| return reject(new Error(IGNORE)); | ||
| } | ||
| @@ -21,7 +30,11 @@ function runAsyncBase(cmd, args, options = {}) { | ||
| err.messageOnly = true; | ||
| return reject(err); | ||
| } | ||
| return resolve(); | ||
| if (captureStdout === 'lines') { | ||
| stdout = stdout.split(/\r?\n/g); | ||
mmarchini marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| if (stdout[stdout.length - 1] === '') stdout.pop(); | ||
| } | ||
| return resolve(stdout); | ||
| }); | ||
| }); | ||
| } | ||
This file contains hidden or 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
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.