Skip to content

Commit

Permalink
Add filters to edenfs_client get_status to match Thrift API
Browse files Browse the repository at this point in the history
Summary:
# Context

We are introducing EdenFS notifications to support scalable and ergonomic file system notifications for EdenFS mounts.

# This Diff

* Adds filter support, includes/exclude of roots/suffixes, to get_status call. Ideally, we would repalce this with a new function that returns an interator, but we can add later when there is more time.

# Next Steps

* Complete the remaining FileWatcher methods

Differential Revision: D68973041

fbshipit-source-id: 5f4208d2dec22f07e7b6767a198ba41894fed252
  • Loading branch information
jdelliot authored and facebook-github-bot committed Feb 1, 2025
1 parent 971ea2d commit cff500a
Showing 1 changed file with 67 additions and 6 deletions.
73 changes: 67 additions & 6 deletions eden/fs/cli_rs/edenfs-client/src/sapling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,21 @@ pub async fn get_mergebase(commit: &str, mergegase_with: &str) -> anyhow::Result

// Get status between two revisions. If second is None, then it is the working copy.
// Limit the number of results to limit_results. If the number of results is greater than
// limit_results return TooManyResults.
pub async fn get_status(
// limit_results return TooManyResults. Apply root and suffix filters if provided.
// TODO: replace with a method that returns an iterator over (SaplingStatus, String)
pub async fn get_status<P, S>(
first: &str,
second: Option<&str>,
limit_results: usize,
) -> anyhow::Result<SaplingGetStatusResult> {
excluded_roots: Option<&[P]>,
included_roots: Option<&[P]>,
excluded_suffixes: Option<&[S]>,
included_suffixes: Option<&[S]>,
) -> anyhow::Result<SaplingGetStatusResult>
where
P: AsRef<Path>,
S: AsRef<str> + AsRef<Path>,
{
let mut args = vec!["status", "-mardu", "--rev", first];
if let Some(second) = second {
args.push("--rev");
Expand All @@ -127,10 +136,18 @@ pub async fn get_status(
let mut lines = reader.lines();
while let Some(line) = lines.next_line().await? {
if let Some(status_line) = process_one_status_line(&line)? {
if status.len() >= limit_results {
return Ok(SaplingGetStatusResult::TooManyChanges);
if is_path_included(
&status_line.1,
&excluded_roots,
&included_roots,
&excluded_suffixes,
&included_suffixes,
) {
if status.len() >= limit_results {
return Ok(SaplingGetStatusResult::TooManyChanges);
}
status.push(status_line);
}
status.push(status_line);
}
}

Expand Down Expand Up @@ -173,6 +190,50 @@ fn process_one_status_line(line: &str) -> anyhow::Result<Option<(SaplingStatus,
}
}

fn is_path_included<P, S>(
path: &str,
excluded_roots: &Option<&[P]>,
included_roots: &Option<&[P]>,
excluded_suffixes: &Option<&[S]>,
included_suffixes: &Option<&[S]>,
) -> bool
where
P: AsRef<Path>,
S: AsRef<str> + AsRef<Path>,
{
let path = Path::new(path);

if !included_roots.map_or(true, |roots| {
roots
.iter()
.any(|included_root| path.starts_with(included_root))
}) {
return false;
}

if !included_suffixes.map_or(true, |suffixes| {
suffixes.iter().any(|suffix| path.ends_with(suffix))
}) {
return false;
}

if excluded_roots.map_or(false, |roots| {
roots
.iter()
.any(|excluded_root| path.starts_with(excluded_root))
}) {
return false;
}

if excluded_suffixes.map_or(false, |suffixes| {
suffixes.iter().any(|suffix| path.ends_with(suffix))
}) {
return false;
}
// Path should be included
true
}

#[cfg(test)]
mod tests {
use crate::sapling::*;
Expand Down

0 comments on commit cff500a

Please sign in to comment.