80 lines
2.1 KiB
Rust
80 lines
2.1 KiB
Rust
use anyhow::Result;
|
|
use axum::http::StatusCode;
|
|
use futures_util::future::try_join;
|
|
use std::path::{Path, PathBuf};
|
|
use tempfile::tempdir;
|
|
use tokio::fs;
|
|
|
|
use crate::{
|
|
git::ThreadSafeRepository,
|
|
http::error::AppError,
|
|
node::{error::StackError, nix::parse_arion_compose},
|
|
};
|
|
|
|
use super::{arion, utils, FileList, COMPOSE_FILE, PACKAGE_CONTENTS, PACKAGE_FILE};
|
|
|
|
pub async fn get(base_dir: &Path, stack_name: &str) -> Result<String> {
|
|
let dir = base_dir.join(stack_name);
|
|
if !utils::is_stack(&dir).await? {
|
|
return Err(StackError::NotFound.into());
|
|
}
|
|
|
|
let contents = tokio::fs::read_to_string(dir.join(COMPOSE_FILE)).await?;
|
|
Ok(contents)
|
|
}
|
|
|
|
pub fn commit(
|
|
repository: ThreadSafeRepository,
|
|
stack_name: &str,
|
|
files: &FileList,
|
|
message: &str,
|
|
) -> Result<()> {
|
|
repository.commit_files(
|
|
&files
|
|
.keys()
|
|
.map(|key| PathBuf::from(format!("{}/{}", stack_name, key)))
|
|
.collect::<Vec<_>>(),
|
|
message,
|
|
)?;
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn check(arion_bin: &Path, source: &str) -> crate::http::error::Result<String> {
|
|
// Check that it's a valid nix tree
|
|
let info = parse_arion_compose(source).map_err(|err| AppError::Client {
|
|
status: StatusCode::NOT_ACCEPTABLE,
|
|
code: "failed-nix-parse",
|
|
message: format!("Parse error: {}", err),
|
|
})?;
|
|
|
|
// Create a temporary stack and check that it generates a YAML tree
|
|
let dir = tempdir()?;
|
|
let path = dir.path();
|
|
|
|
// Create package file and compose file
|
|
try_join(
|
|
fs::write(path.join(PACKAGE_FILE), PACKAGE_CONTENTS),
|
|
fs::write(path.join(COMPOSE_FILE), source),
|
|
)
|
|
.await?;
|
|
|
|
let cmd = arion::run(arion_bin, path, arion::StackCommand::Test).await?;
|
|
|
|
dir.close()?;
|
|
|
|
if let arion::CommandStatus::Failure(_, err) = cmd {
|
|
Err(AppError::Client {
|
|
status: StatusCode::NOT_ACCEPTABLE,
|
|
code: "failed-arion-check",
|
|
message: format!("Arion {}", err),
|
|
})
|
|
} else {
|
|
Ok(info.project)
|
|
}
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub fn path(stack_name: &str) -> PathBuf {
|
|
format!("{}/{}", stack_name, COMPOSE_FILE).into()
|
|
}
|