feat: make sure dir is there as well

Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
2024-01-28 16:41:50 +01:00
parent cc7aaf14eb
commit 85cc1d46db
15 changed files with 1153 additions and 447 deletions

View File

@@ -78,7 +78,7 @@ impl CuddleAction {
log::trace!("preparing to run action");
return match ShellAction::new(
match ShellAction::new(
self.name.clone(),
format!(
"{}/scripts/{}.sh",
@@ -98,7 +98,7 @@ impl CuddleAction {
log::error!("{}", e);
Err(e)
}
};
}
}
CuddleScript::Dagger(_d) => Err(anyhow::anyhow!("not implemented yet!")),
CuddleScript::Lua(l) => {
@@ -183,6 +183,184 @@ impl CuddleAction {
Ok(())
}
CuddleScript::Rust(script) => Ok(()),
}
}
}
pub mod rust_action {
use std::{path::PathBuf, time::Duration};
use anyhow::Context;
use futures_util::StreamExt;
use reqwest::Method;
use tokio::{fs::File, io::AsyncWriteExt};
use crate::model::{CuddleRustScript, CuddleRustUpstream, CuddleVariable};
pub struct RustActionConfig {
pub config_dir: PathBuf,
pub cache_dir: PathBuf,
}
impl Default for RustActionConfig {
fn default() -> Self {
let config = dirs::config_dir().expect("to be able to find a valid .config dir");
let cache = dirs::cache_dir().expect("to be able to find a valid .cache dir");
Self {
config_dir: config,
cache_dir: cache,
}
}
}
pub struct RustAction {
pub config: RustActionConfig,
pub plan: String,
pub binary_name: String,
}
impl RustAction {
pub fn new(plan: String, binary_name: String) -> Self {
Self {
plan,
binary_name,
config: RustActionConfig::default(),
}
}
pub async fn execute(
&self,
script: CuddleRustScript,
variables: impl IntoIterator<Item = CuddleVariable>,
) -> anyhow::Result<()> {
let commit_sha = self
.get_commit_sha()
.await
.context("failed to find a valid commit sha on the inferred path: .cuddle/plan")?;
let binary_hash = self.calculate_hash(commit_sha)?;
// Get cached binary
// let binary = match self.get_binary(&binary_hash).await? {
// Some(binary) => binary,
// None => self.fetch_binary(&script, &binary_hash).await?,
// };
// Execute binary
Ok(())
}
async fn get_binary(
&self,
binary_hash: impl Into<String>,
) -> anyhow::Result<Option<RustBinary>> {
let binary_path = self.get_cached_binary_path(binary_hash);
if !binary_path.exists() {
return Ok(None);
}
Ok(Some(RustBinary {}))
}
fn get_cached_binary_path(&self, binary_hash: impl Into<String>) -> PathBuf {
let cached_binary_name = self.get_cached_binary_name(binary_hash);
let binary_path = self
.config
.cache_dir
.join("binaries")
.join(cached_binary_name);
binary_path
}
#[inline]
fn get_cached_binary_name(&self, binary_hash: impl Into<String>) -> String {
format!("{}-{}", binary_hash.into(), self.binary_name)
}
async fn get_commit_sha(&self) -> anyhow::Result<String> {
let repo = git2::Repository::open(".cuddle/plan")?;
let head = repo.head()?;
let commit = head.peel_to_commit()?;
let commit_sha = commit.id();
Ok(commit_sha.to_string())
}
// async fn fetch_binary(
// &self,
// script: &CuddleRustScript,
// binary_hash: impl Into<String>,
// ) -> anyhow::Result<RustBinary> {
//let upstream = &script.upstream;
//TODO: we should interpret some template variables in the upstream string. Ignore for now though
// match UpstreamRustBinary::from(upstream) {
// UpstreamRustBinary::HttpBased { url } => {
// let client = reqwest::ClientBuilder::new()
// .user_agent(concat!(
// env!("CARGO_PKG_NAME"),
// "/",
// env!("CARGO_PKG_VERSION")
// ))
// .connect_timeout(Duration::from_secs(5))
// .build()?;
// let resp = client.request(Method::GET, url).send().await?;
// let mut stream = resp.bytes_stream();
// let mut file = File::create(self.get_cached_binary_name(binary_hash)).await?;
// while let Some(item) = stream.next().await {
// let chunk = item?;
// file.write_all(&chunk).await?;
// }
// // Make sure the entire file is written before we execute it
// file.flush().await?;
// todo!()
// }
// }
// }
fn calculate_hash(&self, commit_sha: impl Into<Vec<u8>>) -> anyhow::Result<String> {
let mut contents: Vec<u8> = Vec::new();
contents.append(&mut self.plan.clone().into_bytes());
contents.append(&mut commit_sha.into());
let hash = blake3::hash(&contents);
let hex = hash.to_hex();
Ok(hex.to_string())
}
}
pub struct RustBinary {}
pub enum UpstreamRustBinary {
HttpBased { url: String },
}
impl From<CuddleRustUpstream> for UpstreamRustBinary {
fn from(value: CuddleRustUpstream) -> Self {
match value {
CuddleRustUpstream::Gitea { url } => Self::HttpBased { url },
}
}
}
impl From<&CuddleRustUpstream> for UpstreamRustBinary {
fn from(value: &CuddleRustUpstream) -> Self {
match value {
CuddleRustUpstream::Gitea { url } => Self::HttpBased { url: url.clone() },
}
}
}
}