radicle-dev / radicle-git

Everything Radicle growing around Git
Other
44 stars 5 forks source link

radicle-surf: refactoring the design #27

Closed keepsimple1 closed 1 year ago

keepsimple1 commented 2 years ago

There been a desire to come up with a new / refactored design for radicle-surf. This issue is to track that effort, including:

FintanH commented 2 years ago

I've been trying to think about this redesign a bit. I believe there are essentially 4 parts to it:

  1. refdb (reference database) listing
  2. odb (object database) querying
  3. diff'ing
  4. code browsing
  5. other metadata

1. Refdb

This component is all about listing/counting & querying for different types of references. Since we're in the domain of git code browsing we can also specialise these to the known categories:

But being good citizens, we can leave the door open for a supplied refs/<category>.

Being able to query a reference for its Oid will be necessary for then plugging into the Odb component since that's how objects are found.

2. Odb

We will want to be able to query for objects themselves:

On top of this, we will want to be able to wrap around a revwalk, which would help with this issue of loading all of the commit history into memory. It will only need a single Oid and the interface is an iterator.

Instead of our own non-empty Tree implementation, we can probably just adapt around the git2::Tree interface and make it nicer to use.

3. Diff'ing

Similar to git2::Tree, I think we could wrap around git2::Diff to have a nicer interface as opposed to having our own diff'ing implementation.

Another alternative would be to use something like difftastic.

4. Code browsing

This is essentially a combination of Refdb + Odb. The input for its actions will be something that resolves to a Commit's Oid. Some actions could:

There's probably more, but we can add those as we go :)

5. Metadata

This is more of a miscellaneous category such as contributor statistics, for example. I don't have an exhaustive list for these either.

Wdyt? Would be interested to hear if you wanted to design anything differently or if I'm missing anything :)

FintanH commented 2 years ago

Oh, and something I forgot to mention is that the refdb + odb work is pretty much done in git-storage and we could build specialised functions on top of those lower-level abilities.

cloudhead commented 2 years ago

Makes a lot of sense. One thing I'd like to understand better though is: which of the following are we doing, and to what extent: 1) Adding general git functionality not available in the git2 crate 2) Improving on the git2 API to make it more safe to use, either with stronger typing or through other ways 3) Improving on the git2 API to make it easier to use, ie. less friction, more fluid 4) Creating an abstraction over the underlying git backend so that we can later move to eg. gitoxide, or our own implementation 5) Adding functionality that'll make radicle's storage usecase easier, eg. working with the rad/ namespace, COBs etc.

I'm guessing it's all the above, but I'd like to understand which ones are prioritized and which components do which of the above. Generally I think this would be useful as documentation, to understand the rationale behind this interface (given we have git2 which is "okayish"), and to encourage adoption, eg. from both radicle-http-api and radicle-node. Some examples of the above would also be nice, comparing them to git2.

FintanH commented 2 years ago
  1. Adding general git functionality not available in the git2 crate

What do you have in mind here? I don't really foresee writing any custom git code in surf but perhaps custom types, e.g. Contributor

  1. Improving on the git2 API to make it more safe to use, either with stronger typing or through other ways

This is definitely on my radar. That will fall out of implementing something and realising git2 has a ~shit~ poor way of representing it and then writing type-safe code around it :)

  1. Improving on the git2 API to make it easier to use, ie. less friction, more fluid

Ideally, I don't think we expose any git2 at all. But perhaps that's too optimistic :)

  1. Creating an abstraction over the underlying git backend so that we can later move to eg. gitoxide, or our own implementation

My idea here is that git-storage is used and functions would be defined in terms of its traits, for example

pub fn branch<S: refdb::Read>(store: S, name: RefString) -> Result<Option<Reference>, Error> {
  Ok(store.find_reference(refname!("refs/heads").join(name))?)
} 

The only parts where this becomes an issue is that: a. radicle-git-ext is a git2::Oid underneath the hood b. The odb traits expose the git2 objects at the moment -- I didn't want to think about memory usage so I cut this corner for the time being.

  1. Adding functionality that'll make radicle's storage usecase easier, eg. working with the rad/ namespace, COBs etc.

As I mentioned in https://github.com/radicle-dev/radicle-git/issues/27#issuecomment-1266724302, we should leave the API extendable in finding non-git-specific references.

I'm guessing it's all the above, but I'd like to understand which ones are prioritized and which components do which of the above. Generally I think this would be useful as documentation, to understand the rationale behind this interface (given we have git2 which is "okayish"), and to encourage adoption, eg. from both radicle-http-api and radicle-node. Some examples of the above would also be nice, comparing them to git2.

Agreed! I'd like a spec out of this :)

cloudhead commented 2 years ago

Ok great, that helps. It would be nice to make them explicit design goals for the crate(s) if they apply, and for eg. mentioning this in the readme.

What do you have in mind here? I don't really foresee writing any custom git code in surf but perhaps custom types, e.g. Contributor

There's a few things that would be nice to have, eg. an in-process implementation of git-upload-pack, as well as stuff like atomic fetch (which is supported by the git cli, but not libgit2). I can probably think of others, but the question was to understand if there's anything like that currently planned for radicle-git.

FintanH commented 2 years ago

There's a few things that would be nice to have, eg. an in-process implementation of git-upload-pack, as well as stuff like atomic fetch (which is supported by the git cli, but not libgit2). I can probably think of others, but the question was to understand if there's anything like that currently planned for radicle-git.

Ah, I'm with ya. I wasn't considering that because this issue is for radicle-surf in particular :smile:

That kind of custom functionality currently lives in what's called link-git and it should probably keep going in there.

Feel free to open another/other issue/s for those nice to haves :ok_hand:

keepsimple1 commented 1 year ago

This is done. Further improvements will be other issues.