102 lines
3.2 KiB
Rust
102 lines
3.2 KiB
Rust
|
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,
|
||
|
}
|