Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metalsmith fails to ignore broken symbolic links #281

Closed
lonelyelk opened this issue Apr 2, 2017 · 8 comments
Closed

Metalsmith fails to ignore broken symbolic links #281

lonelyelk opened this issue Apr 2, 2017 · 8 comments
Labels

Comments

@lonelyelk
Copy link

It seems that Metalsmith is trying to stat everything in source dir before applying .ignore. That is inconvenient when using Emacs, for example, which creates such symlinks for its own agenda. It also seems that applying .ignore before .source makes no difference.

Error that fails the build

Error: ENOENT: no such file or directory, stat '/path/to/broken/symlink/in/source/dir'

Steps to reproduce

  1. Create broken symbolic link anywhere in source dir
  2. Add link name or matching pattern to .ignore
  3. Build with .build
@Ajedi32
Copy link
Member

Ajedi32 commented Apr 3, 2017

I haven't verified this yet, but it seems like this may be an upstream bug in recursive-readdir.

Found an existing issue: jergason/recursive-readdir#42

@Ajedi32
Copy link
Member

Ajedi32 commented Apr 3, 2017

So upon further investigation, it seems this issue is rather complex.

recursive-readdir (and, by extension, Metalsmith) allow functions to be used as matchers for deciding whether or not to ignore a file. These matchers expect to receive the fs.Stats object of the given file as one of their arguments, and since Metalsmith follows symlinks that object is the Stats object of the file the symlink points to, not the Stats object of the symlink itself. So if a symlink points to a non-existent file, there's no clear way to determine whether the file should be ignored or not (since we can't pass the Stats object of the target file to the ignore matcher, as no such file exists).

There are a few ways we could handle this.

  1. We could pass null as the Stats object to the ignore matcher
  2. We could pass the error message we got when running Stat to the ignore matcher
  3. We could pass the Stat object for the symlink to the ignore matcher (possibly only if trying to Stat the target of the symlink results in an error)
  4. Something else I haven't thought of yet

All of these options (except maybe the third or fourth ones) would be a SemVer-major breaking change to both Metalsmith and recursive-readdir. Not really sure yet which option is best. Maybe some combination of all of them...

Another thing to consider would be allowing the ignore matchers to be asynchronous, in case they end up needing more information from the filesystem before deciding whether or not to ignore a file.

@Ajedi32 Ajedi32 added this to the v3.0 milestone Apr 3, 2017
@lonelyelk
Copy link
Author

I have made a pull request to jergason/recursive-readdir#42. If it is approved, a new ignore function would need to be implemented in order to account for this case.

@lonelyelk
Copy link
Author

If you decide against ignoring all broken symlinks, which is logical, than the patch above should work by mask or any other existing filter. It just should not throw before testing ignore rules.

@lonelyelk
Copy link
Author

Now I discovered, that Metalsmith actually recursive-readdir's the entire project directory, not only source dir. And fails on missing links anywhere in the tree. Is this really necessary?

@Ajedi32
Copy link
Member

Ajedi32 commented Apr 8, 2017

Are you sure that's not just a plugin doing that? I'm fairly sure Metalsmith only calls it on the source directory: https://github.com/segmentio/metalsmith/blob/c24385888bc9dd05d8d1714cda9c63bba949ab73/lib/index.js#L236

@lonelyelk
Copy link
Author

I was not sure about that, that might have been a plugin. For now I ended up using gulpsmith and feed metalsmith with source files selected by gulp.

@webketje
Copy link
Member

Candidate replacement library which may handle this case better: https://www.npmjs.com/package/readdirp
recursive-readdir seems no longer to be in active development

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants