Skip to content

Commit fa548ce

Browse files
committed
[git-ref] clear it out and move existing functionality to git-object
This removes an uncanny dependency. Maybe now we have it the other way around. Possibly there should be a new crate to contain shared validation code? Maybe it should just be duplicated? No, that could mean code drift. It makes sense for the functionality to be included in the crate that needs it, so lets see what kind of input validation needs to happen for refs to work and if it truly is the same. As it's pretty stable there shouldn't be too much worry about somewhat similar code to exist in various crates.
1 parent 251e690 commit fa548ce

File tree

11 files changed

+77
-75
lines changed

11 files changed

+77
-75
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

git-object/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ serde1 = ["serde", "bstr/serde1", "smallvec/serde", "git-hash/serde1"]
1818
all-features = true
1919

2020
[dependencies]
21-
git-ref = { version = "^0.5.0", path = "../git-ref" }
2221
git-hash = { version = "^0.3.0", path = "../git-hash" }
2322
quick-error = "2.0.0"
2423
hex = "0.4.2"

git-object/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@ pub use types::{tree, Error, Kind, Sign, Time};
1616

1717
///
1818
pub mod commit;
19+
///
20+
pub mod tag;

git-object/src/mutable/tag.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ quick_error! {
1010
StartsWithDash {
1111
display("Tags must not start with a dash: '-'")
1212
}
13-
InvalidRefName(err: git_ref::validate::NameError) {
13+
InvalidRefName(err: crate::tag::validate::NameError) {
1414
display("The tag name was no valid reference name")
1515
from()
1616
source(err)
@@ -65,7 +65,7 @@ impl Tag {
6565
}
6666

6767
fn validated_name(name: &BStr) -> Result<&BStr, Error> {
68-
git_ref::validate::name(name)?;
68+
crate::tag::validate::name(name)?;
6969
if name[0] == b'-' {
7070
return Err(Error::StartsWithDash);
7171
}

git-object/src/tag.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
///
2+
pub mod validate {
3+
use bstr::{BStr, BString};
4+
use quick_error::quick_error;
5+
6+
quick_error! {
7+
/// The error returned by [`name()`]
8+
#[derive(Debug)]
9+
#[allow(missing_docs)]
10+
pub enum NameError {
11+
InvalidByte(name: BString) {
12+
display("A ref must not contain invalid bytes or ascii control characters: '{}'", name)
13+
}
14+
DoubleDot {
15+
display("A ref must not contain '..' as it may be mistaken for a range")
16+
}
17+
LockFileSuffix {
18+
display("A ref must not end with '.lock'")
19+
}
20+
ReflogPortion {
21+
display("A ref must not contain '@{{' which is a part of a ref-log")
22+
}
23+
Asterisk {
24+
display("A ref must not contain '*' character")
25+
}
26+
StartsWithDot {
27+
display("A ref must not start with a '.'")
28+
}
29+
EndsWithSlash {
30+
display("A ref must not end with a '/'")
31+
}
32+
Empty {
33+
display("A ref must not be empty")
34+
}
35+
}
36+
}
37+
38+
/// Assure the given `bytes` resemble a valid git ref name, which are returned unchanged on success.
39+
pub fn name(bytes: &BStr) -> Result<&BStr, NameError> {
40+
if bytes.is_empty() {
41+
return Err(NameError::Empty);
42+
}
43+
44+
let mut last = 0;
45+
for byte in bytes.iter() {
46+
match byte {
47+
b'\\' | b'^' | b':' | b'[' | b'?' | b' ' | b'~' | b'\0'..=b'\x1F' | b'\x7F' => {
48+
return Err(NameError::InvalidByte(bytes.into()))
49+
}
50+
b'*' => return Err(NameError::Asterisk),
51+
b'.' if last == b'.' => return Err(NameError::DoubleDot),
52+
b'{' if last == b'@' => return Err(NameError::ReflogPortion),
53+
_ => {}
54+
}
55+
last = *byte;
56+
}
57+
if bytes[0] == b'.' {
58+
return Err(NameError::StartsWithDot);
59+
}
60+
if *bytes.last().expect("non-empty") == b'/' {
61+
return Err(NameError::EndsWithSlash);
62+
}
63+
if bytes.ends_with(b".lock") {
64+
return Err(NameError::LockFileSuffix);
65+
}
66+
Ok(bytes)
67+
}
68+
}

git-object/tests/object.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::path::PathBuf;
22

33
mod immutable;
44
mod mutable;
5+
mod tag;
56

67
type Result<T = ()> = std::result::Result<T, Box<dyn std::error::Error>>;
78

git-object/tests/tag/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mod validate;

git-ref/tests/validated/mod.rs renamed to git-object/tests/tag/validate.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
mod name {
22
mod valid {
33
use bstr::ByteSlice;
4-
use git_ref::validate;
4+
use git_object::tag::validate;
55

66
macro_rules! mktest {
77
($name:ident, $input:expr) => {
@@ -26,7 +26,7 @@ mod name {
2626

2727
mod invalid {
2828
use bstr::ByteSlice;
29-
use git_ref::validate;
29+
use git_object::tag::validate;
3030

3131
macro_rules! mktest {
3232
($name:ident, $input:literal, $expected:ident) => {

git-ref/src/lib.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
11
//! Various functionality related to git references
22
#![forbid(unsafe_code)]
33
#![deny(missing_docs, rust_2018_idioms)]
4-
5-
///
6-
pub mod validate;

git-ref/src/validate.rs

Lines changed: 0 additions & 65 deletions
This file was deleted.

0 commit comments

Comments
 (0)