UNPKG

3.52 kBJavaScriptView Raw
1/**
2 * TODO: demand loading
3 * https://github.com/SBoudrias/Inquirer.js#question
4 * default, choices(if defined as functions), validate, filter and when functions can be called asynchronously.
5 * Either return a promise or use this.async() to get a callback you'll call with the final value.
6 */
7
8const fs = require('fs')
9const path = require('path')
10const { promisify } = require('util')
11
12const rc = require('rc')
13const fullname = require('fullname')
14const username = require('username')
15
16const { util } = require('../common')
17
18const readFile = promisify(fs.readFile)
19const writeFile = promisify(fs.writeFile)
20
21const npmrc = rc('npm')
22const yarnrc = rc('yarn')
23
24const getLatestAnswers = async () => {
25 try {
26 const filename = util.getDataPath('generator', 'answers.json')
27 const json = await readFile(filename, 'utf8')
28 return JSON.parse(json)
29 } catch (e) {
30 // istanbul ignore next
31 return {}
32 }
33}
34
35class Defaults {
36 constructor (dest, defaults) {
37 this.dest = dest
38 // last remember answers
39 Object.assign(this, defaults)
40 }
41
42 name (answers) {
43 return path.basename(this.dest)
44 }
45
46 async username (answers) {
47 // npm > yarn > git > system
48 // istanbul ignore next
49 const name = npmrc['init-author-name'] || yarnrc['init-author-name'] || await util.execute('git config --get user.name') || await username()
50 return name
51 }
52
53 async fullname (answers) {
54 const name = await fullname()
55 return name
56 }
57
58 async email (answers) {
59 // npm > yarn > git
60 // istanbul ignore next
61 const email = npmrc['init-author-email'] || yarnrc['init-author-email'] || await util.execute('git config --get user.email')
62 return email
63 }
64
65 async url (answers) {
66 // npm > yarn > git
67 // istanbul ignore next
68 const url = npmrc['init-author-url'] || yarnrc['init-author-url'] || await util.execute('git config --get user.url')
69 return url
70 }
71
72 async author (answers) {
73 // istanbul ignore next
74 const name = await this.username() || await this.fullname()
75 const email = await this.email()
76 const url = await this.url()
77
78 // istanbul ignore next
79 return `${name}${email ? ` <${email}>` : ''}${url ? ` (${url})` : ''}`
80 }
81
82 version (answers) {
83 // istanbul ignore next
84 return npmrc['init-version'] || yarnrc['init-version'] || '0.1.0'
85 }
86
87 license (answers) {
88 // istanbul ignore next
89 return npmrc['init-license'] || yarnrc['init-license'] || 'MIT'
90 }
91
92 repository (answers) {
93 return util.execute('git config --local --get remote.origin.url', this.dest)
94 }
95
96 /**
97 * Init new defaults.
98 * @param {String} dest destination path
99 */
100 static async init (dest) {
101 if (typeof dest !== 'string') {
102 throw new TypeError(`Expected a string, got ${typeof dest}`)
103 }
104
105 const defaults = await getLatestAnswers()
106
107 return new Defaults(dest, defaults)
108 }
109
110 /**
111 * Save prompt answers.
112 * @param {Object} answers prompt answers
113 */
114 static async save (answers) {
115 // merge
116 const defaults = await getLatestAnswers()
117 Object.assign(defaults, answers)
118
119 // delete ignore
120 delete defaults.name
121 delete defaults.description
122 delete defaults.repo
123 delete defaults.repository
124
125 // save
126 const json = JSON.stringify(defaults, null, 2)
127 await util.mkdirp(util.getDataPath('generator'))
128 await writeFile(util.getDataPath('generator', 'answers.json'), json)
129 }
130}
131
132// alias
133Defaults.prototype.repo = Defaults.prototype.repository
134
135// export
136module.exports = Defaults