feat(dev-infra): migrate rebase tool to use new logging system (#37232)

Migrate the rebase tool in ng-dev to use new logging system rather
than directly calling console.*  to create a better experience
for users.

PR Close #37232
This commit is contained in:
Joey Perrott 2020-05-20 14:32:04 -07:00 committed by Matias Niemelä
parent 9388e47e1e
commit 9b3ca19675
2 changed files with 23 additions and 25 deletions

View File

@ -8,6 +8,8 @@
import {Arguments, Argv} from 'yargs'; import {Arguments, Argv} from 'yargs';
import {error} from '../../utils/console';
import {rebasePr} from './index'; import {rebasePr} from './index';
/** URL to the Github page where personal access tokens can be generated. */ /** URL to the Github page where personal access tokens can be generated. */
@ -25,9 +27,9 @@ export function buildRebaseCommand(yargs: Argv) {
export async function handleRebaseCommand(args: Arguments) { export async function handleRebaseCommand(args: Arguments) {
const githubToken = args.githubToken || process.env.GITHUB_TOKEN || process.env.TOKEN; const githubToken = args.githubToken || process.env.GITHUB_TOKEN || process.env.TOKEN;
if (!githubToken) { if (!githubToken) {
console.error('No Github token set. Please set the `GITHUB_TOKEN` environment variable.'); error('No Github token set. Please set the `GITHUB_TOKEN` environment variable.');
console.error('Alternatively, pass the `--github-token` command line flag.'); error('Alternatively, pass the `--github-token` command line flag.');
console.error(`You can generate a token here: ${GITHUB_TOKEN_GENERATE_URL}`); error(`You can generate a token here: ${GITHUB_TOKEN_GENERATE_URL}`);
process.exit(1); process.exit(1);
} }

View File

@ -6,12 +6,11 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {prompt} from 'inquirer';
import {types as graphQLTypes} from 'typed-graphqlify'; import {types as graphQLTypes} from 'typed-graphqlify';
import {URL} from 'url'; import {URL} from 'url';
import {getConfig, NgDevConfig} from '../../utils/config'; import {getConfig, NgDevConfig} from '../../utils/config';
import {promptConfirm} from '../../utils/console'; import {error, info, promptConfirm} from '../../utils/console';
import {getCurrentBranch, hasLocalChanges} from '../../utils/git'; import {getCurrentBranch, hasLocalChanges} from '../../utils/git';
import {getPr} from '../../utils/github'; import {getPr} from '../../utils/github';
import {exec} from '../../utils/shelljs'; import {exec} from '../../utils/shelljs';
@ -45,7 +44,7 @@ export async function rebasePr(
prNumber: number, githubToken: string, config: Pick<NgDevConfig, 'github'> = getConfig()) { prNumber: number, githubToken: string, config: Pick<NgDevConfig, 'github'> = getConfig()) {
// TODO: Rely on a common assertNoLocalChanges function. // TODO: Rely on a common assertNoLocalChanges function.
if (hasLocalChanges()) { if (hasLocalChanges()) {
console.error('Cannot perform rebase of PR with local changes.'); error('Cannot perform rebase of PR with local changes.');
process.exit(1); process.exit(1);
} }
@ -65,7 +64,7 @@ export async function rebasePr(
// If the PR does not allow maintainers to modify it, exit as the rebased PR cannot // If the PR does not allow maintainers to modify it, exit as the rebased PR cannot
// be pushed up. // be pushed up.
if (!pr.maintainerCanModify && !pr.viewerDidAuthor) { if (!pr.maintainerCanModify && !pr.viewerDidAuthor) {
console.error( error(
`Cannot rebase as you did not author the PR and the PR does not allow maintainers` + `Cannot rebase as you did not author the PR and the PR does not allow maintainers` +
`to modify the PR`); `to modify the PR`);
process.exit(1); process.exit(1);
@ -73,51 +72,48 @@ export async function rebasePr(
try { try {
// Fetch the branch at the commit of the PR, and check it out in a detached state. // Fetch the branch at the commit of the PR, and check it out in a detached state.
console.info(`Checking out PR #${prNumber} from ${fullHeadRef}`); info(`Checking out PR #${prNumber} from ${fullHeadRef}`);
exec(`git fetch ${headRefUrl} ${pr.headRef.name}`); exec(`git fetch ${headRefUrl} ${pr.headRef.name}`);
exec(`git checkout --detach FETCH_HEAD`); exec(`git checkout --detach FETCH_HEAD`);
// Fetch the PRs target branch and rebase onto it. // Fetch the PRs target branch and rebase onto it.
console.info(`Fetching ${fullBaseRef} to rebase #${prNumber} on`); info(`Fetching ${fullBaseRef} to rebase #${prNumber} on`);
exec(`git fetch ${baseRefUrl} ${pr.baseRef.name}`); exec(`git fetch ${baseRefUrl} ${pr.baseRef.name}`);
console.info(`Attempting to rebase PR #${prNumber} on ${fullBaseRef}`); info(`Attempting to rebase PR #${prNumber} on ${fullBaseRef}`);
const rebaseResult = exec(`git rebase FETCH_HEAD`); const rebaseResult = exec(`git rebase FETCH_HEAD`);
// If the rebase was clean, push the rebased PR up to the authors fork. // If the rebase was clean, push the rebased PR up to the authors fork.
if (rebaseResult.code === 0) { if (rebaseResult.code === 0) {
console.info(`Rebase was able to complete automatically without conflicts`); info(`Rebase was able to complete automatically without conflicts`);
console.info(`Pushing rebased PR #${prNumber} to ${fullHeadRef}`); info(`Pushing rebased PR #${prNumber} to ${fullHeadRef}`);
exec(`git push ${baseRefUrl} HEAD:${pr.baseRef.name} --force-with-lease`); exec(`git push ${baseRefUrl} HEAD:${pr.baseRef.name} --force-with-lease`);
console.info(`Rebased and updated PR #${prNumber}`); info(`Rebased and updated PR #${prNumber}`);
cleanUpGitState(); cleanUpGitState();
process.exit(0); process.exit(0);
} }
} catch (err) { } catch (err) {
console.error(err.message); error(err.message);
cleanUpGitState(); cleanUpGitState();
process.exit(1); process.exit(1);
} }
// On automatic rebase failures, prompt to choose if the rebase should be continued // On automatic rebase failures, prompt to choose if the rebase should be continued
// manually or aborted now. // manually or aborted now.
console.info(`Rebase was unable to complete automatically without conflicts.`); info(`Rebase was unable to complete automatically without conflicts.`);
// If the command is run in a non-CI environment, prompt to format the files immediately. // If the command is run in a non-CI environment, prompt to format the files immediately.
const continueRebase = const continueRebase =
process.env['CI'] === undefined && await promptConfirm('Manually complete rebase?'); process.env['CI'] === undefined && await promptConfirm('Manually complete rebase?');
if (continueRebase) { if (continueRebase) {
console.info( info(`After manually completing rebase, run the following command to update PR #${prNumber}:`);
`After manually completing rebase, run the following command to update PR #${prNumber}:`); info(` $ git push ${pr.baseRef.repository.url} HEAD:${pr.baseRef.name} --force-with-lease`);
console.info( info();
` $ git push ${pr.baseRef.repository.url} HEAD:${pr.baseRef.name} --force-with-lease`); info(`To abort the rebase and return to the state of the repository before this command`);
console.info(); info(`run the following command:`);
console.info( info(` $ git rebase --abort && git reset --hard && git checkout ${originalBranch}`);
`To abort the rebase and return to the state of the repository before this command`);
console.info(`run the following command:`);
console.info(` $ git rebase --abort && git reset --hard && git checkout ${originalBranch}`);
process.exit(1); process.exit(1);
} else { } else {
console.info(`Cleaning up git state, and restoring previous state.`); info(`Cleaning up git state, and restoring previous state.`);
} }
cleanUpGitState(); cleanUpGitState();