diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..e717f5e
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,13 @@
+# http://editorconfig.org
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..176a458
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+* text=auto
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..31226a4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+node_modules/
+temp/
diff --git a/.jshintrc b/.jshintrc
new file mode 100644
index 0000000..3368b22
--- /dev/null
+++ b/.jshintrc
@@ -0,0 +1,22 @@
+{
+ "node": true,
+ "es5": true,
+ "esnext": true,
+ "bitwise": true,
+ "camelcase": true,
+ "curly": true,
+ "eqeqeq": true,
+ "immed": true,
+ "indent": 2,
+ "latedef": true,
+ "newcap": true,
+ "noarg": true,
+ "quotmark": "single",
+ "regexp": true,
+ "undef": true,
+ "unused": true,
+ "strict": true,
+ "trailing": true,
+ "smarttabs": true,
+ "white": true
+}
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..2cdacaf
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,4 @@
+language: node_js
+node_js:
+ - '0.10'
+ - '0.8'
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..281e7fd
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright 2013
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
index f2eb641..506ade9 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,34 @@
-generator-node
-==============
+# Node Generator [](https://travis-ci.org/yeoman/generator-node)
-Create a Node.js module with yo, including Nodeunit unit tests.
+> Create a node.js module with [Yeoman][], including nodeunit unit tests.
+
+This generator is based of
+[grunt-init-node](https://github.com/gruntjs/grunt-init-node), authored by the
+magnificient GruntJS team.
+
+Maintained by [Pascal Hartig](https://github.com/passy).
+
+[Yeoman]: http://yeoman.io/
+
+
+## Installation
+
+If you haven't already done so, install [Yeoman][].
+
+Once Yeoman is installed, install this generator via `npm install -g generator-node`.
+
+
+## Usage
+
+At the command-line, cd into an empty directory, run this command and follow the prompts.
+
+```
+yo node
+```
+
+_Note that this template will generate files in the current directory, so be sure to change to a new directory first if you don't want to overwrite existing files._
+
+
+## License
+
+[MIT License](http://en.wikipedia.org/wiki/MIT_License)
diff --git a/app/index.js b/app/index.js
new file mode 100644
index 0000000..37d9c4b
--- /dev/null
+++ b/app/index.js
@@ -0,0 +1,146 @@
+'use strict';
+
+var util = require('util');
+var path = require('path');
+var yeoman = require('yeoman-generator');
+
+var NodeGenerator = module.exports = function NodeGenerator(args, options) {
+ yeoman.generators.Base.apply(this, arguments);
+
+ this.on('end', function () {
+ this.installDependencies({
+ bower: false,
+ skipInstall: options['skip-install']
+ });
+ });
+
+ this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json')));
+};
+util.inherits(NodeGenerator, yeoman.generators.NamedBase);
+
+NodeGenerator.prototype.askFor = function askFor() {
+ var cb = this.async();
+
+ // welcome message
+ var welcome =
+ '\n _-----_' +
+ '\n | |' +
+ '\n |' + '--(o)--'.red + '| .--------------------------.' +
+ '\n `---------´ | ' + 'Welcome to Yeoman,'.yellow.bold + ' |' +
+ '\n ' + '( '.yellow + '_' + '´U`'.yellow + '_' + ' )'.yellow + ' | ' + 'ladies and gentlemen!'.yellow.bold + ' |' +
+ '\n /___A___\\ \'__________________________\'' +
+ '\n | ~ |'.yellow +
+ '\n __' + '\'.___.\''.yellow + '__' +
+ '\n ´ ' + '` |'.red + '° ' + '´ Y'.red + ' `\n' +
+ '\n' +
+ '_Project name_ shouldn\'t contain "node" or "js" and should ' +
+ 'be a unique ID not already in use at search.npmjs.org.' +
+ '\n\n' +
+ 'You should now install project dependencies with _npm ' +
+ 'install_. After that, you may execute project tasks with _grunt_. For ' +
+ 'more information about installing and configuring Grunt, please see ' +
+ 'the Getting Started guide:' +
+ '\n\n' +
+ 'http://gruntjs.com/getting-started';
+
+ console.log(welcome);
+
+ var prompts = [{
+ name: 'name',
+ message: 'Project Name:',
+ // TODO: default to folder name
+ }, {
+ name: 'description',
+ default: 'The best project ever.'
+ }, {
+ name: 'version',
+ default: '0.1.0'
+ }, {
+ name: 'repository',
+ message: 'Project git repository'
+ // TODO: Default to git://github.com/[username]/[projectname].git
+ }, {
+ name: 'homepage',
+ message: 'Project homepage'
+ // TODO: Default to https://github.com/[username]/[projectname]
+ }, {
+ name: 'bugs',
+ message: 'Project issues tracker'
+ // TODO: Default to https://github.com/[username]/[projectname]/issues
+ }, {
+ name: 'license',
+ default: 'MIT'
+ }, {
+ name: 'author_name',
+ // TODO: Default to Name
+ }, {
+ name: 'author_email',
+ // TODO: Default to Email
+ }, {
+ name: 'author_url',
+ // TODO: Default to homepage
+ }, {
+ name: 'node_version',
+ message: 'What versions of node does it run on?',
+ default: '>= 0.10.0'
+ }, {
+ name: 'main',
+ message: 'Main module entry point:',
+ default: 'lib/',
+ // TODO: default to project name
+ }, {
+ name: 'npm_test',
+ message: 'npm test command:',
+ default: 'grunt nodeunit',
+ }, {
+ name: 'travis',
+ message: 'Will this project be tested with Travis CI?'
+ }];
+
+ var nameToMessage = function (name) {
+ return name.split('_').map(
+ function (x) { return this._.capitalize(x); }.bind(this)
+ ).join(' ') + ':';
+ }.bind(this);
+
+ // Generate prompt messages if only the name is defined.
+ prompts.map(function (entry) {
+ if (entry.message === undefined) {
+ entry.message = nameToMessage(entry.name);
+ }
+ return entry;
+ });
+
+ this.currentYear = (new Date()).getFullYear();
+
+ this.prompt(prompts, function (err, props) {
+ if (err) {
+ return this.emit('error', err);
+ }
+
+ this.props = props;
+ // For easier access in the templates.
+ this.slugname = this._.slugify(props.name);
+ cb();
+ }.bind(this));
+};
+
+NodeGenerator.prototype.lib = function lib() {
+ this.mkdir('lib');
+ this.template('lib/name.js', 'lib/' + this.slugname + '.js');
+};
+
+NodeGenerator.prototype.test = function test() {
+ this.mkdir('test');
+ this.template('test/name_test.js', 'test/' + this.slugname + '_test.js');
+};
+
+NodeGenerator.prototype.projectfiles = function projectfiles() {
+ this.copy('jshintrc', '.jshintrc');
+ this.copy('gitignore', '.gitignore');
+ this.copy('travis.yml', '.travis.yml');
+
+ this.template('README.md');
+ this.template('Gruntfile.js');
+ this.template('_package.json', 'package.json');
+};
diff --git a/app/templates/Gruntfile.js b/app/templates/Gruntfile.js
new file mode 100644
index 0000000..b2cce2b
--- /dev/null
+++ b/app/templates/Gruntfile.js
@@ -0,0 +1,48 @@
+'use strict';
+
+module.exports = function(grunt) {
+
+ // Project configuration.
+ grunt.initConfig({
+ nodeunit: {
+ files: ['test/**/*_test.js'],
+ },
+ jshint: {
+ options: {
+ jshintrc: '.jshintrc'
+ },
+ gruntfile: {
+ src: 'Gruntfile.js'
+ },
+ lib: {
+ src: ['lib/**/*.js']
+ },
+ test: {
+ src: ['test/**/*.js']
+ },
+ },
+ watch: {
+ gruntfile: {
+ files: '<%%= jshint.gruntfile.src %>',
+ tasks: ['jshint:gruntfile']
+ },
+ lib: {
+ files: '<%%= jshint.lib.src %>',
+ tasks: ['jshint:lib', 'nodeunit']
+ },
+ test: {
+ files: '<%%= jshint.test.src %>',
+ tasks: ['jshint:test', 'nodeunit']
+ },
+ },
+ });
+
+ // These plugins provide necessary tasks.
+ grunt.loadNpmTasks('grunt-contrib-nodeunit');
+ grunt.loadNpmTasks('grunt-contrib-jshint');
+ grunt.loadNpmTasks('grunt-contrib-watch');
+
+ // Default task.
+ grunt.registerTask('default', ['jshint', 'nodeunit']);
+
+};
diff --git a/app/templates/README.md b/app/templates/README.md
new file mode 100644
index 0000000..efdb10f
--- /dev/null
+++ b/app/templates/README.md
@@ -0,0 +1,31 @@
+# <%= props.title || props.name %>
+
+<%= props.description %>
+
+## Getting Started
+
+Download the [production version][min] or the [development version][max].
+
+[min]: https://raw.github.com/<%= props.github_username %>/jquery-<%= slugname %>/master/dist/jquery.<%= slugname %>.min.js
+[max]: https://raw.github.com/<%= props.github_username %>/jquery-<%= slugname %>/master/dist/jquery.<%= slugname %>.js
+
+In your web page:
+
+```html
+
+
+
+```
+
+## Documentation
+_(Coming soon)_
+
+## Examples
+_(Coming soon)_
+
+## Release History
+_(Nothing yet)_
diff --git a/app/templates/_package.json b/app/templates/_package.json
new file mode 100644
index 0000000..9a03da2
--- /dev/null
+++ b/app/templates/_package.json
@@ -0,0 +1,33 @@
+{
+ "name": "<%= slugname %>",
+ "version": "<%= props.version %>",
+ "description": "<%= props.title %>",
+ "keywords": [
+ ],
+ "homepage": "https://github.com/<%= props.github_username %>/<%= slugname %>",
+ <% if (props.bugs) { %>
+ "bugs": "<%= props.bugs %>",
+ <% } %>
+ "author": {
+ "name": "<%= props.author_name %>",
+ "email": "<%= props.author_email %>",
+ "url": "https://github.com/<%= props.github_username %>"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/<%= props.github_username %>/<%= slugname %>.git"
+ },
+ "licenses": [
+ {
+ "type": "<%= props.license %>"
+ }
+ ],
+ "devDependencies": {
+ "grunt-contrib-jshint": "~0.1.1",
+ "grunt-contrib-qunit": "~0.1.1",
+ "grunt-contrib-concat": "~0.1.2",
+ "grunt-contrib-uglify": "~0.1.1",
+ "grunt-contrib-watch": "~0.2.0",
+ "grunt-contrib-clean": "~0.4.0"
+ }
+}
diff --git a/app/templates/gitignore b/app/templates/gitignore
new file mode 100644
index 0000000..2ccbe46
--- /dev/null
+++ b/app/templates/gitignore
@@ -0,0 +1 @@
+/node_modules/
diff --git a/app/templates/jshintrc b/app/templates/jshintrc
new file mode 100644
index 0000000..2c40c44
--- /dev/null
+++ b/app/templates/jshintrc
@@ -0,0 +1,15 @@
+{
+ "curly": true,
+ "eqeqeq": true,
+ "immed": true,
+ "latedef": true,
+ "newcap": true,
+ "noarg": true,
+ "sub": true,
+ "undef": true,
+ "unused": true,
+ "boss": true,
+ "eqnull": true,
+ "node": true,
+ "es5": true
+}
diff --git a/app/templates/lib/name.js b/app/templates/lib/name.js
new file mode 100644
index 0000000..5fcd5e0
--- /dev/null
+++ b/app/templates/lib/name.js
@@ -0,0 +1,13 @@
+/*
+ * <%= props.name %>
+ * <%= props.homepage %>
+ *
+ * Copyright (c) <%= currentYear %> <%= props.author_name %>
+ * Licensed under the <%= props.license %> license.
+ */
+
+'use strict';
+
+exports.awesome = function() {
+ return 'awesome';
+};
diff --git a/app/templates/test/name_test.js b/app/templates/test/name_test.js
new file mode 100644
index 0000000..aa4126d
--- /dev/null
+++ b/app/templates/test/name_test.js
@@ -0,0 +1,36 @@
+'use strict';
+
+var <%= props.slugname %> = require('../lib/<%= props.slugname %>.js');
+
+/*
+ ======== A Handy Little Nodeunit Reference ========
+ https://github.com/caolan/nodeunit
+
+ Test methods:
+ test.expect(numAssertions)
+ test.done()
+ Test assertions:
+ test.ok(value, [message])
+ test.equal(actual, expected, [message])
+ test.notEqual(actual, expected, [message])
+ test.deepEqual(actual, expected, [message])
+ test.notDeepEqual(actual, expected, [message])
+ test.strictEqual(actual, expected, [message])
+ test.notStrictEqual(actual, expected, [message])
+ test.throws(block, [error], [message])
+ test.doesNotThrow(block, [error], [message])
+ test.ifError(value)
+*/
+
+exports.<%= props.slugname %> = {
+ setUp: function(done) {
+ // setup here
+ done();
+ },
+ 'no args': function(test) {
+ test.expect(1);
+ // tests here
+ test.equal(<%= props.slugname %>.awesome(), 'awesome', 'should be awesome.');
+ test.done();
+ },
+};
diff --git a/app/templates/travis.yml b/app/templates/travis.yml
new file mode 100644
index 0000000..2cdacaf
--- /dev/null
+++ b/app/templates/travis.yml
@@ -0,0 +1,4 @@
+language: node_js
+node_js:
+ - '0.10'
+ - '0.8'
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..b307ba0
--- /dev/null
+++ b/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "generator-node",
+ "version": "0.0.0",
+ "description": "A node generator for Yeoman",
+ "keywords": [
+ "yeoman-generator",
+ "scaffold",
+ "node"
+ ],
+ "homepage": "https://github.com/yeoman/generator-node",
+ "bugs": "https://github.com/yeoman/generator-node/issues",
+ "author": {
+ "name": "Pascal Hartig",
+ "email": "phartig@rdrei.net",
+ "url": "https://github.com/passy"
+ },
+ "main": "app/index.js",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/yeoman/generator-node.git"
+ },
+ "scripts": {
+ "test": "mocha"
+ },
+ "dependencies": {
+ "yeoman-generator": "~0.10.5"
+ },
+ "devDependencies": {
+ "mocha": "~1.9.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ },
+ "licenses": [
+ {
+ "type": "MIT"
+ }
+ ]
+}
diff --git a/test/test-creation.js b/test/test-creation.js
new file mode 100644
index 0000000..22c0834
--- /dev/null
+++ b/test/test-creation.js
@@ -0,0 +1,48 @@
+/*global describe, beforeEach, it*/
+'use strict';
+
+var path = require('path');
+var helpers = require('yeoman-generator').test;
+
+describe('node generator', function () {
+ beforeEach(function (done) {
+ helpers.testDirectory(path.join(__dirname, 'temp'), function (err) {
+ if (err) {
+ return done(err);
+ }
+
+ this.app = helpers.createGenerator('node:app', [
+ '../../app'
+ ]);
+ this.app.options['skip-install'] = true;
+ done();
+ }.bind(this));
+ });
+
+ it('creates expected files', function (done) {
+ var expected = [
+ '.jshintrc',
+ 'lib/mymodule.js',
+ 'test/mymodule_test.js',
+ ['package.json', /"name": "mymodule"/],
+ ];
+
+ helpers.mockPrompt(this.app, {
+ 'name': 'mymodule',
+ 'description': 'awesome module',
+ 'version': '0.1.0',
+ 'repository': 'http://github.com',
+ 'bugs': 'http://jira.com',
+ 'license': 'MIT',
+ 'github_username': 'octocat',
+ 'author_name': 'Octo Cat',
+ 'author_email': 'octo@example.com',
+ 'node_version': '~0.10.5'
+ });
+
+ this.app.run({}, function () {
+ helpers.assertFiles(expected);
+ done();
+ });
+ });
+});
diff --git a/test/test-load.js b/test/test-load.js
new file mode 100644
index 0000000..9549863
--- /dev/null
+++ b/test/test-load.js
@@ -0,0 +1,10 @@
+/*global describe, beforeEach, it*/
+'use strict';
+var assert = require('assert');
+
+describe('node generator', function () {
+ it('can be imported without blowing up', function () {
+ var app = require('../app');
+ assert(app !== undefined);
+ });
+});