rust/rhg/src/commands/status.rs
branchstable
changeset 49000 dd6b67d5c256
parent 48738 00efd2d5037d
child 49110 4d3f6767319f
--- a/rust/rhg/src/commands/status.rs	Tue Apr 05 10:55:27 2022 +0200
+++ b/rust/rhg/src/commands/status.rs	Tue Apr 05 10:55:28 2022 +0200
@@ -25,6 +25,9 @@
 use hg::utils::files::get_bytes_from_path;
 use hg::utils::files::get_path_from_bytes;
 use hg::utils::hg_path::{hg_path_to_path_buf, HgPath};
+use hg::DirstateStatus;
+use hg::PatternFileWarning;
+use hg::StatusError;
 use hg::StatusOptions;
 use log::info;
 use std::io;
@@ -230,117 +233,132 @@
         list_copies,
         collect_traversed_dirs: false,
     };
-    let (mut ds_status, pattern_warnings) = dmap.status(
-        &AlwaysMatcher,
-        repo.working_directory_path().to_owned(),
-        ignore_files(repo, config),
-        options,
-    )?;
-    for warning in pattern_warnings {
-        match warning {
-            hg::PatternFileWarning::InvalidSyntax(path, syntax) => ui
-                .write_stderr(&format_bytes!(
-                    b"{}: ignoring invalid syntax '{}'\n",
-                    get_bytes_from_path(path),
-                    &*syntax
-                ))?,
-            hg::PatternFileWarning::NoSuchFile(path) => {
-                let path = if let Ok(relative) =
-                    path.strip_prefix(repo.working_directory_path())
-                {
-                    relative
-                } else {
-                    &*path
-                };
-                ui.write_stderr(&format_bytes!(
-                    b"skipping unreadable pattern file '{}': \
-                      No such file or directory\n",
-                    get_bytes_from_path(path),
-                ))?
+
+    type StatusResult<'a> =
+        Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>;
+
+    let after_status = |res: StatusResult| -> Result<_, CommandError> {
+        let (mut ds_status, pattern_warnings) = res?;
+        for warning in pattern_warnings {
+            match warning {
+                hg::PatternFileWarning::InvalidSyntax(path, syntax) => ui
+                    .write_stderr(&format_bytes!(
+                        b"{}: ignoring invalid syntax '{}'\n",
+                        get_bytes_from_path(path),
+                        &*syntax
+                    ))?,
+                hg::PatternFileWarning::NoSuchFile(path) => {
+                    let path = if let Ok(relative) =
+                        path.strip_prefix(repo.working_directory_path())
+                    {
+                        relative
+                    } else {
+                        &*path
+                    };
+                    ui.write_stderr(&format_bytes!(
+                        b"skipping unreadable pattern file '{}': \
+                          No such file or directory\n",
+                        get_bytes_from_path(path),
+                    ))?
+                }
             }
         }
-    }
 
-    for (path, error) in ds_status.bad {
-        let error = match error {
-            hg::BadMatch::OsError(code) => {
-                std::io::Error::from_raw_os_error(code).to_string()
-            }
-            hg::BadMatch::BadType(ty) => {
-                format!("unsupported file type (type is {})", ty)
-            }
-        };
-        ui.write_stderr(&format_bytes!(
-            b"{}: {}\n",
-            path.as_bytes(),
-            error.as_bytes()
-        ))?
-    }
-    if !ds_status.unsure.is_empty() {
-        info!(
-            "Files to be rechecked by retrieval from filelog: {:?}",
-            ds_status.unsure.iter().map(|s| &s.path).collect::<Vec<_>>()
-        );
-    }
-    let mut fixup = Vec::new();
-    if !ds_status.unsure.is_empty()
-        && (display_states.modified || display_states.clean)
-    {
-        let p1 = repo.dirstate_parents()?.p1;
-        let manifest = repo.manifest_for_node(p1).map_err(|e| {
-            CommandError::from((e, &*format!("{:x}", p1.short())))
-        })?;
-        for to_check in ds_status.unsure {
-            if unsure_is_modified(repo, &manifest, &to_check.path)? {
-                if display_states.modified {
-                    ds_status.modified.push(to_check);
+        for (path, error) in ds_status.bad {
+            let error = match error {
+                hg::BadMatch::OsError(code) => {
+                    std::io::Error::from_raw_os_error(code).to_string()
+                }
+                hg::BadMatch::BadType(ty) => {
+                    format!("unsupported file type (type is {})", ty)
                 }
-            } else {
-                if display_states.clean {
-                    ds_status.clean.push(to_check.clone());
+            };
+            ui.write_stderr(&format_bytes!(
+                b"{}: {}\n",
+                path.as_bytes(),
+                error.as_bytes()
+            ))?
+        }
+        if !ds_status.unsure.is_empty() {
+            info!(
+                "Files to be rechecked by retrieval from filelog: {:?}",
+                ds_status.unsure.iter().map(|s| &s.path).collect::<Vec<_>>()
+            );
+        }
+        let mut fixup = Vec::new();
+        if !ds_status.unsure.is_empty()
+            && (display_states.modified || display_states.clean)
+        {
+            let p1 = repo.dirstate_parents()?.p1;
+            let manifest = repo.manifest_for_node(p1).map_err(|e| {
+                CommandError::from((e, &*format!("{:x}", p1.short())))
+            })?;
+            for to_check in ds_status.unsure {
+                if unsure_is_modified(repo, &manifest, &to_check.path)? {
+                    if display_states.modified {
+                        ds_status.modified.push(to_check);
+                    }
+                } else {
+                    if display_states.clean {
+                        ds_status.clean.push(to_check.clone());
+                    }
+                    fixup.push(to_check.path.into_owned())
                 }
-                fixup.push(to_check.path.into_owned())
             }
         }
-    }
-    let relative_paths = (!ui.plain(None))
-        && config
-            .get_option(b"commands", b"status.relative")?
-            .unwrap_or(config.get_bool(b"ui", b"relative-paths")?);
-    let output = DisplayStatusPaths {
-        ui,
-        no_status,
-        relativize: if relative_paths {
-            Some(RelativizePaths::new(repo)?)
-        } else {
-            None
-        },
+        let relative_paths = (!ui.plain(None))
+            && config
+                .get_option(b"commands", b"status.relative")?
+                .unwrap_or(config.get_bool(b"ui", b"relative-paths")?);
+        let output = DisplayStatusPaths {
+            ui,
+            no_status,
+            relativize: if relative_paths {
+                Some(RelativizePaths::new(repo)?)
+            } else {
+                None
+            },
+        };
+        if display_states.modified {
+            output.display(b"M ", "status.modified", ds_status.modified)?;
+        }
+        if display_states.added {
+            output.display(b"A ", "status.added", ds_status.added)?;
+        }
+        if display_states.removed {
+            output.display(b"R ", "status.removed", ds_status.removed)?;
+        }
+        if display_states.deleted {
+            output.display(b"! ", "status.deleted", ds_status.deleted)?;
+        }
+        if display_states.unknown {
+            output.display(b"? ", "status.unknown", ds_status.unknown)?;
+        }
+        if display_states.ignored {
+            output.display(b"I ", "status.ignored", ds_status.ignored)?;
+        }
+        if display_states.clean {
+            output.display(b"C ", "status.clean", ds_status.clean)?;
+        }
+
+        let dirstate_write_needed = ds_status.dirty;
+        let filesystem_time_at_status_start =
+            ds_status.filesystem_time_at_status_start;
+
+        Ok((
+            fixup,
+            dirstate_write_needed,
+            filesystem_time_at_status_start,
+        ))
     };
-    if display_states.modified {
-        output.display(b"M ", "status.modified", ds_status.modified)?;
-    }
-    if display_states.added {
-        output.display(b"A ", "status.added", ds_status.added)?;
-    }
-    if display_states.removed {
-        output.display(b"R ", "status.removed", ds_status.removed)?;
-    }
-    if display_states.deleted {
-        output.display(b"! ", "status.deleted", ds_status.deleted)?;
-    }
-    if display_states.unknown {
-        output.display(b"? ", "status.unknown", ds_status.unknown)?;
-    }
-    if display_states.ignored {
-        output.display(b"I ", "status.ignored", ds_status.ignored)?;
-    }
-    if display_states.clean {
-        output.display(b"C ", "status.clean", ds_status.clean)?;
-    }
-
-    let mut dirstate_write_needed = ds_status.dirty;
-    let filesystem_time_at_status_start =
-        ds_status.filesystem_time_at_status_start;
+    let (fixup, mut dirstate_write_needed, filesystem_time_at_status_start) =
+        dmap.with_status(
+            &AlwaysMatcher,
+            repo.working_directory_path().to_owned(),
+            ignore_files(repo, config),
+            options,
+            after_status,
+        )?;
 
     if (fixup.is_empty() || filesystem_time_at_status_start.is_none())
         && !dirstate_write_needed