History

prepare for multi-line parsing and all the bells and whistles

Sebastian Thiel committed 6 years ago

Commit 08f9ec41 parent 6dc57b36 files · +53 −28Browse files

Unified · Split

6 files
  1. README.md +3 −3
  2. git-odb/src/alternate.rs +22 −18
  3. git-odb/src/compound/init.rs +1 −3
  4. git-odb/src/compound/mod.rs +1 −1
  5. git-odb/tests/alternate/mod.rs +21 −3
  6. tasks.md +5 −0
README.md+3−3
@@ -91,9 +91,9 @@ become available. · 90 unmodified lines
91 * **sink**91 * **sink**
92 * [x] write objects and obtain id92 * [x] write objects and obtain id
93 * **alternates**93 * **alternates**
94 * [ ] _database that act as link to other known ODB types on disk_94 * [ ] _database that act as link to other known git ODBs on disk_
95 * [ ] handles cycles95 * [ ] safe with cycles and recursive configurations
96 * [ ] handles recursive configurations96 * [ ] multi-line with comments and quotes
97 * **multi-odb**97 * **multi-odb**
98 * [ ] _an ODB for object lookup from multiple lower level ODB at once_98 * [ ] _an ODB for object lookup from multiple lower level ODB at once_
99 * **promisor**99 * **promisor**
git-odb/src/alternate.rs+22−18
@@ -14,31 +14,35 @@ pub enum Error { · 13 unmodified lines
14 Cycle(Vec<PathBuf>),14 Cycle(Vec<PathBuf>),
15}15}
16 16
17pub fn resolve(objects_directory: impl Into<PathBuf>) -> Result<Option<compound::Db>, Error> {17pub fn resolve(objects_directory: impl Into<PathBuf>) -> Result<Vec<compound::Db>, Error> {
18 let mut dir = objects_directory.into();18 let mut dirs = vec![(0, objects_directory.into())];
19 let mut count = 0;19 let mut out = Vec::new();
20 let mut seen = Vec::new();20 let mut seen = Vec::new();
21 loop {21 while let Some((depth, dir)) = dirs.pop() {
22 if seen.contains(&dir) {22 if seen.contains(&dir) {
23 break Err(Error::Cycle(seen));23 return Err(Error::Cycle(seen));
24 }24 }
25 seen.push(dir.clone());25 seen.push(dir.clone());
26 let content = match fs::read(dir.join("info").join("alternates")) {26 match fs::read(dir.join("info").join("alternates")) {
27 Ok(d) => d,27 Ok(content) => {
28 dirs.push((
29 depth + 1,
30 content
31 .as_bstr()
32 .to_path()
33 .map(ToOwned::to_owned)
34 .map_err(|_| Error::PathConversion(content))?,
35 ));
36 }
28 Err(err) if err.kind() == io::ErrorKind::NotFound => {37 Err(err) if err.kind() == io::ErrorKind::NotFound => {
29 break if count == 0 {38 // Only resolve for repositories with at least one link, otherwise the line below isn't safe to call
30 Ok(None)39 if depth != 0 {
31 } else {40 // The tail of a chain doesn't have alternates, and thus is the real deal
32 Ok(Some(compound::Db::at(dir)?))41 out.push(compound::Db::at(dir)?);
33 }42 }
34 }43 }
35 Err(err) => break Err(err.into()),44 Err(err) => return Err(err.into()),
36 };45 };
37 dir = content
38 .as_bstr()
39 .to_path()
40 .map(ToOwned::to_owned)
41 .map_err(|_| Error::PathConversion(content))?;
42 count += 1;
43 }46 }
47 Ok(out)
44}48}
git-odb/src/compound/init.rs+1−3
@@ -35,9 +35,7 @@ impl compound::Db { · 34 unmodified lines
35 Ok(compound::Db {35 Ok(compound::Db {
36 loose: loose::Db::at(loose_objects.clone()),36 loose: loose::Db::at(loose_objects.clone()),
37 packs,37 packs,
38 alternate: crate::alternate::resolve(loose_objects)38 alternates: crate::alternate::resolve(loose_objects).map_err(Box::new)?,
39 .map_err(Box::new)?
40 .map(Box::new),
41 })39 })
42 }40 }
43}41}
git-odb/src/compound/mod.rs+1−1
@@ -3,7 +3,7 @@ use crate::{loose, pack}; · 2 unmodified lines
3pub struct Db {3pub struct Db {
4 pub loose: loose::Db,4 pub loose: loose::Db,
5 pub packs: Vec<pack::Bundle>,5 pub packs: Vec<pack::Bundle>,
6 pub alternate: Option<Box<Db>>,6 pub alternates: Vec<Db>,
7}7}
8 8
9pub mod object {9pub mod object {
git-odb/tests/alternate/mod.rs+21−3
@@ -2,12 +2,28 @@ use git_odb::alternate; · 1 unmodified line
2use std::{fs, io, path::PathBuf};2use std::{fs, io, path::PathBuf};
3 3
4fn alternate(objects_at: impl Into<PathBuf>, objects_to: impl Into<PathBuf>) -> Result<(PathBuf, PathBuf), io::Error> {4fn alternate(objects_at: impl Into<PathBuf>, objects_to: impl Into<PathBuf>) -> Result<(PathBuf, PathBuf), io::Error> {
5 alternate_with(objects_at, objects_to, None)
6}
7
8fn alternate_with(
9 objects_at: impl Into<PathBuf>,
10 objects_to: impl Into<PathBuf>,
11 content_before_to: Option<&str>,
12) -> Result<(PathBuf, PathBuf), io::Error> {
5 let at = objects_at.into();13 let at = objects_at.into();
6 let to = objects_to.into();14 let to = objects_to.into();
7 let at_info = at.join("info");15 let at_info = at.join("info");
8 fs::create_dir_all(&at_info)?;16 fs::create_dir_all(&at_info)?;
9 fs::create_dir_all(&to)?;17 fs::create_dir_all(&to)?;
10 fs::write(at_info.join("alternates"), to.to_string_lossy().as_bytes())?;18 let contents = if let Some(content) = content_before_to {
19 let mut c = vec![b'\n'];
20 c.extend(content.as_bytes());
21 c.extend(to.to_string_lossy().as_bytes());
22 c
23 } else {
24 to.to_string_lossy().as_bytes().to_owned()
25 };
26 fs::write(at_info.join("alternates"), contents)?;
11 Ok((at, to))27 Ok((at, to))
12}28}
13 29
@@ -38,13 +54,15 @@ fn single_link() -> crate::Result { · 24 unmodified lines
38 let non_alternate = tmp.path().join("actual");54 let non_alternate = tmp.path().join("actual");
39 55
40 let (from, to) = alternate(tmp.path().join("a"), non_alternate)?;56 let (from, to) = alternate(tmp.path().join("a"), non_alternate)?;
41 assert_eq!(alternate::resolve(from).unwrap().unwrap().loose.path, to);57 let alternates = alternate::resolve(from)?;
58 assert_eq!(alternates.len(), 1);
59 assert_eq!(alternates[0].loose.path, to);
42 Ok(())60 Ok(())
43}61}
44 62
45#[test]63#[test]
46fn no_alternate_in_first_objects_dir() -> crate::Result {64fn no_alternate_in_first_objects_dir() -> crate::Result {
47 let tmp = tempdir::TempDir::new("alternates")?;65 let tmp = tempdir::TempDir::new("alternates")?;
48 assert!(alternate::resolve(tmp.path()).unwrap().is_none());66 assert!(alternate::resolve(tmp.path())?.is_empty());
49 Ok(())67 Ok(())
50}68}
tasks.md+5−0
@@ -11,6 +11,11 @@ · 10 unmodified lines
11 * [x] alternate DB (location - it's really must following the chain until a compound DB can be created)11 * [x] alternate DB (location - it's really must following the chain until a compound DB can be created)
12 * [x] circular dependencies test12 * [x] circular dependencies test
13 * [x] basic test13 * [x] basic test
14 * [ ] are multiple alternates supported, too? YES
15 * [ ] comments
16 * [ ] quotes
17 * [ ] support for relative directories
18 * [ ] alternates lookup
14 * [x] loose upgrade: jwalk powered iteration behind a feature flag19 * [x] loose upgrade: jwalk powered iteration behind a feature flag
15 * [ ] full docs20 * [ ] full docs
16* **git-config**21* **git-config**