├── Testing-Tasks.md
├── Community.md
├── Exit-Codes.md
├── README.md
├── Help-Resources.md
├── Blog-2014-03-14-Grunt-0.4.4-released.md
├── package.json
├── Development-helpers.md
├── Grunt-Plugins.md
├── Home.md
├── Blog-2013-03-13-Grunt-0.4.1-released.md
├── Blog-2014-03-07-Grunt-0.4.3-released.md
├── Plugin-Release-Candidate-Versions.md
├── Blog-2013-02-18-Grunt-0.4.0-released.md
├── grunt.fail.md
├── grunt.event.md
├── Using-the-CLI.md
├── Blog-2013-02-15-Updating-plugins-to-Grunt-0.4.md
├── Blog-2014-05-12-Grunt-0.4.5-released.md
├── Built-with-Grunt-Badge.md
├── Creating-plugins.md
├── Blog-2013-11-21-Grunt-0.4.2-released.md
├── Using-plugins.md
├── Development-Team.md
├── grunt.md
├── grunt.option.md
├── Installing-grunt.md
├── grunt.template.md
├── Roadmap.md
├── grunt.config.md
├── grunt.log.md
├── grunt.util.md
├── Frequently-Asked-Questions.md
├── Who-uses-Grunt.md
├── Sample-Gruntfile.md
├── Contributing.md
├── grunt.task.md
├── Inside-Tasks.md
├── Creating-tasks.md
├── Getting-started.md
├── Upgrading-from-0.3-to-0.4.md
├── grunt.file.md
├── Configuring-tasks.md
└── Project-Scaffolding.md
/Testing-Tasks.md:
--------------------------------------------------------------------------------
1 | _TODO_
--------------------------------------------------------------------------------
/Community.md:
--------------------------------------------------------------------------------
1 | Please see the [[Help Resources]] page.
--------------------------------------------------------------------------------
/Exit-Codes.md:
--------------------------------------------------------------------------------
1 | * `0` - No errors!
2 | * `1` - Fatal error
3 | * `2` - Missing gruntfile error
4 | * `3` - Task error
5 | * `4` - Template processing error
6 | * `5` - Invalid shell auto-completion rules error
7 | * `6` - Warning
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ##[View Grunt Documentation](http://gruntjs.com/getting-started)
2 |
3 | This repository contains the wiki files for the official grunt documentation.
4 | Grunt documentation is based on the [Gollum Wiki](https://github.com/gollum/gollum/wiki)
5 |
--------------------------------------------------------------------------------
/Help-Resources.md:
--------------------------------------------------------------------------------
1 | ## IRC
2 |
3 | You can visit us in [#grunt on irc.freenode.net](http://webchat.freenode.net/?channels=grunt)
4 |
5 | ## Forums
6 |
7 | You can post a question at [StackOverflow and tag it with "gruntjs"](http://stackoverflow.com/questions/tagged/gruntjs).
--------------------------------------------------------------------------------
/Blog-2014-03-14-Grunt-0.4.4-released.md:
--------------------------------------------------------------------------------
1 | Grunt 0.4.4 is now available on [npm](https://npmjs.org/package/grunt).
2 |
3 | This release fixes a [regression](https://github.com/gruntjs/grunt/pull/1026) that was introduced in version 0.4.3.
4 |
5 | See the changelog [here](https://github.com/gruntjs/grunt/blob/v0.4.4/CHANGELOG).
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "grunt-docs",
3 | "version": "0.2.0",
4 | "description": "This repository contains the wiki files for the official grunt documentation. Grunt documentation is based on the [Gollum Wiki](https://github.com/gollum/gollum/wiki)",
5 | "repository": {
6 | "type": "git",
7 | "url": "git://github.com/gruntjs/grunt-docs.git"
8 | },
9 | "author": "GruntJS Team",
10 | "license": "MIT",
11 | "bugs": {
12 | "url": "https://github.com/gruntjs/grunt-docs/issues"
13 | },
14 | "homepage": "https://github.com/gruntjs/grunt-docs"
15 | }
16 |
--------------------------------------------------------------------------------
/Development-helpers.md:
--------------------------------------------------------------------------------
1 | Good to do when publishing everything all-at-once.
2 |
3 | ```shell
4 | eachdir grunt grunt-{contrib,lib}-* -- 'git pull'
5 | eachdir grunt grunt-{contrib,lib}-* -- 'rm -rf node_modules; linken . --src ..; npm install'
6 |
7 | # Make sure symlinks were created, if not there's a version mismatch
8 | eachdir grunt grunt-{contrib,lib}-* -- 'll node_modules | grep grunt'
9 |
10 | # Make sure everything passes
11 | eachdir grunt grunt-{contrib,lib}-* -- grunt
12 |
13 | # Make sure all versions are final
14 | eachdir grunt grunt-{contrib,lib}-* -- 'git branch; node -pe "require(\"./package.json\").version"'
15 | ```
--------------------------------------------------------------------------------
/Grunt-Plugins.md:
--------------------------------------------------------------------------------
1 | This plugin listing is automatically generated from the npm module database.
2 | Officially maintained "contrib" plugins are marked with a star
3 | icon.
4 |
5 | To install and use any plugin listed here, checkout [how to install and use the Grunt plugins section](http://gruntjs.com/getting-started#installing-grunt-and-gruntplugins).
6 |
7 | You may also be interested on how to [create your own Grunt plugin](http://gruntjs.com/creating-plugins).
8 |
9 |
10 | In order for a Grunt plugin to be listed here, it must be published on
11 | npm with the
12 | gruntplugin keyword.
13 | Additionally, we recommend that you use the
14 | gruntplugin grunt-init template
15 | when creating a Grunt plugin.
16 |
--------------------------------------------------------------------------------
/Home.md:
--------------------------------------------------------------------------------
1 | > Welcome to the home of **Grunt**, a JavaScript automation tool.
2 |
3 | Stable Version: **0.4.5**
4 |
5 | Development Version: **master**
6 |
7 | ## Documentation
8 | * [[Getting Started]]
9 | * [[Configuring Tasks]]
10 | * [[Sample Gruntfile]]
11 | * [[Creating Tasks]]
12 | * [[Creating Plugins]]
13 | * [[Using the CLI]]
14 |
15 | ### Advanced
16 | * [[API]]
17 | * [[Installing Grunt]]
18 | * [[Frequently Asked Questions]]
19 | * [[Project Scaffolding]]
20 |
21 | ### Community
22 | * [[Help Resources]]
23 | * [[Who uses Grunt]]
24 | * [[Built with Grunt Badge]]
25 | * [[Contributing]]
26 | * [[Development Team]]
27 |
28 | ### Migration guides
29 | * [[Upgrading from 0.3 to 0.4]]
30 |
31 | ## API
32 | * [[grunt]]
33 | * [[grunt.config]]
34 | * [[grunt.event]]
35 | * [[grunt.fail]]
36 | * [[grunt.file]]
37 | * [[grunt.log]]
38 | * [[grunt.option]]
39 | * [[grunt.task]]
40 | * [[grunt.template]]
41 | * [[grunt.util]]
42 |
43 | ### Other
44 | * [[Inside Tasks]]
45 | * [[Exit Codes]]
46 |
--------------------------------------------------------------------------------
/Blog-2013-03-13-Grunt-0.4.1-released.md:
--------------------------------------------------------------------------------
1 | Grunt 0.4.1 is now available from [npm](https://npmjs.org/package/grunt).
2 |
3 | This patch release fixes a number of minor issues that cropped up with the recent release of [Node.js v0.10.0](http://blog.nodejs.org/2013/03/11/node-v0-10-0-stable/), most notably due to changes in the [path](http://nodejs.org/api/path.html) API. If you want to use the latest version of Node.js in your projects, you should probably update Grunt to `~0.4.1` in the [package.json](http://gruntjs.com/getting-started#package.json) file for those projects.
4 |
5 | Either way, Grunt still works with Node.js v0.8.x, so you don't *need* to update if you haven't upgraded to Node.js v0.10.0.
6 |
7 | In addition to the Node.js v0.10.0 changes, we used this opportunity to fix a number of other small issues, like properly handling multibyte I/O when spawning child processes and ensuring the [Gruntfile](http://gruntjs.com/getting-started#the-gruntfile) name is case-insensitive. For a complete list of changes, see the [v0.4.0 - v0.4.1 changelog](https://github.com/gruntjs/grunt/compare/v0.4.0...v0.4.1).
8 |
--------------------------------------------------------------------------------
/Blog-2014-03-07-Grunt-0.4.3-released.md:
--------------------------------------------------------------------------------
1 | Grunt 0.4.3 is now available on [npm](https://npmjs.org/package/grunt).
2 |
3 | This is mostly a bugfix release. Thanks to [Jonathan Krause](https://github.com/jonykrause),
4 | [PatrickJS](https://github.com/gdi2290), [Jason Cust](https://github.com/GlobalDomestic),
5 | [Fabio Crisci](https://github.com/piuccio), [James M. Greene](https://github.com/JamesMGreene)
6 | and [Mike Pennisi](https://github.com/jugglinmike) for their pull requests.
7 |
8 | In addition to closing over 30 issues, we have extracted `grunt.util` into
9 | [its own module](https://github.com/gruntjs/grunt-legacy-util). As mentioned
10 | in the [0.4.2](http://gruntjs.com/blog/2013-11-21-grunt-0.4.2-released) release,
11 | we are in process of deprecating the `grunt.util.*` API. Task developers who use
12 | these APIs should update their plugins to use the libraries recommended in
13 | the [grunt-legacy-util](https://github.com/gruntjs/grunt-legacy-util) README.
14 | You may use `grunt-legacy-util` directly as a stopgap, but we will no longer be supporting it.
15 |
16 | For a full list of changes, see the 0.4.3 changelog [here](https://github.com/gruntjs/grunt/blob/v0.4.3/CHANGELOG).
17 |
18 | **Happy Grunting!**
19 |
--------------------------------------------------------------------------------
/Plugin-Release-Candidate-Versions.md:
--------------------------------------------------------------------------------
1 | Note: because these are pre-release versions, please follow the instructions in the "Installing a published development version of Grunt" section of the [Installing Grunt guide](https://github.com/gruntjs/grunt/wiki/Installing-grunt). And as a reminder, **do not** specify a version range (using ~ or <=) when including a pre-release version of Grunt or Grunt plugin in your project.
2 |
3 | Grunt contrib plugins published to npm that work with Grunt 0.4.0rc8:
4 |
5 | - grunt-contrib-clean@0.4.0rc6
6 | - grunt-contrib-coffee@0.4.0rc7
7 | - grunt-contrib-compass@0.1.1rc8
8 | - grunt-contrib-compress@0.4.0rc7
9 | - grunt-contrib-concat@0.1.2rc6
10 | - grunt-contrib-connect@0.1.1rc6
11 | - grunt-contrib-copy@0.4.0rc7
12 | - grunt-contrib-handlebars@0.5.4rc7
13 | - grunt-contrib-htmlmin@0.1.1rc7
14 | - grunt-contrib-imagemin@0.1.1rc8
15 | - grunt-contrib-jade@0.4.0.rc7
16 | - grunt-contrib-jasmine@0.3.0rc7
17 | - grunt-contrib-jshint@0.1.1rc6
18 | - grunt-contrib-jst@0.4.0rc7
19 | - grunt-contrib-less@0.5.0rc7
20 | - grunt-contrib-livereload@0.1.0rc8
21 | - grunt-contrib-mincss@0.4.0rc7
22 | - grunt-contrib-nodeunit@0.1.2rc6
23 | - grunt-contrib-qunit@0.1.1rc6
24 | - grunt-contrib-requirejs@0.4.0rc7
25 | - grunt-contrib-sass@0.2.2rc7
26 | - grunt-contrib-stylus@0.4.0rc7
27 | - grunt-contrib-uglify@0.1.1rc6
28 | - grunt-contrib-watch@0.2.0rc7
29 | - grunt-contrib-yuidoc@0.4.0rc7
--------------------------------------------------------------------------------
/Blog-2013-02-18-Grunt-0.4.0-released.md:
--------------------------------------------------------------------------------
1 | As of this morning, Grunt v0.4 final is available on npm! For a lengthy writeup on the release, please see [@tkellen's](http://goingslowly.com) article [on the Bocoup blog](http://weblog.bocoup.com/tearing-grunt-apart/).
2 |
3 | ### The Biggest Stuff
4 |
5 | 1. Grunt no longer ships with built in tasks. They've been extracted into officially maintained, standalone plugins under the grunt-contrib namespace. See the [plugin listing](http://gruntjs.com/plugins) on our website for more details.
6 |
7 | 2. Grunt no longer ships with a binary. In order to get the `grunt` command, install [grunt-cli](http://github.com/gruntjs/grunt-cli) globally with `npm install -g grunt-cli`. This package will run any version of Grunt (including 0.3x) after it's been installed locally to your project.
8 |
9 | ### The Future
10 |
11 | Grunt v0.5 will ship with support for a new plugin format called [node-task](http://github.com/tkellen/node-task). It defines a stateless, promise-based, event emitting API that doesn't depend on Grunt. It has a real-live spec, and the Grunt team is working with the front-end developer community in the hopes that compliant modules will be compatible with every task runner under the sun.
12 |
13 | ### Grunt on
14 | If you'd like to know more about Grunt, please read our [Getting Started Guide](http://gruntjs.com/getting-started), and check out all of the ways you can [configure your tasks](http://gruntjs.com/configuring-tasks), too.
--------------------------------------------------------------------------------
/grunt.fail.md:
--------------------------------------------------------------------------------
1 | For when something goes horribly wrong.
2 |
3 | See the [fail lib source](https://github.com/gruntjs/grunt/blob/master/lib/grunt/fail.js) for more information.
4 |
5 | ## The fail API
6 |
7 | If something explodes (or is about to explode) inside a task, it can force Grunt to abort. See the [exit codes documentation](Exit-Codes) for a list of all built-in Grunt exit codes.
8 |
9 | Note that any method marked with a ☃ (unicode snowman) is also available directly on the `grunt` object. Just so you know. See the [API main page](grunt) for more usage information.
10 |
11 | ### grunt.fail.warn ☃
12 | Display a warning and abort Grunt immediately. Grunt will continue processing tasks if the `--force` command-line option was specified. The `error` argument can be a string message or an error object.
13 |
14 | ```javascript
15 | grunt.fail.warn(error [, errorcode])
16 | ```
17 |
18 | If `--stack` is specified on the command-line and an error object was specified, a stack trace will be logged.
19 |
20 | _This method is also available as `grunt.warn`._
21 |
22 | ### grunt.fail.fatal ☃
23 | Display a warning and abort Grunt immediately. The `error` argument can be a string message or an error object.
24 |
25 | ```javascript
26 | grunt.fail.fatal(error [, errorcode])
27 | ```
28 |
29 | If `--stack` is specified on the command-line and an error object was specified, a stack trace will be logged.
30 |
31 | A beep is emitted on fatal unless the `--no-color` option is specified.
32 |
33 | _This method is also available as `grunt.fatal`._
34 |
--------------------------------------------------------------------------------
/grunt.event.md:
--------------------------------------------------------------------------------
1 | Even though only the most relevant methods are listed on this page, the full [EventEmitter2 API][ee2] is available on the `grunt.event` object. Event namespaces may be specified with the `.` (dot) separator, and namespace wildcards have been enabled.
2 |
3 | *Note that Grunt doesn't yet emit any events, but can still be useful in your own tasks.*
4 |
5 | [ee2]: https://github.com/hij1nx/EventEmitter2
6 |
7 | ### grunt.event.on
8 | Adds a listener to the end of the listeners array for the specified event.
9 |
10 | ```js
11 | grunt.event.on(event, listener)
12 | ```
13 |
14 | ### grunt.event.once
15 | Adds a **one time** listener for the event. The listener is invoked only the first time the event is fired, after which it is removed.
16 |
17 | ```js
18 | grunt.event.once(event, listener)
19 | ```
20 |
21 | ### grunt.event.many
22 | Adds a listener that will execute **n times** for the event before being removed.
23 |
24 | ```js
25 | grunt.event.many(event, timesToListen, listener)
26 | ```
27 |
28 | ### grunt.event.off
29 | Remove a listener from the listener array for the specified event.
30 |
31 | ```js
32 | grunt.event.off(event, listener)
33 | ```
34 |
35 | ### grunt.event.removeAllListeners
36 | Removes all listeners, or those of the specified event.
37 |
38 | ```js
39 | grunt.event.removeAllListeners([event])
40 | ```
41 |
42 | ### grunt.event.emit
43 | Execute each of the listeners that may be listening for the specified event name in order with the list of arguments.
44 |
45 | ```js
46 | grunt.event.emit(event, [arg1], [arg2], [...])
47 | ```
--------------------------------------------------------------------------------
/Using-the-CLI.md:
--------------------------------------------------------------------------------
1 | ## Installing the CLI
2 |
3 | Run `sudo npm install -g grunt-cli`.
4 |
5 | The `grunt` command-line interface comes with a series of options. Use `grunt -h` from your terminal to show these options.
6 |
7 | ### --help, -h
8 | Display help text
9 |
10 | ### --base, -b
11 | Specify an alternate base path. By default, all file paths are relative to the `Gruntfile`.
12 |
13 | Alternative to `grunt.file.setBase(...)`
14 |
15 | ### --no-color
16 | Disable colored output.
17 |
18 | ### --gruntfile
19 | Specify an alternate `Gruntfile`.
20 |
21 | By default, grunt looks in the current or parent directories for the nearest `Gruntfile.js` or `Gruntfile.coffee` file.
22 |
23 | ### --debug, -d
24 | Enable debugging mode for tasks that support it.
25 |
26 | ### --stack
27 | Print a stack trace when exiting with a warning or fatal error.
28 |
29 | ### --force, -f
30 | A way to force your way past warnings.
31 |
32 | Want a suggestion? Don't use this option, fix your code.
33 |
34 | ### --tasks
35 | Additional directory paths to scan for task and "extra" files.
36 |
37 | Alternative to `grunt.loadTasks(...)`
38 |
39 | ### --npm
40 | Npm-installed grunt plugins to scan for task and "extra" files.
41 |
42 | Alternative to `grunt.loadNpmTasks(...)`
43 |
44 | ### --no-write
45 | Disable writing files (dry run).
46 |
47 | ### --verbose, -v
48 |
49 | Verbose mode. A lot more information output.
50 |
51 | ### --version, -V
52 | Print the grunt version. Combine with --verbose for more info.
53 |
54 | ### --completion
55 | Output shell auto-completion rules. See the grunt-cli documentation for more information.
56 |
--------------------------------------------------------------------------------
/Blog-2013-02-15-Updating-plugins-to-Grunt-0.4.md:
--------------------------------------------------------------------------------
1 | If your plugin is not already Grunt 0.4 compatible, would you please consider updating it? For an overview of what's changed, please see our [migration guide](https://github.com/gruntjs/grunt/wiki/Upgrading-from-0.3-to-0.4).
2 |
3 | If you'd like to develop against the final version of Grunt before Monday, please specify `"grunt": "0.4.0rc8"` as a devDependency in your project. After Monday's release, you'll be able to use `"grunt": "~0.4.0"` to actually publish your plugin. If you depend on any plugins from the grunt-contrib series, please see our [list of release candidates](https://github.com/gruntjs/grunt/wiki/Plugin-Release-Candidate-Versions) for compatible versions. All of these will be updated to final status when Grunt 0.4 is published.
4 |
5 | Also, in an effort to reduce duplication of effort and fragmentation in the developer community, could you review the [grunt-contrib](https://github.com/gruntjs) series of plugins to see if any of your functionality overlaps significantly with them? Grunt-contrib is community maintained with 40+ contributors—we'd love to discuss any additions you'd like to make.
6 |
7 | Finally, we're working on a new task format that doesn't depend on Grunt: it's called [node-task](https://github.com/tkellen/node-task). Once this is complete, there will be one more conversion, and then we'll never ask you to upgrade your plugins to support our changes again. Until that happens, thanks for bearing with us!
8 |
9 | If you have any questions about how to proceed, please respond here, or join us in `#grunt on irc.freenode.net`.
10 |
11 | Thanks, we really appreciate your work!
--------------------------------------------------------------------------------
/Blog-2014-05-12-Grunt-0.4.5-released.md:
--------------------------------------------------------------------------------
1 | Grunt 0.4.5 is now available on [npm](https://www.npmjs.org/package/grunt).
2 |
3 | Thanks to [Gary Burgess](https://github.com/garyb), [James Smith](https://github.com/jmeas) and [Carlos Mantilla](https://github.com/ceoaliongroo) for their patches. Also, thanks to [Vlad Filippov](https://github.com/vladikoff) for helping triage issues, troubleshooting Windows CI testing and putting together the changelog.
4 |
5 | In this release, we closed around a dozen issues, added the much-requested [grunt.task.exists](http://gruntjs.com/api/grunt.task#grunt.task.exists) and [grunt.config.merge](http://gruntjs.com/api/grunt.config#grunt.config.merge) methods, and set up Windows CI testing through [AppVeyor](http://www.appveyor.com/). Additionally, the logging API has been broken out into a separate module, [grunt-legacy-log](https://github.com/gruntjs/grunt-legacy-log), in order to facilitate maintenance.
6 |
7 | For a full list of changes, see the [0.4.5 changelog](https://github.com/gruntjs/grunt/blob/v0.4.5/CHANGELOG).
8 |
9 | Additionally, we have accepted a number of patches for [Grunt contrib plugins](http://gruntjs.com/plugins/contrib) and would like to thank [Kevin Mårtensson](https://github.com/kevva), [Alexander Futekov](https://github.com/futekov), [Shinnosuke Watanabe](https://github.com/shinnn), [Shane Daniel](https://github.com/simshanith), [Artem Sapegin](https://github.com/sapegin), [Christoph Pojer](https://github.com/cpojer), [Zhang Yichao](https://github.com/echaozh), [Jevon Wright](https://github.com/soundasleep), [Jacob Lauritzen](https://github.com/Jacse), [XhmikosR](https://github.com/XhmikosR) and [Edan Schwartz](https://github.com/eschwartz) for their contributions.
10 |
11 | **Happy Grunting!**
12 |
--------------------------------------------------------------------------------
/Built-with-Grunt-Badge.md:
--------------------------------------------------------------------------------
1 | Do you use Grunt in a project and want to proudly display that in your project README or on your project website? Now you can with the "Built with Grunt" badge!
2 |
3 | [](http://gruntjs.com/)
4 |
5 | ## Using the Badge
6 |
7 | Just copy the following Markdown code snippet and paste it right underneath the headline in your project README. You can also put it on your project website homepage or footer.
8 |
9 | ```
10 | [](http://gruntjs.com/)
11 | ```
12 |
13 | If you need an HTML version, we've got you covered.
14 |
15 | ```html
16 |
17 | ```
18 |
19 | ## For example...
20 |
21 | As you can see, the "Built with Grunt" badge is modern, stylish, and has been designed to fit nicely next to all your project's other mini-badges. You can put it first, last, or anywhere in the middle. Have fun!
22 |
23 | [](http://badge.fury.io/)
24 | [](https://coveralls.io/)
25 | [](http://travis-ci.org/)
26 | [](http://gruntjs.com/)
27 |
28 | ## Shout-outs
29 |
30 | Let us know if you are using the "Built with Grunt" badge by [tweeting at @gruntjs](http://twitter.com/gruntjs).
31 |
32 | _We'd like to especially thank [MaxCDN](http://www.maxcdn.com/) for hosting this badge and for [sponsoring open source development](http://www.maxcdn.com/company/open-source/)._
33 |
34 |
--------------------------------------------------------------------------------
/Creating-plugins.md:
--------------------------------------------------------------------------------
1 | 1. Install [grunt-init](https://github.com/gruntjs/grunt-init) with `npm install -g grunt-init`
2 | 2. Install the gruntplugin template with `git clone git://github.com/gruntjs/grunt-init-gruntplugin.git ~/.grunt-init/gruntplugin`
3 | 3. Run `grunt-init gruntplugin` in an empty directory.
4 | 4. Run `npm install` to prepare the development environment.
5 | 5. Author your plugin.
6 | 6. Run `npm publish` to publish the Grunt plugin to npm!
7 |
8 | ## Notes
9 |
10 | ### Naming your task
11 |
12 | The "grunt-contrib" namespace is reserved for tasks maintained by the Grunt team, please name your task something appropriate that avoids that naming scheme.
13 |
14 | ### Debugging
15 | Grunt hides error stack traces by default, but they can be enabled for easier task debugging with the `--stack` option. If you want Grunt to always log stack traces on errors, create an alias in your shell. Eg, in bash, you could do `alias grunt='grunt --stack'`.
16 |
17 | ### Storing task files
18 |
19 | Only store data files in a .grunt/[npm-module-name]/ directory at the project's root and clean up after yourself when appropriate. This is not a solution for temporary scratch files, use one of the common npm modules (eg [temporary](https://npmjs.org/package/temporary), [tmp](https://npmjs.org/package/tmp)) that take advantage of the OS level temporary directories for that case.
20 |
21 | ### Avoid Changing the Current Working Directory: `process.cwd()`
22 | By default, the current working directory is set to be the directory that contains the gruntfile. The user can change it using `grunt.file.setBase()` in their gruntfile, but plugins should take care to not change it.
23 |
24 | `path.resolve('foo')` can be used to get the absolute path of the filepath 'foo' relative to the `Gruntfile`.
25 |
26 | ### Creating your task
27 |
28 | You might also want to know how to [create your own tasks](http://gruntjs.com/creating-tasks) or take a look at the [API](http://gruntjs.com/api) reference.
29 |
--------------------------------------------------------------------------------
/Blog-2013-11-21-Grunt-0.4.2-released.md:
--------------------------------------------------------------------------------
1 | Grunt 0.4.2 is now available on [npm](https://npmjs.org/package/grunt).
2 |
3 | This release should address a lot of issues for Windows developers, such as pipe-redirection, console output and BOM preservation.
4 |
5 | Besides a number of bug fixes, we have made a few decisions going forward regarding external dependencies in Grunt. **These external libraries are deprecated and should now be required as npm modules:**
6 |
7 | * Use [glob](https://npmjs.org/package/glob) instead of `grunt.file.glob`
8 | * Use [minimatch](https://npmjs.org/package/minimatch) instead of `grunt.file.minimatch`
9 | * Use [findup](https://npmjs.org/package/findup) instead of `grunt.file.findup`
10 | * Use [lodash](https://npmjs.org/package/lodash) instead of `grunt.util._`
11 | * Use [underscore.string](https://npmjs.org/package/underscore.string) instead of `grunt.util._.str`
12 | * Use [hooker](https://npmjs.org/package/hooker) instead of `grunt.util.hooker`
13 | * Use [async](https://npmjs.org/package/async) instead of `grunt.util.async`
14 | * Use [getobject](https://github.com/cowboy/node-getobject) instead of `grunt.util.namespace`
15 |
16 | If you want to use these external libraries in your tasks, please install them as you would [Grunt or any Grunt plugin](http://gruntjs.com/getting-started#installing-grunt-and-gruntplugins) using `npm install --save-dev`. For example, if you used `grunt.util._` before, you'll now require [Lo-Dash](http://lodash.com/) instead with `npm install lodash --save-dev`.
17 |
18 | ```js
19 | // Then change this code:
20 | var newArr = grunt.util._.map(arr, fn);
21 |
22 | // To this:
23 | var _ = require('lodash');
24 | var newArr = _.map(arr, fn);
25 | ```
26 |
27 | The team is also looking for feedback about the future of Grunt, so if you have time, please join the 0.5.0 milestone
28 | [discussions](https://github.com/gruntjs/grunt/issues?direction=desc&milestone=7&page=1&sort=updated&state=open).
29 |
30 | See the 0.4.2 changelog [here](https://github.com/gruntjs/grunt/blob/v0.4.2/CHANGELOG).
31 |
32 | **Happy Grunting!**
--------------------------------------------------------------------------------
/Using-plugins.md:
--------------------------------------------------------------------------------
1 | Grunt plugins define tasks that implement certain build steps and can be reused across multiple projects. The examples will use the plugin _"grunt-contrib-uglify"_. Check the [Grunt website](http://gruntjs.com/) for a list of available plugins.
2 |
3 | ## Installing a Grunt plugin
4 |
5 | The first step to using an existing Grunt plugin is to install it.Grunt plugins are packaged as node modules and can be installed using [npm](http://npmjs.org) like this:
6 |
7 | `npm install --save-dev grunt-contrib-uglify`
8 |
9 | This will install the Grunt plugin _"grunt-contrib-uglify"_ locally into the `node_modules` folder (cf. [npm folders](https://npmjs.org/doc/folders.html)).
10 | Plugins must be installed locally to avoid version conflicts when working with multiple projects.
11 |
12 | Specifying `--save-dev` as option automatically adds this Grunt plugin to the _"devDependency"_ section in the `package.json` file. This file lists all node dependencies of a project.
13 | Adding the Grunt plugin there will allow other developers working on the project to simply run `npm install` to locally install these required dependencies.
14 |
15 | ## Loading plugin tasks
16 |
17 | Now that the plugin is installed, it is time to tell Grunt about it and let it load all defined tasks. To do this, add the following line to your `Gruntfile.js`:
18 |
19 | `grunt.loadNpmTasks('grunt-contrib-uglify')`
20 |
21 | This line should be added within the top level function scope (not the initConfig section) where other `grunt.registerTask()` calls are made.
22 |
23 | ## Running plugin tasks
24 |
25 | Plugin tasks can be run like other Grunt tasks either by specifying them on the command line:
26 |
27 | `grunt uglify`
28 |
29 | Or by registering a new task alias which calls this task, and running that task:
30 |
31 | `grunt.registerTask("dist", ["uglify"])`
32 |
33 | ## Configuring plugins
34 |
35 | Plugin configuration depends on the specific plugin, so check the plugin's documentation for further information. Generally the configuration is located in the `initConfig` section of the Gruntfile.
36 |
37 | **TODO**: Configuration Targets/options (Merge [Configuring tasks](Configuring tasks)?)
--------------------------------------------------------------------------------
/Development-Team.md:
--------------------------------------------------------------------------------
1 | | | | |
2 | | ------------- | ----------- |
3 | |  | **Ben Alman** | [GitHub](https://github.com/cowboy), [Twitter](https://twitter.com/cowboy), [Website](http://benalman.com/) |
4 | |  | **Tyler Kellen** | [GitHub](https://github.com/tkellen), [Twitter](https://twitter.com/tkellen), [Website](http://goingslowly.com/) |
5 | |  | **Kyle Robinson Young** | [GitHub](https://github.com/shama), [Twitter](https://twitter.com/shamakry), [Website](http://dontkry.com/) |
6 | |  | **Vlad Filippov** | [GitHub](https://github.com/vladikoff), [Twitter](https://twitter.com/vladikoff), [Website](http://vf.io/) |
7 | |  | **Sindre Sorhus** | [GitHub](https://github.com/sindresorhus), [Twitter](https://twitter.com/sindresorhus), [Website](http://sindresorhus.com/hi/) |
8 | |  | **Isaac Durazo** | [GitHub](https://github.com/isaacdurazo), [Twitter](https://twitter.com/isaacdurazo), [Website](http://www.isaacdurazo.com/) |
9 | |  | **Jarrod Overson** | [GitHub](https://github.com/tkellen), [Twitter](https://twitter.com/jsoverson), [Website](http://jarrodoverson.com/) |
10 | |  | **Tim Branyen** | [GitHub](https://github.com/tbranyen), [Twitter](https://twitter.com/tbranyen), [Website](http://tbranyen.com/) |
11 | |  | **Jörn Zaefferer** | [GitHub](https://github.com/jzaefferer), [Twitter](https://twitter.com/bassistance), [Website](http://bassistance.de/) |
12 | |  | **James Smith**| [GitHub](https://github.com/jmeas), [Twitter](https://twitter.com/jmeaspls), [Website](http://www.jmeas.com/) |
13 | |  | **Dave Geddes** | [GitHub](https://github.com/geddski) |
14 | | | | |
15 |
--------------------------------------------------------------------------------
/grunt.md:
--------------------------------------------------------------------------------
1 | Grunt exposes all of its methods and properties on the `grunt` object that gets passed into the `module.exports` function exported in your [Gruntfile](Getting-started), Grunt plugin or in a [tasks file](Creating-tasks).
2 |
3 | Nearly all of the following methods are defined elsewhere, but are provided directly on the `grunt` object for convenience. See the individual api section docs for detailed explanations and examples.
4 |
5 | ## Config
6 |
7 | ### grunt.initConfig
8 | _This method is an alias for the [grunt.config.init](grunt.config#grunt.config.init) method._
9 |
10 |
11 | ## Creating Tasks
12 |
13 | ### grunt.registerTask
14 | _This method is an alias for the [grunt.task.registerTask](grunt.task#grunt.task.registerTask) method._
15 |
16 | ### grunt.registerMultiTask
17 | _This method is an alias for the [grunt.task.registerMultiTask](grunt.task#grunt.task.registerMultiTask) method._
18 |
19 | ### grunt.renameTask
20 | _This method is an alias for the [grunt.task.renameTask](grunt.task#grunt.task.renameTask) method._
21 |
22 | ## Loading Externally-Defined Tasks
23 |
24 | ### grunt.loadTasks
25 | _This method is an alias for the [grunt.task.loadTasks](grunt.task#grunt.task.loadTasks) method._
26 |
27 | ### grunt.loadNpmTasks
28 | _This method is an alias for the [grunt.task.loadNpmTasks](grunt.task#grunt.task.loadNpmTasks) method._
29 |
30 |
31 | ## Warnings and Fatal Errors
32 |
33 | ### grunt.warn
34 | _This method is an alias for the [grunt.fail.warn](grunt.fail#grunt.fail.warn) method._
35 |
36 | ### grunt.fatal
37 | _This method is an alias for the [grunt.fail.fatal](grunt.fail#grunt.fail.fatal) method._
38 |
39 |
40 | ## Command-line Options
41 |
42 | ### grunt.option
43 | Retrieve the value of a command-line option, eg. `debug`. Note that for each command-line option, the inverse can be tested, eg. `no-debug`.
44 |
45 | ```javascript
46 | grunt.option(optionName)
47 | ```
48 |
49 | ## Miscellaneous
50 |
51 | ### grunt.package
52 | The current Grunt `package.json` metadata, as an object.
53 |
54 | ```javascript
55 | grunt.package
56 | ```
57 |
58 | ### grunt.version
59 | The current Grunt version, as a string. This is just a shortcut to the `grunt.package.version` property.
60 |
61 | ```javascript
62 | grunt.version
63 | ```
64 |
--------------------------------------------------------------------------------
/grunt.option.md:
--------------------------------------------------------------------------------
1 | The Grunt option API is for sharing parameters across multiple tasks and accessing parameters set on the command line.
2 |
3 | An example would be a flag to target whether your build is for development or staging. On the command line: `grunt deploy --target=staging` would cause `grunt.option('target')` to return `"staging"`.
4 |
5 | An example `Gruntfile` to utilize the `target` option could be:
6 |
7 | ```javascript
8 | grunt.initConfig({
9 | compass: {
10 | dev: {
11 | options: {
12 | /* ... */
13 | outputStyle: 'expanded'
14 | },
15 | },
16 | staging: {
17 | options: {
18 | /* ... */
19 | outputStyle: 'compressed'
20 | },
21 | },
22 | },
23 | });
24 | var target = grunt.option('target') || 'dev';
25 | grunt.registerTask('deploy', ['compass:' + target]);
26 | ```
27 |
28 | As you run `grunt deploy` your stylesheets would default to the `dev` target and output the CSS in the expanded format. If you ran `grunt deploy --target=staging` the `staging` target would instead be ran and your CSS would be in the compressed format.
29 |
30 | `grunt.option` can be used within tasks as well, for example:
31 |
32 | ```javascript
33 | grunt.registerTask('upload', 'Upload code to specified target.', function(n) {
34 | var target = grunt.option('target');
35 | // do something useful with target here
36 | });
37 | grunt.registerTask('deploy', ['validate', 'upload']);
38 | ```
39 |
40 | _Note that boolean options can be specified using just a key without a value. For example, running `grunt deploy --staging` on the command line would cause `grunt.option('staging')` to return `true`._
41 |
42 |
43 | ### grunt.option ☃
44 | Gets or sets an option.
45 |
46 | ```javascript
47 | grunt.option(key[, val])
48 | ```
49 |
50 | Boolean options can be negated by prepending `no-` onto the `key`. For example:
51 |
52 | ```javascript
53 | grunt.option('staging', false);
54 | var isDev = grunt.option('no-staging');
55 | // isDev === true
56 | ```
57 |
58 | ### grunt.option.init
59 | Initialize `grunt.option`. If `initObject` is omitted option will be initialized to an empty object otherwise will be set to `initObject`.
60 |
61 | ```javascript
62 | grunt.option.init([initObject])
63 | ```
64 |
65 | ### grunt.option.flags
66 | Returns the options as an array of command line parameters.
67 |
68 | ```javascript
69 | grunt.option.flags()
70 | ```
71 |
--------------------------------------------------------------------------------
/Installing-grunt.md:
--------------------------------------------------------------------------------
1 | This document explains how to install specific versions of Grunt and Grunt plugins. If you haven't read the [[Getting Started]] guide, you should check that out first.
2 |
3 | ## Overview
4 | Grunt and Grunt plugins should be defined as [devDependencies](https://npmjs.org/doc/json.html#devDependencies) in your project's [package.json](https://npmjs.org/doc/json.html). This will allow you to install all of your project's dependencies with a single command: `npm install`. The current stable and development versions of Grunt are always listed on the wiki's [home page](https://github.com/gruntjs/grunt/wiki/).
5 |
6 | ## Installing a specific version
7 | If you need a specific version of Grunt or a Grunt plugin, run `npm install grunt@VERSION --save-dev` where `VERSION` is the version you need. This will install the specified version, adding it to your package.json devDependencies.
8 |
9 | Note that a [tilde version range] will be used in your `package.json` when you add the `--save-dev` flag to `npm install`. This is typically good, as new patch releases of the specified version will automatically be upgraded as development continues, per [semver].
10 |
11 | [tilde version range]: https://npmjs.org/doc/json.html#Tilde-Version-Ranges
12 | [semver]: http://semver.org
13 |
14 | ## Installing a published development version
15 | Periodically, as new functionality is being developed, Grunt builds may be published to npm. These builds will _never_ be installable without explicitly specifying a version number, and will typically have a build number or alpha/beta/release candidate designation.
16 |
17 | Like installing a specific version of grunt, run `npm install grunt@VERSION --save-dev` where `VERSION` is the version you need, and npm will install that version of Grunt in your project folder, adding it to your `package.json` devDependencies.
18 |
19 | Note that regardless of the version you specify, a [tilde version range][] will be specified in `package.json`. **This is very bad**, as new, possibly incompatible, patch releases of the specified development version may be installed by npm, breaking your build.
20 |
21 | _In this case it is **very important** that you manually edit your `package.json` and remove the ~ (tilde) from the version number. This will lock in the exact development version that you have specified._
22 |
23 | The same process may be used to install a published development version of a Grunt plugin.
24 |
25 | ## Installing directly from github
26 | If you want to install a bleeding-edge, unpublished version of Grunt or Grunt plugin, follow the instructions for specifying a [git URL as a dependency](https://npmjs.org/doc/json.html#Git-URLs-as-Dependencies) and be sure to specify an actual commit SHA (not a branch name) as the `commit-ish`. This will guarantee that your project always uses that exact version of grunt.
27 |
28 | The specified git URL may be that of the official Grunt repo or a fork.
--------------------------------------------------------------------------------
/grunt.template.md:
--------------------------------------------------------------------------------
1 | Template strings can be processed manually using the provided template functions. In addition, the config.get method (used by many tasks) automatically expands `<% %>` style template strings specified as config data inside the `Gruntfile`.
2 |
3 | ### grunt.template.process
4 | Process a [Lo-Dash template](http://lodash.com/docs/#template) string. The `template` argument will be processed recursively until there are no more templates to process.
5 |
6 | The default data object is the entire config object, but if `options.data` is set, that object will be used instead. The default template delimiters are `<% %>` but if `options.delimiters` is set to a custom delimiter name (set with [`grunt.template.addDelimiters`](#grunt.template.adddelimiters)), those template delimiters will be used instead.
7 |
8 | ```js
9 | grunt.template.process(template [, options])
10 | ```
11 |
12 | Inside templates, the `grunt` object is exposed so that you can do things like `<%= grunt.template.today('yyyy') %>`. _Note that if the data object already has a `grunt` property, the `grunt` API will not be accessible in templates._
13 |
14 | In this example, the `baz` property is processed recursively until there are no more `<% %>` templates to process.
15 |
16 | ```js
17 | var obj = {
18 | foo: 'c',
19 | bar: 'b<%= foo %>d',
20 | baz: 'a<%= bar %>e'
21 | };
22 | grunt.template.process('<%= baz %>', {data: obj}) // 'abcde'
23 | ```
24 |
25 | ### grunt.template.setDelimiters
26 | Set the [Lo-Dash template](http://lodash.com/docs/#template) delimiters to a predefined set in case `grunt.util._.template` needs to be called manually. The `config` delimiters `<% %>` are included by default.
27 |
28 | _You probably won't need to use this method, because you'll be using `grunt.template.process` which uses this method internally._
29 |
30 | ```js
31 | grunt.template.setDelimiters(name)
32 | ```
33 |
34 | ### grunt.template.addDelimiters
35 | Add a named set of [Lo-Dash template](http://lodash.com/docs/#template) delimiters. You probably won't need to use this method, because the built-in delimiters should be sufficient, but you could always add `{% %}` or `[% %]` style delimiters.
36 |
37 | The `name` argument should be unique since it is how we access the delimiters from `grunt.template.setDelimiters` and as an option for `grunt.template.process`.
38 |
39 | ```js
40 | grunt.template.addDelimiters(name, opener, closer)
41 | ```
42 |
43 | In this example, if we were to use the `{% %}` style mentioned above we would use the following:
44 |
45 | ```js
46 | grunt.template.addDelimiters('myDelimiters', '{%', '%}')
47 | ```
48 |
49 | ## Helpers
50 |
51 | ### grunt.template.date
52 | Format a date using the [dateformat library](https://github.com/felixge/node-dateformat).
53 |
54 | ```js
55 | grunt.template.date(date, format)
56 | ```
57 |
58 | In this example, a specific date is formatted as month/day/year.
59 |
60 | ```js
61 | grunt.template.date(847602000000, 'yyyy-mm-dd') // '1996-11-10'
62 | ```
63 |
64 | ### grunt.template.today
65 | Format today's date using the [dateformat library](https://github.com/felixge/node-dateformat).
66 |
67 | ```js
68 | grunt.template.today(format)
69 | ```
70 |
71 | In this example, today's date is formatted as a 4-digit year.
72 |
73 | ```js
74 | grunt.template.today('yyyy') // '2014'
75 | ```
76 |
77 | _(somebody remind me to update this date every year so the docs appear current)_
78 |
--------------------------------------------------------------------------------
/Roadmap.md:
--------------------------------------------------------------------------------
1 | ## Grunt 0.next
2 |
3 | * Drop Node.JS 0.8 support
4 | * New logging (https://github.com/cowboy/node-prolog)
5 | * A logger to listen to events and output them to the console. Deals with stderr/stdout, or Grunt itself has this built in.
6 | * node-task (https://github.com/node-task)
7 | * Tasks as npm modules that can be required and run independent of any task runner (if you want to manually build a compliant config object to execute it). Can pipe data between multiple tasks (think coffeescript transpilation + uglify in a single step). All task output emitted as events.
8 | * A library for parsing configurations (merge options, template expansion, glob expansion (using lib from item #2) from the current Gruntfile format, into a valid form for running node-task compliant modules. Will support user-defined middleware for controlling config output.
9 | * A task runner which uses config parsing library from item #3 to execute node-task compatible modules (can be used programmatically, or via cli). Supports defining "alias" tasks which compile a set of tasks which can be run in parallel See: http://github.com/gruntjs/grunt
10 |
11 | ## Grunt 0.5
12 |
13 | ### Update Release
14 |
15 | * Updates dependencies
16 | * Removes external libraries under `grunt.util.`
17 | * A library for glob expansion that handles arrays of globs, negation, etc. See https://github.com/cowboy/node-globule
18 |
19 | See https://github.com/gruntjs/grunt/issues/1045 for updated information.
20 |
21 |
22 |
23 |
24 |
25 |
26 | ## Out of Date Information / Drafts
27 |
28 | **0.5 Gruntfile Ideas**
29 | ```js
30 | var grunt = require('grunt');
31 |
32 | grunt.initConfig({
33 | // defaults for cli
34 | grunt: {
35 | dryRun: true,
36 | stack: true,
37 | verbose: true,
38 | // what about defining loggers specific to a task?
39 | // is this required in your gruntfile or on by default?
40 | logger: [require('grunt-logger')]
41 | },
42 | jshint: {
43 | // ...
44 | },
45 | concat: {
46 | // ...
47 | },
48 | min: {
49 | // ...
50 | }
51 | });
52 |
53 | grunt.registerTask(require('grunt-contrib-jshint'));
54 | grunt.registerTask(require('grunt-contrib-concat'));
55 | grunt.registerTask(require('grunt-contrib-uglify'), 'min'); // optional second param renames
56 |
57 | // generates a node-task compliant object and runs grunt.registerTask on it
58 | grunt.registerTask('name','description', function (config) {
59 | //...
60 | });
61 |
62 | // load a set of tasks to be run in parallel
63 | grunt.registerTask('name', ['jshint', 'concat'], { parallel:true });
64 |
65 | // i think the cli should call this, but putting it here because you mentioned thinking it should go here.
66 | grunt.run();
67 | ```
68 | ***Please ignore the section below. It is a jumbled mess/work in progress and should not be considered anything resembling a roadmap.***
69 |
70 | 527 - parallel execution of tasks
71 | 545 - conditional compilation (probably belongs on the watch task)
72 | 493 - cwd handling
73 |
74 | * more specific error codes
75 | * Task not found
76 | * Task failed
77 | * Task requirement not met
78 | * Config requirement not met
79 |
80 | ## grunt-log
81 | * Log to stderr/stdout. [#586](https://github.com/gruntjs/grunt/issues/586) [#570](https://github.com/gruntjs/grunt/issues/570) [#120](https://github.com/gruntjs/grunt/issues/120)
82 | * https://github.com/tkellen/grunt-decoupled/tree/master/grunt-log
83 |
84 | ## grunt-file
85 | * https://github.com/tkellen/grunt-decoupled/tree/master/grunt-file
86 |
87 | ## grunt-util
88 | * https://github.com/tkellen/grunt-decoupled/tree/master/grunt-util
89 |
--------------------------------------------------------------------------------
/grunt.config.md:
--------------------------------------------------------------------------------
1 | Access project-specific configuration data defined in the `Gruntfile`.
2 |
3 | Note that any method marked with a ☃ (unicode snowman) is also available directly on the `grunt` object, and any method marked with a ☆ (white star) is also available inside tasks on the `this` object. Just so you know.
4 |
5 | ## Initializing Config Data
6 | _Note that the following method is also available on the `grunt` object as `grunt.initConfig`._
7 |
8 | ### grunt.config.init ☃
9 | Initialize a configuration object for the current project. The specified `configObject` is used by tasks and can be accessed using the `grunt.config` method. Nearly every project's `Gruntfile` will call this method.
10 |
11 | ```js
12 | grunt.config.init(configObject)
13 | ```
14 |
15 | Note that any specified `<% %>` template strings will be processed when config data is retrieved.
16 |
17 | This example contains sample config data for the [grunt-contrib-jshint plugin](https://github.com/gruntjs/grunt-contrib-jshint) `jshint` task:
18 |
19 | ```js
20 | grunt.config.init({
21 | jshint: {
22 | all: ['lib/*.js', 'test/*.js', 'Gruntfile.js']
23 | }
24 | });
25 | ```
26 |
27 | See the [[Getting started]] guide for more configuration examples.
28 |
29 | _This method is also available as `grunt.initConfig`._
30 |
31 |
32 | ## Accessing Config Data
33 | The following methods allow Grunt configuration data to be accessed either via dot-delimited string like `'pkg.author.name'` or via array of property name parts like `['pkg', 'author', 'name']`.
34 |
35 | Note that if a specified property name contains a `.` dot, it must be escaped with a literal backslash, eg. `'concat.dist/built\\.js'`. If an array of parts is specified, Grunt will handle the escaping internally with the `grunt.config.escape` method.
36 |
37 | ### grunt.config
38 | Get or set a value from the project's Grunt configuration. This method serves as an alias to other methods; if two arguments are passed, `grunt.config.set` is called, otherwise `grunt.config.get` is called.
39 |
40 | ```js
41 | grunt.config([prop [, value]])
42 | ```
43 |
44 | ### grunt.config.get
45 | Get a value from the project's Grunt configuration. If `prop` is specified, that property's value is returned, or `null` if that property is not defined. If `prop` isn't specified, a copy of the entire config object is returned. Templates strings will be recursively processed using the `grunt.config.process` method.
46 |
47 | ```js
48 | grunt.config.get([prop])
49 | ```
50 |
51 | ### grunt.config.process
52 | Process a value, recursively expanding `<% %>` templates (via the `grunt.template.process` method) in the context of the Grunt config, as they are encountered. this method is called automatically by `grunt.config.get` but _not_ by `grunt.config.getRaw`.
53 |
54 | ```js
55 | grunt.config.process(value)
56 | ```
57 |
58 | If any retrieved value is entirely a single `'<%= foo %>'` or `'<%= foo.bar %>'` template string, and the specified `foo` or `foo.bar` property is a non-string (and not `null` or `undefined`) value, it will be expanded to the _actual_ value. That, combined with grunt's task system automatically flattening arrays, can be extremely useful.
59 |
60 | ### grunt.config.getRaw
61 | Get a raw value from the project's Grunt configuration, without processing `<% %>` template strings. If `prop` is specified, that property's value is returned, or `null` if that property is not defined. If `prop` isn't specified, a copy of the entire config object is returned.
62 |
63 | ```js
64 | grunt.config.getRaw([prop])
65 | ```
66 |
67 | ### grunt.config.set
68 | Set a value into the project's Grunt configuration.
69 |
70 | ```js
71 | grunt.config.set(prop, value)
72 | ```
73 |
74 | Note that any specified `<% %>` template strings will only be processed when config data is retrieved.
75 |
76 | ### grunt.config.escape
77 | Escape `.` dots in the given `propString`. This should be used for property names that contain dots.
78 |
79 | ```js
80 | grunt.config.escape(propString)
81 | ```
82 |
83 | ### grunt.config.merge
84 | *Added in 0.4.5*
85 |
86 | Recursively merges properties of the specified `configObject` into the current project configuration.
87 |
88 | ```js
89 | grunt.config.merge(configObject)
90 | ```
91 | You can use this method to append configuration options, targets, etc., to already defined tasks, for example:
92 | ```js
93 | grunt.config.merge({
94 | watch: {
95 | files: ["path/to/files"],
96 | tasks: ["task"]
97 | }
98 | });
99 | ```
100 |
101 | ## Requiring Config Data
102 | _Note that the method listed below is also available inside tasks on the `this` object as `this.requiresConfig`._
103 |
104 | ### grunt.config.requires ☆
105 | Fail the current task if one or more required config properties is missing, `null` or `undefined`. One or more string or array config properties may be specified.
106 |
107 | ```js
108 | grunt.config.requires(prop [, prop [, ...]])
109 | ```
110 |
111 | _This method is also available inside tasks as `this.requiresConfig`._
112 |
--------------------------------------------------------------------------------
/grunt.log.md:
--------------------------------------------------------------------------------
1 | Output messages to the console.
2 |
3 | See the [log lib source](https://github.com/gruntjs/grunt-legacy-log/blob/master/index.js) for more information.
4 |
5 | ## The log API
6 | Grunt output should look consistent, and maybe even pretty. As such, there is a plethora of logging methods, and a few useful patterns. All of the methods that actually log something are chainable.
7 |
8 | _Note: all methods available under `grunt.verbose` work exactly like `grunt.log` methods, but only log if the `--verbose` command-line option was specified._
9 |
10 | ### grunt.log.write / grunt.verbose.write
11 | Log the specified `msg` string, with no trailing newline.
12 |
13 | ```javascript
14 | grunt.log.write(msg)
15 | ```
16 |
17 | ### grunt.log.writeln / grunt.verbose.writeln
18 | Log the specified `msg` string, with trailing newline.
19 |
20 | ```javascript
21 | grunt.log.writeln([msg])
22 | ```
23 |
24 | ### grunt.log.error / grunt.verbose.error
25 | If `msg` string is omitted, logs `ERROR` in red, otherwise logs `>> msg`, with trailing newline.
26 |
27 | ```javascript
28 | grunt.log.error([msg])
29 | ```
30 |
31 | ### grunt.log.errorlns / grunt.verbose.errorlns
32 | Log an error with `grunt.log.error`, wrapping text to 80 columns using `grunt.log.wraptext`.
33 |
34 | ```javascript
35 | grunt.log.errorlns(msg)
36 | ```
37 |
38 | ### grunt.log.ok / grunt.verbose.ok
39 | If `msg` string is omitted, logs `OK` in green, otherwise logs `>> msg`, with trailing newline.
40 |
41 | ```javascript
42 | grunt.log.ok([msg])
43 | ```
44 |
45 | ### grunt.log.oklns / grunt.verbose.oklns
46 | Log an ok message with `grunt.log.ok`, wrapping text to 80 columns using `grunt.log.wraptext`.
47 |
48 | ```javascript
49 | grunt.log.oklns(msg)
50 | ```
51 |
52 | ### grunt.log.subhead / grunt.verbose.subhead
53 | Log the specified `msg` string in **bold**, with trailing newline.
54 |
55 | ```javascript
56 | grunt.log.subhead(msg)
57 | ```
58 |
59 | ### grunt.log.writeflags / grunt.verbose.writeflags
60 | Log a list of `obj` properties (good for debugging flags).
61 |
62 | ```javascript
63 | grunt.log.writeflags(obj, prefix)
64 | ```
65 |
66 | ### grunt.log.debug / grunt.verbose.debug
67 | Logs a debugging message, but only if the `--debug` command-line option was specified.
68 |
69 | ```javascript
70 | grunt.log.debug(msg)
71 | ```
72 |
73 | ## Verbose and Notverbose
74 | All logging methods available under `grunt.verbose` work exactly like their `grunt.log` counterparts, but only log if the `--verbose` command-line option was specified. There is also a "notverbose" counterpart available at both `grunt.log.notverbose` and `grunt.log.verbose.or`. In fact, the `.or` property can be used on both `verbose` and `notverbose` to effectively toggle between the two.
75 |
76 | ### grunt.verbose / grunt.log.verbose
77 | This object contains all methods of `grunt.log` but only logs if the `--verbose` command-line option was specified.
78 |
79 | ```javascript
80 | grunt.verbose
81 | ```
82 |
83 | ### grunt.verbose.or / grunt.log.notverbose
84 | This object contains all methods of `grunt.log` but only logs if the `--verbose` command-line option was _not_ specified.
85 |
86 | ```javascript
87 | grunt.verbose.or
88 | ```
89 |
90 | ## Utility Methods
91 | These methods don't actually log, they just return strings that can be used in other methods.
92 |
93 | ### grunt.log.wordlist
94 | Returns a comma-separated list of `arr` array items.
95 |
96 | ```javascript
97 | grunt.log.wordlist(arr [, options])
98 | ```
99 |
100 | The `options` object has these possible properties, and default values:
101 |
102 | ```javascript
103 | var options = {
104 | // The separator string (can be colored).
105 | separator: ', ',
106 | // The array item color (specify false to not colorize).
107 | color: 'cyan',
108 | };
109 | ```
110 |
111 | ### grunt.log.uncolor
112 | Removes all color information from a string, making it suitable for testing `.length` or perhaps logging to a file.
113 |
114 | ```javascript
115 | grunt.log.uncolor(str)
116 | ```
117 |
118 | ### grunt.log.wraptext
119 | Wrap `text` string to `width` characters with `\n`, ensuring that words are not split in the middle unless absolutely necessary.
120 |
121 | ```javascript
122 | grunt.log.wraptext(width, text)
123 | ```
124 |
125 | ### grunt.log.table
126 | Wrap `texts` array of strings to columns `widths` characters wide. A wrapper for the `grunt.log.wraptext` method that can be used to generate output in columns.
127 |
128 | ```javascript
129 | grunt.log.table(widths, texts)
130 | ```
131 |
132 | ## An Example
133 |
134 | A common pattern is to only log when in `--verbose` mode OR if an error occurs, like so:
135 |
136 | ```javascript
137 | grunt.registerTask('something', 'Do something interesting.', function(arg) {
138 | var msg = 'Doing something...';
139 | grunt.verbose.write(msg);
140 | try {
141 | doSomethingThatThrowsAnExceptionOnError(arg);
142 | // Success!
143 | grunt.verbose.ok();
144 | } catch(e) {
145 | // Something went wrong.
146 | grunt.verbose.or.write(msg).error().error(e.message);
147 | grunt.fail.warn('Something went wrong.');
148 | }
149 | });
150 | ```
151 |
152 | An explanation of the above code:
153 |
154 | 1. `grunt.verbose.write(msg);` logs the message (no newline), but only in `--verbose` mode.
155 | 2. `grunt.verbose.ok();` logs OK in green, with a newline.
156 | 3. `grunt.verbose.or.write(msg).error().error(e.message);` does a few things:
157 | 1. `grunt.verbose.or.write(msg)` logs the message (no newline) if not in `--verbose` mode, and returns the `notverbose` object.
158 | 2. `.error()` logs ERROR in red, with a newline, and returns the `notverbose` object.
159 | 3. `.error(e.message);` logs the actual error message (and returns the `notverbose` object).
160 | 4. `grunt.fail.warn('Something went wrong.');` logs a warning in bright yellow, exiting Grunt with exit code 1, unless `--force` was specified.
161 |
162 | Take a look at the [grunt-contrib-* tasks source code](https://github.com/gruntjs) for more examples.
163 |
--------------------------------------------------------------------------------
/grunt.util.md:
--------------------------------------------------------------------------------
1 | Miscellaneous utilities for your Gruntfile and tasks.
2 |
3 | ### grunt.util.kindOf
4 | Return the "kind" of a value. Like `typeof` but returns the internal `[[Class]]` value. Possible results are `"number"`, `"string"`, `"boolean"`, `"function"`, `"regexp"`, `"array"`, `"date"`, `"error"`, `"null"`, `"undefined"` and the catch-all `"object"`.
5 |
6 | ```js
7 | grunt.util.kindOf(value)
8 | ```
9 |
10 | ### grunt.util.error
11 | Return a new Error instance (that can be thrown) with the appropriate message. If an Error object is specified instead of `message` that object will be returned.
12 | Also, if an Error object is specified for `origError` and Grunt was run with the `--stack` option, the original Error stack will be dumped.
13 |
14 | ```js
15 | grunt.util.error(message [, origError])
16 | ```
17 |
18 | ### grunt.util.linefeed
19 | The linefeed character, normalized for the current operating system. (`\r\n` on Windows, `\n` otherwise)
20 |
21 | ### grunt.util.normalizelf
22 | Given a string, return a new string with all the linefeeds normalized for the current operating system. (`\r\n` on Windows, `\n` otherwise)
23 |
24 | ```js
25 | grunt.util.normalizelf(string)
26 | ```
27 |
28 | ### grunt.util.recurse
29 | Recurse through nested objects and arrays, executing `callbackFunction` for each non-object value. If `continueFunction` returns `false`, a given object or value will be skipped.
30 |
31 | ```js
32 | grunt.util.recurse(object, callbackFunction, continueFunction)
33 | ```
34 |
35 | ### grunt.util.repeat
36 | Return string `str` repeated `n` times.
37 |
38 | ```js
39 | grunt.util.repeat(n, str)
40 | ```
41 |
42 | ### grunt.util.pluralize
43 | Given `str` of `"a/b"`, If `n` is `1`, return `"a"` otherwise `"b"`. You can specify a custom separator if '/' doesn't work for you.
44 |
45 | ```js
46 | grunt.util.pluralize(n, str, separator)
47 | ```
48 |
49 | ### grunt.util.spawn
50 | Spawn a child process, keeping track of its stdout, stderr and exit code. The method returns a reference to the spawned child. When the child exits, the `doneFunction` is called.
51 |
52 | ```js
53 | grunt.util.spawn(options, doneFunction)
54 | ```
55 |
56 | The `options` object has these possible properties:
57 |
58 | ```js
59 | var options = {
60 | // The command to execute. It should be in the system path.
61 | cmd: commandToExecute,
62 | // If specified, the same grunt bin that is currently running will be
63 | // spawned as the child command, instead of the "cmd" option. Defaults
64 | // to false.
65 | grunt: boolean,
66 | // An array of arguments to pass to the command.
67 | args: arrayOfArguments,
68 | // Additional options for the Node.js child_process spawn method.
69 | opts: nodeSpawnOptions,
70 | // If this value is set and an error occurs, it will be used as the value
71 | // and null will be passed as the error value.
72 | fallback: fallbackValue
73 | };
74 | ```
75 |
76 | The `doneFunction` accepts these arguments:
77 |
78 | ```js
79 | function doneFunction(error, result, code) {
80 | // If the exit code was non-zero and a fallback wasn't specified, an Error
81 | // object, otherwise null.
82 | error
83 | // The result object is an object with the properties .stdout, .stderr, and
84 | // .code (exit code).
85 | result
86 | // When result is coerced to a string, the value is stdout if the exit code
87 | // was zero, the fallback if the exit code was non-zero and a fallback was
88 | // specified, or stderr if the exit code was non-zero and a fallback was
89 | // not specified.
90 | String(result)
91 | // The numeric exit code.
92 | code
93 | }
94 | ```
95 |
96 | ### grunt.util.toArray
97 | Given an array or array-like object, return an array. Great for converting `arguments` objects into arrays.
98 |
99 | ```js
100 | grunt.util.toArray(arrayLikeObject)
101 | ```
102 |
103 | ### grunt.util.callbackify
104 | Normalizes both "returns a value" and "passes result to a callback" functions to always pass a result to the specified callback. If the original function returns a value, that value will now be passed to the callback, which is specified as the last argument, after all other predefined arguments. If the original function passed a value to a callback, it will continue to do so.
105 |
106 | ```js
107 | grunt.util.callbackify(syncOrAsyncFunction)
108 | ```
109 |
110 | This example might better illustrate:
111 |
112 | ```js
113 | function add1(a, b) {
114 | return a + b;
115 | }
116 | function add2(a, b, callback) {
117 | callback(a + b);
118 | }
119 |
120 | var fn1 = grunt.util.callbackify(add1);
121 | var fn2 = grunt.util.callbackify(add2);
122 |
123 | fn1(1, 2, function(result) {
124 | console.log('1 plus 2 equals ' + result);
125 | });
126 | fn2(1, 2, function(result) {
127 | console.log('1 plus 2 equals ' + result);
128 | });
129 | ```
130 |
131 | ## Internal libraries
132 |
133 | ### grunt.util.namespace
134 | An internal library for resolving deeply-nested properties in objects.
135 |
136 | ### grunt.util.task
137 | An internal library for task running.
138 |
139 | ## External libraries
140 | *Deprecated*
141 |
142 | __All external libraries that are listed below are now deprecated.__
143 |
144 | Please use __npm__ to manage these external libraries in your project's dependencies.
145 |
146 | For example if you want to use [Lo-Dash](https://npmjs.org/package/lodash), install it first: `npm install lodash`, then
147 | use it in your `Gruntfile`: `var _ = require('lodash');`.
148 |
149 | #### grunt.util._
150 | *Deprecated*
151 |
152 | [Lo-Dash](http://lodash.com/) and [Underscore.string](https://github.com/epeli/underscore.string)
153 |
154 | `grunt.util._.str` is available for methods that conflict with existing Lo-Dash methods.
155 |
156 | #### grunt.util.async
157 | *Deprecated*
158 |
159 | [Async](https://github.com/caolan/async) - Async utilities for node and the browser.
160 |
161 | #### grunt.util.hooker
162 | *Deprecated*
163 |
164 | [JavaScript Hooker](https://github.com/cowboy/javascript-hooker) - Monkey-patch (hook) functions for debugging and stuff.
165 |
--------------------------------------------------------------------------------
/Frequently-Asked-Questions.md:
--------------------------------------------------------------------------------
1 | ## How do I install grunt?
2 | For general installation instructions, please read the [[Getting Started]] guide. If you need more specific information after having read that, read the comprehensive [[Installing grunt]] guide.
3 |
4 | ## When will I be able to use in-development feature 'X'?
5 | Installing both published and unpublished development versions of Grunt is covered in the [[Installing grunt]] guide.
6 |
7 | ## Does Grunt work on Windows?
8 | Grunt works fine on Windows, because [Node.js](http://nodejs.org/) and [npm](http://npmjs.org/) both work fine on Windows. Usually the problematic part is [Cygwin](http://www.cygwin.com/), because it bundles an outdated version of Node.js.
9 |
10 | The best way to avoid this issue is to use the [msysGit installer](http://msysgit.github.com/) to install the `git` binary and the [Node.js installer](http://nodejs.org/#download) to install the `node` and `npm` binaries, and to use the built-in [Windows command prompt](http://www.cs.princeton.edu/courses/archive/spr05/cos126/cmd-prompt.html) or [PowerShell](http://support.microsoft.com/kb/968929) instead of Cygwin.
11 |
12 | ## Why doesn't my asynchronous task complete?
13 | Chances are this is happening because you have forgotten to call the [this.async](grunt.task#wiki-this-async) method to tell Grunt that your task is asynchronous. For simplicity's sake, Grunt uses a synchronous coding style, which can be switched to asynchronous by calling `this.async()` within the task body.
14 |
15 | Note that passing `false` to the `done()` function tells Grunt that the task has failed.
16 |
17 | For example:
18 |
19 | ```javascript
20 | grunt.registerTask('asyncme', 'My asynchronous task.', function() {
21 | var done = this.async();
22 | doSomethingAsync(done);
23 | });
24 | ```
25 |
26 | ## How do I enable shell tab auto-completion?
27 | To enable bash tab auto-completion for grunt, add the following line to your `~/.bashrc` file:
28 |
29 | ```bash
30 | eval "$(grunt --completion=bash)"
31 | ```
32 |
33 | This assumes that Grunt has been installed globally with `npm install -g grunt`. Currently, the only supported shell is bash.
34 |
35 | ## How can I share parameters across multiple tasks?
36 | While each task can accept its own parameters, there are a few options available for sharing parameters across multiple tasks.
37 |
38 | ### "Dynamic" alias tasks
39 | **This is the preferred method for sharing parameters across multiple tasks.**
40 |
41 | Whereas [alias tasks](grunt#wiki-grunt-registerTask) are necessarily simple, a regular task can use [grunt.task.run](grunt.task#wiki-grunt-task-run) to make it effectively function as a "dynamic" alias task. In this example, running `grunt build:001` on the command line would result in the `foo:001`, `bar:001` and `baz:001` tasks being run.
42 |
43 | ```javascript
44 | grunt.registerTask('build', 'Run all my build tasks.', function(n) {
45 | if (n == null) {
46 | grunt.warn('Build num must be specified, like build:001.');
47 | }
48 | grunt.task.run('foo:' + n, 'bar:' + n, 'baz:' + n);
49 | });
50 | ```
51 |
52 | ### -- options
53 |
54 | Another way to share a parameter across multiple tasks would be to use [grunt.option](grunt#wiki-grunt-option). In this example, running `grunt deploy --target=staging` on the command line would cause `grunt.option('target')` to return `"staging"`.
55 |
56 | ```javascript
57 | grunt.registerTask('upload', 'Upload code to specified target.', function(n) {
58 | var target = grunt.option('target');
59 | // do something useful with target here
60 | });
61 | grunt.registerTask('deploy', ['validate', 'upload']);
62 | ```
63 |
64 | _Note that boolean options can be specified using just a key without a value. For example, running `grunt deploy --staging` on the command line would cause `grunt.option('staging')` to return `true`._
65 |
66 | ### Globals and configs
67 |
68 | In other cases, you may want to expose a way to set configuration or global values. In those cases, register a task that sets its arguments as a global or config value.
69 |
70 | In this example, running `grunt set_global:name:peter set_config:target:staging deploy` on the command line would cause `global.name` to be `"peter"` and `grunt.config('target')` to return `"staging"`. Presumably, the `deploy` task would use those values.
71 |
72 | ```javascript
73 | grunt.registerTask('set_global', 'Set a global variable.', function(name, val) {
74 | global[name] = val;
75 | });
76 |
77 | grunt.registerTask('set_config', 'Set a config property.', function(name, val) {
78 | grunt.config.set(name, val);
79 | });
80 | ```
81 |
82 | ## How I get a stack trace when an error occurs?
83 |
84 | Use the `--stack` option to see stack traces. Such as `grunt task --stack`
85 |
86 | ## Why am I getting a "Maximum call stack size exceeded" error?
87 |
88 | You probably created an alias task with the same name as one of your regular tasks.
89 | Example: `grunt.registerTask('uglify', ['uglify:my_target']);` should be `grunt.registerTask('myUglify', ['uglify:my_target']);`.
90 |
91 | ## How do I uninstall or remove unwanted plugins?
92 |
93 | At least two ways. One way is to use `npm uninstall [GRUNT_PLUGIN] --save-dev`, this will remove the plugin from your `package.json` and from `node_modules`. You may also delete the dependencies you don't want from your `package.json` manually and then run `npm prune`.
94 |
95 | ## Error "Fail to install with npm error: No compatible version found"
96 |
97 | Make sure you have the latest stable version of [NPM and Node.JS](http://nodejs.org/)
98 |
99 |
100 | ***
101 |
102 |
103 | ## grunt 0.3 Questions
104 |
105 | ## On Windows with Grunt 0.3, why does my JS editor open when I try to run grunt?
106 | If you're in the same directory as the [Gruntfile](Getting-started), Windows tries to execute _that file_ when you type grunt. So you need to type `grunt.cmd` instead.
107 |
108 | An alternative would be to use the `DOSKEY` command to create a Grunt macro, following [these directions](http://devblog.point2.com/2010/05/14/setup-persistent-aliases-macros-in-windows-command-prompt-cmd-exe-using-doskey/). That would allow you to use `grunt` instead of `grunt.cmd`.
109 |
110 | This is the `DOSKEY` command you'd use:
111 |
112 | ```
113 | DOSKEY grunt=grunt.cmd $*
114 | ```
115 |
--------------------------------------------------------------------------------
/Who-uses-Grunt.md:
--------------------------------------------------------------------------------
1 | This is just a short list of companies and projects that use Grunt.
2 | If you've used Grunt in a project and would like it listed on this page,
3 | [please edit this page](https://github.com/gruntjs/grunt-docs/blob/master/Who-uses-Grunt.md).
4 |
5 | ### [INK](http://ink.sapo.pt)
6 |
7 | ### [Adobe](http://www.adobe.com/)
8 | - [Brackets](http://brackets.io/) ([Gruntfile](https://github.com/adobe/brackets/blob/master/Gruntfile.js))
9 | - [CSS FilterLab](http://html.adobe.com/webstandards/csscustomfilters/cssfilterlab/) ([Gruntfile](https://github.com/adobe/cssfilterlab/blob/master/grunt.js))
10 |
11 | ### [jQuery](http://jquery.com/)
12 | - [jQuery](http://jquery.com/) - ([Gruntfile](https://github.com/jquery/jquery/blob/master/Gruntfile.js))
13 | - [jQuery UI](http://jqueryui.com/) - ([Gruntfile](https://github.com/jquery/jquery-ui/blob/master/Gruntfile.js))
14 | - [QUnit](http://qunitjs.com/) - ([Gruntfile](https://github.com/jquery/qunit/blob/master/Gruntfile.js))
15 |
16 | ### [Twitter](https://twitter.com/)
17 | - [Tweetdeck](http://www.tweetdeck.com/)
18 | - [Typeahead](https://github.com/twitter/typeahead.js) ([Gruntfile](https://github.com/twitter/typeahead.js/blob/master/Gruntfile.js))
19 |
20 | ### [Mozilla](https://mozilla.org/)
21 | - [Firefox Accounts projects](https://accounts.firefox.com) ([Gruntfile](https://github.com/mozilla/fxa-content-server/blob/master/Gruntfile.js), [Gruntfile](https://github.com/mozilla/fxa-auth-server/blob/master/Gruntfile.js), [Gruntfile](https://github.com/mozilla/fxa-js-client/blob/master/Gruntfile.js))
22 |
23 | ### [Bootstrap](http://getbootstrap.com/)
24 | - [Gruntfile](https://github.com/twbs/bootstrap/blob/master/Gruntfile.js)
25 |
26 | ### [Cloudant](https://cloudant.com/)
27 | - [Backbone Cloudant](https://github.com/cloudant-labs/backbone.cloudant) ([Gruntfile](https://github.com/cloudant-labs/backbone.cloudant/blob/master/Gruntfile.js))
28 |
29 | ### [Bitovi](http://bitovi.com/)
30 | - [CanJS](http://canjs.us/) ([Gruntfile](https://github.com/bitovi/canjs/blob/master/Gruntfile.js))
31 |
32 | ### [TestObject](https://www.testobject.com)
33 |
34 | ### [Filament Group](http://filamentgroup.com/)
35 | - [X-rayHTML](https://github.com/filamentgroup/X-rayHTML) ([Gruntfile](https://github.com/filamentgroup/X-rayHTML/blob/master/grunt.js))
36 | - [Grunticon](https://github.com/filamentgroup/grunticon) ([Gruntfile](https://github.com/filamentgroup/grunticon/blob/master/Gruntfile.js))
37 |
38 | ### [Fuel UX](http://exacttarget.github.com/fuelux/)
39 | - [Fuel UX](http://exacttarget.github.com/fuelux/) ([Gruntfile](https://github.com/ExactTarget/fuelux/blob/master/Gruntfile.js))
40 |
41 | ### [SauceLabs](https://saucelabs.com/)
42 | - [Appium](https://saucelabs.com/appium) ([Gruntfile](https://github.com/appium/appium/blob/master/Gruntfile.js))
43 |
44 | ### [Modernizr](http://modernizr.com/)
45 | - [Modernizr](http://modernizr.com/) ([Gruntfile](https://github.com/Modernizr/Modernizr/blob/master/Gruntfile.js))
46 |
47 | ### [Opera](http://opera.com)
48 | - [Opera GitHub Projects](https://github.com/operasoftware)
49 |
50 | ### [LiveChat](http://www.livechatinc.com)
51 | - [LiveChat Grunt Workflow](http://developers.livechatinc.com/blog/how-livechat-uses-grunt-js-for-easy-product-deployment/)
52 |
53 | ### [WordPress](https://wordpress.org/)
54 | - [WordPress Build Process](https://make.wordpress.org/core/2013/08/06/a-new-frontier-for-core-development/) ([Gruntfile](https://core.trac.wordpress.org/browser/trunk/Gruntfile.js))
55 | - [bbPress](https://bbpress.org) ([Gruntfile](https://bbpress.trac.wordpress.org/browser/trunk/Gruntfile.js))
56 | - [BuddyPress](https://buddypress.org) ([Gruntfile](https://buddypress.trac.wordpress.org/browser/trunk/Gruntfile.js))
57 |
58 | ### [Walmart](http://www.walmart.com/)
59 | - [Thorax](https://github.com/walmartlabs/thorax) ([Gruntfile](https://github.com/walmartlabs/thorax/blob/master/Gruntfile.js))
60 | - [Lumbar](http://walmartlabs.github.io/lumbar/) ([Gruntfile](https://github.com/walmartlabs/lumbar/blob/master/Gruntfile.js))
61 |
62 | ### [Bazaarvoice](http://www.bazaarvoice.com/)
63 |
64 | ### [dscout](http://dscout.com/)
65 | - [Velge](https://github.com/dscout/velge) ([Gruntfile](https://github.com/dscout/velge/blob/master/Gruntfile.js))
66 |
67 | ### [Ghost](https://ghost.org/)
68 | - [Gruntfile](https://github.com/TryGhost/Ghost/blob/master/Gruntfile.js)
69 |
70 | ### [JS Bin](http://jsbin.com/)
71 | - [Gruntfile](https://github.com/remy/jsbin/blob/master/Gruntfile.js)
72 |
73 | ### [SitePen](http://sitepen.com/)
74 | - [generator-dojo](https://github.com/bryanforbes/generator-dojo/) ([Gruntfile](https://github.com/bryanforbes/generator-dojo/blob/master/app/templates/Gruntfile.js))
75 | - [Intern](http://theintern.io/) ([Gruntfile](https://github.com/theintern/intern-examples/blob/master/grunt-example/Gruntfile.js))
76 |
77 | ### [Phaser](http://phaser.io/)
78 | - [phaser](https://github.com/photonstorm/phaser/) ([Gruntfile](https://github.com/photonstorm/phaser/blob/master/Gruntfile.js))
79 |
80 | ### [BufferApp](https://bufferapp.com)
81 |
82 | ### [Shopetti](https://www.shopetti.com)
83 |
84 | ### [Consunet Pty Ltd](https://www.consunet.com.au)
85 | - [WhisperNote](https://www.consunet.com.au/products/whispernote/) - ([Gruntfile](https://github.com/Consunet/Apps/blob/master/WhisperNote/Gruntfile.js))
86 | - [EveryPass](https://www.consunet.com.au/products/everypass/) - ([Gruntfile](https://github.com/Consunet/Apps/blob/master/EveryPass/Gruntfile.js))
87 |
88 | ### [Assemble](http://assemble.io/)
89 | - [Gruntfile](https://github.com/assemble/assemble/blob/master/Gruntfile.js)
90 |
91 | ### [Sourcey](http://sourcey.com)
92 | - [Mesh](https://github.com/sourcey/mesh) ([Gruntfile](https://github.com/sourcey/mesh/blob/master/Gruntfile.js))
93 | - [Symple](https://github.com/sourcey/symple) ([Gruntfile](https://github.com/sourcey/symple/blob/master/client/Gruntfile.js))
94 |
95 | ### [Happy Cog](http://happycog.com)
96 |
97 | ### [MadGlory](http://madglory.com)
98 |
99 | ### [Victoria's Secret](http://www.victoriassecret.com)
100 |
101 | ### [Clevertim CRM](http://www.clevertim.com)
102 |
103 | ### [Kickoff](http://tmwagency.github.io/kickoff/)
104 | - [Gruntfile](https://github.com/tmwagency/kickoff/blob/master/Gruntfile.js)
105 |
106 | ### [Vodori](http://vodori.com)
107 |
108 | ### [Jimdo](http://www.jimdo.com/)
109 | - [angular-spectrum-colorpicker](https://github.com/Jimdo/angular-spectrum-colorpicker) ([Gruntfile](https://github.com/Jimdo/angular-spectrum-colorpicker/blob/master/Gruntfile.js))
110 | - [angular-directive-seed](https://github.com/Jimdo/angular-directive-seed) ([Gruntfile](https://github.com/Jimdo/angular-directive-seed/blob/master/Gruntfile.js))
111 |
112 | ### [Crowdfunder.co.uk](http://www.crowdfunder.co.uk/)
113 |
114 |
--------------------------------------------------------------------------------
/Sample-Gruntfile.md:
--------------------------------------------------------------------------------
1 | Below we walk through a sample `Gruntfile`, but if you're looking for a quick example, here's one:
2 |
3 | ```js
4 | module.exports = function(grunt) {
5 |
6 | grunt.initConfig({
7 | jshint: {
8 | files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
9 | options: {
10 | globals: {
11 | jQuery: true
12 | }
13 | }
14 | },
15 | watch: {
16 | files: ['<%= jshint.files %>'],
17 | tasks: ['jshint']
18 | }
19 | });
20 |
21 | grunt.loadNpmTasks('grunt-contrib-jshint');
22 | grunt.loadNpmTasks('grunt-contrib-watch');
23 |
24 | grunt.registerTask('default', ['jshint']);
25 |
26 | };
27 | ```
28 |
29 | The entire `Gruntfile` is at the bottom of this page, but if you keep reading we'll walk through it a step at a time, using the following five Grunt plugins:
30 |
31 | - [grunt-contrib-uglify](https://github.com/gruntjs/grunt-contrib-uglify)
32 | - [grunt-contrib-qunit](https://github.com/gruntjs/grunt-contrib-qunit)
33 | - [grunt-contrib-concat](https://github.com/gruntjs/grunt-contrib-concat)
34 | - [grunt-contrib-jshint](https://github.com/gruntjs/grunt-contrib-jshint)
35 | - [grunt-contrib-watch](https://github.com/gruntjs/grunt-contrib-watch)
36 |
37 | The first part is the "wrapper" function, which encapsulates your Grunt configuration.
38 |
39 | ```javascript
40 | module.exports = function(grunt) {
41 | }
42 | ```
43 |
44 | Within that function we can initialize our configuration object:
45 |
46 | ```javascript
47 | grunt.initConfig({
48 | });
49 | ```
50 |
51 | Next we can read in the project settings from the `package.json` file into the `pkg` property. This allows us to refer to the values of properties within our `package.json` file, as we'll see shortly.
52 |
53 | ```javascript
54 | pkg: grunt.file.readJSON('package.json')
55 | ```
56 |
57 | This leaves us with this so far:
58 |
59 | ```javascript
60 | module.exports = function(grunt) {
61 | grunt.initConfig({
62 | pkg: grunt.file.readJSON('package.json')
63 | });
64 | };
65 | ```
66 |
67 | Now we can define configuration for each of the tasks we have. The configuration object for a task lives as a property on the configuration object, that's named the same as the task. So the "concat" task goes in our config object under the "concat" key. Below is my configuration object for the "concat" task.
68 |
69 | ```javascript
70 | concat: {
71 | options: {
72 | // define a string to put between each file in the concatenated output
73 | separator: ';'
74 | },
75 | dist: {
76 | // the files to concatenate
77 | src: ['src/**/*.js'],
78 | // the location of the resulting JS file
79 | dest: 'dist/<%= pkg.name %>.js'
80 | }
81 | }
82 | ```
83 |
84 | Note how I refer to the `name` property that's in the JSON file. We access this using `pkg.name` as earlier we defined the `pkg` property to be the result of loading the `package.json` file, which is then parsed to a JavaScript object. Grunt has simple template engine to output the values of properties in the configuration object. Here I tell the concat task to concatenate all files that exist within `src/` and end in `.js`.
85 |
86 | Now lets configure the uglify plugin, which minifies our JavaScript:
87 |
88 | ```javascript
89 | uglify: {
90 | options: {
91 | // the banner is inserted at the top of the output
92 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
93 | },
94 | dist: {
95 | files: {
96 | 'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
97 | }
98 | }
99 | }
100 | ```
101 |
102 | This tells uglify to create a file within `dist/` that contains the result of minifying the JavaScript files. Here I use `<%= concat.dist.dest %>` so uglify will minify the file that the concat task produces.
103 |
104 | The QUnit plugin is really simple to set up. You just need to give it the location of the test runner files, which are the HTML files QUnit runs on.
105 |
106 | ```javascript
107 | qunit: {
108 | files: ['test/**/*.html']
109 | },
110 | ```
111 |
112 | The JSHint plugin is also very simple to configure:
113 |
114 | ```javascript
115 | jshint: {
116 | // define the files to lint
117 | files: ['gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
118 | // configure JSHint (documented at http://www.jshint.com/docs/)
119 | options: {
120 | // more options here if you want to override JSHint defaults
121 | globals: {
122 | jQuery: true,
123 | console: true,
124 | module: true
125 | }
126 | }
127 | }
128 | ```
129 |
130 | JSHint simply takes an array of files and then an object of options. These are all [documented on the JSHint site](http://www.jshint.com/docs/). If you're happy with the JSHint defaults, there's no need to redefine them in the Gruntfile.
131 |
132 | Finally we have the watch plugin:
133 |
134 | ```javascript
135 | watch: {
136 | files: ['<%= jshint.files %>'],
137 | tasks: ['jshint', 'qunit']
138 | }
139 | ```
140 |
141 | This can be run on the command line with `grunt watch`. When it detects any of the files specified have changed (here, I just use the same files I told JSHint to check), it will run the tasks you specify, in the order they appear.
142 |
143 | Finally, we have to load in the Grunt plugins we need. These should have all been installed through npm.
144 |
145 | ```javascript
146 | grunt.loadNpmTasks('grunt-contrib-uglify');
147 | grunt.loadNpmTasks('grunt-contrib-jshint');
148 | grunt.loadNpmTasks('grunt-contrib-qunit');
149 | grunt.loadNpmTasks('grunt-contrib-watch');
150 | grunt.loadNpmTasks('grunt-contrib-concat');
151 | ```
152 |
153 | And finally set up some tasks. Most important is the default task:
154 |
155 |
156 | ```javascript
157 | // this would be run by typing "grunt test" on the command line
158 | grunt.registerTask('test', ['jshint', 'qunit']);
159 |
160 | // the default task can be run just by typing "grunt" on the command line
161 | grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);
162 | ```
163 |
164 | And here's the finished `Gruntfile`:
165 |
166 | ```javascript
167 | module.exports = function(grunt) {
168 |
169 | grunt.initConfig({
170 | pkg: grunt.file.readJSON('package.json'),
171 | concat: {
172 | options: {
173 | separator: ';'
174 | },
175 | dist: {
176 | src: ['src/**/*.js'],
177 | dest: 'dist/<%= pkg.name %>.js'
178 | }
179 | },
180 | uglify: {
181 | options: {
182 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
183 | },
184 | dist: {
185 | files: {
186 | 'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
187 | }
188 | }
189 | },
190 | qunit: {
191 | files: ['test/**/*.html']
192 | },
193 | jshint: {
194 | files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
195 | options: {
196 | // options here to override JSHint defaults
197 | globals: {
198 | jQuery: true,
199 | console: true,
200 | module: true,
201 | document: true
202 | }
203 | }
204 | },
205 | watch: {
206 | files: ['<%= jshint.files %>'],
207 | tasks: ['jshint', 'qunit']
208 | }
209 | });
210 |
211 | grunt.loadNpmTasks('grunt-contrib-uglify');
212 | grunt.loadNpmTasks('grunt-contrib-jshint');
213 | grunt.loadNpmTasks('grunt-contrib-qunit');
214 | grunt.loadNpmTasks('grunt-contrib-watch');
215 | grunt.loadNpmTasks('grunt-contrib-concat');
216 |
217 | grunt.registerTask('test', ['jshint', 'qunit']);
218 |
219 | grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);
220 |
221 | };
222 | ```
223 |
224 |
--------------------------------------------------------------------------------
/Contributing.md:
--------------------------------------------------------------------------------
1 | There are a number of Grunt projects.
2 |
3 | * [grunt](https://github.com/gruntjs/grunt) - the main Grunt project
4 | * [grunt-init](https://github.com/gruntjs/grunt-init) - the standalone grunt-init project scaffolding tool
5 | * [gruntjs.com](https://github.com/gruntjs/gruntjs.com) - the gruntjs.com website
6 | * [grunt-contrib collection](https://github.com/gruntjs/grunt-contrib) - a collection of all Grunt "contrib" plugins
7 |
8 | In addition, each individual grunt-contrib plugin is a separate repository listed on the [gruntjs org homepage](https://github.com/gruntjs).
9 |
10 | ## Contributors License Agreement
11 |
12 | Most forms of contribution aside from providing support to other users requires that you **[sign and submit](http://dojofoundation.org/about/cla)** a Contributors License Agreement (or "CLA" for short) with the Dojo Foundation.
13 |
14 |
15 | In summary, the CLA asserts that when you donate fixes or documentation, you both own the code that you're submitting and that the Dojo Foundation can in turn license that code to other people.
16 |
17 | Sending in a CLA is a one-time thing, and once it's done, you're in the clear to start contributing to all Dojo Foundation projects! To be effective, though, you need to know a little bit about how contributors and Committers coordinate their work, so getting involved and asking questions should be your first step.
18 |
19 | For more on CLAs, read [Alex Russell's Why Do I Need to Sign This?](http://alex.dojotoolkit.org/2008/06/why-do-i-need-to-sign-this/).
20 |
21 | ## Want to contribute?
22 |
23 | If you want to contribute, but don't know where to get started, this is for you.
24 | Issues that are linked below were marked as __needs PR__, this means they need a pull request to be fixed.
25 | Choose any of these issues and make sure to comment if you are working on them.
26 |
27 | * grunt-init - [Contribution guidelines should go into contributing.md](https://github.com/gruntjs/grunt-init/issues/5)
28 | * grunt-contrib-jade - [Add support for basedir option](https://github.com/gruntjs/grunt-contrib-jade/issues/64)
29 | * grunt-init-gruntfile - [Doesn't generate a package.json](https://github.com/gruntjs/grunt-init-gruntfile/issues/6)
30 | * grunt-contrib-coffee - [Support the process option](https://github.com/gruntjs/grunt-contrib-coffee/issues/61)
31 | * grunt - [--gruntfile parameter broken with parent directories](https://github.com/gruntjs/grunt/issues/950)
32 | * grunt-contrib-compress - [Add bzip2 support](https://github.com/gruntjs/grunt-contrib-compress/issues/47)
33 | * grunt-contrib-jasmine - [Enhance logging](https://github.com/gruntjs/grunt-contrib-jasmine/issues/80)
34 | * grunt-contrib-less [Sourcemaps with multiple src files](https://github.com/gruntjs/grunt-contrib-less/issues/89)
35 |
36 | # Non-code contributions
37 |
38 | If you don't feel like writing code you can still contribute to the project!
39 |
40 | * You may submit updates and improvements to the [documentation](https://github.com/gruntjs/grunt-docs).
41 | * Submit articles and guides which are also part of the [documentation](https://github.com/gruntjs/grunt-docs).
42 | * Help Grunt user by answering questions on [StackOverflow](http://stackoverflow.com/questions/tagged/gruntjs), [IRC](http://gruntjs.com/help-resources#irc) and [GitHub](https://github.com/organizations/gruntjs/dashboard/issues/repos?direction=asc&sort=created&state=open).
43 |
44 | ## Filing issues
45 | If something isn't working like you think it should, please read [the documentation](https://github.com/gruntjs/grunt/wiki), especially the [[Getting Started]] guide. If you'd like to chat with someone, [[pop into IRC|contributing#discussing-grunt]] discussing-grunt and ask your question there.
46 |
47 | If you have a question not covered in the documentation or want to report a bug, the best way to ensure it gets addressed is to file it in the appropriate issues tracker.
48 |
49 | * **If there's an issue with grunt, grunt-init, a grunt-lib-??? module, or a specific grunt-contrib-??? plugin**
50 | * Please file an issue on that project's issues tracker.
51 | * **If you'd like to contribute a new plugin**
52 | * Please file an issue on the [grunt-contrib collection issues tracker](https://github.com/gruntjs/grunt-contrib/issues). We don't accept all plugins, but we'll certainly consider yours.
53 | * **If there's an issue with the [website](http://gruntjs.com/)**
54 | * Please file an issue on the [gruntjs.com website issues tracker](https://github.com/gruntjs/gruntjs.com/issues).
55 | * **If there's an issue that isn't specific to any of the above**
56 | * Please file an issue on the [grunt issues tracker](https://github.com/gruntjs/grunt/issues) and let us know why you're filing it there.
57 |
58 | ### Simplify the issue
59 | Try to [reduce your code](http://www.webkit.org/quality/reduction.html) to the bare minimum required to reproduce the issue. This makes it much easier (and much faster) to isolate and fix the issue.
60 |
61 | ### Explain the issue
62 | If we can't reproduce the issue, we can't fix it. Please list the exact steps required to reproduce the issue. Include versions of your OS, Node.js, grunt, etc. Include relevant logs or sample code.
63 |
64 | ## Discussing grunt
65 | Join the [freenode](http://freenode.net/) IRC #grunt channel. We've got a bot and everything.
66 |
67 | _No private messages, please._
68 |
69 | ## Modifying grunt
70 | First, ensure that you have the latest [Node.js](http://nodejs.org/) and [npm](http://npmjs.org/) installed.
71 |
72 | 1. Ensure grunt-cli is installed (see the [[Getting started]] guide for more information)
73 | 1. Fork and clone the repo.
74 | 1. Check out the master branch (most grunt/grunt-contrib development happens there).
75 | 1. Run `npm install` to install all Grunt dependencies.
76 | 1. Run `npm uninstall grunt` this will remove the extra Grunt in your `node_modules`, see [npm issue 3958](https://github.com/npm/npm/issues/3958)
77 | 1. Run `grunt` to Grunt grunt.
78 |
79 | Assuming that you don't see any red, you're ready to go. Just be sure to run `grunt` after making any changes, to ensure that nothing has broken.
80 |
81 | ### Submitting pull requests
82 |
83 | 1. Create a new branch, please don't work in `master` directly.
84 | 1. Add failing tests for the change you want to make. Run `grunt` to see the tests fail.
85 | 1. Fix stuff.
86 | 1. Run `grunt` to see if the tests pass. Repeat steps 2-4 until done.
87 | 1. Update the documentation to reflect any changes.
88 | 1. Push to your fork and submit a pull request.
89 |
90 | ### Syntax
91 |
92 | * Two space indents. Don't use tabs anywhere. Use `\t` if you need a tab character in a string.
93 | * No trailing whitespace, except in markdown files where a linebreak must be forced.
94 | * Don't go overboard with the whitespace.
95 | * No more than [one assignment](http://benalman.com/news/2012/05/multiple-var-statements-javascript/) per `var` statement.
96 | * Delimit strings with single-quotes `'`, not double-quotes `"`.
97 | * Prefer `if` and `else` to ["clever"](http://programmers.stackexchange.com/a/25281) uses of `? :` conditional or `||`, `&&` logical operators.
98 | * Comments are great. Just put them _before_ the line of code, _not_ at the _end_ of the line.
99 | * **When in doubt, follow the conventions you see used in the source already.**
100 |
101 | ### READMEs
102 | All of the grunt-contrib-* plugins use [grunt-contrib-internal](https://github.com/gruntjs/grunt-contrib-internal) to construct the `README.md` and `CONTRIBUTING.md` files. The source files are located in the corresponding `docs/` folder. The change logs in the READMEs are generated from the `CHANGELOG` file.
103 |
104 | When submitting changes to the README files please just edit the source files rather than the README directly.
105 |
--------------------------------------------------------------------------------
/grunt.task.md:
--------------------------------------------------------------------------------
1 | Register, run and load external tasks.
2 |
3 | See the [task lib source](https://github.com/gruntjs/grunt/blob/master/lib/grunt/task.js) and [task util lib source](https://github.com/gruntjs/grunt/blob/master/lib/util/task.js) for more information.
4 |
5 | ## The task API
6 | While a task is running, Grunt exposes many task-specific utility properties and methods inside the task function via the `this` object. See the [[Inside tasks]] guide for a list of these properties and methods.
7 |
8 | Many utility properties and methods are available inside of tasks via the `this` object.
9 |
10 | Note that any method marked with a ☃ (unicode snowman) is also available directly on the `grunt` object. Just so you know. See the [API main page](grunt) for more usage information.
11 |
12 | ## Creating Tasks
13 |
14 | ### grunt.task.registerTask ☃
15 | Register an "alias task" or a task function. This method supports the following two signatures:
16 |
17 | **Alias task**
18 |
19 | If a task list is specified, the new task will be an alias for one or more other tasks. Whenever this "alias task" is run, every specified task in `taskList` will be run, in the order specified. The `taskList` argument must be an array of tasks.
20 |
21 | ```javascript
22 | grunt.task.registerTask(taskName, taskList)
23 | ```
24 |
25 | This example alias task defines a "default" task whereby the "jshint", "qunit", "concat" and "uglify" tasks are run automatically if Grunt is executed without any tasks specified:
26 |
27 | ```javascript
28 | task.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);
29 | ```
30 |
31 | Task arguments can be specified as well. In this example, the alias "dist" runs both the "concat" and "uglify" tasks, each with the "dist" argument:
32 |
33 | ```javascript
34 | task.registerTask('dist', ['concat:dist', 'uglify:dist']);
35 | ```
36 |
37 | **Function task**
38 |
39 | If a `description` and `taskFunction` are passed, the specified function will be executed whenever the task is run. In addition, the specified description will be shown when `grunt --help` is run. Task-specific properties and methods are available inside the task function as properties of the `this` object. The task function can return `false` to indicate that the task has failed.
40 |
41 | Note that the `grunt.task.registerMultiTask` method, explained below, can be used to define a special type of task known as a "multi task."
42 |
43 | ```javascript
44 | grunt.task.registerTask(taskName, description, taskFunction)
45 | ```
46 |
47 | This example task logs `foo, testing 123` if Grunt is run via `grunt foo:testing:123`. If the task is run without arguments as `grunt foo` the task logs `foo, no args`.
48 |
49 | ```javascript
50 | grunt.task.registerTask('foo', 'A sample task that logs stuff.', function(arg1, arg2) {
51 | if (arguments.length === 0) {
52 | grunt.log.writeln(this.name + ", no args");
53 | } else {
54 | grunt.log.writeln(this.name + ", " + arg1 + " " + arg2);
55 | }
56 | });
57 | ```
58 |
59 | See the [creating tasks](Creating-tasks) documentation for more examples of tasks and alias tasks.
60 |
61 | _This method is also available as [grunt.registerTask](grunt)._
62 |
63 | ### grunt.task.registerMultiTask ☃
64 | Register a "multi task." A multi task is a task that implicitly iterates over all of its named sub-properties (AKA targets) if no target was specified. In addition to the default properties and methods, extra multi task-specific properties are available inside the task function as properties of the `this` object.
65 |
66 | Many of the contrib tasks, including the [jshint task](https://github.com/gruntjs/grunt-contrib-jshint), [concat task](https://github.com/gruntjs/grunt-contrib-concat) and [uglify task](https://github.com/gruntjs/grunt-contrib-uglify) are multi tasks.
67 |
68 | ```javascript
69 | grunt.task.registerMultiTask(taskName, description, taskFunction)
70 | ```
71 |
72 | Given the specified configuration, this example multi task would log `foo: 1,2,3` if Grunt was run via `grunt log:foo`, or it would log `bar: hello world` if Grunt was run via `grunt log:bar`. If Grunt was run as `grunt log` however, it would log `foo: 1,2,3` then `bar: hello world` then `baz: false`.
73 |
74 | ```javascript
75 | grunt.initConfig({
76 | log: {
77 | foo: [1, 2, 3],
78 | bar: 'hello world',
79 | baz: false
80 | }
81 | });
82 |
83 | grunt.task.registerMultiTask('log', 'Log stuff.', function() {
84 | grunt.log.writeln(this.target + ': ' + this.data);
85 | });
86 | ```
87 |
88 | See the [creating tasks](Creating-tasks) documentation for more examples of multi tasks.
89 |
90 | _This method is also available as [grunt.registerMultiTask](grunt)._
91 |
92 | ### grunt.task.requires
93 |
94 | Fail the task if some other task failed or never ran.
95 |
96 | ```javascript
97 | grunt.task.requires(taskName);
98 | ```
99 |
100 | ### grunt.task.exists
101 | *Added in 0.4.5*
102 |
103 | Check with the name, if a task exists in the registered tasks. Return a boolean.
104 |
105 | ```javascript
106 | grunt.task.exists(name)
107 | ```
108 |
109 | ### grunt.task.renameTask ☃
110 | Rename a task. This might be useful if you want to override the default behavior of a task, while retaining the old name.
111 |
112 | _Note that if a task has been renamed, the [this.name](inside-tasks#this.name) and [this.nameArgs](inside-tasks#this.nameArgs) properties will change accordingly._
113 |
114 | ```javascript
115 | grunt.task.renameTask(oldname, newname)
116 | ```
117 |
118 | _This method is also available as [grunt.renameTask](grunt)._
119 |
120 | ## Loading Externally-Defined Tasks
121 | For most projects, tasks will be defined in the [Gruntfile](Getting-started). For larger projects, or in cases where tasks need to be shared across projects, tasks can be loaded from one or more external directories or Npm-installed Grunt plugins.
122 |
123 | ### grunt.task.loadTasks ☃
124 | Load task-related files from the specified directory, relative to the [Gruntfile](Getting-started). This method can be used to load task-related files from a local Grunt plugin by specifying the path to that plugin's "tasks" subdirectory.
125 |
126 | ```javascript
127 | grunt.task.loadTasks(tasksPath)
128 | ```
129 |
130 | _This method is also available as [grunt.loadTasks](grunt)._
131 |
132 | ### grunt.task.loadNpmTasks ☃
133 | Load tasks from the specified Grunt plugin. This plugin must be installed locally via npm, and must be relative to the [Gruntfile](Getting-started). Grunt plugins can be created by using the [grunt-init gruntplugin template](https://github.com/gruntjs/grunt-init): `grunt init:gruntplugin`.
134 |
135 | ```javascript
136 | grunt.task.loadNpmTasks(pluginName)
137 | ```
138 |
139 | _This method is also available as [grunt.loadNpmTasks](grunt)._
140 |
141 |
142 | ## Queueing Tasks
143 | Grunt automatically enqueues and runs all tasks specified on the command line, but individual tasks can enqueue additional tasks to be run.
144 |
145 | ### grunt.task.run
146 | Enqueue one or more tasks. Every specified task in `taskList` will be run immediately after the current task completes, in the order specified. The task list can be an array of tasks or individual task arguments.
147 |
148 | ```javascript
149 | grunt.task.run(taskList)
150 | ```
151 |
152 | ### grunt.task.clearQueue
153 | Empty the task queue completely. Unless additional tasks are enqueued, no more tasks will be run.
154 |
155 | ```javascript
156 | grunt.task.clearQueue()
157 | ```
158 |
159 | ### grunt.task.normalizeMultiTaskFiles
160 | Normalizes a task target configuration object into an array of src-dest file mappings. This method is used internally by the multi task system [this.files / grunt.task.current.files](grunt.task#wiki-this-files) property.
161 |
162 | ```javascript
163 | grunt.task.normalizeMultiTaskFiles(data [, targetname])
164 | ```
165 |
--------------------------------------------------------------------------------
/Inside-Tasks.md:
--------------------------------------------------------------------------------
1 | While a task is running, Grunt exposes many task-specific utility properties and methods inside the task function via the `this` object. This same object is also exposed as `grunt.task.current` for use in [templates](grunt.template), eg. the property `this.name` is also available as `grunt.task.current.name`.
2 |
3 | ## Inside All Tasks
4 |
5 | ### this.async
6 | If a task is asynchronous, this method must be invoked to instruct Grunt to wait. It returns a handle to a "done" function that should be called when the task has completed. Either `false` or an `Error` object may be passed to the done function to instruct Grunt that the task has failed.
7 |
8 | If the `this.async` method isn't invoked, the task will execute synchronously.
9 |
10 | ```javascript
11 | // Tell Grunt this task is asynchronous.
12 | var done = this.async();
13 | // Your async code.
14 | setTimeout(function() {
15 | // Let's simulate an error, sometimes.
16 | var success = Math.random() > 0.5;
17 | // All done!
18 | done(success);
19 | }, 1000);
20 | ```
21 |
22 | ### this.requires
23 | If one task depends on the successful completion of another task (or tasks), this method can be used to force Grunt to abort if the other task didn't run, or if the other task failed. The tasks list can be an array of task names or individual task names, as arguments.
24 |
25 | Note that this won't actually run the specified task(s), it will just fail the current task if they haven't already run successfully.
26 |
27 | ```javascript
28 | this.requires(tasksList)
29 | ```
30 |
31 | ### this.requiresConfig
32 | Fail the current task if one or more required [config](grunt.config) properties is missing. One or more string or array config properties may be specified.
33 |
34 | ```javascript
35 | this.requiresConfig(prop [, prop [, ...]])
36 | ```
37 |
38 | See the [grunt.config documentation](grunt.config) for more information about config properties.
39 |
40 | _This method is an alias for the [grunt.config.requires](grunt.config#grunt.config.requires) method._
41 |
42 | ### this.name
43 | The name of the task, as defined in `grunt.registerTask`. For example, if a "sample" task was run as `grunt sample` or `grunt sample:foo`, inside the task function, `this.name` would be `"sample"`.
44 |
45 | _Note that if a task has been renamed with [grunt.task.renameTask](grunt.task#grunt.task.renameTask) this property will reflect the new name._
46 |
47 |
48 | ### this.nameArgs
49 | The name of the task, including any colon-separated arguments or flags specified on the command-line. For example, if a "sample" task was run as `grunt sample:foo`, inside the task function, `this.nameArgs` would be `"sample:foo"`.
50 |
51 | _Note that if a task has been renamed with [grunt.task.renameTask](grunt.task#grunt.task.renameTask) this property will reflect the new name._
52 |
53 | ### this.args
54 | An array of arguments passed to the task. For example, if a "sample" task was run as `grunt sample:foo:bar`, inside the task function, `this.args` would be `["foo", "bar"]`.
55 |
56 | _Note that in multi tasks, the current target is omitted from the `this.args` array._
57 |
58 | ### this.flags
59 | An object generated from the arguments passed to the task. For example, if a "sample" task was run as `grunt sample:foo:bar`, inside the task function, `this.flags` would be `{foo: true, bar: true}`.
60 |
61 | _Note that inside multi tasks, the target name is **not** set as a flag._
62 |
63 | ### this.errorCount
64 | The number of [grunt.log.error](grunt.log#grunt.log.error) calls that occurred during this task. This can be used to fail a task if errors were logged during the task.
65 |
66 | ### this.options
67 | Returns an options object. Properties of the optional `defaultsObj` argument will be overridden by any task-level `options` object properties, which will be further overridden in multi tasks by any target-level `options` object properties.
68 |
69 | ```js
70 | this.options([defaultsObj])
71 | ```
72 |
73 | This example shows how a task might use the `this.options` method:
74 |
75 | ```js
76 | var options = this.options({
77 | enabled: false,
78 | });
79 |
80 | doSomething(options.enabled);
81 | ```
82 |
83 | The [Configuring tasks](configuring-tasks#options) guide shows an example of how options may be specified, from the task user's point of view.
84 |
85 | ## Inside Multi Tasks
86 |
87 | ### this.target
88 | In a multi task, this property contains the name of the target currently being iterated over. For example, if a "sample" multi task was run as `grunt sample:foo` with the config data `{sample: {foo: "bar"}}`, inside the task function, `this.target` would be `"foo"`.
89 |
90 | ### this.files
91 | In a multi task, all files specified using any Grunt-supported [file formats and options](configuring-tasks#files), [globbing patterns](configuring-tasks#globbing-patterns) or [dynamic mappings](configuring-tasks#building-the-files-object-dynamically) will automatically be normalized into a single format: the [Files Array file format](configuring-tasks#files-array-format).
92 |
93 | What this means is that tasks don't need to contain a ton of boilerplate for explicitly handling custom file formats, globbing patterns, mapping source files to destination files or filtering out files or directories. _A task user can just specify files per the [Configuring tasks](configuring-tasks#files) guide, and **Grunt will handle all the details.**_
94 |
95 | Your task should iterate over the `this.files` array, utilizing the `src` and `dest` properties of each object in that array. The `this.files` property will always be an array. The `src` property will also always be an array, in case your task cares about multiple source files per destination file.
96 |
97 | _Note that it's possible that nonexistent files might be included in `src` values, so you may want to explicitly test that source files exist before using them._
98 |
99 | This example shows how a simple "concat" task might use the `this.files` property:
100 |
101 | ```js
102 | this.files.forEach(function(file) {
103 | var contents = file.src.filter(function(filepath) {
104 | // Remove nonexistent files (it's up to you to filter or warn here).
105 | if (!grunt.file.exists(filepath)) {
106 | grunt.log.warn('Source file "' + filepath + '" not found.');
107 | return false;
108 | } else {
109 | return true;
110 | }
111 | }).map(function(filepath) {
112 | // Read and return the file's source.
113 | return grunt.file.read(filepath);
114 | }).join('\n');
115 | // Write joined contents to destination filepath.
116 | grunt.file.write(file.dest, contents);
117 | // Print a success message.
118 | grunt.log.writeln('File "' + file.dest + '" created.');
119 | });
120 | ```
121 |
122 | _If you need the original file object properties, they are available on each individual file object under the `orig` property, but there is no known use-case for accessing the original properties._
123 |
124 | ### this.filesSrc
125 | In a multi task, all `src` files specified via any [file format](configuring-tasks#files) are reduced to a single array. If your task is "read only" and doesn't care about destination filepaths, use this array instead of `this.files`.
126 |
127 | This example shows how a simple "lint" task might use the `this.filesSrc` property:
128 |
129 | ```js
130 | // Lint specified files.
131 | var files = this.filesSrc;
132 | var errorCount = 0;
133 | files.forEach(function(filepath) {
134 | if (!lint(grunt.file.read(filepath))) {
135 | errorCount++;
136 | }
137 | });
138 |
139 | // Fail task if errors were logged.
140 | if (errorCount > 0) { return false; }
141 |
142 | // Otherwise, print a success message.
143 | grunt.log.ok('Files lint free: ' + files.length);
144 | ```
145 |
146 | ### this.data
147 | In a multi task, this is the actual data stored in the Grunt config object for the given target.
148 | For example, if a "sample" multi task was run as `grunt sample:foo` with the config data `{sample: {foo: "bar"}}`, inside the task function, `this.data` would be `"bar"`.
149 |
150 | _It is recommended that `this.options` `this.files` and `this.filesSrc` are used instead of `this.data`, as their values are normalized._
151 |
--------------------------------------------------------------------------------
/Creating-tasks.md:
--------------------------------------------------------------------------------
1 | Tasks are grunt's bread and butter. The stuff you do most often, like `jshint` or `nodeunit`. Every time Grunt is run, you specify one or more tasks to run, which tells Grunt what you'd like it to do.
2 |
3 | If you don't specify a task, but a task named "default" has been defined, that task will run (unsurprisingly) by default.
4 |
5 | ## Alias Tasks
6 | If a task list is specified, the new task will be an alias for one or more other tasks. Whenever this "alias task" is run, every specified tasks in `taskList` will be run, in the order specified. The `taskList` argument must be an array of tasks.
7 |
8 | ```javascript
9 | grunt.registerTask(taskName, [description, ] taskList)
10 | ```
11 |
12 | This example alias task defines a "default" task whereby the "jshint", "qunit", "concat" and "uglify" tasks are run automatically if Grunt is executed without specifying any tasks:
13 |
14 | ```javascript
15 | grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);
16 | ```
17 |
18 | Task arguments can be specified as well. In this example, the alias "dist" runs both the "concat" and "uglify" tasks, each with a "dist" argument:
19 |
20 | ```javascript
21 | grunt.registerTask('dist', ['concat:dist', 'uglify:dist']);
22 | ```
23 |
24 | ## Multi Tasks
25 | When a multi task is run, Grunt looks for a property of the same name in the Grunt configuration. Multi-tasks can have multiple configurations, defined using arbitrarily named "targets."
26 |
27 | Specifying both a task and target like `grunt concat:foo` or `grunt concat:bar` will process just the specified target's configuration, while running `grunt concat` will iterate over _all_ targets, processing each in turn. Note that if a task has been renamed with [grunt.task.renameTask](grunt.task#grunt.task.renameTask), Grunt will look for a property with the _new_ task name in the config object.
28 |
29 | Most of the contrib tasks, including the [grunt-contrib-jshint plugin jshint task](https://github.com/gruntjs/grunt-contrib-jshint#jshint-task) and [grunt-contrib-concat plugin concat task](https://github.com/gruntjs/grunt-contrib-concat#concat-task) are multi tasks.
30 |
31 | ```javascript
32 | grunt.registerMultiTask(taskName, [description, ] taskFunction)
33 | ```
34 |
35 | Given the specified configuration, this example multi task would log `foo: 1,2,3` if Grunt was run via `grunt log:foo`, or it would log `bar: hello world` if Grunt was run via `grunt log:bar`. If Grunt was run as `grunt log` however, it would log `foo: 1,2,3` then `bar: hello world` then `baz: false`.
36 |
37 | ```javascript
38 | grunt.initConfig({
39 | log: {
40 | foo: [1, 2, 3],
41 | bar: 'hello world',
42 | baz: false
43 | }
44 | });
45 |
46 | grunt.registerMultiTask('log', 'Log stuff.', function() {
47 | grunt.log.writeln(this.target + ': ' + this.data);
48 | });
49 | ```
50 |
51 |
52 | ## "Basic" Tasks
53 | When a basic task is run, Grunt doesn't look at the configuration or environment—it just runs the specified task function, passing any specified colon-separated arguments in as function arguments.
54 |
55 | ```javascript
56 | grunt.registerTask(taskName, [description, ] taskFunction)
57 | ```
58 |
59 | This example task logs `foo, testing 123` if Grunt is run via `grunt foo:testing:123`. If the task is run without arguments as `grunt foo` the task logs `foo, no args`.
60 |
61 | ```javascript
62 | grunt.registerTask('foo', 'A sample task that logs stuff.', function(arg1, arg2) {
63 | if (arguments.length === 0) {
64 | grunt.log.writeln(this.name + ", no args");
65 | } else {
66 | grunt.log.writeln(this.name + ", " + arg1 + " " + arg2);
67 | }
68 | });
69 | ```
70 |
71 | ## Custom tasks
72 | You can go crazy with tasks. If your tasks don't follow the "multi task" structure, use a custom task.
73 |
74 | ```javascript
75 | grunt.registerTask('default', 'My "default" task description.', function() {
76 | grunt.log.writeln('Currently running the "default" task.');
77 | });
78 | ```
79 |
80 | Inside a task, you can run other tasks.
81 |
82 | ```javascript
83 | grunt.registerTask('foo', 'My "foo" task.', function() {
84 | // Enqueue "bar" and "baz" tasks, to run after "foo" finishes, in-order.
85 | grunt.task.run('bar', 'baz');
86 | // Or:
87 | grunt.task.run(['bar', 'baz']);
88 | });
89 | ```
90 |
91 | Tasks can be asynchronous.
92 |
93 | ```javascript
94 | grunt.registerTask('asyncfoo', 'My "asyncfoo" task.', function() {
95 | // Force task into async mode and grab a handle to the "done" function.
96 | var done = this.async();
97 | // Run some sync stuff.
98 | grunt.log.writeln('Processing task...');
99 | // And some async stuff.
100 | setTimeout(function() {
101 | grunt.log.writeln('All done!');
102 | done();
103 | }, 1000);
104 | });
105 | ```
106 |
107 | Tasks can access their own name and arguments.
108 |
109 | ```javascript
110 | grunt.registerTask('foo', 'My "foo" task.', function(a, b) {
111 | grunt.log.writeln(this.name, a, b);
112 | });
113 |
114 | // Usage:
115 | // grunt foo foo:bar
116 | // logs: "foo", undefined, undefined
117 | // logs: "foo", "bar", undefined
118 | // grunt foo:bar:baz
119 | // logs: "foo", "bar", "baz"
120 | ```
121 |
122 | Tasks can fail if any errors were logged.
123 |
124 | ```javascript
125 | grunt.registerTask('foo', 'My "foo" task.', function() {
126 | if (failureOfSomeKind) {
127 | grunt.log.error('This is an error message.');
128 | }
129 |
130 | // Fail by returning false if this task had errors
131 | if (ifErrors) { return false; }
132 |
133 | grunt.log.writeln('This is the success message');
134 | });
135 | ```
136 |
137 | When tasks fail, all subsequent tasks will be aborted unless `--force` was specified.
138 |
139 | ```javascript
140 | grunt.registerTask('foo', 'My "foo" task.', function() {
141 | // Fail synchronously.
142 | return false;
143 | });
144 |
145 | grunt.registerTask('bar', 'My "bar" task.', function() {
146 | var done = this.async();
147 | setTimeout(function() {
148 | // Fail asynchronously.
149 | done(false);
150 | }, 1000);
151 | });
152 | ```
153 |
154 | Tasks can be dependent on the successful execution of other tasks. Note that `grunt.task.requires` won't actually RUN the other task(s). It'll just check to see that it has run and not failed.
155 |
156 | ```javascript
157 | grunt.registerTask('foo', 'My "foo" task.', function() {
158 | return false;
159 | });
160 |
161 | grunt.registerTask('bar', 'My "bar" task.', function() {
162 | // Fail task if "foo" task failed or never ran.
163 | grunt.task.requires('foo');
164 | // This code executes if the "foo" task ran successfully.
165 | grunt.log.writeln('Hello, world.');
166 | });
167 |
168 | // Usage:
169 | // grunt foo bar
170 | // doesn't log, because foo failed.
171 | // grunt bar
172 | // doesn't log, because foo never ran.
173 | ```
174 |
175 | Tasks can fail if required configuration properties don't exist.
176 |
177 | ```javascript
178 | grunt.registerTask('foo', 'My "foo" task.', function() {
179 | // Fail task if "meta.name" config prop is missing
180 | // Format 1: String
181 | grunt.config.requires('meta.name');
182 | // or Format 2: Array
183 | grunt.config.requires(['meta', 'name']);
184 | // Log... conditionally.
185 | grunt.log.writeln('This will only log if meta.name is defined in the config.');
186 | });
187 | ```
188 |
189 | Tasks can access configuration properties.
190 |
191 | ```javascript
192 | grunt.registerTask('foo', 'My "foo" task.', function() {
193 | // Log the property value. Returns null if the property is undefined.
194 | grunt.log.writeln('The meta.name property is: ' + grunt.config('meta.name'));
195 | // Also logs the property value. Returns null if the property is undefined.
196 | grunt.log.writeln('The meta.name property is: ' + grunt.config(['meta', 'name']));
197 | });
198 | ```
199 |
200 | Take a look at the [contrib tasks](https://github.com/gruntjs/) for more examples.
201 |
202 | ## CLI options / environment
203 |
204 | Use `process.env` to access the [environment variables](http://en.wikipedia.org/wiki/Environment_variable).
205 |
206 | Read more about the available command-line options on the [Using the CLI](http://gruntjs.com/using-the-cli) page.
207 |
208 | ## Why doesn't my asynchronous task complete?
209 | Chances are this is happening because you have forgotten to call the [this.async](http://gruntjs.com/api/inside-tasks#this.async) method to tell Grunt that your task is asynchronous. For simplicity's sake, Grunt uses a synchronous coding style, which can be switched to asynchronous by calling `this.async()` within the task body.
210 |
211 | Note that passing `false` to the `done()` function tells Grunt that the task has failed.
212 |
213 | For example:
214 |
215 | ```javascript
216 | grunt.registerTask('asyncme', 'My asynchronous task.', function() {
217 | var done = this.async();
218 | doSomethingAsync(done);
219 | });
220 | ```
221 |
222 | ## Extra Reference
223 |
224 | Checkout the [API](http://gruntjs.com/api) documentation if you need extra reference to create your tasks.
225 |
--------------------------------------------------------------------------------
/Getting-started.md:
--------------------------------------------------------------------------------
1 | Grunt and Grunt plugins are installed and managed via [npm](https://npmjs.org/), the [Node.js](http://nodejs.org/) package manager.
2 | Grunt 0.4.x requires stable Node.js versions `>= 0.8.0`. Odd version numbers of Node.js are considered unstable development versions.
3 |
4 | Before setting up Grunt ensure that your [npm](https://npmjs.org/) is up-to-date by running `npm update -g npm` (this might require `sudo` on certain systems).
5 |
6 | If you already have installed Grunt and is now searching for some quick reference, please checkout our [`Gruntfile` example](/sample-gruntfile) and how to [configure a task](/configuring-tasks).
7 |
8 | ## Installing the CLI
9 | **Using Grunt 0.3? Please see [Grunt 0.3 Notes](upgrading-from-0.3-to-0.4#grunt-0.3-notes)**
10 |
11 | In order to get started, you'll want to install Grunt's command line interface (CLI) globally. You may need to use sudo (for OSX, *nix, BSD etc) or run your command shell as Administrator (for Windows) to do this.
12 |
13 | ```shell
14 | npm install -g grunt-cli
15 | ```
16 |
17 | This will put the `grunt` command in your system path, allowing it to be run from any directory.
18 |
19 | Note that installing `grunt-cli` does not install the Grunt task runner! The job of the Grunt CLI is simple: run the version of Grunt which has been installed next to a `Gruntfile`.
20 | This allows multiple versions of Grunt to be installed on the same machine simultaneously.
21 |
22 | ## How the CLI works
23 |
24 | Each time `grunt` is run, it looks for a locally installed Grunt using node's `require()` system. Because of this, you can run `grunt` from any subfolder in your project.
25 |
26 | If a locally installed Grunt is found, the CLI loads the local installation of the Grunt library, applies the configuration from your `Gruntfile`, and executes any tasks you've requested for it to run. To really understand what is happening, [read the code](https://github.com/gruntjs/grunt-cli/blob/master/bin/grunt).
27 |
28 | ## Working with an existing Grunt project
29 | Assuming that the Grunt CLI has been installed and that the project has already been configured with a `package.json` and a `Gruntfile`, it's very easy to start working with Grunt:
30 |
31 | 1. Change to the project's root directory.
32 | 1. Install project dependencies with `npm install`.
33 | 1. Run Grunt with `grunt`.
34 |
35 | That's really all there is to it. Installed Grunt tasks can be listed by running `grunt --help` but it's usually a good idea to start with the project's documentation.
36 |
37 | ## Preparing a new Grunt project
38 | A typical setup will involve adding two files to your project: `package.json` and the `Gruntfile`.
39 |
40 | **package.json**: This file is used by [npm] to store metadata for projects published as npm modules. You will list grunt and the Grunt plugins your project needs as [devDependencies] in this file.
41 |
42 | **Gruntfile**: This file is named `Gruntfile.js` or `Gruntfile.coffee` and is used to configure or define tasks and load Grunt plugins.
43 | **When this documentation mentions a `Gruntfile` it is talking about a file, which is either a `Gruntfile.js` or a `Gruntfile.coffee`**.
44 |
45 | ## package.json
46 |
47 | The `package.json` file belongs in the root directory of your project, next to the `Gruntfile`, and should be committed with your project source. Running `npm install` in the same folder as a `package.json` file will install the correct version of each dependency listed therein.
48 |
49 | There are a few ways to create a `package.json` file for your project:
50 |
51 | * Most [grunt-init] templates will automatically create a project-specific `package.json` file.
52 | * The [npm init] command will create a basic `package.json` file.
53 | * Start with the example below, and expand as needed, following this [specification][json].
54 |
55 | ```js
56 | {
57 | "name": "my-project-name",
58 | "version": "0.1.0",
59 | "devDependencies": {
60 | "grunt": "~0.4.5",
61 | "grunt-contrib-jshint": "~0.10.0",
62 | "grunt-contrib-nodeunit": "~0.4.1",
63 | "grunt-contrib-uglify": "~0.5.0"
64 | }
65 | }
66 | ```
67 |
68 | ### Installing Grunt and gruntplugins
69 | The easiest way to add Grunt and gruntplugins to an existing `package.json` is with the command `npm install --save-dev`. Not only will this install `` locally, but it will automatically be added to the [devDependencies] section, using a [tilde version range].
70 |
71 | For example, this will install the latest version of Grunt in your project folder, adding it to your devDependencies:
72 |
73 | ```shell
74 | npm install grunt --save-dev
75 | ```
76 |
77 | The same can be done for gruntplugins and other node modules. As seen in the following example installing the JSHint task module:
78 |
79 | ```shell
80 | npm install grunt-contrib-jshint --save-dev
81 | ```
82 |
83 | Checkout the current available gruntplugins to be installed and used on your project at the [plugins](http://gruntjs.com/plugins) page.
84 |
85 | Be sure to commit the updated `package.json` file with your project when you're done!
86 |
87 | ## The Gruntfile
88 | The `Gruntfile.js` or `Gruntfile.coffee` file is a valid JavaScript or CoffeeScript file that belongs in the root directory of your project, next to the `package.json` file, and should be committed with your project source.
89 |
90 | A `Gruntfile` is comprised of the following parts:
91 |
92 | * The "wrapper" function
93 | * Project and task configuration
94 | * Loading Grunt plugins and tasks
95 | * Custom tasks
96 |
97 | ### An example Gruntfile
98 | In the following `Gruntfile`, project metadata is imported into the Grunt config from the project's `package.json` file and the [grunt-contrib-uglify] plugin's `uglify` task is configured to minify a source file and generate a banner comment dynamically using that metadata. When `grunt` is run on the command line, the `uglify` task will be run by default.
99 |
100 | ```js
101 | module.exports = function(grunt) {
102 |
103 | // Project configuration.
104 | grunt.initConfig({
105 | pkg: grunt.file.readJSON('package.json'),
106 | uglify: {
107 | options: {
108 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
109 | },
110 | build: {
111 | src: 'src/<%= pkg.name %>.js',
112 | dest: 'build/<%= pkg.name %>.min.js'
113 | }
114 | }
115 | });
116 |
117 | // Load the plugin that provides the "uglify" task.
118 | grunt.loadNpmTasks('grunt-contrib-uglify');
119 |
120 | // Default task(s).
121 | grunt.registerTask('default', ['uglify']);
122 |
123 | };
124 | ```
125 |
126 | Now that you've seen the whole `Gruntfile`, let's look at its component parts.
127 |
128 | ### The "wrapper" function
129 | Every `Gruntfile` (and gruntplugin) uses this basic format, and all of your Grunt code must be specified inside this function:
130 |
131 | ```js
132 | module.exports = function(grunt) {
133 | // Do grunt-related things in here
134 | };
135 | ```
136 |
137 | ### Project and task configuration
138 | Most Grunt tasks rely on configuration data defined in an object passed to the [[grunt.initConfig|grunt#grunt.initconfig]] method.
139 |
140 | In this example, `grunt.file.readJSON('package.json')` imports the JSON metadata stored in `package.json` into the grunt config. Because `<% %>` template strings may reference any config properties, configuration data like filepaths and file lists may be specified this way to reduce repetition.
141 |
142 | You may store any arbitrary data inside of the configuration object, and as long as it doesn't conflict with properties your tasks require, it will be otherwise ignored. Also, because this is JavaScript, you're not limited to JSON; you may use any valid JS here. You can even programmatically generate the configuration if necessary.
143 |
144 | Like most tasks, the [grunt-contrib-uglify] plugin's `uglify` task expects its configuration to be specified in a property of the same name. Here, the `banner` option is specified, along with a single uglify target named `build` that minifies a single source file to a single destination file.
145 |
146 | ```js
147 | // Project configuration.
148 | grunt.initConfig({
149 | pkg: grunt.file.readJSON('package.json'),
150 | uglify: {
151 | options: {
152 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
153 | },
154 | build: {
155 | src: 'src/<%= pkg.name %>.js',
156 | dest: 'build/<%= pkg.name %>.min.js'
157 | }
158 | }
159 | });
160 | ```
161 |
162 | ### Loading Grunt plugins and tasks
163 | Many commonly used tasks like [concatenation], [minification][grunt-contrib-uglify] and [linting] are available as [grunt plugins](https://github.com/gruntjs). As long as a plugin is specified in `package.json` as a dependency, and has been installed via `npm install`, it may be enabled inside your `Gruntfile` with a simple command:
164 |
165 | ```js
166 | // Load the plugin that provides the "uglify" task.
167 | grunt.loadNpmTasks('grunt-contrib-uglify');
168 | ```
169 |
170 | **Note:** the `grunt --help` command will list all available tasks.
171 |
172 | ### Custom tasks
173 | You can configure Grunt to run one or more tasks by default by defining a `default` task. In the following example, running `grunt` at the command line without specifying a task will run the `uglify` task. This is functionally the same as explicitly running `grunt uglify` or even `grunt default`. Any number of tasks (with or without arguments) may be specified in the array.
174 |
175 | ```js
176 | // Default task(s).
177 | grunt.registerTask('default', ['uglify']);
178 | ```
179 |
180 | If your project requires tasks not provided by a Grunt plugin, you may define custom tasks right inside the `Gruntfile`. For example, this `Gruntfile` defines a completely custom `default` task that doesn't even utilize task configuration:
181 |
182 | ```js
183 | module.exports = function(grunt) {
184 |
185 | // A very basic default task.
186 | grunt.registerTask('default', 'Log some stuff.', function() {
187 | grunt.log.write('Logging some stuff...').ok();
188 | });
189 |
190 | };
191 | ```
192 |
193 | Custom project-specific tasks don't need to be defined in the `Gruntfile`; they may be defined in external `.js` files and loaded via the [[grunt.loadTasks|grunt#grunt.loadtasks]] method.
194 |
195 | ## Further Reading
196 |
197 | * The [[Installing grunt]] guide has detailed information about installing specific, production or in-development, versions of Grunt and grunt-cli.
198 | * The [[Configuring Tasks]] guide has an in-depth explanation on how to configure tasks, targets, options and files inside the `Gruntfile`, along with an explanation of templates, globbing patterns and importing external data.
199 | * The [[Creating Tasks]] guide lists the differences between the types of Grunt tasks and shows a number of sample tasks and configurations.
200 | * For more information about writing custom tasks or Grunt plugins, check out the [[developer documentation|grunt]].
201 |
202 | [npm]: https://npmjs.org/
203 | [devDependencies]: https://npmjs.org/doc/json.html#devDependencies
204 | [json]: https://npmjs.org/doc/json.html
205 | [npm init]: https://npmjs.org/doc/init.html
206 | [grunt-init]: Project-Scaffolding
207 | [tilde version range]: https://npmjs.org/doc/misc/semver.html#Ranges
208 | [grunt-contrib-uglify]: http://github.com/gruntjs/grunt-contrib-uglify
209 | [concatenation]: https://github.com/gruntjs/grunt-contrib-concat
210 | [linting]: https://github.com/gruntjs/grunt-contrib-jshint
211 | [grunt.loadTasks]: https://github.com/gruntjs/grunt/wiki/grunt.task
212 |
--------------------------------------------------------------------------------
/Upgrading-from-0.3-to-0.4.md:
--------------------------------------------------------------------------------
1 | _Note that even if you are familiar with grunt, it would be worthwhile to read the new [[Getting started]] guide._
2 |
3 | Grunt is now split into three parts: `grunt`, `grunt-cli` and `grunt-init`.
4 |
5 | 1. The npm module `grunt` should be installed locally to your project. It contains the code and logic for running tasks, loading plugins, etc.
6 | 2. The npm module `grunt-cli` should be installed globally. It puts the `grunt` command in your PATH so you can execute it anywhere. By itself, it doesn't do anything; its job is to load and run the Grunt that has been installed locally to your project, regardless of the version. For more information about why this has changed, please read [npm 1.0: Global vs Local installation](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation).
7 | 3. The `init` task has been broken into its own npm module, `grunt-init`. It should be installed globally with `npm install -g grunt-init` and run with the `grunt-init` command. In the coming months, [Yeoman](http://yeoman.io/) will completely replace grunt-init. See the [grunt-init project page](https://github.com/gruntjs/grunt-init) for more information.
8 |
9 |
10 | ## Grunt 0.3 Notes
11 |
12 | If you are upgrading from Grunt 0.3, make sure to uninstall global `grunt`:
13 |
14 | ```shell
15 | npm uninstall -g grunt
16 | ```
17 |
18 | _Note that for 0.3.x, plugin names and task configuration options may be different than those shown in "The Gruntfile" section._
19 |
20 | _This file was named `grunt.js` for 0.3.x versions of Grunt._
21 |
22 | ## Pre-existing tasks and plugins
23 | All `grunt-contrib-*` series plugins are Grunt 0.4 ready. However, it is highly unlikely that third party plugins written for Grunt 0.3 will continue to work with 0.4 until they have been updated. We are actively working with plugin authors to ensure this happens as swiftly as possible.
24 |
25 | _A forthcoming Grunt release will be focused on decoupling grunt's architecture so that plugins are not affected by future updates._
26 |
27 | ## Requirements
28 | * Grunt now requires Node.js version `>= 0.8.0`
29 |
30 | ## The Gruntfile
31 | * The "Gruntfile" has changed from `grunt.js` to `Gruntfile.js`.
32 | * CoffeeScript is supported in your `Gruntfile.coffee` project `Gruntfile` or `*.coffee` task files (transpiling to JS happens automatically).
33 |
34 | See the "The Gruntfile" section of the [[Getting started]] guide for more information.
35 |
36 | ## Core Tasks are now Grunt Plugins
37 | The eight core tasks that were included in Grunt 0.3 are now separate Grunt plugins. Each is a discrete npm module that must be installed as a plugin per the "Loading Grunt plugins and tasks" section of the [[Getting started]] guide.
38 |
39 | * concat → [grunt-contrib-concat](https://github.com/gruntjs/grunt-contrib-concat) plugin
40 | * init → stand-alone [grunt-init] utility
41 | * lint → [grunt-contrib-jshint](https://github.com/gruntjs/grunt-contrib-jshint) plugin
42 | * min → [grunt-contrib-uglify](https://github.com/gruntjs/grunt-contrib-uglify) plugin
43 | * qunit → [grunt-contrib-qunit](https://github.com/gruntjs/grunt-contrib-qunit) plugin
44 | * server → [grunt-contrib-connect](https://github.com/gruntjs/grunt-contrib-connect) plugin
45 | * test → [grunt-contrib-nodeunit](https://github.com/gruntjs/grunt-contrib-nodeunit) plugin
46 | * watch → [grunt-contrib-watch](https://github.com/gruntjs/grunt-contrib-watch) plugin
47 |
48 | Some task names and options have changed. Be sure to see each plugin's documentation as linked above for the latest configuration details.
49 |
50 | ## Configuration
51 | The configuration format for Grunt 0.4 tasks has been standardized and greatly enhanced. See the [[Configuring tasks]] guide, as well as individual plugin documentation for more information.
52 |
53 | * File globbing (wildcard) patterns may now be negated to exclude matched files.
54 | * Tasks now support a standard `options` object.
55 | * Tasks now support a standard `files` object.
56 |
57 | `<% %>` style template strings specified as config data inside the `Gruntfile` are automatically expanded, see the [[grunt.template]] documentation for more information.
58 |
59 | **Directives have been removed**, but their functionality has been retained. These replacements can be made:
60 |
61 | * `''` → `'<%= prop.subprop %>'`
62 | * `''` → `grunt.file.readJSON('file.json')`
63 | * `''` → `grunt.template.process(grunt.file.read('file.js'))`
64 |
65 | Instead of specifying a banner in a file list with `''` or `''`, the [grunt-contrib-concat](https://github.com/gruntjs/grunt-contrib-concat) and [grunt-contrib-uglify](https://github.com/gruntjs/grunt-contrib-uglify) plugins each have a `banner` option.
66 |
67 | Instead of stripping banners from files individually with `''`, the [grunt-contrib-concat](https://github.com/gruntjs/grunt-contrib-concat) and [grunt-contrib-uglify](https://github.com/gruntjs/grunt-contrib-uglify) plugins each have an option to strip/preserve banners.
68 |
69 | ## Alias task changes
70 | When specifying an alias task, the list of tasks to run must now be specified as an array.
71 |
72 | ```js
73 | // v0.3.x (old format)
74 | grunt.registerTask('default', 'jshint nodeunit concat');
75 | // v0.4.x (new format)
76 | grunt.registerTask('default', ['jshint', 'nodeunit', 'concat']);
77 | ```
78 |
79 | ## Task arguments may now contain spaces
80 | The aforementioned alias task change (task lists must be specified as an array) makes this possible. Just be sure to surround task arguments containing spaces with quotes when specifying them on the command line, so they can be properly parsed.
81 |
82 | ```shell
83 | grunt my-task:argument-without-spaces "other-task:argument with spaces"
84 | ```
85 |
86 | ## Character encodings
87 | The [file.defaultEncoding](grunt.file#wiki-grunt-file-defaultEncoding) method was added to normalize character encodings, and all `grunt.file` methods have been updated to support the specified encoding.
88 |
89 | ## Helpers
90 | Grunt's helper system has been removed in favor of node `require`. For a concise example on how to share functionality between Grunt plugins, please see [grunt-lib-legacyhelpers](https://github.com/gruntjs/grunt-lib-legacyhelpers). Plugin authors are encouraged to upgrade their plugins.
91 |
92 | ## API
93 | The Grunt API saw substantial changes from 0.3 to 0.4.
94 |
95 | * [grunt](grunt)
96 | * Removed `grunt.registerHelper` and `grunt.renameHelper` methods.
97 | * [grunt.config](grunt.config)
98 | * Changed [config.get](grunt.config#wiki-grunt-config-get) method to automatically recursively expand `<% %>` templates.
99 | * Added [config.getRaw](grunt.config#wiki-grunt-config-getRaw) method that will retrieve raw (unexpanded) config data.
100 | * Changed [config.process](grunt.config#wiki-grunt-config-process) method to now process a value as if it had been retrieved from the config, expanding templates recursively. This method is called internally inside of `config.get`, but _not_ inside of `config.getRaw`.
101 | * [grunt.event](grunt.event) added so that tasks may emit events.
102 | * [grunt.fail](grunt.fail)
103 | * Won't emit a beep if `--no-color` option specified.
104 | * Added `fail.code` exit code map.
105 | * Removed `fail.warnAlternate` method.
106 | * [grunt.file](grunt.file)
107 | * Tasks are no longer automatically loaded from `~/.grunt/tasks/` directory (install them locally to your project!).
108 | * Added [file.defaultEncoding](grunt.file#wiki-grunt-file-defaultEncoding) method for normalizing character encoding across all `grunt.file` methods.
109 | * Added [file.delete](grunt.file#wiki-grunt-file-delete) method.
110 | * Added relatively self-explanatory [file.exists](grunt.file#wiki-grunt-file-exists), [file.isDir](grunt.file#wiki-grunt-file-isDir), [file.isFile](grunt.file#wiki-grunt-file-isFile), [file.isLink](grunt.file#wiki-grunt-file-isLink), [file.isPathCwd](grunt.file#wiki-grunt-file-isPathCwd), [file.isPathInCwd](grunt.file#wiki-grunt-file-isPathInCwd), [file.doesPathContain](grunt.file#wiki-grunt-file-doesPathContain), [file.arePathsEquivalent](grunt.file#wiki-grunt-file-arePathsEquivalent) testing methods.
111 | * Added [file.match](grunt.file#wiki-grunt-file-match) and [file.isMatch](grunt.file#wiki-grunt-file-isMatch) methods to facilitate matching wildcard patterns against file paths.
112 | * Added [file.expandMapping](grunt.file#wiki-grunt-file-expandMapping) method for use in generating 1-to-1 src-dest file mappings.
113 | * Added [file.readYAML](grunt.file#wiki-grunt-file-readYAML) method.
114 | * Changed [file.findup](grunt.file#wiki-grunt-file-findup) to use the [findup-sync](https://github.com/cowboy/node-findup-sync) module.
115 | * Changed [file.glob](grunt.file#wiki-grunt-file-glob) to use the [glob](https://github.com/isaacs/node-glob) module.
116 | * Added [file.minimatch](grunt.file#wiki-grunt-file-minimatch) which exposes the [minimatch](https://github.com/isaacs/minimatch) module.
117 | * Removed `file.userDir` method (moved into [grunt-init]).
118 | * Removed `file.clearRequireCache` method.
119 | * Removed `file.expandFiles` and `file.expandDirs` methods, use the `filter` option of `file.expand` instead.
120 | * Removed `file.expandFileURLs` method. Don't specify URLs where files should be specified (eg. the qunit task now allows for a `urls` option).
121 | * [grunt.task](grunt#wiki-grunt-task)
122 | * Tasks registered with both [task.registerTask](grunt.task#wiki-grunt-task-registerTask) and [task.registerMultiTask](grunt.task#wiki-grunt-task-registerMultiTask) get a `this.options` method.
123 | * Added [task.normalizeMultiTaskFiles](grunt.task#wiki-grunt-task-normalizeMultiTaskFiles) method to facilitate the normalization of multi task `files` objects into the `this.file` property.
124 | * Removed `task.registerHelper` and `task.renameHelper` methods.
125 | * Removed `task.searchDirs` property.
126 | * Removed `task.expand` `task.expandDirs` `task.expandFiles` `task.getFile` `task.readDefaults` methods (moved into [grunt-init]).
127 | * [grunt.package](grunt#wiki-grunt-package) reflects the metadata stored in grunt's `package.json`.
128 | * [grunt.version](grunt#wiki-grunt-version) is the current version of Grunt as a string.
129 | * [grunt.template](grunt.template)
130 | * Added [template.addDelimiters](grunt.template#wiki-grunt-template-addDelimiters) method to add new template delimiters.
131 | * Added [template.setDelimiters](grunt.template#wiki-grunt-template-setDelimiters) method to select template delimiters.
132 | * The `init` and `user` template delimiters have been removed, but you can add them in again if you need to with `template.addDelimiters` ([grunt-init] uses this to enable the `{% %}` template delimiters).
133 | * [grunt.util](grunt.util) replaces the now-removed `grunt.utils`.
134 | * Changed `util._` to use [Lo-Dash](http://lodash.com/)
135 | * Added the [util.callbackify](grunt.util#wiki-grunt-util-callbackify) method.
136 | * Changed the [util.spawn](grunt.util#wiki-grunt-util-spawn) method to be much better behaved and pass more consistent arguments into its callback.
137 |
138 | ## Task / plugin authors
139 | **Plugin authors, please indicate clearly on your repository README which version number of your Grunt plugin breaks compatibility with Grunt 0.3.**
140 |
141 | ### Tasks
142 | * Multi tasks
143 | * Multiple src-dest file mappings may now be specified per target in a `files` object (this is optional).
144 | * [this.files / grunt.task.current.files](grunt.task#wiki-this-files)
145 | * The `this.files` property is an array of src-dest file mapping objects to be iterated over in your multi task. It will always be an array, and you should always iterate over it, even if the most common use case is to specify a single file.
146 | * Each src-dest file mapping object has a `src` and `dest` property (and possibly others, depending on what the user specified). The `src` property is already expanded from whatever glob pattern the user may have specified.
147 | * [this.filesSrc / grunt.task.current.filesSrc](grunt.task#wiki-this-filesSrc)
148 | * The `this.filesSrc` property is a reduced, uniqued array of all files matched by all specified `src` properties. Useful for read-only tasks.
149 | * [this.options / grunt.task.current.options](grunt.task#wiki-this-options)
150 | * The `this.options` method may be used within tasks to normalize options. Inside a task, you may specify options defaults like: `var options = this.options({option: 'defaultvalue', ...});`
151 |
152 | ### Plugins
153 | * An updated `gruntplugin` template has been created for Grunt 0.4-compatible plugins, and is available in the standalone [grunt-init].
154 |
155 | ## Troubleshooting
156 | * If you had previously installed a development version of Grunt 0.4 or any grunt-contrib plugins, be sure to flush your npm cache with `npm cache clean` first to ensure that you are pulling the final version of Grunt and grunt-contrib plugins.
157 |
158 | [grunt-init]: https://github.com/gruntjs/grunt-init
--------------------------------------------------------------------------------
/grunt.file.md:
--------------------------------------------------------------------------------
1 | There are many provided methods for reading and writing files, traversing the filesystem and finding files by matching globbing patterns. Many of these methods are wrappers around built-in Node.js file functionality, but with additional error handling, logging and character encoding normalization.
2 |
3 | _Note: all file paths are relative to the `Gruntfile` unless the current working directory is changed with `grunt.file.setBase` or the `--base` command-line option._
4 |
5 | ## Character encoding
6 |
7 | ### grunt.file.defaultEncoding
8 | Set this property to change the default encoding used by all `grunt.file` methods. Defaults to `'utf8'`. If you do have to change this value, it's recommended that you change it as early as possible inside your Gruntfile.
9 |
10 | ```js
11 | grunt.file.defaultEncoding = 'utf8';
12 | ```
13 |
14 |
15 | ### grunt.file.preserveBOM
16 | *Added in 0.4.2*
17 |
18 | Whether to preserve the Byte Order Mark (BOM) on `file.read` rather than strip it.
19 | ```js
20 | grunt.file.preserveBOM = false;
21 | ```
22 |
23 | ## Reading and writing
24 |
25 | ### grunt.file.read
26 | Read and return a file's contents. Returns a string, unless `options.encoding` is `null` in which case it returns a [Buffer](http://nodejs.org/docs/latest/api/buffer.html).
27 |
28 | ```js
29 | grunt.file.read(filepath [, options])
30 | ```
31 |
32 | The `options` object has these possible properties:
33 |
34 | ```js
35 | var options = {
36 | // If an encoding is not specified, default to grunt.file.defaultEncoding.
37 | // If specified as null, returns a non-decoded Buffer instead of a string.
38 | encoding: encodingName
39 | };
40 | ```
41 |
42 | ### grunt.file.readJSON
43 | Read a file's contents, parsing the data as JSON and returning the result. See `grunt.file.read` for a list of supported options.
44 |
45 | ```js
46 | grunt.file.readJSON(filepath [, options])
47 | ```
48 |
49 | ### grunt.file.readYAML
50 | Read a file's contents, parsing the data as YAML and returning the result. See `grunt.file.read` for a list of supported options.
51 |
52 | ```js
53 | grunt.file.readYAML(filepath [, options])
54 | ```
55 |
56 | ### grunt.file.write
57 | Write the specified contents to a file, creating intermediate directories if necessary. Strings will be encoded using the specified character encoding, [Buffers](http://nodejs.org/docs/latest/api/buffer.html) will be written to disk as-specified.
58 |
59 | _If the `--no-write` command-line option is specified, the file won't actually be written._
60 |
61 | ```js
62 | grunt.file.write(filepath, contents [, options])
63 | ```
64 |
65 | The `options` object has these possible properties:
66 |
67 | ```js
68 | var options = {
69 | // If an encoding is not specified, default to grunt.file.defaultEncoding.
70 | // If `contents` is a Buffer, encoding is ignored.
71 | encoding: encodingName
72 | };
73 | ```
74 |
75 | ### grunt.file.copy
76 | Copy a source file to a destination path, creating intermediate directories if necessary.
77 |
78 | _If the `--no-write` command-line option is specified, the file won't actually be written._
79 |
80 | ```js
81 | grunt.file.copy(srcpath, destpath [, options])
82 | ```
83 |
84 | The `options` object has these possible properties:
85 |
86 | ```js
87 | var options = {
88 | // If an encoding is not specified, default to grunt.file.defaultEncoding.
89 | // If null, the `process` function will receive a Buffer instead of String.
90 | encoding: encodingName,
91 | // The source file contents, source file path, and destination file path
92 | // are passed into this function, whose return value will be used as the
93 | // destination file's contents. If this function returns `false`, the file
94 | // copy will be aborted.
95 | process: processFunction,
96 | // These optional globbing patterns will be matched against the filepath
97 | // (not the filename) using grunt.file.isMatch. If any specified globbing
98 | // pattern matches, the file won't be processed via the `process` function.
99 | // If `true` is specified, processing will be prevented.
100 | noProcess: globbingPatterns
101 | };
102 | ```
103 |
104 | ### grunt.file.delete
105 | Delete the specified filepath. Will delete files and folders recursively.
106 |
107 | _Will not delete the current working directory or files outside the current working directory unless the `--force` command-line option is specified._
108 |
109 | _If the `--no-write` command-line option is specified, the filepath won't actually be deleted._
110 |
111 | ```js
112 | grunt.file.delete(filepath [, options])
113 | ```
114 |
115 | The `options` object has one possible property:
116 |
117 | ```js
118 | var options = {
119 | // Enable deleting outside the current working directory. This option may
120 | // be overridden by the --force command-line option.
121 | force: true
122 | };
123 | ```
124 |
125 | ## Directories
126 |
127 | ### grunt.file.mkdir
128 | Works like `mkdir -p`. Create a directory along with any intermediate directories. If `mode` isn't specified, it defaults to `0777 & (~process.umask())`.
129 |
130 | _If the `--no-write` command-line option is specified, directories won't actually be created._
131 |
132 | ```js
133 | grunt.file.mkdir(dirpath [, mode])
134 | ```
135 |
136 | ### grunt.file.recurse
137 | Recurse into a directory, executing `callback` for each file.
138 |
139 | ```js
140 | grunt.file.recurse(rootdir, callback)
141 | ```
142 |
143 | The callback function receives the following arguments:
144 |
145 | ```js
146 | function callback(abspath, rootdir, subdir, filename) {
147 | // The full path to the current file, which is nothing more than
148 | // the rootdir + subdir + filename arguments, joined.
149 | abspath
150 | // The root director, as originally specified.
151 | rootdir
152 | // The current file's directory, relative to rootdir.
153 | subdir
154 | // The filename of the current file, without any directory parts.
155 | filename
156 | }
157 | ```
158 |
159 | ## Globbing patterns
160 | It is often impractical to specify all source filepaths individually, so Grunt supports filename expansion (also know as globbing) via the built-in [node-glob](https://github.com/isaacs/node-glob) library.
161 |
162 | See the "Globbing patterns" section of the [[Configuring tasks]] guide for globbing pattern examples.
163 |
164 |
165 | ### grunt.file.expand
166 | Return a unique array of all file or directory paths that match the given globbing pattern(s). This method accepts either comma separated globbing patterns or an array of globbing patterns. Paths matching patterns that begin with `!` will be excluded from the returned array. Patterns are processed in order, so inclusion and exclusion order is significant.
167 |
168 | ```js
169 | grunt.file.expand([options, ] patterns)
170 | ```
171 |
172 | File paths are relative to the `Gruntfile` unless the current working directory is changed with `grunt.file.setBase` or the `--base` command-line option.
173 |
174 | The `options` object supports all [minimatch library](https://github.com/isaacs/minimatch) options, and a few others. For example:
175 |
176 | * `filter` Either a valid [fs.Stats method name](http://nodejs.org/docs/latest/api/fs.html#fs_class_fs_stats) or a function that is passed the matched `src` filepath and returns `true` or `false`.
177 | * `nonull` Retain `src` patterns even if they fail to match files. Combined with grunt's `--verbose` flag, this option can help debug file path issues.
178 | * `matchBase` Patterns without slashes will match just the basename part. Eg. this makes `*.js` work like `**/*.js`.
179 | * `cwd` Patterns will be matched relative to this path, and all returned filepaths will also be relative to this path.
180 |
181 | ### grunt.file.expandMapping
182 | Returns an array of src-dest file mapping objects. For each source file matched by a specified pattern, join that file path to the specified `dest`. This file path may be flattened or renamed, depending on the options specified. See the `grunt.file.expand` method documentation for an explanation of how the `patterns` and `options` arguments may be specified.
183 |
184 | ```js
185 | grunt.file.expandMapping(patterns, dest [, options])
186 | ```
187 |
188 | _Note that while this method may be used to programmatically generate a `files` array for a multi task, the declarative syntax for doing this described in the "Building the files object dynamically" section of the [[Configuring tasks]] guide is preferred._
189 |
190 | In addition to those the `grunt.file.expand` method supports, the `options` object also supports these properties:
191 |
192 | ```js
193 | var options = {
194 | // The directory from which patterns are matched. Any string specified as
195 | // cwd is effectively stripped from the beginning of all matched paths.
196 | cwd: String,
197 | // Remove the path component from all matched src files. The src file path
198 | // is still joined to the specified dest.
199 | flatten: Boolean,
200 | // Remove anything after (and including) either the first or last "." in the
201 | // destination path (indicated by options.extDot), then append this value.
202 | ext: String,
203 | // *Added in 0.4.3*
204 | // Indicates where the period demarcating the extension is located. Can take:
205 | // - 'first' (extension begins after the first period in the file name)
206 | // - 'last' (extension begins after the last period)
207 | // Default: 'first'
208 | extDot: String,
209 | // If specified, this function will be responsible for returning the final
210 | // dest filepath. By default, it joins dest and matchedSrcPath like so:
211 | rename: function(dest, matchedSrcPath, options) {
212 | return path.join(dest, matchedSrcPath);
213 | }
214 | };
215 | ```
216 |
217 | ### grunt.file.match
218 | Match one or more globbing patterns against one or more file paths. Returns a uniqued array of all file paths that match any of the specified globbing patterns. Both the `patterns` and `filepaths` argument can be a single string or array of strings. Paths matching patterns that begin with `!` will be excluded from the returned array. Patterns are processed in order, so inclusion and exclusion order is significant.
219 |
220 | ```js
221 | grunt.file.match([options, ] patterns, filepaths)
222 | ```
223 |
224 | The `options` object supports all [minimatch library](https://github.com/isaacs/minimatch) options. For example, if `options.matchBase` is true, patterns without slashes will match against the basename of the path even if it contains slashes, eg. pattern `*.js` will match filepath `path/to/file.js`.
225 |
226 | ### grunt.file.isMatch
227 | This method contains the same signature and logic as the `grunt.file.match` method, but simply returns `true` if any files were matched, otherwise `false`.
228 |
229 | ## File types
230 |
231 | ### grunt.file.exists
232 | Does the given path exist? Returns a boolean.
233 |
234 | Like the Node.js [path.join](http://nodejs.org/docs/latest/api/path.html#path_path_join_path1_path2) method, this method will join all arguments together and normalize the resulting path.
235 |
236 | ```js
237 | grunt.file.exists(path1 [, path2 [, ...]])
238 | ```
239 |
240 | ### grunt.file.isLink
241 | Is the given path a symbolic link? Returns a boolean.
242 |
243 | Like the Node.js [path.join](http://nodejs.org/docs/latest/api/path.html#path_path_join_path1_path2) method, this method will join all arguments together and normalize the resulting path.
244 |
245 | ```js
246 | grunt.file.isLink(path1 [, path2 [, ...]])
247 | ```
248 |
249 | Returns false if the path doesn't exist.
250 |
251 | ### grunt.file.isDir
252 | Is the given path a directory? Returns a boolean.
253 |
254 | Like the Node.js [path.join](http://nodejs.org/docs/latest/api/path.html#path_path_join_path1_path2) method, this method will join all arguments together and normalize the resulting path.
255 |
256 | ```js
257 | grunt.file.isDir(path1 [, path2 [, ...]])
258 | ```
259 |
260 | Returns false if the path doesn't exist.
261 |
262 | ### grunt.file.isFile
263 | Is the given path a file? Returns a boolean.
264 |
265 | Like the Node.js [path.join](http://nodejs.org/docs/latest/api/path.html#path_path_join_path1_path2) method, this method will join all arguments together and normalize the resulting path.
266 |
267 | ```js
268 | grunt.file.isFile(path1 [, path2 [, ...]])
269 | ```
270 |
271 | Returns false if the path doesn't exist.
272 |
273 | ## Paths
274 |
275 | ### grunt.file.isPathAbsolute
276 | Is a given file path absolute? Returns a boolean.
277 |
278 | Like the Node.js [path.join](http://nodejs.org/docs/latest/api/path.html#path_path_join_path1_path2) method, this method will join all arguments together and normalize the resulting path.
279 |
280 | ```js
281 | grunt.file.isPathAbsolute(path1 [, path2 [, ...]])
282 | ```
283 |
284 | ### grunt.file.arePathsEquivalent
285 | Do all the specified paths refer to the same path? Returns a boolean.
286 |
287 | ```js
288 | grunt.file.arePathsEquivalent(path1 [, path2 [, ...]])
289 | ```
290 |
291 | ### grunt.file.doesPathContain
292 | Are all descendant path(s) contained within the specified ancestor path? Returns a boolean.
293 |
294 | _Note: does not check to see if paths actually exist._
295 |
296 | ```js
297 | grunt.file.doesPathContain(ancestorPath, descendantPath1 [, descendantPath2 [, ...]])
298 | ```
299 |
300 | ### grunt.file.isPathCwd
301 | Is a given file path the CWD? Returns a boolean.
302 |
303 | Like the Node.js [path.join](http://nodejs.org/docs/latest/api/path.html#path_path_join_path1_path2) method, this method will join all arguments together and normalize the resulting path.
304 |
305 | ```js
306 | grunt.file.isPathCwd(path1 [, path2 [, ...]])
307 | ```
308 |
309 | ### grunt.file.isPathInCwd
310 | Is a given file path inside the CWD? Note: CWD is not _inside_ CWD. Returns a boolean.
311 |
312 | Like the Node.js [path.join](http://nodejs.org/docs/latest/api/path.html#path_path_join_path1_path2) method, this method will join all arguments together and normalize the resulting path.
313 |
314 | ```js
315 | grunt.file.isPathInCwd(path1 [, path2 [, ...]])
316 | ```
317 |
318 | ### grunt.file.setBase
319 | Change grunt's current working directory (CWD). By default, all file paths are relative to the `Gruntfile`. This works just like the `--base` command-line option.
320 |
321 | ```js
322 | grunt.file.setBase(path1 [, path2 [, ...]])
323 | ```
324 |
325 | Like the Node.js [path.join](http://nodejs.org/docs/latest/api/path.html#path_path_join_path1_path2) method, this method will join all arguments together and normalize the resulting path.
326 |
327 | ## External libraries
328 | *Deprecated*
329 |
330 | __All external libraries that are listed below are now deprecated.__
331 |
332 | Please use __npm__ to manage these external libraries in your project's dependencies.
333 |
334 | For example if you want use [Lo-Dash](https://npmjs.org/package/lodash), install it first `npm install lodash`, then
335 | use it in your `Gruntfile`: `var _ = require('lodash');`
336 |
337 | ### grunt.file.glob
338 | *Deprecated*
339 |
340 | [glob](https://github.com/isaacs/node-glob) - File globbing utility.
341 |
342 | ### grunt.file.minimatch
343 | *Deprecated*
344 |
345 | [minimatch](https://github.com/isaacs/minimatch) - File pattern matching utility.
346 |
347 | ### grunt.file.findup
348 | *Deprecated*
349 |
350 | [findup-sync](https://github.com/cowboy/node-findup-sync) - Search upwards for matching file patterns.
351 |
--------------------------------------------------------------------------------
/Configuring-tasks.md:
--------------------------------------------------------------------------------
1 | This guide explains how to configure tasks for your project using a `Gruntfile`. If you don't know what a `Gruntfile` is, please read the [[Getting Started]] guide and check out a [[Sample Gruntfile]].
2 |
3 | ## Grunt Configuration
4 | Task configuration is specified in your `Gruntfile` via the `grunt.initConfig` method. This configuration will mostly be under task-named properties, but may contain any arbitrary data. As long as properties don't conflict with properties your tasks require, they will be otherwise ignored.
5 |
6 | Also, because this is JavaScript, you're not limited to JSON; you may use any valid JavaScript here. You may even programmatically generate the configuration if necessary.
7 |
8 | ```js
9 | grunt.initConfig({
10 | concat: {
11 | // concat task configuration goes here.
12 | },
13 | uglify: {
14 | // uglify task configuration goes here.
15 | },
16 | // Arbitrary non-task-specific properties.
17 | my_property: 'whatever',
18 | my_src_files: ['foo/*.js', 'bar/*.js'],
19 | });
20 | ```
21 |
22 | ## Task Configuration and Targets
23 |
24 | When a task is run, Grunt looks for its configuration under a property of the same name. Multi-tasks can have multiple configurations, defined using arbitrarily named "targets." In the example below, the `concat` task has `foo` and `bar` targets, while the `uglify` task only has a `bar` target.
25 |
26 | ```js
27 | grunt.initConfig({
28 | concat: {
29 | foo: {
30 | // concat task "foo" target options and files go here.
31 | },
32 | bar: {
33 | // concat task "bar" target options and files go here.
34 | },
35 | },
36 | uglify: {
37 | bar: {
38 | // uglify task "bar" target options and files go here.
39 | },
40 | },
41 | });
42 | ```
43 | Specifying both a task and target like `grunt concat:foo` or `grunt concat:bar` will process just the specified target's configuration, while running `grunt concat` will iterate over _all_ targets, processing each in turn. Note that if a task has been renamed with [grunt.task.renameTask](grunt.task#grunt.task.renameTask), Grunt will look for a property with the _new_ task name in the config object.
44 |
45 | ## Options
46 | Inside a task configuration, an `options` property may be specified to override built-in defaults. In addition, each target may have an `options` property which is specific to that target. Target-level options will override task-level options.
47 |
48 | The `options` object is optional and may be omitted if not needed.
49 |
50 | ```js
51 | grunt.initConfig({
52 | concat: {
53 | options: {
54 | // Task-level options may go here, overriding task defaults.
55 | },
56 | foo: {
57 | options: {
58 | // "foo" target options may go here, overriding task-level options.
59 | },
60 | },
61 | bar: {
62 | // No options specified; this target will use task-level options.
63 | },
64 | },
65 | });
66 | ```
67 |
68 | ## Files
69 | Because most tasks perform file operations, Grunt has powerful abstractions for declaring on which files the task should operate. There are several ways to define **src-dest** (source-destination) file mappings, offering varying degrees of verbosity and control. Any multi task will understand all the following formats, so choose whichever format best meets your needs.
70 |
71 | All files formats support `src` and `dest` but the "Compact" and "Files Array" formats support a few additional properties:
72 |
73 | * `filter` Either a valid [fs.Stats method name](http://nodejs.org/docs/latest/api/fs.html#fs_class_fs_stats) or a function that is passed the matched `src` filepath and returns `true` or `false`.
74 | * `nonull` If set to `true` then the operation will include non-matching patterns. Combined with grunt's `--verbose` flag, this option can help debug file path issues.
75 | * `dot` Allow patterns to match filenames starting with a period, even if the pattern does not explicitly have a period in that spot.
76 | * `matchBase` If set, patterns without slashes will be matched against the basename of the path if it contains slashes. For example, a?b would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.
77 | * `expand` Process a dynamic src-dest file mapping, see ["Building the files object dynamically"](configuring-tasks#building-the-files-object-dynamically) for more information.
78 | * Other properties will be passed into the underlying libs as matching options. See the [node-glob][] and [minimatch][] documentation for more options.
79 |
80 | ### Compact Format
81 | This form allows a single **src-dest** (source-destination) file mapping per-target. It is most commonly used for read-only tasks, like [grunt-contrib-jshint](https://github.com/gruntjs/grunt-contrib-jshint), where a single `src` property is needed, and no `dest` key is relevant. This format also supports additional properties per src-dest file mapping.
82 |
83 | ```js
84 | grunt.initConfig({
85 | jshint: {
86 | foo: {
87 | src: ['src/aa.js', 'src/aaa.js']
88 | },
89 | },
90 | concat: {
91 | bar: {
92 | src: ['src/bb.js', 'src/bbb.js'],
93 | dest: 'dest/b.js',
94 | },
95 | },
96 | });
97 | ```
98 |
99 | ### Files Object Format
100 | This form supports multiple src-dest mappings per-target, where the property name is the destination file, and its value is the source file(s). Any number of src-dest file mappings may be specified in this way, but additional properties may not be specified per mapping.
101 |
102 | ```js
103 | grunt.initConfig({
104 | concat: {
105 | foo: {
106 | files: {
107 | 'dest/a.js': ['src/aa.js', 'src/aaa.js'],
108 | 'dest/a1.js': ['src/aa1.js', 'src/aaa1.js'],
109 | },
110 | },
111 | bar: {
112 | files: {
113 | 'dest/b.js': ['src/bb.js', 'src/bbb.js'],
114 | 'dest/b1.js': ['src/bb1.js', 'src/bbb1.js'],
115 | },
116 | },
117 | },
118 | });
119 | ```
120 |
121 | ### Files Array Format
122 | This form supports multiple src-dest file mappings per-target, while also allowing additional properties per mapping.
123 |
124 | ```js
125 | grunt.initConfig({
126 | concat: {
127 | foo: {
128 | files: [
129 | {src: ['src/aa.js', 'src/aaa.js'], dest: 'dest/a.js'},
130 | {src: ['src/aa1.js', 'src/aaa1.js'], dest: 'dest/a1.js'},
131 | ],
132 | },
133 | bar: {
134 | files: [
135 | {src: ['src/bb.js', 'src/bbb.js'], dest: 'dest/b/', nonull: true},
136 | {src: ['src/bb1.js', 'src/bbb1.js'], dest: 'dest/b1/', filter: 'isFile'},
137 | ],
138 | },
139 | },
140 | });
141 | ```
142 |
143 | ### Older Formats
144 | The **dest-as-target** file format is a holdover from before multi tasks and targets existed, where the destination filepath is actually the target name. Unfortunately, because target names are filepaths, running `grunt task:target` can be awkward. Also, you can't specify target-level options or additional properties per src-dest file mapping.
145 |
146 | Consider this format deprecated, and avoid it where possible.
147 |
148 | ```js
149 | grunt.initConfig({
150 | concat: {
151 | 'dest/a.js': ['src/aa.js', 'src/aaa.js'],
152 | 'dest/b.js': ['src/bb.js', 'src/bbb.js'],
153 | },
154 | });
155 | ```
156 |
157 | ### Custom Filter Function
158 | The `filter` property can help you target files with a greater level of detail. Simply use a valid [fs.Stats method name](http://nodejs.org/docs/latest/api/fs.html#fs_class_fs_stats). The following will clean only if the pattern matches an actual file:
159 |
160 | ```js
161 | grunt.initConfig({
162 | clean: {
163 | foo: {
164 | src: ['tmp/**/*'],
165 | filter: 'isFile',
166 | },
167 | },
168 | });
169 | ```
170 |
171 | Or create your own `filter` function and return `true` or `false` whether the file should be matched. For example the following will only clean folders that are empty:
172 |
173 | ```js
174 | grunt.initConfig({
175 | clean: {
176 | foo: {
177 | src: ['tmp/**/*'],
178 | filter: function(filepath) {
179 | return (grunt.file.isDir(filepath) && require('fs').readdirSync(filepath).length === 0);
180 | },
181 | },
182 | },
183 | });
184 | ```
185 |
186 | ### Globbing patterns
187 | It is often impractical to specify all source filepaths individually, so Grunt supports filename expansion (also know as globbing) via the built-in [node-glob][] and [minimatch][] libraries.
188 |
189 | [node-glob]: https://github.com/isaacs/node-glob
190 | [minimatch]: https://github.com/isaacs/minimatch
191 |
192 | While this isn't a comprehensive tutorial on globbing patterns, know that in a filepath:
193 |
194 | * `*` matches any number of characters, but not `/`
195 | * `?` matches a single character, but not `/`
196 | * `**` matches any number of characters, including `/`, as long as it's the only thing in a path part
197 | * `{}` allows for a comma-separated list of "or" expressions
198 | * `!` at the beginning of a pattern will negate the match
199 |
200 | All most people need to know is that `foo/*.js` will match all files ending with `.js` in the `foo/` subdirectory, but `foo/**/*.js` will match all files ending with `.js` in the `foo/` subdirectory _and all of its subdirectories_.
201 |
202 | Also, in order to simplify otherwise complicated globbing patterns, Grunt allows arrays of file paths or globbing patterns to be specified. Patterns are processed in-order, with `!`-prefixed matches excluding matched files from the result set. The result set is uniqued.
203 |
204 | For example:
205 |
206 | ```js
207 | // You can specify single files:
208 | {src: 'foo/this.js', dest: ...}
209 | // Or arrays of files:
210 | {src: ['foo/this.js', 'foo/that.js', 'foo/the-other.js'], dest: ...}
211 | // Or you can generalize with a glob pattern:
212 | {src: 'foo/th*.js', dest: ...}
213 |
214 | // This single node-glob pattern:
215 | {src: 'foo/{a,b}*.js', dest: ...}
216 | // Could also be written like this:
217 | {src: ['foo/a*.js', 'foo/b*.js'], dest: ...}
218 |
219 | // All .js files, in foo/, in alpha order:
220 | {src: ['foo/*.js'], dest: ...}
221 | // Here, bar.js is first, followed by the remaining files, in alpha order:
222 | {src: ['foo/bar.js', 'foo/*.js'], dest: ...}
223 |
224 | // All files except for bar.js, in alpha order:
225 | {src: ['foo/*.js', '!foo/bar.js'], dest: ...}
226 | // All files in alpha order, but with bar.js at the end.
227 | {src: ['foo/*.js', '!foo/bar.js', 'foo/bar.js'], dest: ...}
228 |
229 | // Templates may be used in filepaths or glob patterns:
230 | {src: ['src/<%= basename %>.js'], dest: 'build/<%= basename %>.min.js'}
231 | // But they may also reference file lists defined elsewhere in the config:
232 | {src: ['foo/*.js', '<%= jshint.all.src %>'], dest: ...}
233 | ```
234 |
235 | For more on glob pattern syntax, see the [node-glob][] and [minimatch][] documentation.
236 |
237 | ### Building the files object dynamically
238 | When you want to process many individual files, a few additional properties may be used to build a files list dynamically. These properties may be specified in both "Compact" and "Files Array" mapping formats.
239 |
240 | `expand` Set to `true` to enable the following options:
241 |
242 | * `cwd` All `src` matches are relative to (but don't include) this path.
243 | * `src` Pattern(s) to match, relative to the `cwd`.
244 | * `dest` Destination path prefix.
245 | * `ext` Replace any existing extension with this value in generated `dest` paths.
246 | * `extDot` Used to indicate where the period indicating the extension is located. Can take either `'first'` (extension begins after the first period in the file name) or `'last'` (extension begins after the last period), and is set by default to `'first'` *[Added in 0.4.3]*
247 | * `flatten` Remove all path parts from generated `dest` paths.
248 | * `rename` This function is called for each matched `src` file, (after extension renaming and flattening). The `dest`
249 | and matched `src` path are passed in, and this function must return a new `dest` value. If the same `dest` is returned
250 | more than once, each `src` which used it will be added to an array of sources for it.
251 |
252 | In the following example, the `uglify` task will see the same list of src-dest file mappings for both the `static_mappings` and `dynamic_mappings` targets, because Grunt will automatically expand the `dynamic_mappings` files object into 4 individual static src-dest file mappings—assuming 4 files are found—when the task runs.
253 |
254 | Any combination of static src-dest and dynamic src-dest file mappings may be specified.
255 |
256 | ```js
257 | grunt.initConfig({
258 | uglify: {
259 | static_mappings: {
260 | // Because these src-dest file mappings are manually specified, every
261 | // time a new file is added or removed, the Gruntfile has to be updated.
262 | files: [
263 | {src: 'lib/a.js', dest: 'build/a.min.js'},
264 | {src: 'lib/b.js', dest: 'build/b.min.js'},
265 | {src: 'lib/subdir/c.js', dest: 'build/subdir/c.min.js'},
266 | {src: 'lib/subdir/d.js', dest: 'build/subdir/d.min.js'},
267 | ],
268 | },
269 | dynamic_mappings: {
270 | // Grunt will search for "**/*.js" under "lib/" when the "uglify" task
271 | // runs and build the appropriate src-dest file mappings then, so you
272 | // don't need to update the Gruntfile when files are added or removed.
273 | files: [
274 | {
275 | expand: true, // Enable dynamic expansion.
276 | cwd: 'lib/', // Src matches are relative to this path.
277 | src: ['**/*.js'], // Actual pattern(s) to match.
278 | dest: 'build/', // Destination path prefix.
279 | ext: '.min.js', // Dest filepaths will have this extension.
280 | extDot: 'first' // Extensions in filenames begin after the first dot
281 | },
282 | ],
283 | },
284 | },
285 | });
286 | ```
287 |
288 | ## Templates
289 | Templates specified using `<% %>` delimiters will be automatically expanded when tasks read them from the config. Templates are expanded recursively until no more remain.
290 |
291 | The entire config object is the context in which properties are resolved. Additionally, `grunt` and its methods are available inside templates, eg. `<%= grunt.template.today('yyyy-mm-dd') %>`.
292 |
293 | * `<%= prop.subprop %>` Expand to the value of `prop.subprop` in the config, regardless of type. Templates like this can be used to reference not only string values, but also arrays or other objects.
294 | * `<% %>` Execute arbitrary inline JavaScript code. This is useful with control flow or looping.
295 |
296 | Given the sample `concat` task configuration below, running `grunt concat:sample` will generate a file named `build/abcde.js` by concatenating the banner `/* abcde */` with all files matching `foo/*.js` + `bar/*.js` + `baz/*.js`.
297 |
298 | ```js
299 | grunt.initConfig({
300 | concat: {
301 | sample: {
302 | options: {
303 | banner: '/* <%= baz %> */\n', // '/* abcde */\n'
304 | },
305 | src: ['<%= qux %>', 'baz/*.js'], // [['foo/*.js', 'bar/*.js'], 'baz/*.js']
306 | dest: 'build/<%= baz %>.js', // 'build/abcde.js'
307 | },
308 | },
309 | // Arbitrary properties used in task configuration templates.
310 | foo: 'c',
311 | bar: 'b<%= foo %>d', // 'bcd'
312 | baz: 'a<%= bar %>e', // 'abcde'
313 | qux: ['foo/*.js', 'bar/*.js'],
314 | });
315 | ```
316 |
317 | ## Importing External Data
318 | In the following Gruntfile, project metadata is imported into the Grunt config from a `package.json` file, and the [grunt-contrib-uglify plugin](http://github.com/gruntjs/grunt-contrib-uglify) `uglify` task is configured to minify a source file and generate a banner comment dynamically using that metadata.
319 |
320 | Grunt has `grunt.file.readJSON` and `grunt.file.readYAML` methods for importing JSON and YAML data.
321 |
322 | ```js
323 | grunt.initConfig({
324 | pkg: grunt.file.readJSON('package.json'),
325 | uglify: {
326 | options: {
327 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
328 | },
329 | dist: {
330 | src: 'src/<%= pkg.name %>.js',
331 | dest: 'dist/<%= pkg.name %>.min.js'
332 | }
333 | }
334 | });
335 | ```
336 |
--------------------------------------------------------------------------------
/Project-Scaffolding.md:
--------------------------------------------------------------------------------
1 | ## grunt-init
2 | Grunt-init is a scaffolding tool used to automate project creation. It will build an entire directory structure based on current environment and answers to some questions. The exact files and contents created depend on the template chosen along with the answers to the questions asked.
3 |
4 | _Note: This standalone utility used to be built-in to Grunt as the "init" task. See the Grunt [Upgrading from 0.3 to 0.4](http://gruntjs.com/upgrading-from-0.3-to-0.4) guide for more information about this change._
5 |
6 | ## Installation
7 | In order to use grunt-init, you'll want to install it globally.
8 |
9 | ```shell
10 | npm install -g grunt-init
11 | ```
12 |
13 | This will put the `grunt-init` command in your system path, allowing it to be run from anywhere.
14 |
15 | _Notes: You may need to use sudo or run your command shell as Administrator to do this._
16 |
17 | ## Usage
18 | * Get program help and a listing of available templates with `grunt-init --help`
19 | * Create a project based around an available template with `grunt-init TEMPLATE`
20 | * Create a project based around a arbitrarily-located template with `grunt-init /path/to/TEMPLATE`
21 |
22 | Note that most templates generate their files in the current directory, so be sure to change to a new directory first if you don't want to overwrite existing files.
23 |
24 | ## Installing templates
25 | Once templates are installed into your `~/.grunt-init/` directory (`%USERPROFILE%\.grunt-init\` on Windows) they will be available for use via grunt-init. It's recommended that you use git to clone a template into that directory. For example, the [grunt-init-jquery](https://github.com/gruntjs/grunt-init-jquery) template can be installed like so:
26 |
27 | ```
28 | git clone https://github.com/gruntjs/grunt-init-jquery.git ~/.grunt-init/jquery
29 | ```
30 |
31 | _Note: if you want to make the template available locally as "foobarbaz" you could specify `~/.grunt-init/foobarbaz` while cloning. Grunt-init will use the actual template directory name as it exists inside of the `~/.grunt-init/` directory._
32 |
33 | A few grunt-init templates are maintained officially:
34 |
35 | * [grunt-init-commonjs](https://github.com/gruntjs/grunt-init-commonjs) - Create a commonjs module, including Nodeunit unit tests. ([sample "generated" repo](https://github.com/gruntjs/grunt-init-commonjs-sample/tree/generated) | [creation transcript](https://github.com/gruntjs/grunt-init-commonjs-sample#project-creation-transcript))
36 | * [grunt-init-gruntfile](https://github.com/gruntjs/grunt-init-gruntfile) - Create a basic Gruntfile. ([sample "generated" repo](https://github.com/gruntjs/grunt-init-gruntfile-sample/tree/generated) | [creation transcript](https://github.com/gruntjs/grunt-init-gruntfile-sample#project-creation-transcript))
37 | * [grunt-init-gruntplugin](https://github.com/gruntjs/grunt-init-gruntplugin) - Create a Grunt plugin, including Nodeunit unit tests. ([sample "generated" repo](https://github.com/gruntjs/grunt-init-gruntplugin-sample/tree/generated) | [creation transcript](https://github.com/gruntjs/grunt-init-gruntplugin-sample#project-creation-transcript))
38 | * [grunt-init-jquery](https://github.com/gruntjs/grunt-init-jquery) - Create a jQuery plugin, including QUnit unit tests. ([sample "generated" repo](https://github.com/gruntjs/grunt-init-jquery-sample/tree/generated) | [creation transcript](https://github.com/gruntjs/grunt-init-jquery-sample#project-creation-transcript))
39 | * [grunt-init-node](https://github.com/gruntjs/grunt-init-node) - Create a Node.js module, including Nodeunit unit tests. ([sample "generated" repo](https://github.com/gruntjs/grunt-init-node-sample/tree/generated) | [creation transcript](https://github.com/gruntjs/grunt-init-node-sample#project-creation-transcript))
40 |
41 | ## Custom templates
42 | You can create and use custom templates. Your template must follow the same structure as the aforementioned templates.
43 |
44 | A sample template named `my-template` would follow this general file structure:
45 |
46 | * `my-template/template.js` - the main template file.
47 | * `my-template/rename.json` - template-specific rename rules, processed as templates.
48 | * `my-template/root/` - files to be copied into the target location.
49 |
50 | Assuming these files exist at `/path/to/my-template`, the command `grunt-init /path/to/my-template` would be used to process the template. Multiple uniquely-named templates may exist in the same directory.
51 |
52 | Additionally, if you place this custom template in your `~/.grunt-init/` directory (`%USERPROFILE%\.grunt-init\` on Windows) it will be automatically available to be used with just `grunt-init my-template`.
53 |
54 | ### Copying files
55 | As long as a template uses the `init.filesToCopy` and `init.copyAndProcess` methods, any files in the `root/` subdirectory will be copied to the current directory when the init template is run.
56 |
57 | Note that all copied files will be processed as templates, with any `{% %}` template being processed against the collected `props` data object, unless the `noProcess` option is set. See the [jquery template](https://github.com/gruntjs/grunt-init-jquery) for an example.
58 |
59 | ### Renaming or excluding template files
60 | The `rename.json` describes `sourcepath` to `destpath` rename mappings. The `sourcepath` must be the path of the file-to-be-copied relative to the `root/` folder, but the `destpath` value can contain `{% %}` templates, describing what the destination path will be.
61 |
62 | If `false` is specified as a `destpath` the file will not be copied. Also, glob patterns are supported for `srcpath`.
63 |
64 | ## Specifying default prompt answers
65 | Each init prompt either has a default value hard-coded or it looks at the current environment to attempt to determine that default value. If you want to override a particular prompt's default value, you can do so in the optional OS X or Linux `~/.grunt-init/defaults.json` or Windows `%USERPROFILE%\.grunt-init\defaults.json` file.
66 |
67 | For example, my `defaults.json` file looks like this, because I want to use a slightly different name than the default name, I want to exclude my email address, and I want to specify an author url automatically.
68 |
69 | ```json
70 | {
71 | "author_name": "\"Cowboy\" Ben Alman",
72 | "author_email": "none",
73 | "author_url": "http://benalman.com/"
74 | }
75 | ```
76 |
77 | _Note: until all the built-in prompts have been documented, you can find their names and default values in the [source code](https://github.com/gruntjs/grunt-init/blob/master/tasks/init.js)._
78 |
79 | ## Defining an init template
80 |
81 | ### exports.description
82 | This brief template description will be displayed along with the template name when the user runs `grunt init` or `grunt-init ` to display a list of all available init templates.
83 |
84 | ```js
85 | exports.description = descriptionString;
86 | ```
87 |
88 | ### exports.notes
89 | If specified, this optional extended description will be displayed before any prompts are displayed. This is a good place to give the user a little help explaining naming conventions, which prompts may be required or optional, etc.
90 |
91 | ```js
92 | exports.notes = notesString;
93 | ```
94 |
95 | ### exports.warnOn
96 | If this optional (but recommended) wildcard pattern or array of wildcard patterns is matched, Grunt will abort with a warning that the user can override with `--force`. This is very useful in cases where the init template could potentially override existing files.
97 |
98 | ```js
99 | exports.warnOn = wildcardPattern;
100 | ```
101 |
102 | While the most common value will be `'*'`, matching any file or directory, the [minimatch](https://github.com/isaacs/minimatch) wildcard pattern syntax used allows for a lot of flexibility. For example:
103 |
104 | ```js
105 | exports.warnOn = 'Gruntfile.js'; // Warn on a Gruntfile.js file.
106 | exports.warnOn = '*.js'; // Warn on any .js file.
107 | exports.warnOn = '*'; // Warn on any non-dotfile or non-dotdir.
108 | exports.warnOn = '.*'; // Warn on any dotfile or dotdir.
109 | exports.warnOn = '{.*,*}'; // Warn on any file or dir (dot or non-dot).
110 | exports.warnOn = '!*/**'; // Warn on any file (ignoring dirs).
111 | exports.warnOn = '*.{png,gif,jpg}'; // Warn on any image file.
112 |
113 | // This is another way of writing the last example.
114 | exports.warnOn = ['*.png', '*.gif', '*.jpg'];
115 | ```
116 |
117 | ### exports.template
118 | While the `exports` properties are defined outside this function, all the actual init code is specified inside. Three arguments are passed into this function. The `grunt` argument is a reference to grunt, containing all the [grunt methods and libs](api/grunt). The `init` argument is an object containing methods and properties specific to this init template. The `done` argument is a function that must be called when the init template is done executing.
119 |
120 | ```js
121 | exports.template = function(grunt, init, done) {
122 | // See the "Inside an init template" section.
123 | };
124 | ```
125 |
126 | ## Inside an init template
127 |
128 | ### init.addLicenseFiles
129 | Add properly-named license files to the files object.
130 |
131 | ```js
132 | var files = {};
133 | var licenses = ['MIT'];
134 | init.addLicenseFiles(files, licenses);
135 | // files === {'LICENSE-MIT': 'licenses/LICENSE-MIT'}
136 | ```
137 |
138 | ### init.availableLicenses
139 | Return an array of available licenses.
140 |
141 | ```js
142 | var licenses = init.availableLicenses();
143 | // licenses === [ 'Apache-2.0', 'GPL-2.0', 'MIT', 'MPL-2.0' ]
144 | ```
145 |
146 | ### init.copy
147 | Given an absolute or relative source path, and an optional relative
148 | destination path, copy a file, optionally processing it through the
149 | passed callback.
150 |
151 | ```js
152 | init.copy(srcpath[, destpath], options)
153 | ```
154 |
155 | ### init.copyAndProcess
156 | Iterate over all files in the passed object, copying the source file to
157 | the destination, processing the contents.
158 |
159 | ```js
160 | init.copyAndProcess(files, props[, options])
161 | ```
162 |
163 | ### init.defaults
164 | User-specified default init values from `defaults.json`.
165 |
166 | ```js
167 | init.defaults
168 | ```
169 |
170 | ### init.destpath
171 | Absolute destination file path.
172 |
173 | ```js
174 | init.destpath()
175 | ```
176 |
177 | ### init.expand
178 | Same as [grunt.file.expand](https://github.com/gruntjs/grunt/wiki/grunt.file#wiki-grunt-file-expand).
179 |
180 | Return a unique array of all file or directory paths that match the given wildcard pattern(s). This method accepts either comma separated wildcard patterns or an array of wildcard patterns. Paths matching patterns that begin with ! will be excluded from the returned array. Patterns are processed in order, so inclusion and exclusion order is significant.
181 |
182 | ```js
183 | init.expand([options, ] patterns)
184 | ```
185 |
186 | ### init.filesToCopy
187 | Return an object containing files to copy with their absolute source path and relative destination path, renamed (or omitted) according to rules in rename.json (if it exists).
188 |
189 | ```js
190 | var files = init.filesToCopy(props);
191 | /* files === { '.gitignore': 'template/root/.gitignore',
192 | '.jshintrc': 'template/root/.jshintrc',
193 | 'Gruntfile.js': 'template/root/Gruntfile.js',
194 | 'README.md': 'template/root/README.md',
195 | 'test/test_test.js': 'template/root/test/name_test.js' } */
196 | ```
197 |
198 | ### init.getFile
199 | Get a single task file path.
200 |
201 | ```js
202 | init.getFile(filepath[, ...])
203 | ```
204 |
205 | ### init.getTemplates
206 | Returns an object of all the available templates.
207 |
208 | ```js
209 | init.getTemplates()
210 | ```
211 |
212 | ### init.initSearchDirs
213 | Initialize the directories to search for init templates. `template` is the
214 | location of a template. Will also include `~/.grunt-init/` and the core init
215 | tasks within grunt-init.
216 |
217 | ```js
218 | init.initSearchDirs([filename])
219 | ```
220 |
221 | ### init.process
222 | Start up the process to begin prompting for input.
223 |
224 | ```js
225 | init.process(options, prompts, done)
226 | ```
227 |
228 | ```js
229 | init.process({}, [
230 | // Prompt for these values
231 | init.prompt('name'),
232 | init.prompt('description'),
233 | init.prompt('version')
234 | ], function(err, props) {
235 | // All finished, do something with the properties
236 | });
237 | ```
238 |
239 | ### init.prompt
240 | Prompt a user for a value.
241 |
242 | ```js
243 | init.prompt(name[, default])
244 | ```
245 |
246 | ### init.prompts
247 | An object of all the prompts.
248 |
249 | ```js
250 | var prompts = init.prompts;
251 | ```
252 |
253 | ### init.readDefaults
254 | Read JSON defaults from task files (if they exist), merging them into one data object.
255 |
256 | ```js
257 | init.readDefaults(filepath[, ...])
258 | ```
259 |
260 | ### init.renames
261 | The rename rules for the template.
262 |
263 | ```js
264 | var renames = init.renames;
265 | // renames === { 'test/name_test.js': 'test/{%= name %}_test.js' }
266 | ```
267 |
268 | ### init.searchDirs
269 | An array of directories to search for templates in.
270 |
271 | ```js
272 | var dirs = init.searchDirs;
273 | /* dirs === [ '/Users/shama/.grunt-init',
274 | '/usr/local/lib/node_modules/grunt-init/templates' ] */
275 | ```
276 |
277 | ### init.srcpath
278 | Search init template paths for filename and return an absolute path.
279 |
280 | ```js
281 | init.srcpath(filepath[, ...])
282 | ```
283 |
284 | ### init.userDir
285 | Returns the absolute path to the user's template directory.
286 |
287 | ```js
288 | var dir = init.userDir();
289 | // dir === '/Users/shama/.grunt-init'
290 | ```
291 |
292 | ### init.writePackageJSON
293 | Save a package.json file in the destination directory. The callback can be used to post-process properties to add/remove/whatever.
294 |
295 | ```js
296 | init.writePackageJSON(filename, props[, callback])
297 | ```
298 |
299 | ## Built-in prompts
300 |
301 | ### author_email
302 | Author's email address to use in the `package.json`. Will attempt to find a default value from the user's git config.
303 |
304 | ### author_name
305 | Author's full name to use in the `package.json` and copyright notices. Will attempt to find a default value from the user's git config.
306 |
307 | ### author_url
308 | A public URL to the author's website to use in the `package.json`.
309 |
310 | ### bin
311 | A relative path from the project root for a cli script.
312 |
313 | ### bugs
314 | A public URL to the project's issues tracker. Will default to the github issue tracker if the project has a github repository.
315 |
316 | ### description
317 | A description of the project. Used in the `package.json` and README files.
318 |
319 | ### grunt_version
320 | A valid semantic version range descriptor of Grunt the project requires.
321 |
322 | ### homepage
323 | A public URL to the project's home page. Will default to the github url if a github repository.
324 |
325 | ### jquery_version
326 | If a jQuery project, the version of jQuery the project requires. Must be a valid semantic version range descriptor.
327 |
328 | ### licenses
329 | The license(s) for the project. Multiple licenses are separated by spaces. The licenses built-in are: `MIT`, `MPL-2.0`, `GPL-2.0`, and `Apache-2.0`. Defaults to `MIT`. Add custom licenses with [init.addLicenseFiles](#initaddlicensefiles).
330 |
331 | ### main
332 | The primary entry point of the project. Defaults to the project name within the `lib` folder.
333 |
334 | ### name
335 | The name of the project. Will be used heavily throughout the project template. Defaults to the current working directory.
336 |
337 | ### node_version
338 | The version of Node.js the project requires. Must be a valid semantic version range descriptor.
339 |
340 | ### npm_test
341 | The command to run tests on your project. Defaults to `grunt`.
342 |
343 | ### repository
344 | Project's git repository. Defaults to a guess of a github url.
345 |
346 | ### title
347 | A human readable project name. Defaults to the actual project name altered to be more human readable.
348 |
349 | ### version
350 | The version of the project. Defaults to the first valid semantic version, `0.1.0`.
351 |
--------------------------------------------------------------------------------