use crate::get_azure_devops_cli_config;
use cloud_terrastodon_azure_devops_types::AzureDevOpsProjectName;
use cloud_terrastodon_command::CacheInvalidatable;
use cloud_terrastodon_command::async_trait;
use eyre::OptionExt;
use eyre::bail;
use std::pin::Pin;
#[must_use = "This is a future request, you must .await it"]
pub struct DefaultAzureDevOpsProjectNameRequest;
pub fn get_default_project_name() -> DefaultAzureDevOpsProjectNameRequest {
DefaultAzureDevOpsProjectNameRequest
}
#[async_trait]
impl CacheInvalidatable for DefaultAzureDevOpsProjectNameRequest {
async fn invalidate(&self) -> eyre::Result<()> {
get_azure_devops_cli_config().invalidate().await?;
Ok(())
}
}
impl IntoFuture for DefaultAzureDevOpsProjectNameRequest {
type Output = eyre::Result<AzureDevOpsProjectName>;
type IntoFuture = Pin<Box<dyn std::future::Future<Output = Self::Output> + Send>>;
fn into_future(self) -> Self::IntoFuture {
Box::pin(async move {
let config = get_azure_devops_cli_config().await?;
let project = config
.lines()
.find(|line| line.contains("project"))
.ok_or_eyre("Expected project to be configured using `az devops configure --defaults project=MyProject`")?;
let Some((_, project)) = project.split_once('=') else {
bail!("Expected project to have a slash before the name, found {project:?}");
};
let project = project.trim();
AzureDevOpsProjectName::try_new(project.to_string())
})
}
}
#[cfg(test)]
mod test {
use crate::get_default_project_name;
#[tokio::test]
pub async fn it_works() -> eyre::Result<()> {
let x = get_default_project_name().await?;
assert!(!format!("{x:?}").is_empty());
Ok(())
}
}