yeoman/generator — pull request #272 by stephenplusplus (2013-06-05 03:31:49+00:00)
Title: fixes #233 - template race condition.

Life is good again.

I didn't realize this was an issue, so I'm sorry I've just been adding to the problem rather than working towards fixing it. However, this fixes things!

`actions.js:write()` and `actions.js:copy()` are the only two functions which call `actions.js:checkForCollision()`, which is the only place a listener is set up for the `resolved:*filename*` event. When the `resolved:*filename*` event is triggered, the callback passed into `actions.js:checkForCollision()` is executed. And guess what's in that callback? The `next` async function from `conflicter.js:resolve()`. After all of these `conflicter.collisions` are resolved that the final `next` will eventually be called, which then fires off the callback from the async process, which gives control back to `base.js:run()`, so the generator's prototype methods continue executing as usual.

I'll try explaining another way, since ^ was nuts.

- base.js
- run()
- finds a method that says `var blah = this.async()`
- waits for `blah` to be called

- custom generator's index.js
- someMethod()
- says `var blah = this.async()`
- calls `this.directory()`

- actions.js
- executes `this.directory()`
- executes `this.copy()`
- executes `this.checkForCollision(callback)`
- binds `callback` on the conflicter's `resolved:*filename*` event

- custom generator's index.js
- ~~someMethod()~~
- ~~says `var blah = this.async()`~~
- ~~calls `this.directory()`~~
- calls `blah()`

- base.js
- run()
- `blah()` now calls `conflicter.resolve`, passing a callback that when called will continue the execution of the rest of the generator's methods

- conflicter.js
- resolve(callback)
- was just called with a callback from `base.js:run`
- uses `async.series` to go through each conflicted file
- resolves each file
- emits a `resolved` event with a new argument; an object containing the `next` async callback

- actions.js
- calls the callback that is bound to the `resolved:*filename*` event, which was passed into `actions.js -> checkForCollision()`
- among other things, this will call the original `next()` from `base.js -> run()`, which will enable the execution of the generator's methods to continue

Ok, there's clearly no good way to explain this. It works, I swear! :deciduous_tree: