W2ZEVC64ORZWKRPSQ3JFLIV54FYOTHIK2VW7H7HASO3Z6RC66LSQC
// TODO pijul: When this endpoint returns a 4XX or 5XX status code, it thinks the push still
// succeeded.
#[post("/<org_path>/<proj_path>/.pijul?<apply>", data = "<patch>")]
async fn apply(
db: &State<Database>,
repoman: &State<RepoMan>,
org_path: String,
proj_path: String,
apply: String,
mut patch: TempFile<'_>,
) -> rocket::http::Status {
let p = if let Some(p) = projects::find(db, org_path, proj_path).await {
p
} else {
return rocket::http::Status::NotFound;
};
let patch_path = p
.repository(&repoman.storage_root)
.unwrap()
.changestore()
.change_file(apply)
.unwrap();
match patch.persist_to(patch_path).await {
Ok(_) => rocket::http::Status::Accepted,
Err(_e) => rocket::http::Status::InternalServerError,
}
}
use std::path::PathBuf;
use libpijul::Base32;
use libpijul::Hash;
use anyhow::bail;
const CHANGES_DIR: &str = "changes";
pub struct Changestore {
path: PathBuf,
}
impl Changestore {
pub fn new(repo_path: PathBuf) -> Self {
Changestore { path: repo_path }
}
// change_file will ensure parent directories are created thus has side-effects on disk
pub fn change_file(&self, hash: String) -> Result<PathBuf, anyhow::Error> {
let h = if let Some(h) = Hash::from_base32(hash.as_bytes()) {
h
} else {
bail!("invalid hash to store a change")
};
let mut path = self.dir().clone();
libpijul::changestore::filesystem::push_filename(&mut path, &h);
std::fs::create_dir_all(path.parent().unwrap())?;
Ok(path)
}
fn dir(&self) -> PathBuf {
self.path.join(CHANGES_DIR)
}
}