Skip to content

Commit

Permalink
frmae for dir walking and handling of untracked files.
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Jan 4, 2024
1 parent 696cbb8 commit fe143ee
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 23 deletions.
51 changes: 28 additions & 23 deletions Cargo.lock

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

6 changes: 6 additions & 0 deletions gix-dir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,9 @@ rust-version = "1.65"
doctest = false

[dependencies]
gix-index = { version = "^0.28.1", path = "../gix-index" }

thiserror = "1.0.56"

[dev-dependencies]
gix-testtools = { path = "../tests/tools" }
93 changes: 93 additions & 0 deletions gix-dir/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,96 @@
//! A crate for handling a git-style directory walk.
#![deny(rust_2018_idioms)]
#![forbid(unsafe_code)]

/// A directory entry, typically obtained using [`walk()`].
pub struct Entry<'a> {
/// The path at which the file or directory could be found.
pub path: &'a Path,
/// The kind of entry.
pub kind: entry::Kind,
pub mode: entry::Mode,
}

///
pub mod entry {

/// The git-style filesystem mode.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum Mode {
/// The entry is a blob, executable or not.
Blob,
/// The entry is a symlink.
Symlink,
/// The entry is an ordinary directory, which is either untracked or ignored along with all its contents.
Directory,
/// The entry is a directory which contains a `.git` folder.
Submodule,
}

/// The kind of entry as obtained from a directory.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum Kind {
/// The entry is not tracked by git yet, it was not found in the [index](gix_index::State).
Untracked,
}
}

///
pub mod walk {
/// Options for use in [`walk()`] function.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub struct Options {
/// If true, the filesystem will store paths as decomposed unicode, i.e. `ä` becomes `"a\u{308}"`, which means that
/// we have to turn these forms back from decomposed to precomposed unicode before storing it in the index or generally
/// using it. This also applies to input received from the command-line, so callers may have to be aware of this and
/// perform conversions accordingly.
/// If false, no conversions will be performed.
pub precompose_unicode: bool,
/// If true, the filesystem ignores the case of input, which makes `A` the same file as `a`.
/// This is also called case-folding.
pub ignore_case: bool,
}

/// Additional information collected as outcome of [`walk()`].
#[derive(Debug, Clone, Copy)]
pub struct Outcome {
/// The amount of calls to read the directory contents.
pub read_dir_calls: usize,
/// The amount of returned entries.
pub returned_entries: usize,
/// The amount of entries, prior to pathspecs filtering them out or otherwise excluding them.
pub seen_entries: usize,
}

/// The error returned by [`walk()`].
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
#[error("TBD")]
pub enum Error {}

pub(crate) mod function {
use crate::walk::{Error, Options, Outcome};
use std::path::Path;

/// A function to perform a git-style directory walk.
///
/// * `root` - the starting point of the walk and a readable directory.
/// * `worktree_root` - the top-most root of the worktree, which must be a prefix to `root`.
/// * `index` - access to see which files or directories are tracked.
pub fn walk(
root: &Path,
worktree_root: &Path,
_index: &gix_index::State,
_options: Options,
) -> Result<Outcome, Error> {
debug_assert!(
root.strip_prefix(worktree_root).is_ok(),
"{root:?} must be contained in {worktree_root:?}"
);
todo!()
}
}
}

use std::path::Path;
pub use walk::function::walk;
3 changes: 3 additions & 0 deletions gix-dir/tests/dir.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub use gix_testtools::Result;

mod walk;
Binary file not shown.
17 changes: 17 additions & 0 deletions gix-dir/tests/fixtures/walk_baseline.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash
set -eu -o pipefail


function baseline() {
local name=${1:?First argument is the repo path to get the status baseline from}
git -C $name status --porcelain=2 > ${name}.baseline
}

git init untracked-in-root
(cd untracked-in-root
touch file
mkdir dir
touch dir/a dir/b
)

baseline untracked-in-root
32 changes: 32 additions & 0 deletions gix-dir/tests/walk/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use gix_testtools::scripted_fixture_read_only;

mod baseline {
use std::path::Path;

/// Parse multiple walks out of a single `fixture`.
pub fn extract_walks(_fixture: &Path) -> crate::Result {
Ok(())
}
}

#[test]
fn baseline() -> crate::Result {
let _sets = baseline::extract_walks(&scripted_fixture_read_only("walk_baseline.sh")?)?;
Ok(())
}

#[test]
#[ignore = "to be implemented"]
fn precompose_unicode() {}

#[test]
#[ignore = "need case-insensitive testing as well"]
fn case_insensitive_usecases() {}

#[test]
#[ignore = "what about partial checkouts?"]
fn partial_checkouts() {}

#[test]
#[ignore = "what about submodules - are they treated specifically?"]
fn submodules() {}

0 comments on commit fe143ee

Please sign in to comment.