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

Automatically adding directories causing issues with hidden files #45

Closed
t3hmrman opened this issue Aug 6, 2013 · 6 comments
Closed
Milestone

Comments

@t3hmrman
Copy link

t3hmrman commented Aug 6, 2013

I am using Gaze in conjunction with grunt-contrib-watch (and grunt, of course) -- And I have found that despite my best efforts trying to exclude certain files from being watched (and subsequently reloaded), emacs temporary files (.#*) were being picked up, despite a very constrained list of exact files.

Looking at the Gaze source code, it looks like the _addToWatched method is purposefully adding folders of the files that were submitted.

It doesn't seem like this functionality is intended, and if it was, is there any way I can specify an 'strict' parameter or something that will ensure that gaze does not pull directories that might contain other files I don't want it to watch?

@shama
Copy link
Owner

shama commented Aug 6, 2013

Could you post what you're trying to do? Maybe your Gruntfile that is an example of the issue?

@t3hmrman
Copy link
Author

t3hmrman commented Aug 6, 2013

Thanks for the quick response, here are some lines from my grunt file:

Lines from grunt file:

        // Watch                                                                                                                                                                                                                             
        watch: {
            js: {
                files: ['public/javascripts/script.js'],
                tasks: ['jshint']
            },
            csslint: {
                files: ['public/stylesheets/style.css'],
                strict: {
                    src: 'public/stylesheets/**/*.css',
                    tasks: ['csslint']
                }
            },
            jade: {
                files: ['views/index.jade',
                        'views/contact.jade',
                        'views/layout.jade'],
                tasks: ['jade']
            },
            express: {
                files: ['public/javascripts/script.js',
                        'public/stylesheets/style.css',
                        'views/index.jade',
                        'views/contact.jade',
                        'views/layout.jade'
                       ],
                tasks: ['express:dev'],
                options: {
                    nospawn: true
                }
            }
        },

And here's what the error looks like. It occurs when I edit two files in Emacs and save only one (the save triggers the grunt reload, but the unsaved file still has a .#* temp file lingering, which is NOT marked for watching, but still gets picked up.

Here's what the error looks like (I opened views/index and views/layout and changed both but saved one):

Running "jade:compile" (jade) task
File "views/debug.html" created.

Running "jshint:app" (jshint) task
 1 file lint free.

Running "uglify:app" (uglify) task
File "dist/public/javascripts/app.min.js" created.

Running "express:dev" (express) task
Starting background Express server
Express server listening on port 3000

Running "watch" task
Waiting...Warning: ENOENT, no such file or directory 'path/to/webapp/views/.#index.jade'

@juniorplenty
Copy link

Having this same issue, causes watch to exit. @t3hmrman did you ever find a solution? In my case I'm using globs, but setting dot:false and it still picks up .#* emacs tmp files -

@t3hmrman
Copy link
Author

Hi @juniorplenty, I actually didn't... I just started saving all my files, every time...

I would have expected the problem with globs, but definitely not with files explicitly specified...

@zeripath
Copy link
Contributor

zeripath commented Dec 6, 2013

The issue is in gaze\lib\gaze.js:

Gaze.prototype._addToWatched = function(files) {
  for (var i = 0; i < files.length; i++) {
    var file = files[i];
    var filepath = path.resolve(this.options.cwd, file);

    var dirname = (helper.isDir(file)) ? filepath : path.dirname(filepath);
    dirname = helper.markDir(dirname);

    // If a new dir is added
    if (helper.isDir(file) && !(filepath in this._watched)) {
      helper.objectPush(this._watched, filepath, []);
    }

    if (file.slice(-1) === '/') { filepath += path.sep; }
    helper.objectPush(this._watched, path.dirname(filepath) + path.sep, filepath);

    // add folders into the mix
    var readdir = fs.readdirSync(dirname);
    for (var j = 0; j < readdir.length; j++) {
      var dirfile = path.join(dirname, readdir[j]);
      if (fs.statSync(dirfile).isDirectory()) {
        helper.objectPush(this._watched, dirname, dirfile + path.sep);
      }
    }
  }
  return this;
};

The trouble here is that although Gaze is passed in an exact list of files to watch it re-reads the directory of those files and tries to stat every file in the directory, be they specifically excluded or not.

The killer line is:

      if (fs.statSync(dirfile).isDirectory()) {

which runs on every file in the parent directories of a watched file. The emacs interlock files can't be stat'd so this throws an error. (Which I guess should just be caught.)

This has two other bugs:

  1. Say you try to exclude a directory from being watched, this code will also ignore that if it ever passes through the parent directory. Although I guess the exclusion filter will later run again.
  2. If the file is deleted between readDirSync and statSync then the statSync will throw an exception too.

I guess the answer is to simply catch the error around the statSync and ignore it, or at worst log it.

@shama
Copy link
Owner

shama commented Dec 6, 2013

Thanks for the analysis @zeripath! It would be great if we could get these issues exemplified with a test case. Then we can write a fix and prevent regressions. I'll try to look into this more as soon as I can as well.

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

Successfully merging a pull request may close this issue.

4 participants