From 6b428b194b62f1c6555ccb1de218ff13af59a1b9 Mon Sep 17 00:00:00 2001 From: Kyle Robinson Young Date: Wed, 15 May 2013 21:44:14 -0700 Subject: [PATCH] Copy over grunt-init-node basic template --- .editorconfig | 13 +++ .gitattributes | 1 + .gitignore | 2 + .jshintrc | 22 +++++ .travis.yml | 4 + LICENSE | 20 +++++ README.md | 36 +++++++- app/index.js | 146 ++++++++++++++++++++++++++++++++ app/templates/Gruntfile.js | 48 +++++++++++ app/templates/README.md | 31 +++++++ app/templates/_package.json | 33 ++++++++ app/templates/gitignore | 1 + app/templates/jshintrc | 15 ++++ app/templates/lib/name.js | 13 +++ app/templates/test/name_test.js | 36 ++++++++ app/templates/travis.yml | 4 + package.json | 39 +++++++++ test/test-creation.js | 48 +++++++++++ test/test-load.js | 10 +++ 19 files changed, 519 insertions(+), 3 deletions(-) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .jshintrc create mode 100644 .travis.yml create mode 100644 LICENSE create mode 100644 app/index.js create mode 100644 app/templates/Gruntfile.js create mode 100644 app/templates/README.md create mode 100644 app/templates/_package.json create mode 100644 app/templates/gitignore create mode 100644 app/templates/jshintrc create mode 100644 app/templates/lib/name.js create mode 100644 app/templates/test/name_test.js create mode 100644 app/templates/travis.yml create mode 100644 package.json create mode 100644 test/test-creation.js create mode 100644 test/test-load.js 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 [![Build Status](https://secure.travis-ci.org/yeoman/generator-node.png?branch=master)](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); + }); +});