78 lines
2.1 KiB
Rust
78 lines
2.1 KiB
Rust
use axum::{
|
|
extract::{Multipart, Path, State},
|
|
http::StatusCode,
|
|
response::Redirect,
|
|
};
|
|
|
|
use crate::{
|
|
http::error::{AppError, Result},
|
|
stack::{self, arion, compose, FileList, COMPOSE_FILE},
|
|
AppState,
|
|
};
|
|
|
|
pub(super) async fn edit_stack(
|
|
Path(stack_name): Path<String>,
|
|
State(state): State<AppState>,
|
|
mut multipart: Multipart,
|
|
) -> Result<Redirect> {
|
|
let mut commit_message = format!("Update {}", stack_name);
|
|
let mut files = FileList::new();
|
|
while let Ok(Some(field)) = multipart.next_field().await {
|
|
let name = field.name().unwrap_or_default().to_string();
|
|
let data = field.text().await.map_err(|e| AppError::Client {
|
|
status: StatusCode::BAD_REQUEST,
|
|
code: "invalid-data",
|
|
message: e.to_string(),
|
|
})?;
|
|
|
|
if name.starts_with("files/") {
|
|
// Clean up source (like line endings) in each file
|
|
let source = data.replace("\r\n", "\n");
|
|
files.insert(name.strip_prefix("files/").unwrap().to_string(), source);
|
|
} else if name == "commit_message" && !data.is_empty() {
|
|
commit_message = data;
|
|
}
|
|
}
|
|
|
|
if files.is_empty() {
|
|
return Err(AppError::Client {
|
|
status: StatusCode::BAD_REQUEST,
|
|
code: "invalid-files",
|
|
message: "no files provided".to_string(),
|
|
});
|
|
}
|
|
|
|
edit_stack_int(state, &stack_name, &files, &commit_message).await?;
|
|
Ok(Redirect::to("./"))
|
|
}
|
|
|
|
pub(super) async fn edit_stack_int(
|
|
state: AppState,
|
|
stack_name: &str,
|
|
files: &FileList,
|
|
commit_message: &str,
|
|
) -> Result<()> {
|
|
// Get compose
|
|
if let Some(compose_file) = files.get(COMPOSE_FILE) {
|
|
// Make sure file is ok
|
|
compose::check(&state.arion_bin, compose_file).await?;
|
|
}
|
|
|
|
// Write compose file
|
|
stack::write(&state.stack_dir, stack_name, files).await?;
|
|
|
|
// Git commit
|
|
compose::commit(state.repository, stack_name, files, commit_message)?;
|
|
|
|
// Update stack
|
|
arion::command(
|
|
&state.stack_dir,
|
|
stack_name,
|
|
&state.arion_bin,
|
|
arion::StackCommand::Start,
|
|
)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|