use colored::Colorize;
use std::collections::{BTreeMap, BTreeSet};
use crate::actions::{Action, DefinedAction, UsedAction};
use crate::bmap;
use crate::entities::custom_command::CustomCommand;
use crate::entities::info::ShortName;
use crate::entities::variables::Variable;
use crate::project::DeployerProjectOptions;
impl UsedAction {
pub fn prompt_setup_for_project(
&self,
variables: &BTreeMap<ShortName, Variable>,
definitions: &BTreeSet<DefinedAction>,
) -> anyhow::Result<Self> {
let defined = self.definition(definitions)?;
let used_action = match &defined.action {
Action::Custom(cmd) => cmd.prompt_setup_for_project(self, variables)?,
Action::Test(cmd) => cmd.prompt_setup_for_project(self, variables)?,
Action::Staged(cmd) => cmd.prompt_setup_for_project(self, variables)?,
Action::Observe(cmd) => cmd.prompt_setup_for_project(self, variables)?,
Action::Interrupt
| Action::Patch(_)
| Action::UseFromStorage { .. }
| Action::AddToStorage(_)
| Action::SyncToRemote { .. }
| Action::SyncFromRemote { .. } => self.clone(),
};
Ok(used_action)
}
}
impl CustomCommand {
pub fn prompt_setup_for_project(
&self,
used_action: &UsedAction,
variables: &BTreeMap<ShortName, Variable>,
) -> anyhow::Result<UsedAction> {
use inquire_reorder::Select;
let mut configured_action = UsedAction {
title: used_action.title.clone(),
used: used_action.used.clone(),
with: Default::default(),
};
let mut h = bmap!();
let mut k = vec![];
for short_name in variables.keys() {
let item = format!("Variable `{}`", short_name.as_str());
k.push(item.clone());
h.insert(item, short_name);
}
for required_substituion in &self.placeholders {
let selection = Select::new(
&format!(
"Select variable to replace `{}` in `{}` shell command (action `{}`{}):",
required_substituion.green().italic(),
self.cmd.green(),
used_action.used.to_str().blue(),
if let Some(title) = used_action.title.as_deref() {
format!(" - {}", title.blue())
} else {
String::new()
},
),
k.clone(),
)
.prompt_skippable()?;
if let Some(selection) = selection {
let selected = h.get(&selection).unwrap();
configured_action
.with
.insert(required_substituion.clone(), (*selected).clone());
}
}
for required_env in &self.env {
let selection = Select::new(
&format!(
"Select variable to pass as environmental `{}` to command `{}` (action `{}`{}):",
required_env.green().italic(),
self.cmd.green(),
used_action.used.to_str().blue(),
if let Some(title) = used_action.title.as_deref() {
format!(" - {}", title.blue())
} else {
String::new()
},
),
k.clone(),
)
.prompt_skippable()?;
if let Some(selection) = selection {
let selected = h.get(&selection).unwrap();
configured_action.with.insert(required_env.clone(), (*selected).clone());
}
}
Ok(configured_action)
}
}
pub fn specify_pipeline_short_name(config: &mut DeployerProjectOptions, short_name: &mut String) -> anyhow::Result<()> {
while config.pipelines.iter().any(|p| p.title.as_str() == short_name)
&& !inquire_reorder::Confirm::new(&format!(
"Do you want to overwrite an existing pipeline `{}` for this project? (y/n)",
short_name.as_str()
))
.prompt()?
{
*short_name = inquire_reorder::Text::new("Write the Pipeline's short name (only for this project) (or hit `esc`):")
.prompt_skippable()?
.ok_or_else(|| anyhow::anyhow!("Hitted Escape."))?;
}
Ok(())
}