added interactive mode (#44)
Co-authored-by: kjuulh <contact@kjuulh.io> Reviewed-on: #44
This commit is contained in:
parent
c00b3a97d2
commit
0dedf9268d
@ -66,6 +66,15 @@ pub fn execute_cmd() -> Command {
|
|||||||
.default_value("true")
|
.default_value("true")
|
||||||
.required(false),
|
.required(false),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("interactive")
|
||||||
|
.long("interactive")
|
||||||
|
.short('i')
|
||||||
|
.action(ArgAction::Set)
|
||||||
|
.env("OCTOPUSH_INTERACTIVE")
|
||||||
|
.default_value("false")
|
||||||
|
.required(false),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn execute_subcommand(args: &ArgMatches) -> eyre::Result<()> {
|
pub async fn execute_subcommand(args: &ArgMatches) -> eyre::Result<()> {
|
||||||
@ -84,6 +93,11 @@ pub async fn execute_subcommand(args: &ArgMatches) -> eyre::Result<()> {
|
|||||||
.ok_or(eyre::anyhow!("--dry-run is required"))?
|
.ok_or(eyre::anyhow!("--dry-run is required"))?
|
||||||
.parse()?;
|
.parse()?;
|
||||||
|
|
||||||
|
let interactive: bool = args
|
||||||
|
.get_one::<String>("interactive")
|
||||||
|
.ok_or(eyre::anyhow!("--interactive is required"))?
|
||||||
|
.parse()?;
|
||||||
|
|
||||||
if dryrun {
|
if dryrun {
|
||||||
tracing::info!("running in dry-run mode");
|
tracing::info!("running in dry-run mode");
|
||||||
}
|
}
|
||||||
@ -123,21 +137,21 @@ pub async fn execute_subcommand(args: &ArgMatches) -> eyre::Result<()> {
|
|||||||
if let Some(git) = &select.git {
|
if let Some(git) = &select.git {
|
||||||
service_register
|
service_register
|
||||||
.git_selector
|
.git_selector
|
||||||
.run(git, &action_path, &action, dryrun)
|
.run(git, &action_path, &action, dryrun, interactive)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(gitea) = &select.gitea {
|
if let Some(gitea) = &select.gitea {
|
||||||
service_register
|
service_register
|
||||||
.gitea_selector
|
.gitea_selector
|
||||||
.run(gitea, &action_path, &action, dryrun)
|
.run(gitea, &action_path, &action, dryrun, interactive)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(github) = &select.github {
|
if let Some(github) = &select.github {
|
||||||
service_register
|
service_register
|
||||||
.github_selector
|
.github_selector
|
||||||
.run(github, &action_path, &action, dryrun)
|
.run(github, &action_path, &action, dryrun, interactive)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,3 +5,4 @@ pub mod schema;
|
|||||||
pub mod selectors;
|
pub mod selectors;
|
||||||
mod shell;
|
mod shell;
|
||||||
pub mod storage;
|
pub mod storage;
|
||||||
|
pub mod ui;
|
||||||
|
@ -6,18 +6,21 @@ use crate::{
|
|||||||
executor::executor::DynExecutor,
|
executor::executor::DynExecutor,
|
||||||
git::DynGitProvider,
|
git::DynGitProvider,
|
||||||
schema::models::{Action, Git},
|
schema::models::{Action, Git},
|
||||||
|
ui::DynUI,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct GitSelector {
|
pub struct GitSelector {
|
||||||
git_provider: DynGitProvider,
|
git_provider: DynGitProvider,
|
||||||
executor: DynExecutor,
|
executor: DynExecutor,
|
||||||
|
ui: DynUI,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GitSelector {
|
impl GitSelector {
|
||||||
pub fn new(git_provider: DynGitProvider, executor: DynExecutor) -> Self {
|
pub fn new(git_provider: DynGitProvider, executor: DynExecutor, ui: DynUI) -> Self {
|
||||||
Self {
|
Self {
|
||||||
git_provider,
|
git_provider,
|
||||||
executor,
|
executor,
|
||||||
|
ui,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,6 +30,7 @@ impl GitSelector {
|
|||||||
action_path: &PathBuf,
|
action_path: &PathBuf,
|
||||||
action: &Action,
|
action: &Action,
|
||||||
dryrun: bool,
|
dryrun: bool,
|
||||||
|
interactive: bool,
|
||||||
) -> eyre::Result<()> {
|
) -> eyre::Result<()> {
|
||||||
tracing::info!("fetching repos");
|
tracing::info!("fetching repos");
|
||||||
for repo in &git.repositories {
|
for repo in &git.repositories {
|
||||||
@ -46,6 +50,10 @@ impl GitSelector {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if interactive {
|
||||||
|
self.ui.confirm().await?;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(push) = &git.push {
|
if let Some(push) = &git.push {
|
||||||
self.git_provider
|
self.git_provider
|
||||||
.push_branch(repo, &push.branch.name)
|
.push_branch(repo, &push.branch.name)
|
||||||
|
@ -6,12 +6,14 @@ use crate::{
|
|||||||
executor::executor::DynExecutor,
|
executor::executor::DynExecutor,
|
||||||
git::{gitea::DynGiteaProvider, DynGitProvider},
|
git::{gitea::DynGiteaProvider, DynGitProvider},
|
||||||
schema::models::{Action, Gitea},
|
schema::models::{Action, Gitea},
|
||||||
|
ui::DynUI,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct GiteaSelector {
|
pub struct GiteaSelector {
|
||||||
gitea_provider: DynGiteaProvider,
|
gitea_provider: DynGiteaProvider,
|
||||||
git_provider: DynGitProvider,
|
git_provider: DynGitProvider,
|
||||||
executor: DynExecutor,
|
executor: DynExecutor,
|
||||||
|
ui: DynUI,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GiteaSelector {
|
impl GiteaSelector {
|
||||||
@ -19,11 +21,13 @@ impl GiteaSelector {
|
|||||||
gitea_provider: DynGiteaProvider,
|
gitea_provider: DynGiteaProvider,
|
||||||
git_provider: DynGitProvider,
|
git_provider: DynGitProvider,
|
||||||
executor: DynExecutor,
|
executor: DynExecutor,
|
||||||
|
ui: DynUI,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
gitea_provider,
|
gitea_provider,
|
||||||
git_provider,
|
git_provider,
|
||||||
executor,
|
executor,
|
||||||
|
ui,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +37,7 @@ impl GiteaSelector {
|
|||||||
action_path: &PathBuf,
|
action_path: &PathBuf,
|
||||||
action: &Action,
|
action: &Action,
|
||||||
dryrun: bool,
|
dryrun: bool,
|
||||||
|
interactive: bool,
|
||||||
) -> eyre::Result<()> {
|
) -> eyre::Result<()> {
|
||||||
tracing::info!("fetching repos");
|
tracing::info!("fetching repos");
|
||||||
for repo in &git.repositories {
|
for repo in &git.repositories {
|
||||||
@ -52,6 +57,10 @@ impl GiteaSelector {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if interactive {
|
||||||
|
self.ui.confirm().await?;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(push) = &git.push {
|
if let Some(push) = &git.push {
|
||||||
self.git_provider
|
self.git_provider
|
||||||
.push_branch(repo, &push.pull_request.name)
|
.push_branch(repo, &push.pull_request.name)
|
||||||
|
@ -6,12 +6,14 @@ use crate::{
|
|||||||
executor::executor::DynExecutor,
|
executor::executor::DynExecutor,
|
||||||
git::{github::DynGitHubProvider, DynGitProvider},
|
git::{github::DynGitHubProvider, DynGitProvider},
|
||||||
schema::models::{Action, GitHub},
|
schema::models::{Action, GitHub},
|
||||||
|
ui::DynUI,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct GitHubSelector {
|
pub struct GitHubSelector {
|
||||||
github_provider: DynGitHubProvider,
|
github_provider: DynGitHubProvider,
|
||||||
git_provider: DynGitProvider,
|
git_provider: DynGitProvider,
|
||||||
executor: DynExecutor,
|
executor: DynExecutor,
|
||||||
|
ui: DynUI,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GitHubSelector {
|
impl GitHubSelector {
|
||||||
@ -19,11 +21,13 @@ impl GitHubSelector {
|
|||||||
github_provider: DynGitHubProvider,
|
github_provider: DynGitHubProvider,
|
||||||
git_provider: DynGitProvider,
|
git_provider: DynGitProvider,
|
||||||
executor: DynExecutor,
|
executor: DynExecutor,
|
||||||
|
ui: DynUI,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
github_provider,
|
github_provider,
|
||||||
git_provider,
|
git_provider,
|
||||||
executor,
|
executor,
|
||||||
|
ui,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +37,7 @@ impl GitHubSelector {
|
|||||||
action_path: &PathBuf,
|
action_path: &PathBuf,
|
||||||
action: &Action,
|
action: &Action,
|
||||||
dryrun: bool,
|
dryrun: bool,
|
||||||
|
interactive: bool,
|
||||||
) -> eyre::Result<()> {
|
) -> eyre::Result<()> {
|
||||||
tracing::info!("fetching repos");
|
tracing::info!("fetching repos");
|
||||||
for repo in &git.repositories {
|
for repo in &git.repositories {
|
||||||
@ -52,6 +57,10 @@ impl GitHubSelector {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if interactive {
|
||||||
|
self.ui.confirm().await?;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(push) = &git.push {
|
if let Some(push) = &git.push {
|
||||||
self.git_provider
|
self.git_provider
|
||||||
.push_branch(repo, &push.pull_request.name)
|
.push_branch(repo, &push.pull_request.name)
|
||||||
|
12
crates/octopush_core/src/ui/mod.rs
Normal file
12
crates/octopush_core/src/ui/mod.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
pub mod terminal_ui;
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
pub trait UI {
|
||||||
|
async fn confirm(&self) -> eyre::Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type DynUI = Arc<dyn UI + Send + Sync>;
|
47
crates/octopush_core/src/ui/terminal_ui.rs
Normal file
47
crates/octopush_core/src/ui/terminal_ui.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
use std::{
|
||||||
|
io::{self, Write},
|
||||||
|
process::exit,
|
||||||
|
};
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
|
||||||
|
use super::UI;
|
||||||
|
|
||||||
|
pub struct TerminalUI {}
|
||||||
|
|
||||||
|
impl TerminalUI {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn query_console(&self) -> eyre::Result<()> {
|
||||||
|
print!("Continue? ([Y]es/[N]o): ");
|
||||||
|
std::io::stdout().lock().flush()?;
|
||||||
|
let mut input = String::new();
|
||||||
|
let _ = io::stdin().read_line(&mut input)?;
|
||||||
|
|
||||||
|
if input.to_lowercase().starts_with("y") {
|
||||||
|
return Ok(());
|
||||||
|
} else if input.to_lowercase().starts_with("n") {
|
||||||
|
exit(0)
|
||||||
|
} else {
|
||||||
|
Err(eyre::anyhow!("input not valid"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl UI for TerminalUI {
|
||||||
|
async fn confirm(&self) -> eyre::Result<()> {
|
||||||
|
match self.query_console().await {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(e) => {
|
||||||
|
if e.to_string().starts_with("input not valid") {
|
||||||
|
self.query_console().await
|
||||||
|
} else {
|
||||||
|
Err(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -22,6 +22,7 @@ use octopush_core::{
|
|||||||
git_selector::GitSelector, gitea_selector::GiteaSelector, github_selector::GitHubSelector,
|
git_selector::GitSelector, gitea_selector::GiteaSelector, github_selector::GitHubSelector,
|
||||||
},
|
},
|
||||||
storage::{local::LocalStorageEngine, DynStorageEngine},
|
storage::{local::LocalStorageEngine, DynStorageEngine},
|
||||||
|
ui::{terminal_ui::TerminalUI, DynUI},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct ServiceRegister {
|
pub struct ServiceRegister {
|
||||||
@ -35,6 +36,7 @@ pub struct ServiceRegister {
|
|||||||
pub gitea_selector: Arc<GiteaSelector>,
|
pub gitea_selector: Arc<GiteaSelector>,
|
||||||
pub github_provider: DynGitHubProvider,
|
pub github_provider: DynGitHubProvider,
|
||||||
pub github_selector: Arc<GitHubSelector>,
|
pub github_selector: Arc<GitHubSelector>,
|
||||||
|
pub ui: DynUI,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServiceRegister {
|
impl ServiceRegister {
|
||||||
@ -57,11 +59,19 @@ impl ServiceRegister {
|
|||||||
storage_engine.clone(),
|
storage_engine.clone(),
|
||||||
gitea_client.clone(),
|
gitea_client.clone(),
|
||||||
));
|
));
|
||||||
let git_selector = Arc::new(GitSelector::new(git_provider.clone(), executor.clone()));
|
|
||||||
|
let ui = Arc::new(TerminalUI::new());
|
||||||
|
|
||||||
|
let git_selector = Arc::new(GitSelector::new(
|
||||||
|
git_provider.clone(),
|
||||||
|
executor.clone(),
|
||||||
|
ui.clone(),
|
||||||
|
));
|
||||||
let gitea_selector = Arc::new(GiteaSelector::new(
|
let gitea_selector = Arc::new(GiteaSelector::new(
|
||||||
gitea_provider.clone(),
|
gitea_provider.clone(),
|
||||||
git_provider.clone(),
|
git_provider.clone(),
|
||||||
executor.clone(),
|
executor.clone(),
|
||||||
|
ui.clone(),
|
||||||
));
|
));
|
||||||
let github_client = Arc::new(DefaultGitHubClient::new(&github_client_options)?);
|
let github_client = Arc::new(DefaultGitHubClient::new(&github_client_options)?);
|
||||||
let github_provider = Arc::new(DefaultGitHubProvider::new(
|
let github_provider = Arc::new(DefaultGitHubProvider::new(
|
||||||
@ -73,6 +83,7 @@ impl ServiceRegister {
|
|||||||
github_provider.clone(),
|
github_provider.clone(),
|
||||||
git_provider.clone(),
|
git_provider.clone(),
|
||||||
executor.clone(),
|
executor.clone(),
|
||||||
|
ui.clone(),
|
||||||
));
|
));
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@ -86,6 +97,7 @@ impl ServiceRegister {
|
|||||||
gitea_selector,
|
gitea_selector,
|
||||||
github_provider,
|
github_provider,
|
||||||
github_selector,
|
github_selector,
|
||||||
|
ui,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user