UNPKG

6.27 kBJavaScriptView Raw
1'use strict'
2
3var path = require('path')
4 , npm = require('npm')
5 , npmName = require('npm-name')
6 , yeoman = require('yeoman-generator')
7 , getUsername = require('username')
8 , getFullname = require('fullname')
9 , _ = require('lodash')
10 , mkdirp = require('mkdirp')
11 , cwd = process.cwd()
12
13module.exports = yeoman.generators.Base.extend({
14 init: function init () {
15 var done = this.async()
16 this.pkg = require('../package.json')
17 this.log(
18 this.yeoman +
19 '\nThe name of your project shouldn\'t contain "node" or "js" and' +
20 '\nshould be a unique ID not already in use at npmjs.org.')
21 npm.load(done)
22 }
23
24 , askForModuleName: function askForModuleName () {
25 var done = this.async()
26 , prompts
27
28 prompts = [{
29 name: 'name'
30 , message: 'Module Name'
31 , 'default': path.basename(cwd)
32 }
33 , {
34 type: 'confirm'
35 , name: 'pkgName'
36 , message: 'The name above already exists on npm, choose another?'
37 , 'default': true
38 , when: function when (answers) {
39 var whenDone = this.async()
40
41 npmName(answers.name, function gotNPMName (err, available) {
42 if (err || !available){
43 return void whenDone(true)
44 }
45
46 whenDone(false)
47 })
48 }
49 }]
50
51 this.prompt(prompts, function onPrompt (props) {
52 if (props.pkgName) return this.askForModuleName()
53
54 this.slugname = _.deburr(props.name).split(' ').join('-')
55 this.escapedSlugname = encodeURIComponent(props.name)
56 this.safeSlugname = this.slugname.replace(/-+([a-zA-Z0-9])/g, function safedTheSlugName (g) {
57 return g[1].toUpperCase()
58 }).replace('@', '').replace('/', '-')
59
60 done()
61 }.bind(this))
62 }
63
64 , askFor: function askFor () {
65 var done = this.async()
66 , fullname = ''
67 , prompts
68
69 getFullname(function gotFullname (err, name) {
70 if (err) console.info('could not get fullname from system')
71 fullname = name
72
73 prompts = [{
74 name: 'description'
75 , message: 'Description'
76 , 'default': 'The best module ever.'
77 }
78 , {
79 name: 'homepage'
80 , message: 'Homepage'
81 }
82 , {
83 name: 'keywords'
84 , message: 'Key your keywords (comma to split)'
85 }
86 , {
87 name: 'license'
88 , message: 'License'
89 , 'default': 'Artistic-2.0'
90 , store: true
91 // TODO: present options from https://spdx.org/licenses/
92 }
93 , {
94 name: 'githubUsername'
95 , message: 'GitHub username'
96 , 'default': getUsername.sync()
97 , store: true
98 }
99 , {
100 name: 'authorName'
101 , message: 'Author\'s Name'
102 , 'default': npm.config.get('init.author.name') || fullname
103 , store: true
104 }
105 , {
106 name: 'authorEmail'
107 , message: 'Author\'s Email'
108 , 'default': npm.config.get('init.author.email')
109 , store: true
110 }
111 , {
112 name: 'authorUrl'
113 , message: 'Author\'s Homepage'
114 , 'default': npm.config.get('init.author.site')
115 , store: true
116 }
117 , {
118 name: 'isEs6'
119 , message: 'Will you use ES6 or JSX?'
120 , type: 'confirm'
121 , 'default': true
122 }
123 , {
124 name: 'isServer'
125 , message: 'Is this a node module? (Will it run on the server)'
126 , type: 'confirm'
127 , 'default': true
128 }
129 , {
130 name: 'isBrowser'
131 , message: 'Will this run in the browser?'
132 , type: 'confirm'
133 , 'default': true
134 }
135 , {
136 name: 'isCLI'
137 , message: 'Will have a CLI API?'
138 , type: 'confirm'
139 , 'default': false
140 }
141 , {
142 name: 'extension'
143 , message: 'Default extension?'
144 , 'default': '.js'
145 }
146 , {
147 name: 'isPrivate'
148 , message: 'Is this a private module?'
149 , store: true
150 , type: 'confirm'
151 , 'default': true
152 }]
153
154 this.currentYear = (new Date()).getFullYear()
155
156 this.prompt(prompts, function onPrompt (props) {
157 this.repoName = this.slugname.split('/').filter(function removeName (part, i) {
158 if (i === 0 && part.toLowerCase() === '@' + props.githubUsername.toLowerCase()) return false
159 else return true
160 }).join('-')
161
162 if (props.githubUsername){
163 this.repoUrl = props.githubUsername + '/' + this.repoName.replace('@', '')
164 }
165 else {
166 this.repoUrl = 'user/repo'
167 }
168
169 this.keywords = props.keywords.split(',')
170 .map(function trimKeywords (el) {
171 return el.trim()
172 })
173 .filter(Boolean)
174 .sort()
175
176 this.publicness = props.isPrivate ? 'restricted' : 'public'
177
178 props.extension = props.extension.trim()
179 if (props.extension.indexOf('.') !== 0) {
180 props.extension = '.' + props.extension
181 }
182
183 props.isServerAndBrowser = (props.isServer || props.isCLI) && props.isBrowser
184
185 this.props = props
186
187 done()
188 }.bind(this))
189 }.bind(this))
190 }
191
192 , app: function app () {
193 this.config.save()
194 this.copy('editorconfig', '.editorconfig')
195 this.copy('gitignore', '.gitignore')
196 this.copy('npmrc', '.npmrc')
197 this.copy('scripts.sh', 'scripts.sh')
198 this.copy('travis.yml', '.travis.yml')
199
200 if (this.props.isEs6) {
201 this.copy('babelrc', '.babelrc')
202 }
203
204 this.template('eslintrc', '.eslintrc')
205 this.template('npmignore', '.npmignore')
206 this.template('README.md', 'README.md')
207 this.template('_package.json', 'package.json')
208 this.template('CONTRIBUTING.md', 'CONTRIBUTING.md')
209 this.template('CHANGELOG.md', 'CHANGELOG.md')
210 this.template('LICENSE', 'LICENSE')
211 }
212
213 , projectfiles: function projectfiles () {
214 this.template('index.js', 'index' + this.props.extension)
215 mkdirp(path.join(cwd, 'test'))
216 this.template('test/test.js', 'test/test' + this.props.extension)
217 if (this.props.isCLI) {
218 mkdirp(path.join(cwd, 'bin'))
219 this.template('bin/cli', 'bin/' + this.repoName)
220 }
221 }
222
223 , install: function install () {
224 this.installDependencies({
225 bower: false
226 , skipInstall: this.options['skip-install']
227 })
228 }
229})