FS2NWBVN2SZB2FFPB3JSYT5URTVZEAZWMQ7QW4JUYPNJVDVAJTTQC BAWJ3BJ5X7JY7BFSEO2PLC4ZYIQ7WLAWKCVHIW4EP2DZLBDA2K2AC ESKQM7MASZKH333Z53IVRDG5XSMXPMLWLRI5GQS2TIBESL644YHAC TWIZ7QV4GCTQK743IKZSOJCIAEX62GZHFIYGOIFCFGIBOGPSY2WAC W3M3C7CCWHJWRWHULDWO45D3OFD4NL3V4OTJVIJCYRQG57Z2JTWQC 5UNA2DEALCSRBINR27KSA6OMD6GQAXHYZ35ICQ7NB62G2XP4FT5QC T7TT5B4G3RBWVEG3BK6TPZQJJ3PSBBUZZCNBUM5KWYPVVPJ2VKAAC K4JNAJOFEJLHHWP6YSCC2U3CNK3ZPPX6EMBAVQG4VRPZWZRXMPCQC KFVJ3KMWXEGILN4NWIWPPX7AU65M4H4UEAUIAQL2QSXOW3B5RFGQC EIIUUAKGFBWJJ67QKWXX3X7TC2ASQIAUZV4734C5KQKWNHOVYJGAC IWM4EE63YXP2B6KHE2UL3CORFZGXMUKLWB43TXYCYABKAFSTA6FQC use std::path::PathBuf;pub struct RepoMan {pub storage_root: PathBuf,}pub fn new(root: String) -> RepoMan {RepoMan {storage_root: PathBuf::from(root),}}
use crate::database::Database;use crate::models::projects;use crate::repoman::RepoMan;use rocket::{Route, State};#[derive(FromForm)]struct ChangelistReq {channel: String, // TODO check if this breaks non-UTF-8 channelsid: Option<String>,}// TODO is this for push and/or pull???#[get("/<org_path>/<proj_path>/.pijul?<cl_req..>")]async fn changelist(db: &State<Database>,repoman: &State<RepoMan>,org_path: String,proj_path: String,cl_req: ChangelistReq,) -> Option<String> {let p = match projects::find(db, org_path, proj_path).await {Some(p) => p,None => return None,};match p.repository(&repoman.storage_root) {Ok(r) => r.channel_remote_id(cl_req.channel),Err(e) => {println!("{}", e);None}}// - Reverse engineer the rest of Push}pub fn routes() -> Vec<Route> {routes![changelist]}
pub async fn find(db: &State<Database>, org_path: String, proj_path: String) -> Option<Project> {let result = sqlx::query_as!(Project,"SELECT * FROM projects WHERE name = $1 AND owner_id = (SELECT id FROM users WHERE name = $2)",proj_path, org_path).fetch_optional(&**db).await.ok()?;result}pub async fn create(db: &State<Database>,owner_id: i32,name: String,) -> Result<Project, sqlx::Error> {let result = query_as!(Project,"INSERT INTO projects (owner_id, name) VALUES ($1, $2) RETURNING *",owner_id,name.to_lowercase(),).fetch_one(&**db).await?;
pub async fn create(&self, db: &State<Database>) -> Result<i32, sqlx::Error> {let result = query!("INSERT INTO projects (owner_id, name) VALUES ($1, $2) RETURNING id",&self.owner_id,&self.name.to_lowercase(),).fetch_one(&**db).await?;
pub fn repository(&self, root: &PathBuf) -> Result<Repository> {Ok(Repository::init_or_open(root, self.repo_path())?)}
use std::path::PathBuf;use libpijul::pristine::sanakirja::Pristine;use libpijul::MutTxnT;use libpijul::TxnT;use anyhow::bail;pub struct Repository {/// full_path is the fully qualified path on diskfull_path: PathBuf,}const DEFAULT_CHANNEL: &str = "main";const PRISTINE_DIR: &str = "pristine";impl Repository {fn pristine_dir(&self) -> PathBuf {self.full_path.join(PRISTINE_DIR)}fn pristine(&self) -> Result<Pristine, anyhow::Error> {// TODO error should be logged, or handled somehow, not like thismatch Pristine::new(self.pristine_dir().join("db")) {Ok(p) => Ok(p),Err(e) => bail!("Failed to open pristine: {}", e),}}fn new(full_path: PathBuf) -> Repository {Repository {full_path: full_path,}}// init returns an error if there's already something on diskfn init(&self) -> Result<(), anyhow::Error> {if std::fs::metadata(self.pristine_dir()).is_err() {std::fs::create_dir_all(self.pristine_dir())?;} else {bail!("Already a repository on disk")}// TODO why the f does libpijul do this? It's properly weird even small// actions can just create their own txnlet mut txn = self.pristine()?.mut_txn_begin()?;txn.open_or_create_channel(DEFAULT_CHANNEL)?;txn.set_current_channel(DEFAULT_CHANNEL)?;txn.commit()?;Ok(())}pub fn init_or_open(root: &PathBuf, repo_path: PathBuf) -> Result<Self, anyhow::Error> {let repo = Self::new(root.join(repo_path));// If the pristine can't be construsted, assume nothing is on disk// TODO make a proper is_valid();match repo.pristine() {Ok(_) => Ok(repo),Err(e) => {println!("{}", e);repo.init()?;Ok(repo)}}}pub fn channel_remote_id(&self, channel: String) -> Option<String> {let txn = match self.pristine().ok()?.mut_txn_begin() {Err(_) => return None,Ok(txn) => txn,};// TODO validate the txn needs closing?//// Or does the drop function do that?//let chan = match txn.load_channel(&channel) {Ok(c) => c,Err(_) => None,};match chan {Some(c) => Some(c.read().id.to_string()),None => {println!("No chan found");None}}}}
pub mod repositories;
pub mod pijul;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";ALTER TABLE projects ADD repository_uuid uuid NOT NULL DEFAULT uuid_generate_v4();
ALTER TABLE projects DROP COLUMN repository_uuid;DROP EXTENSION IF EXISTS "uuid-ossp";
"cipher",
"cipher 0.2.5",][[package]]name = "aes"version = "0.7.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"dependencies = ["cfg-if 1.0.0","cipher 0.3.0","cpufeatures 0.2.1","ctr 0.8.0","opaque-debug 0.3.0",
name = "anyhow"version = "1.0.43"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf"[[package]]name = "arrayref"version = "0.3.6"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"[[package]]
][[package]]name = "blake3"version = "1.0.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "dcd555c66291d5f836dbb6883b48660ece810fe25a31f3bdfb911945dff2691f"dependencies = ["arrayref","arrayvec 0.7.1","cc","cfg-if 1.0.0","constant_time_eq","digest 0.9.0",
][[package]]name = "crossbeam-deque"version = "0.8.1"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"dependencies = ["cfg-if 1.0.0","crossbeam-epoch","crossbeam-utils",][[package]]name = "crossbeam-epoch"version = "0.9.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"dependencies = ["cfg-if 1.0.0","crossbeam-utils","lazy_static","memoffset","scopeguard",
name = "curve25519-dalek"version = "3.2.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61"dependencies = ["byteorder","digest 0.9.0","rand_core 0.5.1","serde","subtle","zeroize",][[package]]name = "data-encoding"version = "2.3.2"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57"[[package]]
name = "ed25519"version = "1.2.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc"dependencies = ["serde","signature",][[package]]name = "ed25519-dalek"version = "1.0.1"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d"dependencies = ["curve25519-dalek","ed25519","rand 0.7.3","serde","serde_bytes","sha2","zeroize",][[package]]
"crypto-mac",
"crypto-mac 0.10.0","digest 0.9.0",][[package]]name = "hmac"version = "0.11.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b"dependencies = ["crypto-mac 0.11.1",
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
checksum = "ffbd6c9d230f5db81cadc7cbfd824bdd594a864df8fb173487717dc4a6d0c6cb"dependencies = ["adler32","aes 0.7.5","bincode","bitflags","blake3","bs58","byteorder","canonical-path","cfg-if 1.0.0","chrono","crossbeam-deque","crossbeam-utils","curve25519-dalek","data-encoding","diffs","ed25519-dalek","encoding_rs","generic-array 0.14.4","hmac 0.11.0","ignore","lazy_static","log","lru-cache","memchr","parking_lot","path-slash","pbkdf2","pijul-macros","rand 0.7.3","rand_core 0.6.3","regex","sanakirja","serde","serde_derive","serde_json","sha2","tempfile","thiserror","tokio","toml","twox-hash","zstd-seekable",][[package]]name = "linked-hash-map"version = "0.5.4"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
name = "memmap"version = "0.7.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"dependencies = ["libc","winapi 0.3.9",][[package]]name = "memoffset"version = "0.6.4"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"dependencies = ["autocfg",][[package]]
name = "path-slash"version = "0.1.4"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "3cacbb3c4ff353b534a67fb8d7524d00229da4cb1dc8c79f4db96e375ab5b619"[[package]]name = "pbkdf2"version = "0.8.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa"dependencies = ["crypto-mac 0.11.1",][[package]]
version = "0.7.3"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"dependencies = ["getrandom 0.1.16","libc","rand_chacha 0.2.2","rand_core 0.5.1","rand_hc 0.2.0",][[package]]name = "rand"
"rand_chacha","rand_core","rand_hc",
"rand_chacha 0.3.1","rand_core 0.6.3","rand_hc 0.3.1",][[package]]name = "rand_chacha"version = "0.2.2"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"dependencies = ["ppv-lite86","rand_core 0.5.1",
"rand_core",
"rand_core 0.6.3",][[package]]name = "rand_core"version = "0.5.1"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"dependencies = ["getrandom 0.1.16",
"getrandom",
"getrandom 0.2.3",][[package]]name = "rand_hc"version = "0.2.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"dependencies = ["rand_core 0.5.1",
][[package]]name = "sanakirja"version = "1.2.11"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "be030ebfecb0589e7c83817620ee833b98c3de089b1a9393b195dfc04b7fc9fe"dependencies = ["crc32fast","fs2","lazy_static","log","memmap","parking_lot","sanakirja-core","thiserror",][[package]]name = "sanakirja-core"version = "1.2.13"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "9828a6c9219969d6b19cfb0b53a8aed96e29983d0944a67db0a8c44db20ebe00"dependencies = ["crc32fast",
[[package]]name = "zeroize"version = "1.4.1"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd"dependencies = ["zeroize_derive",][[package]]name = "zeroize_derive"version = "1.1.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1"dependencies = ["proc-macro2","quote","syn","synstructure",][[package]]name = "zstd-seekable"version = "0.1.7"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "3e3b99cee88f0309ca765c6aa8c284a00394c35ef8ca012e2409485fc369bf2f"dependencies = ["cc","libc","pkg-config","thiserror","threadpool",]