Repository: lalrpop/lalrpop (language: rust)

Issue:
Dangling symlinks anywhere in the crate cause obscure build failures
How to reproduce:
1. Create a new crate with `build.rs` file `fn main() { lalrpop::process_root().unwrap() }`
2. Create a dangling symlink: `ln -sf /file/does/not/exist dangling-symlink`
3. Run `cargo build`:

```shell
$ cargo build
   Compiling cargo-dangling-symlinks v0.1.0 (/home/liri/cargo-dangling-symlinks)
error: failed to run custom build command for `cargo-dangling-symlinks v0.1.0 (/home/liri/cargo-dangling-symlinks)`

Caused by:
  process didn't exit successfully: `/home/liri/cargo-dangling-symlinks/target/debug/build/cargo-dangling-symlinks-6e4fe4fd1c3bb576/build-script-build` (exit status: 101)
  --- stderr
  thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', build.rs:2:29
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```

Full crate example: https://github.com/legeana/lalrpop-dangling-symlinks

This was quite frustrating to debug as the error message is extremely obscure. I had to resort to `strace -f target/.../build-script-build` to determine what file lalrpop was trying to open.

I believe lalrpop should do two things:
1. Improve error messages by indicating the path that doesn't exist.
2. Ignore dangling symlinks.



Discussion / hints:
Hi! Thanks for reporting. I personally have little time currently to dive in new issues on LALRPOP, but I would be happy to review and merge any PR fixing this.

Fix patch:
diff --git a/lalrpop/src/build/mod.rs b/lalrpop/src/build/mod.rs
index 9bcb6d4c7..02f906470 100644
--- a/lalrpop/src/build/mod.rs
+++ b/lalrpop/src/build/mod.rs
@@ -186,16 +186,26 @@ fn lalrpop_files<P: AsRef<Path>>(root_dir: P) -> io::Result<Vec<PathBuf>> {
             result.extend(lalrpop_files(&path)?);
         }
 
-        let is_symlink_file = || -> io::Result<bool> {
+        let is_valid_symlink_file = || -> bool {
             if !file_type.is_symlink() {
-                Ok(false)
+                false
             } else {
-                // Ensure all symlinks are resolved
-                Ok(fs::metadata(&path)?.is_file())
+                // Ensure all symlinks are resolved to a file
+                // Or ignore erroneous ones https://github.com/lalrpop/lalrpop/issues/808
+                fs::metadata(&path).map_or_else(
+                    |_| {
+                        eprintln!(
+                            "Warning: ignoring dangling/erroneous symlink {}",
+                            path.display()
+                        );
+                        false
+                    },
+                    |m| m.is_file(),
+                )
             }
         };
 
-        if (file_type.is_file() || is_symlink_file()?)
+        if (file_type.is_file() || is_valid_symlink_file())
             && path.extension().is_some()
             && path.extension().unwrap() == "lalrpop"
         {


Test patch: