2 var glob = require('glob')
3 var path = require('path')
4 var validateLicense = require('validate-npm-package-license')
5 var validateName = require('validate-npm-package-name')
6 var npa = require('npm-package-arg')
7 var semver = require('semver')
9 // more popular packages should go here, maybe?
10 function isTestPkg (p) {
11 return !!p.match(/^(expresso|mocha|tap|coffee-script|coco|streamline)$/)
14 function niceName (n) {
15 return n.replace(/^node-|[.-]js$/g, '').toLowerCase()
18 function readDeps (test) { return function (cb) {
19 fs.readdir('node_modules', function (er, dir) {
23 if (n === 0) return cb(null, deps)
24 dir.forEach(function (d) {
25 if (d.match(/^\./)) return next()
26 if (test !== isTestPkg(d))
29 var dp = path.join(dirname, 'node_modules', d, 'package.json')
30 fs.readFile(dp, 'utf8', function (er, p) {
32 try { p = JSON.parse(p) }
33 catch (e) { return next() }
34 if (!p.version) return next()
36 if (!p._requiredBy.some(function (req) { return req === '#USER' })) return next()
38 deps[d] = config.get('save-exact') ? p.version : config.get('save-prefix') + p.version
43 if (--n === 0) return cb(null, deps)
48 var name = package.name || basename
50 var scope = config.get('scope')
52 if (scope.charAt(0) !== '@') scope = '@' + scope
54 name = scope + '/' + spec.name.split('/')[1]
56 name = scope + '/' + name
59 exports.name = yes ? name : prompt('name', name, function (data) {
60 var its = validateName(data)
61 if (its.validForNewPackages) return data
62 var errors = (its.errors || []).concat(its.warnings || [])
63 var er = new Error('Sorry, ' + errors.join(' and ') + '.')
68 var version = package.version ||
69 config.get('init.version') ||
70 config.get('init-version') ||
72 exports.version = yes ?
74 prompt('version', version, function (version) {
75 if (semver.valid(version)) return version
76 var er = new Error('Invalid version: "' + version + '"')
81 if (!package.description) {
82 exports.description = yes ? '' : prompt('description')
86 exports.main = function (cb) {
87 fs.readdir(dirname, function (er, f) {
90 f = f.filter(function (f) {
91 return f.match(/\.js$/)
94 if (f.indexOf('index.js') !== -1)
96 else if (f.indexOf('main.js') !== -1)
98 else if (f.indexOf(basename + '.js') !== -1)
103 var index = f || 'index.js'
104 return cb(null, yes ? index : prompt('entry point', index))
110 exports.bin = function (cb) {
111 fs.readdir(path.resolve(dirname, 'bin'), function (er, d) {
114 // just take the first js file we find there, or nada
115 return cb(null, d.filter(function (f) {
116 return f.match(/\.js$/)
122 exports.directories = function (cb) {
123 fs.readdir(dirname, function (er, dirs) {
124 if (er) return cb(er)
126 dirs.forEach(function (d) {
128 case 'example': case 'examples': return res.example = d
129 case 'test': case 'tests': return res.test = d
130 case 'doc': case 'docs': return res.doc = d
131 case 'man': return res.man = d
134 if (Object.keys(res).length === 0) res = undefined
139 if (!package.dependencies) {
140 exports.dependencies = readDeps(false)
143 if (!package.devDependencies) {
144 exports.devDependencies = readDeps(true)
147 // MUST have a test script!
148 var s = package.scripts || {}
149 var notest = 'echo "Error: no test specified" && exit 1'
150 if (!package.scripts) {
151 exports.scripts = function (cb) {
152 fs.readdir(path.join(dirname, 'node_modules'), function (er, d) {
153 setupScripts(d || [], cb)
157 function setupScripts (d, cb) {
158 // check to see what framework is in use, if any
160 return test || notest
162 if (!s.test || s.test === notest) {
164 'tap':'tap test/*.js'
165 , 'expresso':'expresso test'
169 Object.keys(commands).forEach(function (k) {
170 if (d.indexOf(k) !== -1) command = commands[k]
172 var ps = 'test command'
174 s.test = command || notest
176 s.test = command ? prompt(ps, command, tx) : prompt(ps, tx)
182 if (!package.repository) {
183 exports.repository = function (cb) {
184 fs.readFile('.git/config', 'utf8', function (er, gconf) {
186 return cb(null, yes ? '' : prompt('git repository'))
188 gconf = gconf.split(/\r?\n/)
189 var i = gconf.indexOf('[remote "origin"]')
192 if (!u.match(/^\s*url =/)) u = gconf[i + 2]
193 if (!u.match(/^\s*url =/)) u = null
194 else u = u.replace(/^\s*url = /, '')
196 if (u && u.match(/^git@github.com:/))
197 u = u.replace(/^git@github.com:/, 'https://github.com/')
199 return cb(null, yes ? u : prompt('git repository', u))
204 if (!package.keywords) {
205 exports.keywords = yes ? '' : prompt('keywords', function (s) {
206 if (!s) return undefined
207 if (Array.isArray(s)) s = s.join(' ')
208 if (typeof s !== 'string') return s
209 return s.split(/[\s,]+/)
213 if (!package.author) {
214 exports.author = config.get('init.author.name') ||
215 config.get('init-author-name')
217 "name" : config.get('init.author.name') ||
218 config.get('init-author-name'),
219 "email" : config.get('init.author.email') ||
220 config.get('init-author-email'),
221 "url" : config.get('init.author.url') ||
222 config.get('init-author-url')
224 : yes ? '' : prompt('author')
227 var license = package.license ||
228 config.get('init.license') ||
229 config.get('init-license') ||
231 exports.license = yes ? license : prompt('license', license, function (data) {
232 var its = validateLicense(data)
233 if (its.validForNewPackages) return data
234 var errors = (its.errors || []).concat(its.warnings || [])
235 var er = new Error('Sorry, ' + errors.join(' and ') + '.')