node: Fix repository layout

Signed-off-by: Alexis Sellier <self@cloudhead.io>
This commit is contained in:
Alexis Sellier 2022-09-01 20:58:44 +02:00
parent 14395ad873
commit 6830a044d7
No known key found for this signature in database
5 changed files with 38 additions and 35 deletions

View File

@ -54,7 +54,7 @@ pub fn list_remotes(url: &Url) -> Result<Remotes<Unverified>, ListRefsError> {
pub fn parse_ref<T: FromStr>(s: &str) -> Result<(T, format::RefString), RefError> { pub fn parse_ref<T: FromStr>(s: &str) -> Result<(T, format::RefString), RefError> {
let input = format::RefStr::try_from_str(s)?; let input = format::RefStr::try_from_str(s)?;
let suffix = input let suffix = input
.strip_prefix(format::refname!("refs/namespaces")) .strip_prefix(format::refname!("refs/remotes"))
.ok_or_else(|| RefError::InvalidName(input.to_owned()))?; .ok_or_else(|| RefError::InvalidName(input.to_owned()))?;
let mut components = suffix.components(); let mut components = suffix.components();

View File

@ -136,7 +136,6 @@ pub trait ReadRepository {
pub trait WriteRepository: ReadRepository { pub trait WriteRepository: ReadRepository {
fn fetch(&mut self, url: &Url) -> Result<(), git2::Error>; fn fetch(&mut self, url: &Url) -> Result<(), git2::Error>;
fn namespace(&mut self, user: &UserId) -> Result<&mut git2::Repository, git2::Error>;
} }
impl<T, S> ReadStorage for T impl<T, S> ReadStorage for T

View File

@ -20,9 +20,9 @@ use super::{
}; };
pub static RADICLE_ID_REF: Lazy<refspec::PatternString> = pub static RADICLE_ID_REF: Lazy<refspec::PatternString> =
Lazy::new(|| refspec::pattern!("refs/heads/radicle/id")); Lazy::new(|| refspec::pattern!("heads/radicle/id"));
pub static NAMESPACES_GLOB: Lazy<refspec::PatternString> = pub static REMOTES_GLOB: Lazy<refspec::PatternString> =
Lazy::new(|| refspec::pattern!("refs/namespaces/*")); Lazy::new(|| refspec::pattern!("refs/remotes/*"));
pub struct Storage { pub struct Storage {
path: PathBuf, path: PathBuf,
@ -103,7 +103,7 @@ impl Storage {
} }
pub struct Repository { pub struct Repository {
backend: git2::Repository, pub(crate) backend: git2::Repository,
} }
impl Repository { impl Repository {
@ -128,7 +128,7 @@ impl Repository {
} }
pub fn find_reference(&self, remote: &UserId, name: &str) -> Result<Oid, Error> { pub fn find_reference(&self, remote: &UserId, name: &str) -> Result<Oid, Error> {
let name = format!("refs/namespaces/{}/{}", remote, name); let name = format!("refs/remotes/{}/{}", remote, name);
let target = self let target = self
.backend .backend
.find_reference(&name)? .find_reference(&name)?
@ -163,7 +163,7 @@ impl ReadRepository for Repository {
} }
fn remotes(&self) -> Result<Remotes<Unverified>, Error> { fn remotes(&self) -> Result<Remotes<Unverified>, Error> {
let refs = self.backend.references_glob(NAMESPACES_GLOB.as_str())?; let refs = self.backend.references_glob(REMOTES_GLOB.as_str())?;
let mut remotes = HashMap::default(); let mut remotes = HashMap::default();
for r in refs { for r in refs {
@ -189,30 +189,24 @@ impl WriteRepository for Repository {
// //
// Repository layout should look like this: // Repository layout should look like this:
// //
// /refs/namespaces/<remote> // /refs/remotes/<remote>
// /heads // /heads
// /master // /master
// /tags // /tags
// ... // ...
// //
let url = url.to_string(); let url = url.to_string();
let refs: &[&str] = &["refs/namespaces/*:refs/namespaces/*"]; let refs: &[&str] = &["refs/remotes/*:refs/remotes/*"];
let mut remote = self.backend.remote_anonymous(&url)?; let mut remote = self.backend.remote_anonymous(&url)?;
let mut opts = git2::FetchOptions::default(); let mut opts = git2::FetchOptions::default();
// TODO: Make sure we verify before pruning, as pruning may get us into
// a state we can't roll back.
opts.prune(git2::FetchPrune::On);
remote.fetch(refs, Some(&mut opts), None)?; remote.fetch(refs, Some(&mut opts), None)?;
Ok(()) Ok(())
} }
fn namespace(&mut self, user: &UserId) -> Result<&mut git2::Repository, git2::Error> {
let path = self.backend.path();
self.backend = git2::Repository::open_bare(path)?;
self.backend.set_namespace(&user.to_string())?;
Ok(&mut self.backend)
}
} }
impl From<git2::Repository> for Repository { impl From<git2::Repository> for Repository {
@ -257,7 +251,7 @@ mod tests {
let inventory = alice.inventory().unwrap(); let inventory = alice.inventory().unwrap();
let proj = inventory.first().unwrap(); let proj = inventory.first().unwrap();
let remotes = alice.repository(proj).unwrap().remotes().unwrap(); let remotes = alice.repository(proj).unwrap().remotes().unwrap();
let refname = "refs/heads/master"; let refname = "heads/master";
// Have Bob fetch Alice's refs. // Have Bob fetch Alice's refs.
bob.repository(proj) bob.repository(proj)

View File

@ -3,7 +3,7 @@ use std::path::Path;
use crate::git; use crate::git;
use crate::identity::{ProjId, UserId}; use crate::identity::{ProjId, UserId};
use crate::storage::git::Storage; use crate::storage::git::Storage;
use crate::storage::{WriteRepository, WriteStorage}; use crate::storage::WriteStorage;
use crate::test::arbitrary; use crate::test::arbitrary;
use crate::test::crypto::MockSigner; use crate::test::crypto::MockSigner;
@ -17,23 +17,40 @@ pub fn storage<P: AsRef<Path>>(path: P) -> Storage {
for proj in proj_ids.iter() { for proj in proj_ids.iter() {
log::debug!("creating {}...", proj); log::debug!("creating {}...", proj);
let mut repo = storage.repository(proj).unwrap(); let repo = storage.repository(proj).unwrap();
for user in user_ids.iter() { for user in user_ids.iter() {
let repo = repo.namespace(user).unwrap(); let repo = &repo.backend;
let sig = git2::Signature::now(&user.to_string(), "anonymous@radicle.xyz").unwrap(); let sig = git2::Signature::now(&user.to_string(), "anonymous@radicle.xyz").unwrap();
let head = git::initial_commit(repo, &sig).unwrap(); let head = git::initial_commit(repo, &sig).unwrap();
log::debug!("{}: creating {}...", proj, repo.namespace().unwrap()); log::debug!("{}: creating {}...", proj, user);
repo.reference("refs/rad/root", head.id(), false, "test") repo.reference(
.unwrap(); &format!("refs/remotes/{user}/heads/radicle/id"),
head.id(),
false,
"test",
)
.unwrap();
let head = git::commit(repo, &head, "Second commit", &user.to_string()).unwrap(); let head = git::commit(repo, &head, "Second commit", &user.to_string()).unwrap();
repo.branch("master", &head, false).unwrap(); repo.reference(
&format!("refs/remotes/{user}/heads/master"),
head.id(),
false,
"test",
)
.unwrap();
let head = git::commit(repo, &head, "Third commit", &user.to_string()).unwrap(); let head = git::commit(repo, &head, "Third commit", &user.to_string()).unwrap();
repo.branch("patch/3", &head, false).unwrap(); repo.reference(
&format!("refs/remotes/{user}/heads/patch/3"),
head.id(),
false,
"test",
)
.unwrap();
} }
} }
storage storage

View File

@ -82,11 +82,4 @@ impl WriteRepository for MockRepository {
fn fetch(&mut self, _url: &Url) -> Result<(), git2::Error> { fn fetch(&mut self, _url: &Url) -> Result<(), git2::Error> {
Ok(()) Ok(())
} }
fn namespace(
&mut self,
_user: &crate::identity::UserId,
) -> Result<&mut git2::Repository, git2::Error> {
todo!()
}
} }