Skip to content

Commit fe143ee

Browse files
committed
frmae for dir walking and handling of untracked files.
1 parent 696cbb8 commit fe143ee

File tree

7 files changed

+179
-23
lines changed

7 files changed

+179
-23
lines changed

Cargo.lock

Lines changed: 28 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gix-dir/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,9 @@ rust-version = "1.65"
1212
doctest = false
1313

1414
[dependencies]
15+
gix-index = { version = "^0.28.1", path = "../gix-index" }
16+
17+
thiserror = "1.0.56"
18+
19+
[dev-dependencies]
20+
gix-testtools = { path = "../tests/tools" }

gix-dir/src/lib.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,96 @@
11
//! A crate for handling a git-style directory walk.
22
#![deny(rust_2018_idioms)]
33
#![forbid(unsafe_code)]
4+
5+
/// A directory entry, typically obtained using [`walk()`].
6+
pub struct Entry<'a> {
7+
/// The path at which the file or directory could be found.
8+
pub path: &'a Path,
9+
/// The kind of entry.
10+
pub kind: entry::Kind,
11+
pub mode: entry::Mode,
12+
}
13+
14+
///
15+
pub mod entry {
16+
17+
/// The git-style filesystem mode.
18+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
19+
pub enum Mode {
20+
/// The entry is a blob, executable or not.
21+
Blob,
22+
/// The entry is a symlink.
23+
Symlink,
24+
/// The entry is an ordinary directory, which is either untracked or ignored along with all its contents.
25+
Directory,
26+
/// The entry is a directory which contains a `.git` folder.
27+
Submodule,
28+
}
29+
30+
/// The kind of entry as obtained from a directory.
31+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
32+
pub enum Kind {
33+
/// The entry is not tracked by git yet, it was not found in the [index](gix_index::State).
34+
Untracked,
35+
}
36+
}
37+
38+
///
39+
pub mod walk {
40+
/// Options for use in [`walk()`] function.
41+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
42+
pub struct Options {
43+
/// If true, the filesystem will store paths as decomposed unicode, i.e. `ä` becomes `"a\u{308}"`, which means that
44+
/// we have to turn these forms back from decomposed to precomposed unicode before storing it in the index or generally
45+
/// using it. This also applies to input received from the command-line, so callers may have to be aware of this and
46+
/// perform conversions accordingly.
47+
/// If false, no conversions will be performed.
48+
pub precompose_unicode: bool,
49+
/// If true, the filesystem ignores the case of input, which makes `A` the same file as `a`.
50+
/// This is also called case-folding.
51+
pub ignore_case: bool,
52+
}
53+
54+
/// Additional information collected as outcome of [`walk()`].
55+
#[derive(Debug, Clone, Copy)]
56+
pub struct Outcome {
57+
/// The amount of calls to read the directory contents.
58+
pub read_dir_calls: usize,
59+
/// The amount of returned entries.
60+
pub returned_entries: usize,
61+
/// The amount of entries, prior to pathspecs filtering them out or otherwise excluding them.
62+
pub seen_entries: usize,
63+
}
64+
65+
/// The error returned by [`walk()`].
66+
#[derive(Debug, thiserror::Error)]
67+
#[allow(missing_docs)]
68+
#[error("TBD")]
69+
pub enum Error {}
70+
71+
pub(crate) mod function {
72+
use crate::walk::{Error, Options, Outcome};
73+
use std::path::Path;
74+
75+
/// A function to perform a git-style directory walk.
76+
///
77+
/// * `root` - the starting point of the walk and a readable directory.
78+
/// * `worktree_root` - the top-most root of the worktree, which must be a prefix to `root`.
79+
/// * `index` - access to see which files or directories are tracked.
80+
pub fn walk(
81+
root: &Path,
82+
worktree_root: &Path,
83+
_index: &gix_index::State,
84+
_options: Options,
85+
) -> Result<Outcome, Error> {
86+
debug_assert!(
87+
root.strip_prefix(worktree_root).is_ok(),
88+
"{root:?} must be contained in {worktree_root:?}"
89+
);
90+
todo!()
91+
}
92+
}
93+
}
94+
95+
use std::path::Path;
96+
pub use walk::function::walk;

gix-dir/tests/dir.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub use gix_testtools::Result;
2+
3+
mod walk;
Binary file not shown.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/bin/bash
2+
set -eu -o pipefail
3+
4+
5+
function baseline() {
6+
local name=${1:?First argument is the repo path to get the status baseline from}
7+
git -C $name status --porcelain=2 > ${name}.baseline
8+
}
9+
10+
git init untracked-in-root
11+
(cd untracked-in-root
12+
touch file
13+
mkdir dir
14+
touch dir/a dir/b
15+
)
16+
17+
baseline untracked-in-root

gix-dir/tests/walk/mod.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use gix_testtools::scripted_fixture_read_only;
2+
3+
mod baseline {
4+
use std::path::Path;
5+
6+
/// Parse multiple walks out of a single `fixture`.
7+
pub fn extract_walks(_fixture: &Path) -> crate::Result {
8+
Ok(())
9+
}
10+
}
11+
12+
#[test]
13+
fn baseline() -> crate::Result {
14+
let _sets = baseline::extract_walks(&scripted_fixture_read_only("walk_baseline.sh")?)?;
15+
Ok(())
16+
}
17+
18+
#[test]
19+
#[ignore = "to be implemented"]
20+
fn precompose_unicode() {}
21+
22+
#[test]
23+
#[ignore = "need case-insensitive testing as well"]
24+
fn case_insensitive_usecases() {}
25+
26+
#[test]
27+
#[ignore = "what about partial checkouts?"]
28+
fn partial_checkouts() {}
29+
30+
#[test]
31+
#[ignore = "what about submodules - are they treated specifically?"]
32+
fn submodules() {}

0 commit comments

Comments
 (0)