• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1
2module.exports = init
3module.exports.yes = yes
4
5var PZ = require('promzard').PromZard
6var path = require('path')
7var def = require.resolve('./default-input.js')
8
9var fs = require('fs')
10var semver = require('semver')
11var read = require('read')
12
13// to validate the data object at the end as a worthwhile package
14// and assign default values for things.
15// readJson.extras(file, data, cb)
16var readJson = require('read-package-json')
17
18function yes (conf) {
19  return !!(
20    conf.get('yes') || conf.get('y') ||
21    conf.get('force') || conf.get('f')
22  )
23}
24
25function init (dir, input, config, cb) {
26  if (typeof config === 'function')
27    cb = config, config = {}
28
29  // accept either a plain-jane object, or a config object
30  // with a "get" method.
31  if (typeof config.get !== 'function') {
32    var data = config
33    config = {
34      get: function (k) {
35        return data[k]
36      },
37      toJSON: function () {
38        return data
39      }
40    }
41  }
42
43  var packageFile = path.resolve(dir, 'package.json')
44  input = path.resolve(input)
45  var pkg
46  var ctx = { yes: yes(config) }
47
48  var es = readJson.extraSet
49  readJson.extraSet = es.filter(function (fn) {
50    return fn.name !== 'authors' && fn.name !== 'mans'
51  })
52  readJson(packageFile, function (er, d) {
53    readJson.extraSet = es
54
55    if (er) pkg = {}
56    else pkg = d
57
58    ctx.filename = packageFile
59    ctx.dirname = path.dirname(packageFile)
60    ctx.basename = path.basename(ctx.dirname)
61    if (!pkg.version || !semver.valid(pkg.version))
62      delete pkg.version
63
64    ctx.package = pkg
65    ctx.config = config || {}
66
67    // make sure that the input is valid.
68    // if not, use the default
69    var pz = new PZ(input, ctx)
70    pz.backupFile = def
71    pz.on('error', cb)
72    pz.on('data', function (data) {
73      Object.keys(data).forEach(function (k) {
74        if (data[k] !== undefined && data[k] !== null) pkg[k] = data[k]
75      })
76
77      // only do a few of these.
78      // no need for mans or contributors if they're in the files
79      var es = readJson.extraSet
80      readJson.extraSet = es.filter(function (fn) {
81        return fn.name !== 'authors' && fn.name !== 'mans'
82      })
83      readJson.extras(packageFile, pkg, function (er, pkg) {
84        readJson.extraSet = es
85        if (er) return cb(er, pkg)
86        pkg = unParsePeople(pkg)
87        // no need for the readme now.
88        delete pkg.readme
89        delete pkg.readmeFilename
90
91        // really don't want to have this lying around in the file
92        delete pkg._id
93
94        // ditto
95        delete pkg.gitHead
96
97        // if the repo is empty, remove it.
98        if (!pkg.repository)
99          delete pkg.repository
100
101        // readJson filters out empty descriptions, but init-package-json
102        // traditionally leaves them alone
103        if (!pkg.description)
104          pkg.description = data.description
105
106        var d = JSON.stringify(pkg, null, 2) + '\n'
107        function write (yes) {
108          fs.writeFile(packageFile, d, 'utf8', function (er) {
109            if (!er && yes && !config.get('silent')) {
110              console.log('Wrote to %s:\n\n%s\n', packageFile, d)
111            }
112            return cb(er, pkg)
113          })
114        }
115        if (ctx.yes) {
116          return write(true)
117        }
118        console.log('About to write to %s:\n\n%s\n', packageFile, d)
119        read({prompt:'Is this OK? ', default: 'yes'}, function (er, ok) {
120          if (er) {
121            return cb(er)
122          }
123          if (!ok || ok.toLowerCase().charAt(0) !== 'y') {
124            console.log('Aborted.')
125          } else {
126            return write()
127          }
128        })
129      })
130    })
131  })
132
133}
134
135// turn the objects into somewhat more humane strings.
136function unParsePeople (data) {
137  if (data.author) data.author = unParsePerson(data.author)
138  ;["maintainers", "contributors"].forEach(function (set) {
139    if (!Array.isArray(data[set])) return;
140    data[set] = data[set].map(unParsePerson)
141  })
142  return data
143}
144
145function unParsePerson (person) {
146  if (typeof person === "string") return person
147  var name = person.name || ""
148  var u = person.url || person.web
149  var url = u ? (" ("+u+")") : ""
150  var e = person.email || person.mail
151  var email = e ? (" <"+e+">") : ""
152  return name+email+url
153}
154
155