cuddle-v2/crates/cuddle-actions/src/lib.rs

102 lines
3.2 KiB
Rust
Raw Normal View History

use std::path::{Path, PathBuf};
use cuddle_actions_api::ExecutableActions;
use cuddle_rust_actions::RustActionsBuilder;
use cuddle_value::Value;
pub struct Actions {
variants: Vec<ActionVariant>,
}
impl Actions {
pub async fn new(path: &Path, value: &Value) -> anyhow::Result<Option<Self>> {
let Some(project) = value.get(&["project", "actions"]) else {
tracing::debug!("found no actions folder");
return Ok(None);
};
let mut variants = Vec::default();
if let Some(Value::Bool(true)) = project.get(&["rust"]) {
tracing::debug!("rust actions enabled");
variants.push(ActionVariant::Rust {
root_path: path.to_path_buf(),
});
} else {
tracing::trace!("rust actions not enabled");
}
Ok(Some(Self { variants }))
}
pub async fn build(&mut self) -> anyhow::Result<ExecutableActions> {
let mut executable_actions = Vec::default();
self.clean_cache().await?;
for variant in &mut self.variants {
match variant {
ActionVariant::Rust { root_path } => {
let actions = RustActionsBuilder::new(root_path.clone()).build().await?;
executable_actions.push(actions);
}
ActionVariant::Docker => todo!(),
}
}
let mut exec_actions = ExecutableActions::default();
for mut actions in executable_actions {
exec_actions.actions.append(&mut actions.actions);
}
Ok(exec_actions)
}
fn global_registry(&self) -> anyhow::Result<Option<PathBuf>> {
if let Some(dir) = dirs::cache_dir().map(|c| c.join("sh.cuddle/registry/actions/rust")) {
if !dir.exists() {
std::fs::create_dir_all(&dir)?;
}
Ok(Some(dir))
} else {
Ok(None)
}
}
/// clean_cache checks whether a given function has been used in the last month, if it hasn't it is automatically removed, and potentially reconstructed again on demand
pub async fn clean_cache(&mut self) -> anyhow::Result<()> {
let now = std::time::SystemTime::now();
let mut file_stream = tokio::fs::read_dir(
self.global_registry()?
.ok_or(anyhow::anyhow!("failed to get global registry"))?,
)
.await?;
while let Ok(Some(entry)) = file_stream.next_entry().await {
tracing::trace!("checking file: {}", entry.path().display());
let metadata = entry.metadata().await?;
if metadata.is_dir() {
let modified = metadata.modified()?;
let cache_threshold = now
.checked_sub(std::time::Duration::from_secs(60 * 24 * 30)) // Cache duration is a month
.expect("to be able to have a systemtime above a week");
if modified < cache_threshold {
tracing::debug!("cleaning up entry: {}", entry.path().display());
tokio::fs::remove_dir_all(entry.path()).await?;
}
}
}
Ok(())
}
}
pub enum ActionVariant {
Rust { root_path: PathBuf },
Docker,
}