Skip to content

Commit eb344e2

Browse files
committed
Create package.json and jshint config only if they do not exist
Update grunt module functions to file-utils module functions Fix package.json empty name property
1 parent d94ab9e commit eb344e2

File tree

4 files changed

+137
-71
lines changed

4 files changed

+137
-71
lines changed

app/index.js

+45-37
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,48 @@
11
'use strict';
2-
var grunt = require('grunt');
32
var yeoman = require('yeoman-generator');
43

54
var GruntfileGenerator = yeoman.generators.Base.extend({
65
initializing: function () {
76
this.pkg = require('../package.json');
7+
8+
// Check if package.json or jshint config exist
9+
// to determine if they should be created later
10+
if (this.dest.exists('package.json')) {
11+
this.packageJSON = this.dest.readJSON('package.json');
12+
this.appname = this.packageJSON.name || this.appname;
13+
this.hasJshint = this.packageJSON.hasOwnProperty('jshintConfig') || this.dest.exists('.jshintrc');
14+
} else {
15+
this.hasJshint = this.dest.exists('.jshintrc');
16+
}
17+
18+
function prefer(arr, preferred) {
19+
for (var i = 0; i < preferred.length; ++i) {
20+
if (arr.indexOf(preferred[i]) !== -1) {
21+
return preferred[i];
22+
}
23+
}
24+
return preferred[0];
25+
}
26+
27+
var dirs = this.dest.expand({ filter: 'isDirectory' }, '*').map(function (d) {
28+
return d.slice(0, -1);
29+
});
30+
31+
this.jquery = this.dest.expand({ filter: 'isFile' }, '**/jquery*.js').length > 0;
32+
this.libDir = prefer(dirs, ['lib', 'src']);
33+
this.testDir = prefer(dirs, ['test', 'tests', 'unit', 'spec']);
834
},
935

1036
prompting: function () {
1137
var done = this.async();
1238

13-
this.log(this.yeoman);
14-
this.log('This template tries to guess file and directory paths, but ' +
15-
'you will most likely need to edit the generated Gruntfile.js file before ' +
16-
'running grunt. _If you run grunt after generating the Gruntfile, and ' +
17-
'it exits with errors, edit the file!_');
18-
39+
if (!this.options['skip-install-message']) {
40+
this.log(this.yeoman);
41+
this.log('This template tries to guess file and directory paths, but ' +
42+
'you will most likely need to edit the generated Gruntfile.js file before ' +
43+
'running grunt. _If you run grunt after generating the Gruntfile, and ' +
44+
'it exits with errors, edit the file!_');
45+
}
1946

2047
var prompts = [{
2148
type: 'checkbox',
@@ -24,47 +51,22 @@ var GruntfileGenerator = yeoman.generators.Base.extend({
2451
choices: [{
2552
name: 'Is the DOM involved in ANY way?',
2653
value: 'dom',
27-
checked: false
54+
checked: true
2855
}, {
2956
name: 'Will files be concatenated or minified?',
3057
value: 'minConcat',
31-
checked: false
32-
}, {
33-
name: 'Will you use a package.json file?',
34-
value: 'packageJSON',
35-
checked: false
58+
checked: true
3659
}]
3760
}];
3861

39-
function prefer(arr, preferred) {
40-
for (var i = 0; i < preferred.length; ++i) {
41-
if (arr.indexOf(preferred[i]) !== -1) {
42-
return preferred[i];
43-
}
44-
}
45-
return preferred[0];
46-
}
47-
48-
var dirs = grunt.file.expand({ filter: 'isDirectory' }, '*').map(function (d) {
49-
return d.slice(0, -1);
50-
});
51-
52-
this.jquery = grunt.file.expand({ filter: 'isFile' }, '**/jquery*.js').length > 0;
53-
this.libDir = prefer(dirs, ['lib', 'src']);
54-
this.testDir = prefer(dirs, ['test', 'tests', 'unit', 'spec']);
55-
5662
this.prompt(prompts, function (answers) {
57-
var features = answers.features;
58-
5963
function hasFeature(feat) {
60-
return features.indexOf(feat) !== -1;
64+
return answers.features.indexOf(feat) !== -1;
6165
}
6266

6367
this.dom = hasFeature('dom');
6468
this.minConcat = hasFeature('minConcat');
65-
this.packageJSON = hasFeature('packageJSON');
6669
this.testTask = hasFeature('dom') ? 'qunit' : 'nodeunit';
67-
this.fileName = hasFeature('packageJSON') ? '<%= pkg.name %>' : 'FILE_NAME';
6870

6971
done();
7072
}.bind(this));
@@ -76,9 +78,15 @@ var GruntfileGenerator = yeoman.generators.Base.extend({
7678

7779
writing: function () {
7880
if (!this.packageJSON) {
79-
this.template('package.json');
81+
this.template('_package.json', 'package.json');
82+
}
83+
this.template('_Gruntfile.js', 'Gruntfile.js');
84+
},
85+
86+
install: function () {
87+
if (!this.options['skip-install']) {
88+
this.installDependencies();
8089
}
81-
this.template('gruntfile.js');
8290
}
8391
});
8492

app/templates/gruntfile.js renamed to app/templates/_Gruntfile.js

+14-23
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,23 @@
11
module.exports = function (grunt) {
2-
'use strict';
2+
'use strict';
33
// Project configuration
4-
grunt.initConfig({<% if (minConcat) { %>
5-
// Metadata<% if (packageJSON) { %>
4+
grunt.initConfig({
5+
// Metadata
66
pkg: grunt.file.readJSON('package.json'),
77
banner: '/*! <%%= pkg.name %> - v<%%= pkg.version %> - ' +
88
'<%%= grunt.template.today("yyyy-mm-dd") %>\n' +
99
'<%%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
1010
'* Copyright (c) <%%= grunt.template.today("yyyy") %> <%%= pkg.author.name %>;' +
11-
' Licensed <%%= props.license %> */\n',<% } else { %>
12-
meta: {
13-
version: '0.1.0'
14-
},
15-
banner: '/*! PROJECT_NAME - v<%%= meta.version %> - ' +
16-
'<%%= grunt.template.today("yyyy-mm-dd") %>\n' +
17-
'* http://PROJECT_WEBSITE/\n' +
18-
'* Copyright (c) <%%= grunt.template.today("yyyy") %> ' +
19-
'YOUR_NAME; Licensed MIT */\n',<% } } %>
11+
' Licensed <%%= props.license %> */\n',
2012
// Task configuration<% if (minConcat) { %>
2113
concat: {
2214
options: {
2315
banner: '<%%= banner %>',
2416
stripBanners: true
2517
},
2618
dist: {
27-
src: ['<%= libDir %>/<%= fileName %>.js'],
28-
dest: 'dist/<%= fileName %>.js'
19+
src: ['<%= libDir %>/<%= appname %>.js'],
20+
dest: 'dist/<%= appname %>.js'
2921
}
3022
},
3123
uglify: {
@@ -34,9 +26,9 @@ module.exports = function (grunt) {
3426
},
3527
dist: {
3628
src: '<%%= concat.dist.dest %>',
37-
dest: 'dist/<%= fileName %>.min.js'
29+
dest: 'dist/<%= appname %>.min.js'
3830
}
39-
},<% } %>
31+
},<% } %><% if (!hasJshint) {%>
4032
jshint: {
4133
options: {
4234
node: true,
@@ -49,13 +41,11 @@ module.exports = function (grunt) {
4941
sub: true,
5042
undef: true,
5143
unused: true,
52-
boss: true,
5344
eqnull: true,<% if (dom) { %>
54-
browser: true,<% } %>
55-
globals: {<% if (jquery) { %>
56-
jQuery: true
57-
<% } %>}
58-
},
45+
browser: true,<% } %><% if (jquery || testTask === 'qunit') { %>
46+
globals: { jQuery: true },<% } %>
47+
boss: true
48+
},<% } %>
5949
gruntfile: {
6050
src: 'gruntfile.js'
6151
},
@@ -90,4 +80,5 @@ module.exports = function (grunt) {
9080

9181
// Default task
9282
grunt.registerTask('default', ['jshint', '<%= testTask %>'<%= minConcat ? ", 'concat', 'uglify'" : "" %>]);
93-
};
83+
};
84+
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "",
2+
"name": "<%= _.slugify(appname) %>",
33
"version": "0.0.0",
44
"dependencies": {},
55
"devDependencies": {
@@ -8,6 +8,6 @@
88
"grunt-contrib-concat": "~0.3.0",
99
"grunt-contrib-uglify": "~0.2.7",<% } %>
1010
"grunt-contrib-jshint": "~0.7.2",
11-
"grunt-contrib-<%= testTask %>": ""
11+
"grunt-contrib-<%= testTask %>": "*"
1212
}
1313
}

test/test.js

+76-9
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
/*global beforeEach, describe, it */
22
'use strict';
33

4+
var file = require('yeoman-generator').file;
45
var helpers = require('yeoman-generator').test;
56
var path = require('path');
67

7-
describe('gruntfile:app', function () {
8+
describe('gruntfile:app empty project', function () {
89
var generator;
910

10-
beforeEach(function (cb) {
11-
helpers.testDirectory(path.join(__dirname, 'temp'), function () {
12-
var deps = ['../../app'];
13-
generator = helpers.createGenerator('gruntfile:app', deps);
14-
cb();
11+
beforeEach(function (done) {
12+
helpers.testDirectory(path.join(__dirname, 'temp'), function (err) {
13+
if (err) {
14+
done(err);
15+
}
16+
generator = helpers.createGenerator('gruntfile:app', ['../../app']);
17+
generator.options['skip-install'] = true;
18+
generator.options['skip-install-message'] = true;
19+
done();
1520
});
1621
});
1722

18-
it('creates expected files', function (cb) {
19-
var expected = ['gruntfile.js'];
23+
it('creates expected files', function (done) {
24+
var expected = ['Gruntfile.js', 'package.json'];
2025

2126
helpers.mockPrompt(generator, {
2227
features: [
@@ -27,7 +32,69 @@ describe('gruntfile:app', function () {
2732

2833
generator.run({}, function () {
2934
helpers.assertFile(expected);
30-
cb();
35+
done();
3136
});
3237
});
3338
});
39+
40+
describe('gruntfile:app with existing package.json', function () {
41+
var generator;
42+
43+
beforeEach(function (done) {
44+
helpers.testDirectory(path.join(__dirname, 'temp'), function (err) {
45+
if (err) {
46+
done(err);
47+
}
48+
file.write('package.json', '{"jshintConfig":{}}');
49+
generator = helpers.createGenerator('gruntfile:app', ['../../app']);
50+
generator.options['skip-install-message'] = true;
51+
generator.options['skip-install'] = true;
52+
done();
53+
});
54+
});
55+
56+
it('creates expected files', function (done) {
57+
var expected = ['Gruntfile.js', 'package.json'];
58+
59+
helpers.mockPrompt(generator, {
60+
features: [
61+
'dom',
62+
'minConcat'
63+
]
64+
});
65+
66+
generator.run({}, function () {
67+
helpers.assertFile(expected);
68+
done();
69+
});
70+
});
71+
72+
it('does not replace existing package.json', function (done) {
73+
helpers.mockPrompt(generator, {
74+
features: [
75+
'dom',
76+
'minConcat'
77+
]
78+
});
79+
80+
generator.run({}, function () {
81+
helpers.assertFileContent('./package.json', /jshintConfig/);
82+
done();
83+
});
84+
});
85+
86+
it('does not conflict with jshintConfig property', function (done) {
87+
helpers.mockPrompt(generator, {
88+
features: [
89+
'dom',
90+
'minConcat'
91+
]
92+
});
93+
94+
generator.run({}, function () {
95+
helpers.assertNoFileContent('./Gruntfile.js', /jshint: {/);
96+
done();
97+
});
98+
});
99+
});
100+

0 commit comments

Comments
 (0)