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

n00b question about watch #265

Closed
malcolmalex opened this issue May 20, 2014 · 11 comments
Closed

n00b question about watch #265

malcolmalex opened this issue May 20, 2014 · 11 comments

Comments

@malcolmalex
Copy link

I'm very new with lineman, but finding it great. A question, though ... I am trying to convert to a directory structure where the unit tests (*_test.coffee) are right alongside the code to be tested more along the lines of the google angular project structure recommendation, using the following kind of structure in my files.coffee file:

  coffee:
    app: [
      "app/**/*.coffee"
      "!app/**/*_test.coffee"
    ]
    spec: "app/**/*_test.coffee"

But watch is not including the *_test.coffee files, even though my watch says says ...

  "coffeeSpecs": {
    "files": [
      "<%= files.coffee.specHelpers %>",
      "<%= files.coffee.spec %>"
    ],

It's like the files for watch get all put together, then the "app/*_/__test.coffee" gets removed from the list. Am I missing something or is there a better way to accomplish this? Thanks.

@davemo
Copy link
Member

davemo commented May 20, 2014

Hi @malcolmalex, you'll need to update the watch targets to account for the folder structure changes you want to make. To see what they look like you can run lineman config from the command line and it will spit out a formatted Object that showcases the entire config object.

If you want to narrow it down you can traverse the individual keys, like: lineman config watch

The section you'll need to modify is watch.coffee, the default values look like this:

$ lineman config watch.coffee
{
  "files": "<%= files.coffee.app %>",
  "tasks": [
    "coffee",
    "concat_sourcemap:js"
  ]
}

You can see there's an internal reference there to files.coffee.app, the default for that looks like this:

$ lineman config files.coffee
{
  "app": "app/js/**/*.coffee",
  "spec": "spec/**/*.coffee",
  "specHelpers": "spec/helpers/**/*.coffee",
  "generated": "generated/js/app.coffee.js",
  "generatedSpec": "generated/js/spec.coffee.js",
  "generatedSpecHelpers": "generated/js/spec-helpers.coffee.js"
}

The files.coffee.app key there is what you'll need to update to account for your changes.

@malcolmalex
Copy link
Author

Thanks @davemo - I've been using lineman config .. heavily and it's helpful. Perhaps I'm going about it wrong ... I've tried to put the *_test.coffe in the files.coffee.spec key. So here's what I've got:

> lineman config files.coffee.app
[
  "app/**/*.coffee",
  "!app/**/*_test.coffee"
]

and

> lineman config files.coffee.spec
app/**/*_test.coffee

With my watch set up like ...

> lineman config watch.coffee
{
  "files": "<%= files.coffee.app %>",
  "tasks": [
    "coffee",
    "concat_sourcemap:js"
  ]
}

and

> lineman config watch.coffeeSpecs
{
  "files": [
    "<%= files.coffee.specHelpers %>",
    "<%= files.coffee.spec %>"
  ],
  "tasks": [
    "coffee",
    "concat_sourcemap:spec"
  ]
}

But ... the 'app/*_/__test.spec' files are not getting picked up in the watch. Is it possible that the full watch list is put together by concatenating all the watch arrays, then the "!..." stuff is removed - rather than taking each array, processing the "!..." on them individually, and then assembling the results?

@davemo
Copy link
Member

davemo commented May 20, 2014

So with files.coffee.app set to ignore *_test.coffee files the watch target won't trigger changes there. I think you'll want to override files.coffee in config/files.js like so:

{
    coffee: { 
        "spec" : "app/**/*_test.coffee"
    }
}

This will setup the watch.coffeeSpecs to point to the right file references located inside your app dir.

@davemo
Copy link
Member

davemo commented May 20, 2014

Hmm, I re-read what you posted and see you do have files.coffee.spec pointing to the right spot, this may be an issue with the watch task not handling the ! paths properly..

@davemo
Copy link
Member

davemo commented May 20, 2014

One other tip @malcolmalex, you can expand the interpolated strings using lineman config --process, this will help debug with the output of all matched paths being displayed :)

@davemo
Copy link
Member

davemo commented May 20, 2014

And yet another option, is to be able to see the actual file paths matched by globs is to use the -v flag with lineman run -v. Between those two improvements I think you should be able to debug it hopefully :)

@malcolmalex
Copy link
Author

That is a helpful option. Running each of these with this option gives me what I would expect:

> lineman config watch.coffee --process
{
  "files": [
    "app/**/*.coffee",
    "!app/**/*_test.coffee"
  ],
  "tasks": [
    "coffee",
    "concat_sourcemap:js"
  ]
}

and

> lineman config watch.coffeeSpecs --process
{
  "files": [
    "spec/helpers/**/*.coffee",
    "app/**/*_test.coffee"
  ],
  "tasks": [
    "coffee",
    "concat_sourcemap:spec"
  ]
}

I wonder if it's related, but I just realized I'm getting some tasks executing twice - watch executes and then I get concat_sourcemap ... I will try and create a smaller project to duplicate and file separately if it's not a known issue.

@malcolmalex
Copy link
Author

Gotcha - ok, I'll try the -v option and see what I can find out and comment back.

@davemo
Copy link
Member

davemo commented May 20, 2014

FYI, I realized there's an additional feature to lineman config that would be nice to have, something like a lineman config --expand flag that would both process the interpolations and expand globs, so I opened #266

@malcolmalex
Copy link
Author

I think my initial suspicion was on track - lineman's watch is using grunt-watch-nospawn, which is using gaze, which is using fileset. In gaze the various arrays of file patterns get unioned. It is scanned to build an "include" and an "exclude" array, and then fileset is used to create a final array and all instances of "exclude" files are removed... which is why my !app/**/*_test.coffee are removed...

In gaze.js:

...
  this._patterns = union(this._patterns, files);

  var include = [], exclude = [];
  this._patterns.forEach(function(p) {
    if (p.slice(0, 1) === '!') {
      exclude.push(p.slice(1));
    } else {
      include.push(p);
    }
  });

  fileset(include, exclude, _this.options, function(err, files) {
    if (err) {
      _this.emit('error', err);
      return done(err);
    }
    _this._addToWatched(files);
    _this.close(false);
    _this._initWatched(done);
  });
};

and in fileset the files are processed one-by-one and excludes are thrown out ... fileset.js

Makes it difficult to co-locate the files like this!

@malcolmalex
Copy link
Author

I think my solution for this in the angular context is going to be to search for specific patterns in files.app ... "app/*/{Controller,Directive,Service,Whatever}.html. I'm going to close out this issue. Thanks

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

No branches or pull requests

2 participants