Skip to content

Commit

Permalink
and the entire test-suite passes (#450)
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Aug 6, 2022
1 parent d7c2789 commit 3fa52f8
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 7 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion git-refspec/Cargo.toml
Expand Up @@ -14,8 +14,11 @@ doctest = false
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bstr = { version = "0.2.13", default-features = false, features = ["std"]}
git-revision = { version = "^0.3.0", path = "../git-revision" }
git-validate = { version = "^0.5.4", path = "../git-validate" }
git-hash = { version = "^0.9.6", path = "../git-hash" }

bstr = { version = "0.2.13", default-features = false, features = ["std"]}
thiserror = "1.0.26"
smallvec = "1.9.0"

Expand Down
88 changes: 83 additions & 5 deletions git-refspec/src/parse.rs
Expand Up @@ -11,7 +11,9 @@ pub enum Error {
#[error("Both sides of the specification need a pattern, like 'a/*:b/*'")]
PatternUnbalanced,
#[error(transparent)]
Refname(#[from] git_validate::refname::Error),
ReferenceName(#[from] git_validate::refname::Error),
#[error(transparent)]
RevSpec(#[from] git_revision::spec::parse::Error),
}

pub(crate) mod function {
Expand Down Expand Up @@ -84,8 +86,8 @@ pub(crate) mod function {
}
};

let (src, src_had_pattern) = validated(src)?;
let (dst, dst_had_pattern) = validated(dst)?;
let (src, src_had_pattern) = validated(src, operation == Operation::Push)?;
let (dst, dst_had_pattern) = validated(dst, false)?;
if mode != Mode::Negative && src_had_pattern != dst_had_pattern {
return Err(Error::PatternUnbalanced);
}
Expand All @@ -97,7 +99,7 @@ pub(crate) mod function {
})
}

fn validated(spec: Option<&BStr>) -> Result<(Option<&BStr>, bool), Error> {
fn validated(spec: Option<&BStr>, allow_revspecs: bool) -> Result<(Option<&BStr>, bool), Error> {
match spec {
Some(spec) => {
let glob_count = spec.iter().filter(|b| **b == b'*').take(2).count();
Expand All @@ -111,11 +113,87 @@ pub(crate) mod function {
buf[glob_pos] = b'a';
git_validate::reference::name_partial(buf.as_bstr())?;
} else {
git_validate::reference::name_partial(spec)?;
git_validate::reference::name_partial(spec)
.map_err(Error::from)
.or_else(|err| {
if allow_revspecs {
match git_revision::spec::parse(spec, &mut super::revparse::Noop) {
Ok(_) => {
if spec.iter().any(|b| b.is_ascii_whitespace()) {
Err(err)
} else {
Ok(spec)
}
}
Err(err) => Err(err.into()),
}
} else {
Err(err)
}
})?;
}
Ok((Some(spec), glob_count == 1))
}
None => Ok((None, false)),
}
}
}

mod revparse {
use bstr::BStr;
use git_revision::spec::parse::delegate::{
Kind, Navigate, PeelTo, PrefixHint, ReflogLookup, Revision, SiblingBranch, Traversal,
};

pub(crate) struct Noop;

impl Revision for Noop {
fn find_ref(&mut self, _name: &BStr) -> Option<()> {
Some(())
}

fn disambiguate_prefix(&mut self, _prefix: git_hash::Prefix, _hint: Option<PrefixHint<'_>>) -> Option<()> {
Some(())
}

fn reflog(&mut self, _query: ReflogLookup) -> Option<()> {
Some(())
}

fn nth_checked_out_branch(&mut self, _branch_no: usize) -> Option<()> {
Some(())
}

fn sibling_branch(&mut self, _kind: SiblingBranch) -> Option<()> {
Some(())
}
}

impl Navigate for Noop {
fn traverse(&mut self, _kind: Traversal) -> Option<()> {
Some(())
}

fn peel_until(&mut self, _kind: PeelTo<'_>) -> Option<()> {
Some(())
}

fn find(&mut self, _regex: &BStr, _negated: bool) -> Option<()> {
Some(())
}

fn index_lookup(&mut self, _path: &BStr, _stage: u8) -> Option<()> {
Some(())
}
}

impl Kind for Noop {
fn kind(&mut self, _kind: git_revision::spec::Kind) -> Option<()> {
Some(())
}
}

impl git_revision::spec::parse::Delegate for Noop {
fn done(&mut self) {}
}
}
1 change: 0 additions & 1 deletion git-refspec/tests/parse/mod.rs
Expand Up @@ -4,7 +4,6 @@ use git_testtools::scripted_fixture_repo_read_only;
use std::panic::catch_unwind;

#[test]
#[should_panic]
fn baseline() {
let dir = scripted_fixture_repo_read_only("make_baseline.sh").unwrap();
let baseline = std::fs::read(dir.join("baseline.git")).unwrap();
Expand Down

0 comments on commit 3fa52f8

Please sign in to comment.