Skip to content

feat(core+cli): add --recursive to dvs get#203

Open
CGMossa wants to merge 1 commit into
mainfrom
feat/dvs-get-recursive-core
Open

feat(core+cli): add --recursive to dvs get#203
CGMossa wants to merge 1 commit into
mainfrom
feat/dvs-get-recursive-core

Conversation

@CGMossa
Copy link
Copy Markdown
Contributor

@CGMossa CGMossa commented May 16, 2026

AI-written details

Summary

Rust-only layer of dvs get --recursive. Carved out of #154 as part of a 3-way split (this PR → rpkg binding → ui walkthrough).

  • dvs/src/globbing.rs: resolve_paths_for_get gains a recursive parameter so a positional directory argument can be walked recursively without requiring an explicit --glob. Mirrors the existing recursive behavior of dvs status for command symmetry. New tests cover directory + recursive, mixed file/directory inputs, and the no-glob default path.
  • dvs-cli/src/main.rs: dvs get gains -r, --recursive (clap short + long) wired through to resolve_paths_for_get.
  • dvs/src/files/status.rs: one-line propagation of the new globbing signature.

No behavior change for callers that don't pass --recursive.

Test plan

  • cargo test -p dvs --lib passes (73 + new cases)
  • cargo check --workspace -- -D warnings clean
  • ./target/release/dvs get --help shows -r, --recursive
  • ./target/release/dvs get some/dir -r walks the directory; without -r it errors as before

Follow-ups

  • dvs-rpkg binding for dvs_get(recursive = ...) — separate PR (depends on this).
  • ui walkthrough ui/main_recursive.sh exercising the matrix across add/get/status — separate PR.

Drafted by Claude (claude-opus-4-7). Reviewed by the author.

Carved out of #154 as the Rust-only layer. The R binding and the
ui walkthrough follow as separate PRs.

In dvs/src/globbing.rs:
- resolve_paths_for_get gains a `recursive` parameter so that a
  positional directory argument can be walked recursively without
  requiring an explicit --glob. Mirrors the existing recursive
  behavior of `dvs status` for symmetry.
- New tests cover: directory + recursive flag, mixed file +
  directory inputs, and the no-glob default path.

In dvs-cli/src/main.rs:
- `dvs get` gains `-r, --recursive` (clap short+long) wired through
  to resolve_paths_for_get.

In dvs/src/files/status.rs:
- One-line touch propagating the new globbing signature.

No behavior change for callers that don't pass --recursive.
@CGMossa CGMossa force-pushed the feat/dvs-get-recursive-core branch from 64dd1e1 to d340c2b Compare May 17, 2026 09:17
Comment thread dvs-cli/src/main.rs
/// At least one path or --glob must be provided.
#[command(next_display_order = 100)]
Get {
#[clap(required_unless_present = "glob")]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather keep that than custom error messages since the CLI is unlikely to be used by most people, let's keep it simple.

Comment thread dvs/src/files/status.rs
/// We need to handle `.`, `./` etc but we can't canonicalize because
/// the path might not exist and we want the path relative to the directory so no symlink resolution
fn normalize_path(p: PathBuf) -> Option<PathBuf> {
pub(crate) fn normalize_path(p: PathBuf) -> Option<PathBuf> {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move it somewhere else if it's used by other parts of the code

Comment thread dvs/src/globbing.rs
// If no paths given, default to cwd (or repo root if at root)
let dir_filters: Vec<PathBuf> = if paths.is_empty() {
vec![cwd_prefix.map(|p| p.to_path_buf()).unwrap_or_default()]
// None means no path restriction — all tracked files under cwd are candidates.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is that true? It's later that the files under cwd is handled

Comment thread dvs/src/globbing.rs
vec![cwd_prefix.map(|p| p.to_path_buf()).unwrap_or_default()]
// None means no path restriction — all tracked files under cwd are candidates.
// The `recursive` flag only applies when explicit paths are given.
let dir_filters: Option<Vec<PathBuf>> = if paths.is_empty() {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't need the Option, it makes things more confusing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants