From d669ecce55970c9b55f4fd417cca6480596f8e8e Mon Sep 17 00:00:00 2001 From: Matheus Marchini Date: Tue, 1 Oct 2019 09:22:55 -0700 Subject: [PATCH] land: add non-interactive mode Non-interactive mode will try to land a Pull Request without asking any questions. This is meant to be used by scripts and CI landing tools. --- components/git/land.js | 10 ++++++++++ docs/git-node.md | 5 +++++ lib/cli.js | 8 ++++++++ lib/landing_session.js | 14 ++++++++++---- test/unit/cli.test.js | 20 ++++++++++++++++++++ 5 files changed, 53 insertions(+), 4 deletions(-) diff --git a/components/git/land.js b/components/git/land.js index 465ec7c0..dc6aa9df 100644 --- a/components/git/land.js +++ b/components/git/land.js @@ -30,6 +30,13 @@ const landOptions = { abort: { describe: 'Abort the current landing session', type: 'boolean' + }, + yes: { + type: 'boolean', + default: false, + describe: 'Assume "yes" as answer to all prompts and run ' + + 'non-interactively. If an undesirable situation occurs, such as a pull ' + + 'request or commit check fails, then git node land will abort.' } }; @@ -93,6 +100,9 @@ function handler(argv) { function land(state, argv) { const cli = new CLI(process.stderr); + if (argv.yes) { + cli.setAssumeYes(); + } const req = new Request(); const dir = process.cwd(); diff --git a/docs/git-node.md b/docs/git-node.md index 69b5b3c6..c0e8879c 100644 --- a/docs/git-node.md +++ b/docs/git-node.md @@ -40,6 +40,11 @@ Options: --continue, -c Continue the landing session [boolean] --final Verify the landed PR and clean up [boolean] --abort Abort the current landing session [boolean] + --yes Assume "yes" as answer to all prompts and run + non-interactively. If an undesirable situation occurs, such as + a pull request or commit check fails, then git node land will + abort. [boolean] [default: false] + Examples: git node land 12344 Land https://github.com/nodejs/node/pull/12344 in diff --git a/lib/cli.js b/lib/cli.js index 165771f8..3d134a89 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -24,6 +24,7 @@ class CLI { this.spinner = ora({ stream: this.stream }); this.SPINNER_STATUS = SPINNER_STATUS; this.figureIndent = ' '; + this.assumeYes = false; } get eolIndent() { @@ -36,6 +37,9 @@ class CLI { async prompt(question, defaultAnswer = true) { this.separator(); + if (this.assumeYes) { + return defaultAnswer; + } const { answer } = await inquirer.prompt([{ type: 'confirm', name: 'answer', @@ -45,6 +49,10 @@ class CLI { return answer; } + setAssumeYes() { + this.assumeYes = true; + } + startSpinner(text) { this.spinner.text = text; this.spinner.start(); diff --git a/lib/landing_session.js b/lib/landing_session.js index eb2315f4..bf0b97f5 100644 --- a/lib/landing_session.js +++ b/lib/landing_session.js @@ -22,10 +22,14 @@ class LandingSession extends Session { const { cli } = this; this.startLanding(); 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 + // metadata check. + const defaultAnswer = !cli.assumeYes ? true : metadata.status; const shouldContinue = await cli.prompt( - `This PR ${status} to land, do you want to continue?`); + `This PR ${status} to land, do you want to continue?`, defaultAnswer); if (!shouldContinue) { - return this.abort(); + return this.abort(false); } this.saveMetadata(metadata); @@ -33,10 +37,12 @@ class LandingSession extends Session { return this.apply(); } - async abort() { + async abort(tryResetBranch = true) { const { cli } = this; this.cleanFiles(); - await this.tryResetBranch(); + if (tryResetBranch) { + await this.tryResetBranch(); + } cli.ok(`Aborted \`git node land\` session in ${this.ncuDir}`); } diff --git a/test/unit/cli.test.js b/test/unit/cli.test.js index 21160b8a..7f1f3a99 100644 --- a/test/unit/cli.test.js +++ b/test/unit/cli.test.js @@ -165,4 +165,24 @@ describe('cli', () => { }); }); }); + + describe('prompt assume yes', () => { + beforeEach(() => { + stream = new LogStream(); + cli = new CLI(stream); + cli.setAssumeYes(); + }); + + it('should return true if no default is given', async() => { + assert.strictEqual(await cli.prompt('Question?'), true); + }); + + it('should return true if default is set to true', async() => { + assert.strictEqual(await cli.prompt('Question?', true), true); + }); + + it('should return false if default is set to false', async() => { + assert.strictEqual(await cli.prompt('Question?', false), false); + }); + }); });