Don't freak out on symlinks #769

Krinkle opened this Issue Dec 10, 2012 · 4 comments

4 participants


In a directory with an (not javascript related) symlink:

/workspace$ jshint .

  return binding.stat(pathModule._makeLong(path));
Error: ENOENT, no such file or directory 'deployment.ini'
    at Object.fs.statSync (fs.js:524:18)
    at _collect (jshint/lib/hint.js:90:12)
    at jshint/lib/hint.js:92:13
    at Array.forEach (native)
    at _collect (jshint/lib/hint.js:91:34)
    at module.exports.hint._cache.directories (jshint/lib/hint.js:110:13)
    at Array.forEach (native)
    at Object.module.exports.hint (jshint/lib/hint.js:109:17)
    at Object.module.exports.interpret (jshint/lib/cli.js:157:21)
    at Object.<anonymous> (jshint/bin/hint:2:25)

deployment.ini in this case is a relative symlink of which the target does not exist on my disk. The repository in question is used on a deployment server (where the target does exist, something like /etc/foobar/deployment.ini).

JSHint shouldn't throw an uncaught exception on this as this is not related to jshint. The path doesn't even have js file extension.

p commented Jan 8, 2013 suggests that jshint only checks .js files. If so it should only attempt to collect .js files.

Meaning, somewhere in it should first check if file name ends with .js and only then call collect on it.


@p though jshint still needs to stat all files to determine if they are a directory in order to recurse directories.

p commented Jan 8, 2013
pie@reactor t % mkdir dir
pie@reactor t % ln -s dir symlink-to-dir
pie@reactor t % ln -s nonexistent symlink-to-nonexistent
pie@reactor t % test -d symlink-to-dir; echo $?
pie@reactor t % test -d symlink-to-nonexistent; echo $?
pie@reactor t % test -e symlink-to-dir; echo $?       
pie@reactor t % test -e symlink-to-nonexistent; echo $?

jshint is calling test -e on each directory entry and aborting if it does not exist. Then it checks if the directory entry is itself a directory via test -d.

Instead it can first call test -d, if that returns true (which it will for directories and symlinks to directories) then recurse, otherwise call test -e and if that returns true (which it will now for files and symlinks to files) collect the file. Broken symlinks will return false in both tests and will be silently skipped.

The question then becomes whether it is jshint's job to report broken symlinks or to validate files that are accessible in the tree being given to it.

pie@reactor t % test -f symlink-to-nonexistent; echo $?

A broken symlink is not a file either, giving rise to the following alternate solution for the submitter:

find . -type f -name '*.js' -exec jshint {} \;
JSHint member

I don't think this is a problem with 1.0.0. I just tested it and everything seems to work fine:

jshint $ ./bin/jshint demo/
jshint $ ls -l demo/
total 32
lrwxr-xr-x  1 akovalyov  staff  13 Jan 18 14:50 config.ini -> config.broken
drwxr-xr-x  2 akovalyov  staff  68 Jan 18 14:46 dir
lrwxr-xr-x  1 akovalyov  staff  14 Jan 18 14:50 sup.ini -> ../jshint.json
lrwxr-xr-x  1 akovalyov  staff   6 Jan 18 14:46 symlink-to-broken -> broken
lrwxr-xr-x  1 akovalyov  staff   3 Jan 18 14:46 symlink-to-dir -> dir
jshint $ 

Correct me if I'm wrong.

@valueof valueof closed this Jan 18, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment