Allo' Allo' today we're happy to announce the release of yeoman-generator@0.18.0!
It's been multiple months since our last minor version bump. This new release bring lots of new features and strive at improving the composability features (first introduced in 0.17).
New features!
Storing prompt answers
Using the {store: true}
property on a prompt will store the user answers in a machine global storage. This mean next time the user run a generator, the default answer will be filled with the value previously stored.
Careful notice, providing a default value prevent user from returning empty answers.
Huge thanks to @stefanbuck for the PR https://github.com/yeoman/generator/pull/688
New File System
Since version 0.17, the Yeoman file system proved to be poorly designed to attack composability issues. That's why with 0.18 we release a completely rethought file system abstraction. You can see the discussion and design process taking place in this issue.
Every legacy methods (this.write
, this.copy
, etc) have been back ported to use this new system. So updating to 0.18.0 should magically improve your generator.
New fs
methods
The core system can be accessed on generator.fs
. This object is an instance of mem-fs-editor and provide the same methods.
This system is way simpler than the current legacy method and doesn't do any kind of magic. It won't automatically compile templates (use this.fs.copyTpl()
for this), it won't pass this
as template context, and it won't automatically assume paths are relative to anything.
An example/usual usage would be:
this.fs.copyTpl(
this.templatePath('mocha/base-test.js'),
this.destinationPath('test/index.js'),
{ projectName: 'my-awesome-module' }
)
As you can see, we also added two new paths helpers:
this.templatePath()
which is:path.join(this.sourceRoot(), ...rest)
this.destinationPath()
which is:path.join(this.destinationRoot(), ...rest)
Try it out and please give us feedback on how you like this new API. It is more verbose than our legacy methods, but it is clearer and less magical.
Note that the legacy system will remain available at least until version 1.0.0
What about the 0.17.0 this.src
and this.dest
file utils
These should be considered deprecated. The design decision they make isn't a good fit with composability and will create issues on the long run.
File writing filters
Ever wished to apply custom filters on every file write? Beautifying files, normalizing whitespace, etc, is now possible.
Once per Yeoman process, we will write every modified files to disk. This process is passed through a vinyl object stream (just like gulp). Any author can register a transformStream
to modify the file path or content.
For example:
var beautify = require('gulp-beautify');
this.registerTransformStream(beautify({indentSize: 2 }));
Note that every file type will be passed through this stream. So make sure any transform stream passthrough unsupported files. Tools like gulp-if or gulp-filter will help filter invalid type and pass them through.
This new feature means you can basically use any gulp plugins to process generated files during the writing phase.
Improvements
- Tests using
helpers.run()
won't output to the console keeping the test output clean. Every log method is now asinon.stub()
making it easy to assert your generator outputted the correct content. - Testing run context now automatically run your tests in a unique tmpdir. No need to manually call
helper.run().inDir()
anymore. assert.fileContent
andassert.noFileContent
accept a String as arguments (before we just accepted Regex)- The Conflicter have been refactored to be simple and easy to use.
Installation methods only running once
npm
and bower
installation helpers are now always running once per process. This was a change made in 0.17, but we extended the feature to cover every use/methods who could launch these process.
This was a breaking an edge case in 0.17. But for the sake of clarity, let's be clear. The following construct will break:
this.installDependencies({
callback: this.async() // This will block the process forever, and node will fail
});
Every install method will be registered on the install
run queue. Using this.async()
as a callback will create a deadlock.
Fixes
- Installation methods (npm, bower helpers) now correctly pass the options to the spawn process.
- When a conflict occurs on a directory, we don't show the
diff
option anymore. (selecting diff on directory threw an error) - You can now correctly overwrite the
stdio
withgenerator.spawnCommand()
generator.composeWith()
now correctly resolve thelocal
option path.
Meta
- We've extracted yeoman-environment on it's own repository. This mean these two core Yeoman parts can now evolve at their own pace.
- All our tests now uses tmpdir for testing making them more reliable.
- Completely remove network connection from our test suite - it is now way faster.
Potentially breaking change
- We stopped manually mocking Inquirer in tests. Mainly because Inquirer parses values in ways we didn't imitate and this caused too much issue. Now we rely more on Inquirer and only mock the minimum. This also mean we don't create the magic
errors
property during test. You can listen for generator errors instead. - We removed
require('yeoman-generator').inquirer
. Require your own version from now on. - We removed
generator.shell
andgenerator.request
. Require your own version.
In conclusion
The work is still not completed. We still need to update some of our website documentation to include the new APIs methods. And we'll need to update our core generators to this new version. These should come soon, in the meantime refer to this post about the new features.
So, enjoy this new release! Please upgrade and let us know how the API feels, and as usual feel free to report any bug you encounter!
Cheers