Skip to content
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

feat: Add confirm step type #978

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion crates/knope/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,17 @@ pub fn run() -> Result<()> {
RunType::Real(state)
};

workflow::run(workflow, state)?;
let assume_yes = matches.get_flag("assumeyes");

workflow::run(workflow, state, assume_yes)?;
Ok(())
}

const OVERRIDE_ONE_VERSION: &str = "override-one-version";
const OVERRIDE_MULTIPLE_VERSIONS: &str = "override-multiple-versions";
const PRERELEASE_LABEL: &str = "prerelease-label";
const VERBOSE: &str = "verbose";
const ASSUMEYES: &str = "assumeyes";

fn build_cli(config: &ConfigSource) -> Command {
let mut command = command!()
Expand All @@ -113,6 +116,11 @@ fn build_cli(config: &ConfigSource) -> Command {
.help("Pretend to run a workflow, outputting what _would_ happen without actually doing it.")
.action(ArgAction::SetTrue)
.global(true)
).arg(
Arg::new(ASSUMEYES).long(ASSUMEYES).short('y')
.help("Automatic yes to prompts. Assume \"yes\" as answer to all prompts and run non-interactively.")
.action(ArgAction::SetTrue)
.global(true)
).arg(
Arg::new(VERBOSE).long(VERBOSE).short('v')
.help("Print extra information (for debugging)")
Expand Down Expand Up @@ -157,10 +165,12 @@ fn build_cli(config: &ConfigSource) -> Command {
.steps
.iter()
.any(|step| matches!(*step, Step::BumpVersion(_)));

let contains_prepare_release = workflow
.steps
.iter()
.any(|step| matches!(*step, Step::PrepareRelease(_)));

if contains_bump_version || contains_prepare_release {
if let Some(arg) = version_override_arg.clone() {
subcommand = subcommand.arg(arg);
Expand Down
9 changes: 8 additions & 1 deletion crates/knope/src/prompt.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fmt::Display;

use inquire::{InquireError, Password, Select};
use inquire::{Confirm, InquireError, Password, Select};
use miette::{Diagnostic, Result};

pub(crate) fn select<T: Display>(items: Vec<T>, prompt: &str) -> Result<T, Error> {
Expand All @@ -15,6 +15,13 @@ pub(crate) fn get_input(prompt: &str) -> Result<String, Error> {
.map_err(Error)
}

pub(crate) fn confirm(prompt: &str) -> Result<bool, Error> {
Confirm::new(prompt)
.with_default(true)
.prompt()
.map_err(Error)
}

#[derive(Debug, Diagnostic, thiserror::Error)]
#[error("Failed to get user input")]
#[diagnostic(
Expand Down
41 changes: 41 additions & 0 deletions crates/knope/src/step/confirm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use miette::Diagnostic;

use crate::{prompt, RunType};

pub(crate) fn confirm(
mut run_type: RunType,
message: &str,
assume_yes: bool,
) -> Result<RunType, Error> {
if assume_yes {
return Ok(run_type);
}
let (_, dry_run_stdout) = match &mut run_type {
RunType::DryRun { state, stdout } => (state, Some(stdout)),
RunType::Real(state) => (state, None),
};

if let Some(stdout) = dry_run_stdout {
writeln!(stdout, "Would prompt for the following message {message}")?;
return Ok(run_type);
}

let confirmation = prompt::confirm(message)?;

if confirmation {
Ok(run_type)
} else {
Err(Error::Confirm)
}
}

#[derive(Debug, Diagnostic, thiserror::Error)]
pub(crate) enum Error {
#[error("User did not confirm")]
Confirm,
#[error("Unable to write to stdout: {0}")]
Stdout(#[from] std::io::Error),
#[error(transparent)]
#[diagnostic(transparent)]
Prompt(#[from] prompt::Error),
}
9 changes: 8 additions & 1 deletion crates/knope/src/step/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::{
};

pub mod command;
pub mod confirm;
mod create_pull_request;
pub mod issues;
pub mod releases;
Expand Down Expand Up @@ -95,10 +96,12 @@ pub(crate) enum Step {
title: Template,
body: Template,
},
/// Prompt the user to confirm the next step.
Confirm { message: String },
}

impl Step {
pub(crate) fn run(self, run_type: RunType) -> Result<RunType, Error> {
pub(crate) fn run(self, run_type: RunType, assume_yes: bool) -> Result<RunType, Error> {
Ok(match self {
Step::SelectJiraIssue { status } => issues::jira::select_issue(&status, run_type)?,
Step::TransitionJiraIssue { status } => {
Expand Down Expand Up @@ -127,6 +130,7 @@ impl Step {
Step::CreatePullRequest { base, title, body } => {
create_pull_request::run(&base, title, body, run_type)?
}
Step::Confirm { message } => confirm::confirm(run_type, message.as_str(), assume_yes)?,
})
}

Expand Down Expand Up @@ -167,6 +171,9 @@ pub(super) enum Error {
#[error(transparent)]
#[diagnostic(transparent)]
CreatePullRequest(#[from] create_pull_request::Error),
#[error(transparent)]
#[diagnostic(transparent)]
Confirm(#[from] confirm::Error),
}

/// The inner content of a [`Step::PrepareRelease`] step.
Expand Down
5 changes: 3 additions & 2 deletions crates/knope/src/workflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ pub struct Error {
}

/// Run a series of [`Step`], each of which updates `state`.
pub(crate) fn run(workflow: Workflow, mut state: RunType) -> Result<(), Error> {
pub(crate) fn run(workflow: Workflow, mut state: RunType, assume_yes: bool) -> Result<(), Error> {
for step in workflow.steps {
state = match step.run(state) {
state = match step.run(state, assume_yes) {
Ok(state) => state,
Err(err) => {
return Err(Error {
Expand All @@ -90,6 +90,7 @@ pub(crate) fn validate(
state: state.clone(),
stdout: Box::new(sink()),
},
false,
)
.err()
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
Usage: knope[EXE] document-change [OPTIONS]

Options:
--dry-run Pretend to run a workflow, outputting what _would_ happen without actually doing it.
-v, --verbose Print extra information (for debugging)
-h, --help Print help
-V, --version Print version
--dry-run Pretend to run a workflow, outputting what _would_ happen without actually doing it.
-y, --assumeyes Automatic yes to prompts. Assume "yes" as answer to all prompts and run non-interactively.
-v, --verbose Print extra information (for debugging)
-h, --help Print help
-V, --version Print version
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Options:
Override the version set by `BumpVersion` or `PrepareRelease` for multiple packages. Format is like package_name=version, can be set multiple times.
--prerelease-label <prerelease-label>
Set the `prerelease_label` attribute of any `PrepareRelease` steps at runtime. [env: KNOPE_PRERELEASE_LABEL=]
-y, --assumeyes
Automatic yes to prompts. Assume "yes" as answer to all prompts and run non-interactively.
-v, --verbose
Print extra information (for debugging)
-h, --help
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Options:
Override the version set by `BumpVersion` or `PrepareRelease` for the package.
--prerelease-label <prerelease-label>
Set the `prerelease_label` attribute of any `PrepareRelease` steps at runtime. [env: KNOPE_PRERELEASE_LABEL=]
-y, --assumeyes
Automatic yes to prompts. Assume "yes" as answer to all prompts and run non-interactively.
-v, --verbose
Print extra information (for debugging)
-h, --help
Expand Down
26 changes: 26 additions & 0 deletions docs/src/content/docs/reference/Config File/Steps/confirm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: Confirm
---

Prompt the user to confirm a given message. Approving the prompt will continue to run the workflow.
Rejecting the prompt will stop the workflow and no further steps will be run.

Check warning on line 6 in docs/src/content/docs/reference/Config File/Steps/confirm.md

View workflow job for this annotation

GitHub Actions / Vale

[vale] reported by reviewdog 🐶 [Microsoft.Passive] 'be run' looks like passive voice. Raw Output: {"message": "[Microsoft.Passive] 'be run' looks like passive voice.", "location": {"path": "docs/src/content/docs/reference/Config File/Steps/confirm.md", "range": {"start": {"line": 6, "column": 71}}}, "severity": "INFO"}

## Example

```toml
[[workflows.steps]]
type = "Confirm"
message = "Are you sure you want to run the cleanup step?"
```

The example workflow above will promp the user with the following message:

Check warning on line 16 in docs/src/content/docs/reference/Config File/Steps/confirm.md

View workflow job for this annotation

GitHub Actions / Vale

[vale] reported by reviewdog 🐶 [Microsoft.Vocab] Verify your use of 'above' with the A-Z word list. Raw Output: {"message": "[Microsoft.Vocab] Verify your use of 'above' with the A-Z word list.", "location": {"path": "docs/src/content/docs/reference/Config File/Steps/confirm.md", "range": {"start": {"line": 16, "column": 22}}}, "severity": "INFO"}

Check failure on line 16 in docs/src/content/docs/reference/Config File/Steps/confirm.md

View workflow job for this annotation

GitHub Actions / Vale

[vale] reported by reviewdog 🐶 [Vale.Spelling] Did you really mean 'promp'? Raw Output: {"message": "[Vale.Spelling] Did you really mean 'promp'?", "location": {"path": "docs/src/content/docs/reference/Config File/Steps/confirm.md", "range": {"start": {"line": 16, "column": 33}}}, "severity": "ERROR"}

```shell

? Are you sure you want to run the cleanup step? (Y/n)

```

## Automatic confirmation

If you want to automatically confirm all steps in a workflow, you can run the workflow with either the `--assumeyes` or `-y` flag.
4 changes: 4 additions & 0 deletions docs/src/content/docs/reference/command-line-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,7 @@

[`BumpVersion`]: /reference/config-file/steps/bump-version
[`PrepareRelease`]: /reference/config-file/steps/prepare-release

### `--assumeyes`

Automatically answer all confirmation steps with a "yes". See [`Confirm`](/reference/config-file/steps/confirm/) for more information about the `Confirm` step type.

Check failure on line 77 in docs/src/content/docs/reference/command-line-arguments.md

View workflow job for this annotation

GitHub Actions / Vale

[vale] reported by reviewdog 🐶 [Microsoft.Quotes] Punctuation should be inside the quotes. Raw Output: {"message": "[Microsoft.Quotes] Punctuation should be inside the quotes.", "location": {"path": "docs/src/content/docs/reference/command-line-arguments.md", "range": {"start": {"line": 77, "column": 52}}}, "severity": "ERROR"}