Skip to content

predicates::path::missing() should handle broken symlinks #118

Description

@gibfahn

The docs for predicates::path::missing() say:

Creates a new Predicate that ensures the path doesn’t exist.

However, if the path is a symlink pointing to nothing, then it will be treated as not existing, when in fact the symlink is a file that exists.

Open to the idea that a broken link should count as not existing, but either way it would be useful for the function's docs to cover this.

It also gets complicated as a symlink may start to exist or not exist based on changes to other parts of the filesystem.

I tried this code:

use predicates::prelude::*;
use std::{fs, os::unix, path::Path};

fn main() {
    let _ = fs::remove_file("symlink-to-non-existent-path");
    unix::fs::symlink("non-existent-path", "symlink-to-non-existent-path").unwrap();

    let predicate_fn = predicate::path::missing();
    // Shouldn't be missing as symlink is a real file.
    assert_eq!(false, predicate_fn.eval(Path::new("non-existent-file.foo")));
}

I expected the assert to pass, but it failed.

Meta

predicates-rs version: 2.1.0
rustc --version: 1.57.0

I think instead of:

    fn eval(&self, path: &path::Path) -> bool {
        path.exists() == self.exists
    }
    fn eval(&self, path: &path::Path) -> bool {
        ( path.exists() || path.symlink_metadata().is_ok() ) == self.exists
    }

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions