Skip to content

Commit

Permalink
fix: support for proper identification of '.' remote paths in
Browse files Browse the repository at this point in the history
`reference::remote::Name` (#450)
  • Loading branch information
Byron committed Nov 1, 2022
1 parent 449ff06 commit b219033
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 57 deletions.
Expand Up @@ -15,63 +15,7 @@ pub enum Name<'repo> {
Url(Cow<'repo, BStr>),
}

mod name {
use super::Name;
use crate::bstr::{BStr, ByteSlice, ByteVec};
use std::borrow::Cow;
use std::convert::TryFrom;

impl Name<'_> {
/// Obtain the name as string representation.
pub fn as_bstr(&self) -> &BStr {
match self {
Name::Symbol(v) => v.as_ref().into(),
Name::Url(v) => v.as_ref(),
}
}

/// Return this instance as a symbolic name, if it is one.
pub fn as_symbol(&self) -> Option<&str> {
match self {
Name::Symbol(n) => n.as_ref().into(),
Name::Url(_) => None,
}
}

/// Return this instance as url, if it is one.
pub fn as_url(&self) -> Option<&BStr> {
match self {
Name::Url(n) => n.as_ref().into(),
Name::Symbol(_) => None,
}
}
}

impl<'a> TryFrom<Cow<'a, BStr>> for Name<'a> {
type Error = Cow<'a, BStr>;

fn try_from(name: Cow<'a, BStr>) -> Result<Self, Self::Error> {
if name.contains(&b'/') {
Ok(Name::Url(name))
} else {
match name {
Cow::Borrowed(n) => n.to_str().ok().map(Cow::Borrowed).ok_or(name),
Cow::Owned(n) => Vec::from(n)
.into_string()
.map_err(|err| Cow::Owned(err.into_vec().into()))
.map(Cow::Owned),
}
.map(Name::Symbol)
}
}
}

impl<'a> AsRef<BStr> for Name<'a> {
fn as_ref(&self) -> &BStr {
self.as_bstr()
}
}
}
mod name;

/// Remotes
impl<'repo> Reference<'repo> {
Expand Down
55 changes: 55 additions & 0 deletions git-repository/src/reference/remote/name.rs
@@ -0,0 +1,55 @@
use super::Name;
use crate::bstr::{BStr, ByteSlice, ByteVec};
use std::borrow::Cow;
use std::convert::TryFrom;

impl Name<'_> {
/// Obtain the name as string representation.
pub fn as_bstr(&self) -> &BStr {
match self {
Name::Symbol(v) => v.as_ref().into(),
Name::Url(v) => v.as_ref(),
}
}

/// Return this instance as a symbolic name, if it is one.
pub fn as_symbol(&self) -> Option<&str> {
match self {
Name::Symbol(n) => n.as_ref().into(),
Name::Url(_) => None,
}
}

/// Return this instance as url, if it is one.
pub fn as_url(&self) -> Option<&BStr> {
match self {
Name::Url(n) => n.as_ref().into(),
Name::Symbol(_) => None,
}
}
}

impl<'a> TryFrom<Cow<'a, BStr>> for Name<'a> {
type Error = Cow<'a, BStr>;

fn try_from(name: Cow<'a, BStr>) -> Result<Self, Self::Error> {
if name.contains(&b'/') || name.as_ref() == "." {
Ok(Name::Url(name))
} else {
match name {
Cow::Borrowed(n) => n.to_str().ok().map(Cow::Borrowed).ok_or(name),
Cow::Owned(n) => Vec::from(n)
.into_string()
.map_err(|err| Cow::Owned(err.into_vec().into()))
.map(Cow::Owned),
}
.map(Name::Symbol)
}
}
}

impl<'a> AsRef<BStr> for Name<'a> {
fn as_ref(&self) -> &BStr {
self.as_bstr()
}
}
6 changes: 6 additions & 0 deletions git-repository/tests/fixtures/make_remote_repos.sh
Expand Up @@ -126,6 +126,12 @@ git clone --shared base branch-push-remote
git config branch.main.pushRemote myself
)

git clone --shared base branch-dot-remote
(cd branch-dot-remote

git config branch.main.remote .
)

git init --bare url-rewriting
(cd url-rewriting

Expand Down
34 changes: 34 additions & 0 deletions git-repository/tests/reference/remote.rs
Expand Up @@ -82,6 +82,40 @@ fn not_configured() -> crate::Result {
Ok(())
}

#[test]
fn dot_remote_behind_symbol() -> crate::Result {
let repo = remote::repo("branch-dot-remote");
let head = repo.head()?;
let branch = head.clone().try_into_referent().expect("history");

assert_eq!(
branch
.remote_name(git::remote::Direction::Push)
.expect("derived push")
.as_url(),
Some(".".into())
);
assert_eq!(
branch
.remote_name(git::remote::Direction::Fetch)
.expect("fetch")
.as_url(),
Some(".".into())
);

{
let remote = branch
.remote(git::remote::Direction::Push)
.transpose()?
.expect("present");
assert_eq!(remote.name(), None, "It's a url after all, anonymous");
assert_eq!(remote.url(git::remote::Direction::Push).unwrap().path, ".");
assert_eq!(remote.url(git::remote::Direction::Fetch).unwrap().path, ".");
}

Ok(())
}

#[test]
fn url_as_remote_name() -> crate::Result {
let repo = remote::repo("remote-as-url");
Expand Down

0 comments on commit b219033

Please sign in to comment.