generator-cg-angular
Advanced tools
Comparing version 2.1.1 to 3.0.0
@@ -5,4 +5,4 @@ 'use strict'; | ||
var yeoman = require('yeoman-generator'); | ||
var cgUtils = require('../utils.js'); | ||
var CgangularGenerator = module.exports = function CgangularGenerator(args, options, config) { | ||
@@ -12,2 +12,20 @@ yeoman.generators.Base.apply(this, arguments); | ||
this.on('end', function () { | ||
this.config.set('partialDirectory','partial/'); | ||
this.config.set('directiveDirectory','directive/'); | ||
this.config.set('filterDirectory','filter/'); | ||
this.config.set('serviceDirectory','service/'); | ||
var inject = { | ||
js: { | ||
file: 'index.html', | ||
marker: cgUtils.JS_MARKER, | ||
template: '<script src="<%= filename %>"></script>' | ||
}, | ||
less: { | ||
file: 'app.less', | ||
marker: cgUtils.LESS_MARKER, | ||
template: '@import "<%= filename %>";' | ||
} | ||
}; | ||
this.config.set('inject',inject); | ||
this.config.save(); | ||
this.installDependencies({ skipInstall: options['skip-install'] }); | ||
@@ -32,3 +50,30 @@ }); | ||
this.appname = props.appname; | ||
cb(); | ||
}.bind(this)); | ||
}; | ||
CgangularGenerator.prototype.askForUiRouter = function askFor() { | ||
var cb = this.async(); | ||
var prompts = [{ | ||
name: 'router', | ||
type:'list', | ||
message: 'Which router would you like to use?', | ||
default: 0, | ||
choices: ['Standard Angular Router','Angular UI Router'] | ||
}]; | ||
this.prompt(prompts, function (props) { | ||
if (props.router === 'Angular UI Router') { | ||
this.uirouter = true; | ||
this.routerJs = 'bower_components/angular-ui-router/release/angular-ui-router.js'; | ||
this.routerModuleName = 'ui.router'; | ||
this.routerViewDirective = 'ui-view'; | ||
} else { | ||
this.uirouter = false; | ||
this.routerJs = 'bower_components/angular-route/angular-route.js'; | ||
this.routerModuleName = 'ngRoute'; | ||
this.routerViewDirective = 'ng-view'; | ||
} | ||
this.config.set('uirouter',this.uirouter); | ||
cb(); | ||
@@ -40,7 +85,2 @@ }.bind(this)); | ||
this.directory('skeleton/','./'); | ||
this.template('skeleton/js/setup.js','./js/setup.js'); | ||
this.template('skeleton/bower.json','./bower.json'); | ||
this.template('skeleton/Gruntfile.js','./Gruntfile.js'); | ||
this.template('skeleton/index.html','./index.html'); | ||
this.template('skeleton/package.json','./package.json'); | ||
}; |
@@ -15,3 +15,3 @@ { | ||
"angular": "~1.2", | ||
"angular-route": "~1.2", | ||
<% if(uirouter) { print('"angular-ui-router": "~0.2",'); } else { print('"angular-route": "~1.2",'); } %> | ||
"angular-animate": "~1.2", | ||
@@ -24,5 +24,5 @@ "angular-resource": "~1.2", | ||
"moment": "~2.5", | ||
"less.js": "~1.5", | ||
"less.js": "~1.6", | ||
"font-awesome": "~4.0" | ||
} | ||
} |
@@ -0,6 +1,29 @@ | ||
/*jslint node: true */ | ||
'use strict'; | ||
var path = require('path'); | ||
var folderMount = function folderMount(connect, point) { | ||
return connect.static(path.resolve(point)); | ||
//Using exclusion patterns slows down Grunt significantly | ||
//instead of creating a set of patterns like '**/*.js' and '!**/node_modules/**' | ||
//this method is used to create a set of inclusive patterns for all subdirectories | ||
//skipping node_modules, bower_components, dist, and any .dirs | ||
//This enables users to create any directory structure they desire. | ||
var createFolderGlobs = function(fileTypePatterns) { | ||
fileTypePatterns = Array.isArray(fileTypePatterns) ? fileTypePatterns : [fileTypePatterns]; | ||
var ignore = ['node_modules','bower_components','dist','temp']; | ||
var fs = require('fs'); | ||
return fs.readdirSync(process.cwd()) | ||
.map(function(file){ | ||
if (ignore.indexOf(file) !== -1 || | ||
file.indexOf('.') === 0 || | ||
!fs.lstatSync(file).isDirectory()) { | ||
return null; | ||
} else { | ||
return fileTypePatterns.map(function(pattern) { | ||
return file + '/**/' + pattern; | ||
}); | ||
} | ||
}) | ||
.filter(function(patterns){ | ||
return patterns; | ||
}) | ||
.concat(fileTypePatterns); | ||
}; | ||
@@ -18,6 +41,3 @@ | ||
options: { | ||
port: 9001, | ||
middleware: function(connect, options) { | ||
return [folderMount(connect, options.base)] | ||
} | ||
port: 9001 | ||
} | ||
@@ -32,3 +52,3 @@ } | ||
}, | ||
files: ['js/**/*','css/**/*','img/**/*','partial/**/*','service/**/*','filter/**/*','directive/**/*','index.html'], | ||
files: [createFolderGlobs(['*.js','*.less','*.html']),'!_SpecRunner.html','!.grunt'], | ||
tasks: [] //all the tasks are run dynamically during the watch event handler | ||
@@ -42,3 +62,3 @@ } | ||
}, | ||
src: ['js/**/*.js','partial/**/*.js','service/**/*.js','filter/**/*.js','directive/**/*.js'] | ||
src: createFolderGlobs('*.js') | ||
} | ||
@@ -59,3 +79,3 @@ }, | ||
files: { | ||
"temp/app.css": "css/app.less" | ||
'temp/app.css': 'app.less' | ||
} | ||
@@ -68,14 +88,5 @@ } | ||
module:'<%= _.slugify(appname) %>', | ||
htmlmin: { | ||
collapseBooleanAttributes: true, | ||
collapseWhitespace: true, | ||
removeAttributeQuotes: true, | ||
removeComments: true, | ||
removeEmptyAttributes: true, | ||
removeRedundantAttributes: true, | ||
removeScriptTypeAttributes: true, | ||
removeStyleLinkTypeAttributes: true | ||
} | ||
htmlmin:'<%%= htmlmin.main.options %>' | ||
}, | ||
src: [ 'partial/**/*.html','directive/**/*.html' ], | ||
src: [createFolderGlobs('*.html'),'!index.html','!_SpecRunner.html'], | ||
dest: 'temp/templates.js' | ||
@@ -87,8 +98,7 @@ } | ||
files: [ | ||
{src: ['index.html'], dest: 'dist/'}, | ||
{src: ['img/**'], dest: 'dist/'}, | ||
{src: ['bower_components/angular-ui-utils/ui-utils-ieshiv.min.js'], dest: 'dist/'}, | ||
{src: ['bower_components/font-awesome/fonts/**'], dest: 'dist/',filter:'isFile',expand:true} | ||
// {src: ['bower_components/select2/*.png','bower_components/select2/*.gif'], dest:'dist/css/',flatten:true,expand:true}, | ||
// {src: ['bower_components/angular-mocks/angular-mocks.js'], dest: 'dist/'} | ||
//{src: ['bower_components/angular-ui-utils/ui-utils-ieshiv.min.js'], dest: 'dist/'}, | ||
//{src: ['bower_components/select2/*.png','bower_components/select2/*.gif'], dest:'dist/css/',flatten:true,expand:true}, | ||
//{src: ['bower_components/angular-mocks/angular-mocks.js'], dest: 'dist/'} | ||
] | ||
@@ -98,39 +108,21 @@ } | ||
dom_munger:{ | ||
readscripts: { | ||
read: { | ||
options: { | ||
read:{selector:'script[data-build!="exclude"]',attribute:'src',writeto:'appjs'} | ||
read:[ | ||
{selector:'script[data-build!="exclude"]',attribute:'src',writeto:'appjs'}, | ||
{selector:'link[rel="stylesheet"]',attribute:'href',writeto:'appcss'} | ||
] | ||
}, | ||
src:'index.html' | ||
src: 'index.html' | ||
}, | ||
readcss: { | ||
update: { | ||
options: { | ||
read:{selector:'link[rel="stylesheet"]',attribute:'href',writeto:'appcss'} | ||
remove: ['script[data-remove!="exclude"]','link'], | ||
append: [ | ||
{selector:'body',html:'<script src="app.full.min.js"></script>'}, | ||
{selector:'head',html:'<link rel="stylesheet" href="app.full.min.css">'} | ||
] | ||
}, | ||
src:'index.html' | ||
}, | ||
removescripts: { | ||
options:{ | ||
remove:'script[data-remove!="exclude"]', | ||
append:{selector:'head',html:'<script src="app.full.min.js"></script>'} | ||
}, | ||
src:'dist/index.html' | ||
}, | ||
addscript: { | ||
options:{ | ||
append:{selector:'body',html:'<script src="app.full.min.js"></script>'} | ||
}, | ||
src:'dist/index.html' | ||
}, | ||
removecss: { | ||
options:{ | ||
remove:'link', | ||
append:{selector:'head',html:'<link rel="stylesheet" href="css/app.full.min.css">'} | ||
}, | ||
src:'dist/index.html' | ||
}, | ||
addcss: { | ||
options:{ | ||
append:{selector:'head',html:'<link rel="stylesheet" href="css/app.full.min.css">'} | ||
}, | ||
src:'dist/index.html' | ||
src:'index.html', | ||
dest: 'dist/index.html' | ||
} | ||
@@ -141,3 +133,3 @@ }, | ||
src:['temp/app.css','<%%= dom_munger.data.appcss %>'], | ||
dest:'dist/css/app.full.min.css' | ||
dest:'dist/app.full.min.css' | ||
} | ||
@@ -193,4 +185,4 @@ }, | ||
options: { | ||
keepRunner: true, | ||
specs: ['js/**/*-spec.js','partial/**/*-spec.js','service/**/*-spec.js','filter/**/*-spec.js','directive/**/*-spec.js'] | ||
keepRunner: false, | ||
specs: createFolderGlobs('*-spec.js') | ||
} | ||
@@ -201,5 +193,5 @@ } | ||
grunt.registerTask('build',['jshint','clean:before','less','dom_munger:readcss','dom_munger:readscripts','ngtemplates','cssmin','concat','ngmin','uglify','copy','dom_munger:removecss','dom_munger:addcss','dom_munger:removescripts','dom_munger:addscript','htmlmin','imagemin','clean:after']); | ||
grunt.registerTask('server', ['dom_munger:readscripts','jshint','connect', 'watch']); | ||
grunt.registerTask('test',['dom_munger:readscripts','jasmine']); | ||
grunt.registerTask('build',['jshint','clean:before','less','dom_munger','ngtemplates','cssmin','concat','ngmin','uglify','copy','htmlmin','imagemin','clean:after']); | ||
grunt.registerTask('serve', ['dom_munger:read','jshint','connect', 'watch']); | ||
grunt.registerTask('test',['dom_munger:read','jasmine']); | ||
@@ -219,3 +211,3 @@ | ||
if (filepath.lastIndexOf('-spec.js') === -1 || filepath.lastIndexOf('-spec.js') !== filepath.length - 8) { | ||
var spec = filepath.substring(0,filepath.length - 3) + '-spec.js'; | ||
spec = filepath.substring(0,filepath.length - 3) + '-spec.js'; | ||
} | ||
@@ -233,7 +225,6 @@ | ||
if (filepath === 'index.html') { | ||
grunt.task.run('dom_munger:readscripts'); | ||
grunt.task.run('dom_munger:read'); | ||
} | ||
}); | ||
}; |
@@ -6,3 +6,3 @@ { | ||
"grunt": "~0.4", | ||
"grunt-dom-munger": "~3.1", | ||
"grunt-dom-munger": "~3.4", | ||
"grunt-angular-templates": "~0.5", | ||
@@ -21,5 +21,5 @@ "grunt-ngmin": "0.0.3", | ||
"grunt-contrib-watch": "~0.5", | ||
"grunt-contrib-jasmine": "~0.5", | ||
"grunt-contrib-jasmine": "~0.6", | ||
"load-grunt-tasks": "~0.2" | ||
} | ||
} |
@@ -6,12 +6,18 @@ 'use strict'; | ||
var cgUtils = require('../utils.js'); | ||
var chalk = require('chalk'); | ||
var _ = require('underscore'); | ||
var fs = require('fs'); | ||
_.str = require('underscore.string'); | ||
_.mixin(_.str.exports()); | ||
var DirectiveGenerator = module.exports = function DirectiveGenerator(args, options, config) { | ||
yeoman.generators.NamedBase.apply(this, arguments); | ||
yeoman.generators.NamedBase.apply(this, arguments); | ||
try { | ||
this.appname = require(path.join(process.cwd(), 'package.json')).name; | ||
} catch (e) { | ||
this.appname = 'Cant find name from package.json'; | ||
} | ||
try { | ||
this.appname = require(path.join(process.cwd(), 'package.json')).name; | ||
} catch (e) { | ||
this.appname = 'Cant find name from package.json'; | ||
} | ||
@@ -23,16 +29,33 @@ }; | ||
DirectiveGenerator.prototype.askFor = function askFor() { | ||
var cb = this.async(); | ||
var cb = this.async(); | ||
var name = this.name; | ||
var defaultDir = this.config.get('directiveDirectory'); | ||
if (!_(defaultDir).endsWith('/')) { | ||
defaultDir += '/'; | ||
} | ||
var prompts = [{ | ||
type:'confirm', | ||
name: 'needpartial', | ||
message: 'Does this directive need an external html file (i.e. partial)?', | ||
default: true | ||
}]; | ||
var prompts = [{ | ||
type:'confirm', | ||
name: 'needpartial', | ||
message: 'Does this directive need an external html file (i.e. partial)?', | ||
default: true | ||
},{ | ||
name:'dir', | ||
message:'Where would you like to create the directive files?', | ||
default: function(props){ | ||
if (props.needpartial){ | ||
return defaultDir + name + '/'; | ||
} else { | ||
return defaultDir; | ||
} | ||
} | ||
}]; | ||
this.prompt(prompts, function (props) { | ||
this.needpartial = props.needpartial; | ||
this.prompt(prompts, function (props) { | ||
this.needpartial = props.needpartial; | ||
this.dir = cgUtils.cleanDirectory(props.dir); | ||
cb(); | ||
}.bind(this)); | ||
cb(); | ||
}.bind(this)); | ||
}; | ||
@@ -42,21 +65,11 @@ | ||
if (this.needpartial){ | ||
this.template('directive.js', 'directive/'+this.name+'/'+this.name+'.js'); | ||
this.template('directive.html', 'directive/'+this.name+'/'+this.name+'.html'); | ||
this.template('directive.less', 'directive/'+this.name+'/'+this.name+'.less'); | ||
this.template('spec.js', 'directive/'+this.name+'/'+this.name+'-spec.js'); | ||
var configName = 'directiveSimpleTemplates'; | ||
var defaultDir = 'templates/simple'; | ||
if (this.needpartial) { | ||
configName = 'directiveComplexTemplates'; | ||
defaultDir = 'templates/complex'; | ||
} | ||
cgUtils.addToFile('index.html','<script src="directive/'+this.name+'/'+this.name+'.js"></script>',cgUtils.DIRECTIVE_JS_MARKER,' '); | ||
this.log.writeln(' updating'.green + ' %s','index.html'); | ||
cgUtils.processTemplates(this.name,this.dir,'service',this,defaultDir,configName); | ||
cgUtils.addToFile('css/app.less','@import "../directive/'+this.name+'/'+this.name+'.less";',cgUtils.DIRECTIVE_LESS_MARKER,''); | ||
this.log.writeln(' updating'.green + ' %s','app/app.less'); | ||
} else { | ||
this.template('directive_simple.js', 'directive/'+this.name+'.js'); | ||
this.template('spec.js', 'directive/'+this.name+'-spec.js'); | ||
cgUtils.addToFile('index.html','<script src="directive/'+this.name+'.js"></script>',cgUtils.DIRECTIVE_JS_MARKER,' '); | ||
this.log.writeln(' updating'.green + ' %s','index.html'); | ||
} | ||
}; |
@@ -6,3 +6,9 @@ 'use strict'; | ||
var cgUtils = require('../utils.js'); | ||
var chalk = require('chalk'); | ||
var _ = require('underscore'); | ||
var fs = require('fs'); | ||
_.str = require('underscore.string'); | ||
_.mixin(_.str.exports()); | ||
var FilterGenerator = module.exports = function FilterGenerator(args, options, config) { | ||
@@ -22,8 +28,29 @@ | ||
FilterGenerator.prototype.askFor = function askFor() { | ||
var cb = this.async(); | ||
var name = this.name; | ||
var defaultDir = this.config.get('filterDirectory'); | ||
if (!_(defaultDir).endsWith('/')) { | ||
defaultDir += '/'; | ||
} | ||
var prompts = [ | ||
{ | ||
name:'dir', | ||
message:'Where would you like to create the filter files?', | ||
default: defaultDir | ||
} | ||
]; | ||
this.prompt(prompts, function (props) { | ||
this.dir = cgUtils.cleanDirectory(props.dir); | ||
cb(); | ||
}.bind(this)); | ||
}; | ||
FilterGenerator.prototype.files = function files() { | ||
this.template('filter.js', 'filter/'+this.name+'.js'); | ||
this.template('spec.js', 'filter/'+this.name+'-spec.js'); | ||
cgUtils.addToFile('index.html','<script src="filter/'+this.name+'.js"></script>',cgUtils.FILTER_JS_MARKER,' '); | ||
this.log.writeln(' updating'.green + ' %s','index.html'); | ||
cgUtils.processTemplates(this.name,this.dir,'filter',this); | ||
}; |
{ | ||
"name": "generator-cg-angular", | ||
"version": "2.1.1", | ||
"version": "3.0.0", | ||
"description": "Yeoman Generator for Enterprise Angular projects.", | ||
@@ -25,5 +25,6 @@ "keywords": [ | ||
"dependencies": { | ||
"yeoman-generator": "~0.15", | ||
"underscore": "~1.5", | ||
"underscore.string": "~2.3" | ||
"underscore.string": "~2.3", | ||
"yeoman-generator": "~0.16", | ||
"chalk": "~0.4.0" | ||
}, | ||
@@ -30,0 +31,0 @@ "devDependencies": { |
@@ -5,4 +5,7 @@ 'use strict'; | ||
var path = require('path'); | ||
var fs = require('fs'); | ||
var cgUtils = require('../utils.js'); | ||
var _ = require('underscore'); | ||
var chalk = require('chalk'); | ||
var fs = require('fs'); | ||
@@ -14,9 +17,9 @@ _.str = require('underscore.string'); | ||
yeoman.generators.NamedBase.apply(this, arguments); | ||
yeoman.generators.NamedBase.apply(this, arguments); | ||
try { | ||
this.appname = require(path.join(process.cwd(), 'package.json')).name; | ||
} catch (e) { | ||
this.appname = 'Cant find name from package.json'; | ||
} | ||
try { | ||
this.appname = require(path.join(process.cwd(), 'package.json')).name; | ||
} catch (e) { | ||
this.appname = 'Cant find name from package.json'; | ||
} | ||
@@ -28,14 +31,27 @@ }; | ||
PartialGenerator.prototype.askFor = function askFor() { | ||
var cb = this.async(); | ||
var cb = this.async(); | ||
var name = this.name; | ||
var defaultDir = this.config.get('partialDirectory'); | ||
if (!_(defaultDir).endsWith('/')) { | ||
defaultDir += '/'; | ||
} | ||
var prompts = [{ | ||
name: 'route', | ||
message: 'Enter your route name (i.e. /mypartial/:id). If you don\'t want a route added for you, leave this empty.' | ||
}]; | ||
var prompts = [ | ||
{ | ||
name: 'route', | ||
message: 'Enter your route url (i.e. /mypartial/:id). If you don\'t want a route added for you, leave this empty.' | ||
}, | ||
{ | ||
name:'dir', | ||
message:'Where would you like to create the partial files?', | ||
default: defaultDir + name + '/' | ||
} | ||
]; | ||
this.prompt(prompts, function (props) { | ||
this.route = props.route; | ||
this.prompt(prompts, function (props) { | ||
this.route = props.route; | ||
this.dir = cgUtils.cleanDirectory(props.dir); | ||
cb(); | ||
}.bind(this)); | ||
cb(); | ||
}.bind(this)); | ||
}; | ||
@@ -45,20 +61,19 @@ | ||
this.ctrlname = _.camelize(_.classify(this.name)) + 'Ctrl'; | ||
this.ctrlname = _.camelize(_.classify(this.name)) + 'Ctrl'; | ||
this.template('partial.js', 'partial/'+this.name+'/'+this.name+'.js'); | ||
this.template('partial.html', 'partial/'+this.name+'/'+this.name+'.html'); | ||
this.template('partial.less', 'partial/'+this.name+'/'+this.name+'.less'); | ||
this.template('spec.js', 'partial/'+this.name+'/'+this.name+'-spec.js'); | ||
cgUtils.processTemplates(this.name,this.dir,'partial',this); | ||
cgUtils.addToFile('index.html','<script src="partial/'+this.name+'/'+this.name+'.js"></script>',cgUtils.PARTIAL_JS_MARKER,' '); | ||
this.log.writeln(' updating'.green + ' %s','index.html'); | ||
if (this.route && this.route.length > 0){ | ||
cgUtils.addToFile('css/app.less','@import "../partial/'+this.name+'/'+this.name+'.less";',cgUtils.PARTIAL_LESS_MARKER,''); | ||
this.log.writeln(' updating'.green + ' %s','app/app.less'); | ||
var partialUrl = this.dir + this.name + '.html'; | ||
if (this.route && this.route.length > 0){ | ||
cgUtils.addToFile('js/setup.js','when(\''+this.route+'\',{templateUrl: \'partial/'+this.name+'/'+this.name+'.html\'}).',cgUtils.ROUTE_MARKER,'\t'); | ||
this.log.writeln(' updating'.green + ' %s','js/setup.js'); | ||
} | ||
if (this.config.get('uirouter')) { | ||
var code = '$stateProvider.state(\''+this.name+'\', {\n url: \''+this.route+'\',\n templateUrl: \''+partialUrl+'\'\n });'; | ||
cgUtils.addToFile('app.js',code,cgUtils.STATE_MARKER,' '); | ||
} else { | ||
cgUtils.addToFile('app.js','when(\''+this.route+'\',{templateUrl: \''+partialUrl+'\'}).',cgUtils.ROUTE_MARKER,' '); | ||
} | ||
this.log.writeln(chalk.green(' updating') + ' %s','app.js'); | ||
} | ||
}; |
@@ -12,3 +12,3 @@ #generator-cg-angular | ||
* Build uses [grunt-ngmin](https://github.com/btford/grunt-ngmin) so you don't have to use the Angular injection syntax for safe minification (i.e. you dont need `$inject` or `(['$scope','$http',...`. | ||
* `grunt server` task allows you to run a simple development server with watch/livereload enabled. Additionally, JSHint and the appropriate unit tests are run for the changed files. | ||
* `grunt serve` task allows you to run a simple development server with watch/livereload enabled. Additionally, JSHint and the appropriate unit tests are run for the changed files. | ||
* Integrates Bower for package management | ||
@@ -21,29 +21,36 @@ * Includes Yeoman sub-generators for directives, services, partials, and filters | ||
------------- | ||
Below is an explanation of the folder structure. | ||
Below is an example of the folder structure. In v3.0, all sub-generators for partials, services, directives, and filters, allow the user to specify where to save the new files. Thus you can create your own directory structure (including nesting) as you desire. In this example, the user has chosen to group the app into an `admin` folder, a `search` folder, and a `service` folder. | ||
/css ........................... usually only contains app.less | ||
app.less ................... main app-wide styles | ||
/img ........................... images (not created by default but included in /dist if added) | ||
/js ............................ app global javascript files | ||
setup.js ................... angular module initialization and route setup | ||
/directive ..................... angular directives folder | ||
my-directive.js ............ example simple directive | ||
my-directive-spec.js ....... example simple directive unit test | ||
/my-directive2 ............. example complex directive (contains external partial) | ||
my-directive2.js ....... complex directive javascript | ||
my-directive2.html...... complex directive partial | ||
my-directive2.less ..... complex directive LESS | ||
my-directive2-spec.js .. complex directive unit test | ||
/filter ........................ angular filters folder | ||
my-filter.js ............... example filter | ||
my-filter-spec.js .......... example filter unit test | ||
/partial ....................... angular partials folder | ||
/my-partial ................ example partial | ||
my-partial.html ........ example partial html | ||
my-partial.js .......... example partial controller | ||
my-partial.less ........ example partial LESS | ||
my-partial-spec.js ..... example partial unit test | ||
app.less ....................... main app-wide styles | ||
app.js ......................... angular module initialization and route setup | ||
index.html ..................... main HTML file | ||
/admin ......................... example admin component folder | ||
/admin-directive1 ............ angular directives folder | ||
admin-directive1.js ........ example simple directive | ||
admin-directive-spec1.j..... example simple directive unit test | ||
/admin-directive2 ............ example complex directive (contains external partial) | ||
admin-directive2.js ........ complex directive javascript | ||
admin-directive2.html ...... complex directive partial | ||
admin-directive2.less ...... complex directive LESS | ||
admin-directive2-spec.js ... complex directive unit test | ||
/admin-partial ............... example partial | ||
admin-partial.html ......... example partial html | ||
admin-partial.js ........... example partial controller | ||
admin-partial.less ......... example partial LESS | ||
admin-partial-spec.js ...... example partial unit test | ||
/search ........................ example search component folder | ||
my-filter.js ................. example filter | ||
my-filter-spec.js ............ example filter unit test | ||
/search-partial .............. example partial | ||
search-partial.html ........ example partial html | ||
search-partial.js .......... example partial controller | ||
search-partial.less ........ example partial LESS | ||
search-partial-spec.js ..... example partial unit test | ||
/service ....................... angular services folder | ||
my-service.js .............. example service | ||
my-service-spec.js ......... example service unit test | ||
my-service2.js ............. example service | ||
my-service2-spec.js ........ example service unit test | ||
/img ........................... images (not created by default but included in /dist if added) | ||
/dist .......................... distributable version of app built using grunt and Gruntfile.js | ||
@@ -53,4 +60,2 @@ /bower_component................ 3rd party libraries managed by bower | ||
The `directive`, `filter`, `partial`, and `service` directories won't exist until one of the relevant components is created using a sub-generator. | ||
Getting Started | ||
@@ -78,7 +83,7 @@ ------------- | ||
grunt server #This will run a development server with watch & livereload enabled. | ||
grunt serve #This will run a development server with watch & livereload enabled. | ||
grunt test #Run unit tests. | ||
grunt build #Places a fully optimized (minified, concatenated, and more) in /dist | ||
When `grunt server` is running, any changed javascript files will be validated using JSHint as well as have their appropriate unit tests executed. Only the unit tests that correspond to the changed file will be run. | ||
When `grunt serve` is running, any changed javascript files will be linted using JSHint as well as have their appropriate unit tests executed. Only the unit tests that correspond to the changed file will be run. | ||
@@ -93,3 +98,3 @@ Yeoman Subgenerators | ||
* Update app.less and add the @import as needed. | ||
* For partials, update the setup.js, adding the necessary route call if a route was entered in the generator prompts. | ||
* For partials, update the app.js, adding the necessary route call if a route was entered in the generator prompts. | ||
@@ -105,10 +110,12 @@ There are generators for `directive`,`partial`,`service`, and `filter`. | ||
The name paramater passed (i.e. 'my-awesome-directive') will be used for directory and/or file names. The generators will derive appropriate class names from this parameter (ex. 'my-awesome-directive' will convert to a class name of 'MyAwesomeDirective'). | ||
The name paramater passed (i.e. 'my-awesome-directive') will be used the file names. The generators will derive appropriate class names from this parameter (ex. 'my-awesome-directive' will convert to a class name of 'MyAwesomeDirective'). Each sub-generator will ask for the folder in which to create the new skeleton files. You may override the default folder for each sub-generator in the `.yo-rc.json` file. | ||
One quick note, each sub-generator pulls the Angular app/module name from the package.json. Therefore, if you choose to change the name of your Angular app/module, you must ensure that the name in the package.json stays in sync. | ||
Each sub-generator pulls the Angular app/module name from the package.json. Therefore, if you choose to change the name of your Angular app/module, you must ensure that the name in the package.json stays in sync. | ||
Sub-generators are also customizable. Please read [CUSTOMIZING.md](CUSTOMIZING.md) for details. | ||
Preconfigured Libraries | ||
------------- | ||
The new app will have a handful of preconfigured libraries included. This includes Angular 1.2, Bootstrap 3, AngularUI Bootstrap, AngularUI Utils, FontAwesome 4, JQuery 2, Underscore 1.5, LESS 1.5, and Moment 2.5. You may of course add to or remove any of these libraries. But the work to integrate them into the app and into the build process has already been done for you. | ||
The new app will have a handful of preconfigured libraries included. This includes Angular 1.2, Bootstrap 3, AngularUI Bootstrap, AngularUI Utils, FontAwesome 4, JQuery 2, Underscore 1.5, LESS 1.6, and Moment 2.5. You may of course add to or remove any of these libraries. But the work to integrate them into the app and into the build process has already been done for you. | ||
@@ -138,2 +145,3 @@ Build Process | ||
------------- | ||
* 3/03/2014 - v3.0.0 - All sub-generators now ask the user for a directory enabling any user-defined project structure. Gruntfile has been altered to allow scripts, partials, and LESS files to be located anywhere in the project directory structure. An option to use `angular-ui-router` is now available when initializing a new project. `js/setup.js` and `css/app.less` moved to `app.js` and `app.less`. `grunt server` is now `grunt serve`. Inside `index.html` all user script tags are grouped together instead of split out into groups for services/filters/etc. New ability to customize the sub-generators. | ||
* 2/10/2014 - v2.1.1 - Fix for the directive spec file named with a .less extension. | ||
@@ -140,0 +148,0 @@ * 1/06/2014 - v2.1.0 - Nice enhancements for unit testing. Specs are now placed in the same directory as the component they're testing. Additionally, unit tests are now run during `grunt server` allowing for an easy and efficient test-driven workflow. |
@@ -6,3 +6,9 @@ 'use strict'; | ||
var cgUtils = require('../utils.js'); | ||
var chalk = require('chalk'); | ||
var _ = require('underscore'); | ||
var fs = require('fs'); | ||
_.str = require('underscore.string'); | ||
_.mixin(_.str.exports()); | ||
var ServiceGenerator = module.exports = function ServiceGenerator(args, options, config) { | ||
@@ -22,8 +28,29 @@ | ||
ServiceGenerator.prototype.askFor = function askFor() { | ||
var cb = this.async(); | ||
var name = this.name; | ||
var defaultDir = this.config.get('serviceDirectory'); | ||
if (!_(defaultDir).endsWith('/')) { | ||
defaultDir += '/'; | ||
} | ||
var prompts = [ | ||
{ | ||
name:'dir', | ||
message:'Where would you like to create the service files?', | ||
default: defaultDir | ||
} | ||
]; | ||
this.prompt(prompts, function (props) { | ||
this.dir = cgUtils.cleanDirectory(props.dir); | ||
cb(); | ||
}.bind(this)); | ||
}; | ||
ServiceGenerator.prototype.files = function files() { | ||
this.template('service.js', 'service/'+this.name+'.js'); | ||
this.template('spec.js', 'service/'+this.name+'-spec.js'); | ||
cgUtils.addToFile('index.html','<script src="service/'+this.name+'.js"></script>',cgUtils.SERVICE_JS_MARKER,' '); | ||
this.log.writeln(' updating'.green + ' %s','index.html'); | ||
cgUtils.processTemplates(this.name,this.dir,'service',this); | ||
}; |
77
utils.js
var path = require('path'); | ||
var fs = require('fs'); | ||
var _ = require('underscore'); | ||
var chalk = require('chalk'); | ||
_.str = require('underscore.string'); | ||
_.mixin(_.str.exports()); | ||
exports.addToFile = function(filename,lineToAdd,beforeMarker,spacing){ | ||
@@ -10,3 +15,5 @@ try { | ||
var indexOf = fileSrc.indexOf(beforeMarker); | ||
fileSrc = fileSrc.substring(0,indexOf) + lineToAdd + "\n" + spacing + fileSrc.substring(indexOf); | ||
var lineStart = fileSrc.substring(0,indexOf).lastIndexOf('\n') + 1; | ||
var indent = fileSrc.substring(lineStart,indexOf); | ||
fileSrc = fileSrc.substring(0,indexOf) + lineToAdd + "\n" + indent + fileSrc.substring(indexOf); | ||
@@ -20,9 +27,65 @@ fs.writeFileSync(fullPath,fileSrc); | ||
exports.DIRECTIVE_LESS_MARKER = "/* Add Directive LESS Above */"; | ||
exports.DIRECTIVE_JS_MARKER = "<!-- Add New Directive JS Above -->"; | ||
exports.FILTER_JS_MARKER = "<!-- Add New Filter JS Above -->"; | ||
exports.SERVICE_JS_MARKER = "<!-- Add New Service JS Above -->"; | ||
exports.PARTIAL_LESS_MARKER = "/* Add Partial LESS Above */"; | ||
exports.PARTIAL_JS_MARKER = "<!-- Add New Partial JS Above -->"; | ||
exports.JS_MARKER = "<!-- Add New Component JS Above -->"; | ||
exports.LESS_MARKER = "/* Add Component LESS Above */"; | ||
exports.ROUTE_MARKER = "/* Add New Routes Above */"; | ||
exports.STATE_MARKER = "/* Add New States Above */"; | ||
exports.cleanDirectory = function(directoryName) { | ||
if (_(directoryName).startsWith('/') || _(directoryName).startsWith('\\')) { | ||
directoryName = directoryName.substring(1); | ||
} | ||
if (_(directoryName).endsWith('/') || _(directoryName).endsWith('\\')) { | ||
directoryName = directoryName.substring(0,directoryName.length - 1); | ||
} | ||
return directoryName + '/'; | ||
}; | ||
exports.processTemplates = function(name,dir,type,that,defaultDir,configName){ | ||
if (!defaultDir) { | ||
defaultDir = 'templates' | ||
} | ||
if (!configName) { | ||
configName = type + 'Templates'; | ||
} | ||
var templateDirectory = path.join(path.dirname(that.resolved),defaultDir); | ||
if(that.config.get(configName)){ | ||
templateDirectory = path.join(process.cwd(),that.config.get(configName)); | ||
} | ||
_.chain(fs.readdirSync(templateDirectory)) | ||
.filter(function(template){ | ||
return template[0] !== '.'; | ||
}) | ||
.each(function(template){ | ||
var customTemplateName = template.replace(type,name); | ||
var templateFile = path.join(templateDirectory,template); | ||
//create the file | ||
that.template(templateFile,dir + customTemplateName); | ||
//inject the file reference into index.html/app.less/etc as appropriate | ||
exports.inject(dir + customTemplateName,that); | ||
}); | ||
}; | ||
exports.inject = function(filename,that) { | ||
//special case to skip unit tests | ||
if (_(filename).endsWith('-spec.js')) { | ||
return; | ||
} | ||
var ext = path.extname(filename); | ||
if (ext[0] === '.') { | ||
ext = ext.substring(1); | ||
} | ||
var config = that.config.get('inject')[ext]; | ||
if (config) { | ||
var lineTemplate = _.template(config.template)({filename:filename}); | ||
exports.addToFile(config.file,lineTemplate,config.marker); | ||
that.log.writeln(chalk.green(' updating') + ' %s',config.file); | ||
} | ||
}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
44547
41
712
148
4
11
+ Addedchalk@~0.4.0
+ Addedyeoman-generator@0.16.0(transitive)
- Removedyeoman-generator@0.15.0(transitive)
Updatedyeoman-generator@~0.16