|
| 1 | +'use strict'; |
| 2 | +var util = require('util'), |
| 3 | + yeoman = require('yeoman-generator'), |
| 4 | + fs = require('fs'), |
| 5 | + _ = require('lodash'), |
| 6 | + _s = require('underscore.string'), |
| 7 | + pluralize = require('pluralize'); |
| 8 | + |
| 9 | +var EntityGenerator = module.exports = function EntityGenerator(args, options, config) { |
| 10 | + // By calling `NamedBase` here, we get the argument to the subgenerator call |
| 11 | + // as `this.name`. |
| 12 | + yeoman.generators.NamedBase.apply(this, arguments); |
| 13 | + |
| 14 | + console.log('You called the entity subgenerator with the argument ' + this.name + '.'); |
| 15 | + |
| 16 | + fs.readFile('generator.json', 'utf8', function (err, data) { |
| 17 | + if (err) { |
| 18 | + console.log('Error: ' + err); |
| 19 | + return; |
| 20 | + } |
| 21 | + this.generatorConfig = JSON.parse(data); |
| 22 | + }.bind(this)); |
| 23 | +}; |
| 24 | + |
| 25 | +util.inherits(EntityGenerator, yeoman.generators.NamedBase); |
| 26 | + |
| 27 | +EntityGenerator.prototype.askFor = function askFor() { |
| 28 | + var cb = this.async(); |
| 29 | + |
| 30 | + console.log('\nPlease specify an attribute:'); |
| 31 | + |
| 32 | + var prompts = [{ |
| 33 | + type: 'input', |
| 34 | + name: 'attrName', |
| 35 | + message: 'What is the name of the attribute?', |
| 36 | + default: 'myattr' |
| 37 | + }, |
| 38 | + { |
| 39 | + type: 'list', |
| 40 | + name: 'attrType', |
| 41 | + message: 'What is the type of the attribute?', |
| 42 | + choices: ['String', 'Integer', 'Float', 'Boolean', 'Date', 'Enum'], |
| 43 | + default: 'String' |
| 44 | + }, |
| 45 | + { |
| 46 | + when: function (props) { return (/String/).test(props.attrType); }, |
| 47 | + type: 'input', |
| 48 | + name: 'minLength', |
| 49 | + message: 'Enter the minimum length for the String attribute, or hit enter:', |
| 50 | + validate: function (input) { |
| 51 | + if (input && isNaN(input)) { |
| 52 | + return "Please enter a number."; |
| 53 | + } |
| 54 | + return true; |
| 55 | + } |
| 56 | + }, |
| 57 | + { |
| 58 | + when: function (props) { return (/String/).test(props.attrType); }, |
| 59 | + type: 'input', |
| 60 | + name: 'maxLength', |
| 61 | + message: 'Enter the maximum length for the String attribute, or hit enter:', |
| 62 | + validate: function (input) { |
| 63 | + if (input && isNaN(input)) { |
| 64 | + return "Please enter a number."; |
| 65 | + } |
| 66 | + return true; |
| 67 | + } |
| 68 | + }, |
| 69 | + { |
| 70 | + when: function (props) { return (/Integer|Float/).test(props.attrType); }, |
| 71 | + type: 'input', |
| 72 | + name: 'min', |
| 73 | + message: 'Enter the minimum value for the numeric attribute, or hit enter:', |
| 74 | + validate: function (input) { |
| 75 | + if (input && isNaN(input)) { |
| 76 | + return "Please enter a number."; |
| 77 | + } |
| 78 | + return true; |
| 79 | + } |
| 80 | + }, |
| 81 | + { |
| 82 | + when: function (props) { return (/Integer|Float/).test(props.attrType); }, |
| 83 | + type: 'input', |
| 84 | + name: 'max', |
| 85 | + message: 'Enter the maximum value for the numeric attribute, or hit enter:', |
| 86 | + validate: function (input) { |
| 87 | + if (input && isNaN(input)) { |
| 88 | + return "Please enter a number."; |
| 89 | + } |
| 90 | + return true; |
| 91 | + } |
| 92 | + }, |
| 93 | + { |
| 94 | + when: function (props) { return (/Date/).test(props.attrType); }, |
| 95 | + type: 'list', |
| 96 | + name: 'dateConstraint', |
| 97 | + message: 'Constrain the date as follows:', |
| 98 | + choices: ['None', 'Past dates only', 'Future dates only'], |
| 99 | + filter: function (input) { |
| 100 | + if (/Past/.test(input)) return 'Past'; |
| 101 | + if (/Future/.test(input)) return 'Future'; |
| 102 | + return ''; |
| 103 | + }, |
| 104 | + default: 'None' |
| 105 | + }, |
| 106 | + { |
| 107 | + when: function (props) { return (/Enum/).test(props.attrType); }, |
| 108 | + type: 'input', |
| 109 | + name: 'enumValues', |
| 110 | + message: 'Enter an enumeration of values, separated by commas' |
| 111 | + }, |
| 112 | + { |
| 113 | + type: 'confirm', |
| 114 | + name: 'required', |
| 115 | + message: 'Is the attribute required to have a value?', |
| 116 | + default: true |
| 117 | + }, |
| 118 | + { |
| 119 | + type: 'confirm', |
| 120 | + name: 'again', |
| 121 | + message: 'Would you like to enter another attribute or reenter a previous attribute?', |
| 122 | + default: true |
| 123 | + }]; |
| 124 | + |
| 125 | + this.prompt(prompts, function (props) { |
| 126 | + this.attrs = this.attrs || []; |
| 127 | + var attrType = props.attrType; |
| 128 | + var attrImplType = props.attrType; |
| 129 | + if (attrType === 'String') { |
| 130 | + attrImplType = 'string'; |
| 131 | + } else if (attrType === 'Integer') { |
| 132 | + attrImplType = 'int64'; |
| 133 | + } else if (attrType === 'Float') { |
| 134 | + attrImplType = 'float64'; |
| 135 | + } else if (attrType === 'Boolean') { |
| 136 | + attrImplType = 'bool'; |
| 137 | + } else if (attrType === 'Date') { |
| 138 | + attrImplType = 'time.Time'; |
| 139 | + } else if (attrType === 'Enum') { |
| 140 | + attrImplType = 'enum'; |
| 141 | + } |
| 142 | + this.attrs = _.reject(this.attrs, function (attr) { return attr.attrName === props.attrName; }); |
| 143 | + this.attrs.push({ |
| 144 | + attrName: props.attrName, |
| 145 | + attrType: attrType, |
| 146 | + attrImplType: attrImplType, |
| 147 | + minLength: props.minLength, |
| 148 | + maxLength: props.maxLength, |
| 149 | + min: props.min, |
| 150 | + max: props.max, |
| 151 | + dateConstraint: props.dateConstraint, |
| 152 | + enumValues: props.enumValues ? props.enumValues.split(',') : [], |
| 153 | + required: props.required |
| 154 | + }); |
| 155 | + |
| 156 | + if (props.again) { |
| 157 | + this.askFor(); |
| 158 | + } else { |
| 159 | + cb(); |
| 160 | + } |
| 161 | + }.bind(this)); |
| 162 | +}; |
| 163 | + |
| 164 | +EntityGenerator.prototype.files = function files() { |
| 165 | + |
| 166 | + this.baseName = this.generatorConfig.baseName; |
| 167 | + this.packageName = this.generatorConfig.packageName; |
| 168 | + this.entities = this.generatorConfig.entities; |
| 169 | + this.entities = _.reject(this.entities, function (entity) { return entity.name === this.name; }.bind(this)); |
| 170 | + this.entities.push({ name: this.name, attrs: this.attrs}); |
| 171 | + this.pluralize = pluralize; |
| 172 | + this.generatorConfig.entities = this.entities; |
| 173 | + this.generatorConfigStr = JSON.stringify(this.generatorConfig, null, '\t'); |
| 174 | + |
| 175 | + this.template('_generator.json', 'generator.json'); |
| 176 | + this.template('../../app/templates/_server.go', 'server.go'); |
| 177 | + this.template('../../app/templates/models/_gorp.go', 'models/gorp.go'); |
| 178 | + this.template('models/_entity.go', 'models/' + this.name + '.go'); |
| 179 | + this.template('routes/_entities.go', 'routes/' + pluralize(this.name) + '.go'); |
| 180 | + |
| 181 | + var publicDir = 'public/'; |
| 182 | + var publicCssDir = publicDir + 'css/'; |
| 183 | + var publicJsDir = publicDir + 'js/'; |
| 184 | + var publicViewDir = publicDir + 'views/'; |
| 185 | + var publicEntityJsDir = publicJsDir + this.name + '/'; |
| 186 | + var publicEntityViewDir = publicViewDir + this.name + '/'; |
| 187 | + this.mkdir(publicEntityJsDir); |
| 188 | + this.mkdir(publicEntityViewDir); |
| 189 | + this.template('../../app/templates/public/_index.html', publicDir + 'index.html'); |
| 190 | + this.template('public/js/entity/_entity-controller.js', publicEntityJsDir + this.name + '-controller.js'); |
| 191 | + this.template('public/js/entity/_entity-router.js', publicEntityJsDir + this.name + '-router.js'); |
| 192 | + this.template('public/js/entity/_entity-service.js', publicEntityJsDir + this.name + '-service.js'); |
| 193 | + this.template('public/views/entity/_entities.html', publicEntityViewDir + pluralize(this.name) + '.html'); |
| 194 | +}; |
0 commit comments