mirror of
https://seed.radicle.dev/rad:z6cFWeWpnZNHh9rUW8phgA3b5yGt.git
synced 2026-10-18 19:10:31 +08:00
merge radicle-source into radicle-surf
Initially, radicle-source was envisioned to be another layer on top of radicle-surf, however, it ended up duplicating a lot of concepts. We consolidate them by merging radicle-source into radicle-surf. This meant removing modules branch.rs, tag.rs, oid.rs and error.rs.
This commit is contained in:
@@ -87,8 +87,8 @@ jobs:
|
||||
# The 'main' branch is needed for radicle-surf vcs::git::tests::test_submodule_failure,
|
||||
# however actions/checkout uses the default branch 'master' at this moment.
|
||||
# We will improve the test soon to remove this need.
|
||||
- run: git branch main
|
||||
- run: git branch -u origin/main main
|
||||
# - run: git branch main
|
||||
# - run: git branch -u origin/main main
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
|
||||
@@ -6,7 +6,6 @@ members = [
|
||||
"radicle-git-ext",
|
||||
"radicle-git-types",
|
||||
"radicle-macros",
|
||||
"radicle-source",
|
||||
"radicle-std-ext",
|
||||
"radicle-surf",
|
||||
# TODO: port gitd-lib over
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
[package]
|
||||
name = "radicle-source"
|
||||
description = "A high level API for browsing source files"
|
||||
version = "0.4.0"
|
||||
authors = ["The Radicle Team <dev@radicle.xyz>"]
|
||||
edition = "2018"
|
||||
homepage = "https://github.com/radicle-dev/radicle-surf"
|
||||
repository = "https://github.com/radicle-dev/radicle-surf"
|
||||
license = "GPL-3.0-or-later"
|
||||
|
||||
[features]
|
||||
syntax = ["syntect"]
|
||||
|
||||
[dependencies]
|
||||
base64 = "0.13"
|
||||
log = "0.4"
|
||||
lazy_static = "1.4"
|
||||
nonempty = "0.6"
|
||||
serde = { version = "1.0", features = [ "derive" ] }
|
||||
syntect = { version = "4.2", optional = true }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dependencies.git2]
|
||||
version = ">= 0.12"
|
||||
default-features = false
|
||||
features = []
|
||||
|
||||
[dependencies.radicle-surf]
|
||||
version = "^0.8.0"
|
||||
features = ["serialize"]
|
||||
path = "../radicle-surf"
|
||||
@@ -1,108 +0,0 @@
|
||||
// This file is part of radicle-surf
|
||||
// <https://github.com/radicle-dev/radicle-surf>
|
||||
//
|
||||
// Copyright (C) 2019-2020 The Radicle Team <dev@radicle.xyz>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 3 or
|
||||
// later as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use radicle_surf::vcs::git::{self, Browser, RefScope};
|
||||
|
||||
use crate::error::Error;
|
||||
|
||||
/// Branch name representation.
|
||||
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Deserialize, Serialize)]
|
||||
pub struct Branch(pub(crate) String);
|
||||
|
||||
impl From<String> for Branch {
|
||||
fn from(name: String) -> Self {
|
||||
Self(name)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<git::Branch> for Branch {
|
||||
fn from(branch: git::Branch) -> Self {
|
||||
Self(branch.name.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Branch {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a project id to a repo returns the list of branches.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Will return [`Error`] if the project doesn't exist or the surf interaction
|
||||
/// fails.
|
||||
pub fn branches(browser: &Browser<'_>, filter: RefScope) -> Result<Vec<Branch>, Error> {
|
||||
let mut branches = browser
|
||||
.list_branches(filter)?
|
||||
.into_iter()
|
||||
.map(|b| Branch(b.name.name().to_string()))
|
||||
.collect::<Vec<Branch>>();
|
||||
|
||||
branches.sort();
|
||||
|
||||
Ok(branches)
|
||||
}
|
||||
|
||||
/// Information about a locally checked out repository.
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct LocalState {
|
||||
/// List of branches.
|
||||
branches: Vec<Branch>,
|
||||
}
|
||||
|
||||
/// Given a path to a repo returns the list of branches and if it is managed by
|
||||
/// coco.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Will return [`Error`] if the repository doesn't exist.
|
||||
pub fn local_state(repo_path: &str, default_branch: &str) -> Result<LocalState, Error> {
|
||||
let repo = git2::Repository::open(repo_path).map_err(git::error::Error::from)?;
|
||||
let first_branch = repo
|
||||
.branches(Some(git2::BranchType::Local))
|
||||
.map_err(git::error::Error::from)?
|
||||
.filter_map(|branch_result| {
|
||||
let (branch, _) = branch_result.ok()?;
|
||||
let name = branch.name().ok()?;
|
||||
name.map(String::from)
|
||||
})
|
||||
.min()
|
||||
.ok_or(Error::NoBranches)?;
|
||||
|
||||
let repo = git::Repository::new(repo_path)?;
|
||||
|
||||
let browser = match Browser::new(&repo, git::Branch::local(default_branch)) {
|
||||
Ok(browser) => browser,
|
||||
Err(_) => Browser::new(&repo, git::Branch::local(&first_branch))?,
|
||||
};
|
||||
|
||||
let mut branches = browser
|
||||
.list_branches(RefScope::Local)?
|
||||
.into_iter()
|
||||
.map(|b| Branch(b.name.name().to_string()))
|
||||
.collect::<Vec<Branch>>();
|
||||
|
||||
branches.sort();
|
||||
|
||||
Ok(LocalState { branches })
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
// This file is part of radicle-surf
|
||||
// <https://github.com/radicle-dev/radicle-surf>
|
||||
//
|
||||
// Copyright (C) 2019-2020 The Radicle Team <dev@radicle.xyz>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 3 or
|
||||
// later as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use radicle_surf::{file_system, git};
|
||||
|
||||
/// An error occurred when interacting with [`radicle_surf`] for browsing source
|
||||
/// code.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
/// We expect at least one [`crate::revision::Revisions`] when looking at a
|
||||
/// project, however the computation found none.
|
||||
#[error(
|
||||
"while trying to get user revisions we could not find any, there should be at least one"
|
||||
)]
|
||||
EmptyRevisions,
|
||||
|
||||
/// An error occurred during a [`radicle_surf::file_system`] operation.
|
||||
#[error(transparent)]
|
||||
FileSystem(#[from] file_system::Error),
|
||||
|
||||
/// An error occurred during a [`radicle_surf::git`] operation.
|
||||
#[error(transparent)]
|
||||
Git(#[from] git::error::Error),
|
||||
|
||||
/// When trying to query a repositories branches, but there are none.
|
||||
#[error("the repository has no branches")]
|
||||
NoBranches,
|
||||
|
||||
/// Trying to find a file path which could not be found.
|
||||
#[error("the path '{0}' was not found")]
|
||||
PathNotFound(file_system::Path),
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
// This file is part of radicle-surf
|
||||
// <https://github.com/radicle-dev/radicle-surf>
|
||||
//
|
||||
// Copyright (C) 2019-2020 The Radicle Team <dev@radicle.xyz>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 3 or
|
||||
// later as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! Source code related functionality.
|
||||
|
||||
/// To avoid incompatible versions of `radicle-surf`, `radicle-source`
|
||||
/// re-exports the package under the `surf` alias.
|
||||
pub use radicle_surf as surf;
|
||||
|
||||
pub mod branch;
|
||||
pub use branch::{branches, local_state, Branch, LocalState};
|
||||
|
||||
pub mod commit;
|
||||
pub use commit::{commit, commits, Commit};
|
||||
|
||||
pub mod error;
|
||||
pub use error::Error;
|
||||
|
||||
pub mod object;
|
||||
pub use object::{blob, tree, Blob, BlobContent, Info, ObjectType, Tree};
|
||||
|
||||
pub mod oid;
|
||||
pub use oid::Oid;
|
||||
|
||||
pub mod person;
|
||||
pub use person::Person;
|
||||
|
||||
pub mod revision;
|
||||
pub use revision::Revision;
|
||||
|
||||
#[cfg(feature = "syntax")]
|
||||
pub mod syntax;
|
||||
#[cfg(feature = "syntax")]
|
||||
pub use syntax::SYNTAX_SET;
|
||||
|
||||
pub mod tag;
|
||||
pub use tag::{tags, Tag};
|
||||
@@ -1,44 +0,0 @@
|
||||
// This file is part of radicle-surf
|
||||
// <https://github.com/radicle-dev/radicle-surf>
|
||||
//
|
||||
// Copyright (C) 2019-2020 The Radicle Team <dev@radicle.xyz>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 3 or
|
||||
// later as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
|
||||
#[serde(try_from = "&str", into = "String")]
|
||||
pub struct Oid(pub git2::Oid);
|
||||
|
||||
impl TryFrom<&str> for Oid {
|
||||
type Error = git2::Error;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
value.parse().map(Oid)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Oid> for String {
|
||||
fn from(oid: Oid) -> Self {
|
||||
oid.0.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Oid> for git2::Oid {
|
||||
fn from(oid: Oid) -> Self {
|
||||
oid.0
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
// This file is part of radicle-surf
|
||||
// <https://github.com/radicle-dev/radicle-surf>
|
||||
//
|
||||
// Copyright (C) 2019-2020 The Radicle Team <dev@radicle.xyz>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 3 or
|
||||
// later as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
use radicle_surf::{git::RefScope, vcs::git::Browser};
|
||||
|
||||
use crate::error::Error;
|
||||
|
||||
/// Tag name representation.
|
||||
///
|
||||
/// We still need full tag support.
|
||||
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
pub struct Tag(pub(crate) String);
|
||||
|
||||
impl From<String> for Tag {
|
||||
fn from(name: String) -> Self {
|
||||
Self(name)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Tag {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieves the list of [`Tag`] for the given project `id`.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Will return [`Error`] if the project doesn't exist or the surf interaction
|
||||
/// fails.
|
||||
pub fn tags(browser: &Browser<'_>) -> Result<Vec<Tag>, Error> {
|
||||
let tag_names = browser.list_tags(RefScope::Local)?;
|
||||
let mut tags: Vec<Tag> = tag_names
|
||||
.into_iter()
|
||||
.map(|tag_name| Tag(tag_name.name().to_string()))
|
||||
.collect();
|
||||
|
||||
tags.sort();
|
||||
|
||||
Ok(tags)
|
||||
}
|
||||
@@ -24,9 +24,11 @@ serialize = ["serde"]
|
||||
gh-actions = []
|
||||
|
||||
[dependencies]
|
||||
base64 = "0.13"
|
||||
either = "1.5"
|
||||
nom = "6"
|
||||
nonempty = "0.5"
|
||||
radicle-git-ext = { path = "../radicle-git-ext", features = ["serde"] }
|
||||
regex = ">= 1.5.5"
|
||||
serde = { features = ["serde_derive"], optional = true, version = "1" }
|
||||
thiserror = "1.0"
|
||||
|
||||
@@ -15,22 +15,27 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! Represents a commit.
|
||||
|
||||
use std::convert::TryFrom as _;
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
use serde::{
|
||||
ser::{SerializeStruct as _, Serializer},
|
||||
Serialize,
|
||||
};
|
||||
|
||||
use radicle_surf::{
|
||||
use crate::{
|
||||
diff,
|
||||
vcs::git::{self, Browser, Rev},
|
||||
file_system,
|
||||
person::Person,
|
||||
revision::Revision,
|
||||
vcs::git::{self, BranchName, Browser, Rev},
|
||||
};
|
||||
|
||||
use crate::{branch::Branch, error::Error, person::Person, revision::Revision};
|
||||
|
||||
/// Commit statistics.
|
||||
#[derive(Clone, Serialize)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
#[derive(Clone)]
|
||||
pub struct Stats {
|
||||
/// Additions.
|
||||
pub additions: u64,
|
||||
@@ -39,7 +44,8 @@ pub struct Stats {
|
||||
}
|
||||
|
||||
/// Representation of a changeset between two revs.
|
||||
#[derive(Clone, Serialize)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
#[derive(Clone)]
|
||||
pub struct Commit {
|
||||
/// The commit header.
|
||||
pub header: Header,
|
||||
@@ -48,7 +54,7 @@ pub struct Commit {
|
||||
/// The changeset introduced by this commit.
|
||||
pub diff: diff::Diff,
|
||||
/// The list of branches this commit belongs to.
|
||||
pub branches: Vec<Branch>,
|
||||
pub branches: Vec<BranchName>,
|
||||
}
|
||||
|
||||
/// Representation of a code commit.
|
||||
@@ -101,6 +107,7 @@ impl From<&git::Commit> for Header {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl Serialize for Header {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@@ -118,12 +125,12 @@ impl Serialize for Header {
|
||||
}
|
||||
|
||||
/// A selection of commit headers and their statistics.
|
||||
#[derive(Serialize)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
pub struct Commits {
|
||||
/// The commit headers
|
||||
pub headers: Vec<Header>,
|
||||
/// The statistics for the commit headers
|
||||
pub stats: radicle_surf::vcs::git::Stats,
|
||||
pub stats: git::Stats,
|
||||
}
|
||||
|
||||
/// Retrieves a [`Commit`].
|
||||
@@ -188,7 +195,7 @@ pub fn commit(browser: &mut Browser<'_>, sha1: git2::Oid) -> Result<Commit, Erro
|
||||
let branches = browser
|
||||
.revision_branches(sha1)?
|
||||
.into_iter()
|
||||
.map(Branch::from)
|
||||
.map(|b| b.name)
|
||||
.collect();
|
||||
|
||||
Ok(Commit {
|
||||
@@ -241,3 +248,19 @@ where
|
||||
|
||||
Ok(Commits { headers, stats })
|
||||
}
|
||||
|
||||
/// An error reported by commit API.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
/// An error occurred during a file system operation.
|
||||
#[error(transparent)]
|
||||
FileSystem(#[from] file_system::Error),
|
||||
|
||||
/// An error occurred during a git operation.
|
||||
#[error(transparent)]
|
||||
Git(#[from] git::error::Error),
|
||||
|
||||
/// Trying to find a file path which could not be found.
|
||||
#[error("the path '{0}' was not found")]
|
||||
PathNotFound(file_system::Path),
|
||||
}
|
||||
@@ -86,6 +86,23 @@ pub mod diff;
|
||||
pub mod file_system;
|
||||
pub mod vcs;
|
||||
|
||||
pub mod commit;
|
||||
pub use commit::{commit, commits, Commit};
|
||||
|
||||
pub mod object;
|
||||
pub use object::{blob, tree as objectTree, Blob, BlobContent, Info, ObjectType, Tree};
|
||||
|
||||
pub mod person;
|
||||
pub use person::Person;
|
||||
|
||||
pub mod revision;
|
||||
pub use revision::Revision;
|
||||
|
||||
#[cfg(feature = "syntax")]
|
||||
pub mod syntax;
|
||||
#[cfg(feature = "syntax")]
|
||||
pub use syntax::SYNTAX_SET;
|
||||
|
||||
// Private modules
|
||||
mod nonempty;
|
||||
mod tree;
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! Common definitions for git objects (blob and tree).
|
||||
//! See git [doc](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects) for more details.
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
use serde::{
|
||||
ser::{SerializeStruct as _, Serializer},
|
||||
Serialize,
|
||||
@@ -26,7 +30,7 @@ pub use blob::{blob, Blob, BlobContent};
|
||||
pub mod tree;
|
||||
pub use tree::{tree, Tree, TreeEntry};
|
||||
|
||||
use crate::commit;
|
||||
use crate::{commit, file_system, git};
|
||||
|
||||
/// Git object types.
|
||||
///
|
||||
@@ -39,6 +43,7 @@ pub enum ObjectType {
|
||||
Blob,
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl Serialize for ObjectType {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@@ -62,6 +67,7 @@ pub struct Info {
|
||||
pub last_commit: Option<commit::Header>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl Serialize for Info {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@@ -74,3 +80,19 @@ impl Serialize for Info {
|
||||
state.end()
|
||||
}
|
||||
}
|
||||
|
||||
/// An error reported by object types.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
/// An error occurred during a file system operation.
|
||||
#[error(transparent)]
|
||||
FileSystem(#[from] file_system::Error),
|
||||
|
||||
/// An error occurred during a git operation.
|
||||
#[error(transparent)]
|
||||
Git(#[from] git::error::Error),
|
||||
|
||||
/// Trying to find a file path which could not be found.
|
||||
#[error("the path '{0}' was not found")]
|
||||
PathNotFound(file_system::Path),
|
||||
}
|
||||
@@ -15,26 +15,26 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! Represents git object type 'blob', i.e. actual file contents.
|
||||
//! See git [doc](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects) for more details.
|
||||
|
||||
use std::{
|
||||
convert::TryFrom as _,
|
||||
str::{self, FromStr as _},
|
||||
};
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
use serde::{
|
||||
ser::{SerializeStruct as _, Serializer},
|
||||
Serialize,
|
||||
};
|
||||
|
||||
use radicle_surf::{
|
||||
file_system,
|
||||
vcs::git::{Browser, Rev},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
commit,
|
||||
error::Error,
|
||||
object::{Info, ObjectType},
|
||||
file_system,
|
||||
object::{Error, Info, ObjectType},
|
||||
revision::Revision,
|
||||
vcs::git::{Browser, Rev},
|
||||
};
|
||||
|
||||
#[cfg(feature = "syntax")]
|
||||
@@ -64,6 +64,7 @@ impl Blob {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl Serialize for Blob {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@@ -94,6 +95,7 @@ pub enum BlobContent {
|
||||
Binary(Vec<u8>),
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl Serialize for BlobContent {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@@ -15,23 +15,23 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! Represents git object type 'tree', i.e. like directory entries in Unix.
|
||||
//! See git [doc](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects) for more details.
|
||||
|
||||
use std::{convert::TryFrom as _, str::FromStr as _};
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
use serde::{
|
||||
ser::{SerializeStruct as _, Serializer},
|
||||
Serialize,
|
||||
};
|
||||
|
||||
use radicle_surf::{
|
||||
file_system,
|
||||
vcs::git::{Browser, Rev},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
commit,
|
||||
error::Error,
|
||||
object::{Info, ObjectType},
|
||||
file_system,
|
||||
object::{Error, Info, ObjectType},
|
||||
revision::Revision,
|
||||
vcs::git::{Browser, Rev},
|
||||
};
|
||||
|
||||
/// Result of a directory listing, carries other trees and blobs.
|
||||
@@ -44,6 +44,7 @@ pub struct Tree {
|
||||
pub info: Info,
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl Serialize for Tree {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@@ -66,6 +67,7 @@ pub struct TreeEntry {
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl Serialize for TreeEntry {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@@ -15,11 +15,15 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! Represents a person in a repo.
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
use serde::Serialize;
|
||||
|
||||
/// Representation of a person (e.g. committer, author, signer) from a
|
||||
/// repository. Usually extracted from a signature.
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Person {
|
||||
/// Name part of the commit signature.
|
||||
pub name: String,
|
||||
@@ -15,37 +15,56 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! Represents revisions
|
||||
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use nonempty::NonEmpty;
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use radicle_surf::vcs::git::{self, Browser, RefScope, Rev};
|
||||
use radicle_git_ext::Oid;
|
||||
|
||||
use crate::{
|
||||
branch::{branches, Branch},
|
||||
error::Error,
|
||||
oid::Oid,
|
||||
tag::{tags, Tag},
|
||||
git::BranchName,
|
||||
vcs::git::{self, error::Error, Browser, RefScope, Rev, TagName},
|
||||
};
|
||||
|
||||
/// Types of a peer.
|
||||
pub enum Category<P, U> {
|
||||
Local { peer_id: P, user: U },
|
||||
Remote { peer_id: P, user: U },
|
||||
/// Local peer.
|
||||
Local {
|
||||
/// Peer Id
|
||||
peer_id: P,
|
||||
/// User name
|
||||
user: U,
|
||||
},
|
||||
/// Remote peer.
|
||||
Remote {
|
||||
/// Peer Id
|
||||
peer_id: P,
|
||||
/// User name
|
||||
user: U,
|
||||
},
|
||||
}
|
||||
|
||||
/// A revision selector for a `Browser`.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase", tag = "type")]
|
||||
#[cfg_attr(
|
||||
feature = "serialize",
|
||||
derive(Deserialize, Serialize),
|
||||
serde(rename_all = "camelCase", tag = "type")
|
||||
)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Revision<P> {
|
||||
/// Select a tag under the name provided.
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))]
|
||||
Tag {
|
||||
/// Name of the tag.
|
||||
name: String,
|
||||
},
|
||||
/// Select a branch under the name provided.
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))]
|
||||
Branch {
|
||||
/// Name of the branch.
|
||||
name: String,
|
||||
@@ -53,7 +72,7 @@ pub enum Revision<P> {
|
||||
peer_id: Option<P>,
|
||||
},
|
||||
/// Select a SHA1 under the name provided.
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))]
|
||||
Sha {
|
||||
/// The SHA1 value.
|
||||
sha: Oid,
|
||||
@@ -83,18 +102,18 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Bundled response to retrieve both [`Branch`]es and [`Tag`]s for a user's
|
||||
/// repo.
|
||||
/// Bundled response to retrieve both [`BranchName`]es and [`TagName`]s for
|
||||
/// a user's repo.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Revisions<P, U> {
|
||||
/// The peer peer_id for the user.
|
||||
pub peer_id: P,
|
||||
/// The user who owns these revisions.
|
||||
pub user: U,
|
||||
/// List of [`git::Branch`].
|
||||
pub branches: NonEmpty<Branch>,
|
||||
/// List of [`git::Tag`].
|
||||
pub tags: Vec<Tag>,
|
||||
/// List of [`git::BranchName`].
|
||||
pub branches: NonEmpty<BranchName>,
|
||||
/// List of [`git::TagName`].
|
||||
pub tags: Vec<TagName>,
|
||||
}
|
||||
|
||||
/// Provide the [`Revisions`] for the given `peer_id`, looking for the
|
||||
@@ -113,7 +132,7 @@ pub fn remote<P, U>(
|
||||
where
|
||||
P: Clone + ToString,
|
||||
{
|
||||
let remote_branches = branches(browser, Some(peer_id.clone()).into())?;
|
||||
let remote_branches = browser.branch_names(Some(peer_id.clone()).into())?;
|
||||
Ok(
|
||||
NonEmpty::from_vec(remote_branches).map(|branches| Revisions {
|
||||
peer_id,
|
||||
@@ -138,8 +157,8 @@ pub fn local<P, U>(browser: &Browser, peer_id: P, user: U) -> Result<Option<Revi
|
||||
where
|
||||
P: Clone + ToString,
|
||||
{
|
||||
let local_branches = branches(browser, RefScope::Local)?;
|
||||
let tags = tags(browser)?;
|
||||
let local_branches = browser.branch_names(RefScope::Local)?;
|
||||
let tags = browser.tag_names()?;
|
||||
Ok(
|
||||
NonEmpty::from_vec(local_branches).map(|branches| Revisions {
|
||||
peer_id,
|
||||
@@ -616,6 +616,24 @@ impl<'a> Browser<'a> {
|
||||
self.repository.list_branches(filter)
|
||||
}
|
||||
|
||||
/// Given a project id to a repo returns the list of branches.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Will return [`Error`] if the project doesn't exist or the surf
|
||||
/// interaction fails.
|
||||
pub fn branch_names(&self, filter: RefScope) -> Result<Vec<BranchName>, Error> {
|
||||
let mut branches = self
|
||||
.list_branches(filter)?
|
||||
.into_iter()
|
||||
.map(|b| b.name)
|
||||
.collect::<Vec<BranchName>>();
|
||||
|
||||
branches.sort();
|
||||
|
||||
Ok(branches)
|
||||
}
|
||||
|
||||
/// List the names of the _tags_ that are contained in the underlying
|
||||
/// [`Repository`].
|
||||
///
|
||||
@@ -713,6 +731,23 @@ impl<'a> Browser<'a> {
|
||||
self.repository.list_tags(scope)
|
||||
}
|
||||
|
||||
/// Returns a sorted list of [`TagName`] from the browser.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// * [`error::Error::Git`]
|
||||
pub fn tag_names(&self) -> Result<Vec<TagName>, Error> {
|
||||
let tag_names = self.list_tags(RefScope::Local)?;
|
||||
let mut tags: Vec<TagName> = tag_names
|
||||
.into_iter()
|
||||
.map(|tag_name| tag_name.name())
|
||||
.collect();
|
||||
|
||||
tags.sort();
|
||||
|
||||
Ok(tags)
|
||||
}
|
||||
|
||||
/// List the namespaces within a `Browser`, filtering out ones that do not
|
||||
/// parse correctly.
|
||||
///
|
||||
|
||||
@@ -31,9 +31,12 @@ pub struct Author {
|
||||
/// Email of the author.
|
||||
pub email: String,
|
||||
/// Time the action was taken, e.g. time of commit.
|
||||
#[serde(
|
||||
serialize_with = "serialize_time",
|
||||
deserialize_with = "deserialize_time"
|
||||
#[cfg_attr(
|
||||
feature = "serialize",
|
||||
serde(
|
||||
serialize_with = "serialize_time",
|
||||
deserialize_with = "deserialize_time"
|
||||
)
|
||||
)]
|
||||
pub time: git2::Time,
|
||||
}
|
||||
@@ -91,7 +94,7 @@ impl<'repo> TryFrom<git2::Signature<'repo>> for Author {
|
||||
pub struct Commit {
|
||||
// TODO: Replace git2::Oid with git_ext::Oid (https://github.com/radicle-dev/radicle-git/issues/5)
|
||||
/// Object ID of the Commit, i.e. the SHA1 digest.
|
||||
#[serde(deserialize_with = "deserialize_oid")]
|
||||
#[cfg_attr(feature = "serialize", serde(deserialize_with = "deserialize_oid"))]
|
||||
pub id: Oid,
|
||||
/// The author of the commit.
|
||||
pub author: Author,
|
||||
@@ -102,7 +105,7 @@ pub struct Commit {
|
||||
/// The summary message of the commit.
|
||||
pub summary: String,
|
||||
/// The parents of this commit.
|
||||
#[serde(deserialize_with = "deserialize_vec_oid")]
|
||||
#[cfg_attr(feature = "serialize", serde(deserialize_with = "deserialize_vec_oid"))]
|
||||
pub parents: Vec<Oid>,
|
||||
}
|
||||
|
||||
@@ -193,6 +196,7 @@ impl<'repo> TryFrom<git2::Commit<'repo>> for Commit {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use git2::Oid;
|
||||
|
||||
Reference in New Issue
Block a user