Skip to content

Commit f372f55

Browse files
committed
feat: allow saving multiple presets
1 parent 9856549 commit f372f55

File tree

19 files changed

+250
-191
lines changed

19 files changed

+250
-191
lines changed

__mocks__/inquirer.js

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ exports.prompt = prompts => {
2828
const a = pendingAssertions[i - skipped]
2929
if (!a) {
3030
console.error(`no matching assertion for prompt:`, prompt)
31+
console.log(prompts)
32+
console.log(pendingAssertions)
3133
}
3234

3335
if (a.message) {

packages/@vue/cli-plugin-pwa/__tests__/pwaPlugin.spec.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ jest.setTimeout(30000)
33
const path = require('path')
44
const portfinder = require('portfinder')
55
const { createServer } = require('http-server')
6-
const { defaults } = require('@vue/cli/lib/options')
6+
const { defaultPreset } = require('@vue/cli/lib/options')
77
const create = require('@vue/cli-test-utils/createTestProject')
88
const launchPuppeteer = require('@vue/cli-test-utils/launchPuppeteer')
99

1010
let server, browser
1111
test('pwa', async () => {
1212
// it's ok to mutate here since jest loads each test in a separate vm
13-
defaults.plugins['@vue/cli-plugin-pwa'] = {}
14-
const project = await create('pwa-build', defaults)
13+
defaultPreset.plugins['@vue/cli-plugin-pwa'] = {}
14+
const project = await create('pwa-build', defaultPreset)
1515
expect(project.has('src/registerServiceWorker.js')).toBe(true)
1616

1717
const { stdout } = await project.run('vue-cli-service build')

packages/@vue/cli-service/__tests__/build.spec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ jest.setTimeout(30000)
33
const path = require('path')
44
const portfinder = require('portfinder')
55
const { createServer } = require('http-server')
6-
const { defaults } = require('@vue/cli/lib/options')
6+
const { defaultPreset } = require('@vue/cli/lib/options')
77
const create = require('@vue/cli-test-utils/createTestProject')
88
const launchPuppeteer = require('@vue/cli-test-utils/launchPuppeteer')
99

1010
let server, browser, page
1111
test('build', async () => {
12-
const project = await create('e2e-build', defaults)
12+
const project = await create('e2e-build', defaultPreset)
1313

1414
// test public copy
1515
project.write('public/foo.js', '1')

packages/@vue/cli-service/__tests__/buildDLL.spec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ jest.setTimeout(30000)
33
const path = require('path')
44
const portfinder = require('portfinder')
55
const { createServer } = require('http-server')
6-
const { defaults } = require('@vue/cli/lib/options')
6+
const { defaultPreset } = require('@vue/cli/lib/options')
77
const create = require('@vue/cli-test-utils/createTestProject')
88
const launchPuppeteer = require('@vue/cli-test-utils/launchPuppeteer')
99

1010
let server, browser, page
1111
test('build with DLL', async () => {
12-
const project = await create('e2e-build-dll', Object.assign({}, defaults, {
12+
const project = await create('e2e-build-dll', Object.assign({}, defaultPreset, {
1313
router: true,
1414
vuex: true
1515
}))

packages/@vue/cli-service/__tests__/serve.spec.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
jest.setTimeout(30000)
22

3-
const { defaults } = require('@vue/cli/lib/options')
3+
const { defaultPreset } = require('@vue/cli/lib/options')
44
const create = require('@vue/cli-test-utils/createTestProject')
55
const serve = require('@vue/cli-test-utils/serveWithPuppeteer')
66

77
const sleep = n => new Promise(resolve => setTimeout(resolve, n))
88

99
test('serve', async () => {
10-
const project = await create('e2e-serve', defaults)
10+
const project = await create('e2e-serve', defaultPreset)
1111

1212
await serve(
1313
() => project.run('vue-cli-service serve'),
@@ -26,7 +26,7 @@ test('serve', async () => {
2626
})
2727

2828
test('serve with router', async () => {
29-
const project = await create('e2e-serve-router', Object.assign({}, defaults, {
29+
const project = await create('e2e-serve-router', Object.assign({}, defaultPreset, {
3030
router: true
3131
}))
3232

Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module.exports = function silence (exports) {
1+
module.exports = function silence (logName, exports) {
22
const logs = {}
33
Object.keys(exports).forEach(key => {
44
if (key !== 'error') {
@@ -8,5 +8,5 @@ module.exports = function silence (exports) {
88
}
99
}
1010
})
11-
exports.logs = logs
11+
exports[logName] = logs
1212
}

packages/@vue/cli-shared-utils/lib/logger.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,5 @@ exports.clearConsole = title => {
4545

4646
// silent all logs except errors during tests and keep record
4747
if (process.env.VUE_CLI_TEST) {
48-
require('./_silence')(exports)
48+
require('./_silence')('logs', exports)
4949
}

packages/@vue/cli-shared-utils/lib/spinner.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,5 @@ exports.resumeSpinner = () => {
4545

4646
// silent all logs except errors during tests and keep record
4747
if (process.env.VUE_CLI_TEST) {
48-
require('./_silence')(exports)
48+
require('./_silence')('spinner', exports)
4949
}

packages/@vue/cli-shared-utils/lib/validate.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@ const { error } = require('./logger')
44
// proxy to joi for option validation
55
exports.createSchema = fn => fn(joi)
66

7-
exports.validate = (obj, schema, options = {}) => {
7+
exports.validate = (obj, schema, options = {}, noExit) => {
88
joi.validate(obj, schema, options, err => {
99
if (err) {
1010
error(`vue-cli options validation failed:\n` + err.message)
11-
process.exit(1)
11+
if (!noExit) {
12+
process.exit(1)
13+
} else {
14+
throw err
15+
}
1216
}
1317
})
1418
}
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// using this requires mocking fs & inquirer
22

33
const Creator = require('@vue/cli/lib/Creator')
4+
const { loadOptions } = require('@vue/cli/lib/options')
45
const { expectPrompts } = require('inquirer') // from mock
56

67
module.exports = async function assertPromptModule (
@@ -13,7 +14,7 @@ module.exports = async function assertPromptModule (
1314
if (opts.plguinsOnly) {
1415
expectedPrompts.unshift(
1516
{
16-
message: 'project creation mode',
17+
message: 'Please pick a preset',
1718
choose: 1
1819
}
1920
)
@@ -23,23 +24,24 @@ module.exports = async function assertPromptModule (
2324
choose: 1 // package.json
2425
},
2526
{
26-
message: 'package manager',
27-
choose: 0 // yarn
28-
},
29-
{
30-
message: 'Save the preferences',
27+
message: 'Save this as a preset',
3128
confirm: false
3229
}
3330
)
31+
if (!loadOptions().packageManager) {
32+
expectedPrompts.push({
33+
message: 'package manager',
34+
choose: 0 // yarn
35+
})
36+
}
3437
}
3538

3639
expectPrompts(expectedPrompts)
3740
const creator = new Creator('test', '/', [].concat(module))
38-
const options = await creator.promptAndResolveOptions()
41+
const preset = await creator.promptAndResolvePreset()
3942

4043
if (opts.plguinsOnly) {
41-
delete options.packageManager
42-
delete options.useConfigFiles
44+
delete preset.useConfigFiles
4345
}
44-
expect(options).toEqual(expectedOptions)
46+
expect(preset).toEqual(expectedOptions)
4547
}

packages/@vue/cli-test-utils/createTestProject.js

+3-9
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,9 @@ const readFile = promisify(fs.readFile)
66
const writeFile = promisify(fs.writeFile)
77
const mkdirp = promisify(require('mkdirp'))
88

9-
module.exports = function createTestProject (name, config, cwd) {
9+
module.exports = function createTestProject (name, preset, cwd) {
1010
cwd = cwd || path.resolve(__dirname, '../../test')
1111

12-
config = Object.assign({
13-
packageManager: 'yarn',
14-
useTaobaoRegistry: false,
15-
plugins: {}
16-
}, config)
17-
1812
const projectRoot = path.resolve(cwd, name)
1913

2014
const read = file => {
@@ -46,8 +40,8 @@ module.exports = function createTestProject (name, config, cwd) {
4640
'create',
4741
name,
4842
'--force',
49-
'--config',
50-
JSON.stringify(config)
43+
'--inlinePreset',
44+
JSON.stringify(preset)
5145
]
5246

5347
const options = {

packages/@vue/cli/__tests__/Creator.spec.js

+14-11
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,20 @@ const assertPromptModule = require('@vue/cli-test-utils/assertPromptModule')
77
test('default', async () => {
88
const epxectedPrompts = [
99
{
10-
message: 'project creation mode',
10+
message: 'pick a preset',
1111
choices: [
12-
'Zero-config',
12+
'default',
1313
'Manually select'
1414
],
1515
choose: 0
16+
},
17+
{
18+
message: 'package manager',
19+
choices: ['Yarn', 'NPM'],
20+
choose: 0
1621
}
1722
]
18-
assertPromptModule([], epxectedPrompts, defaults)
23+
await assertPromptModule([], epxectedPrompts, defaults.presets.default)
1924
})
2025

2126
test('manual + PromptModuleAPI', async () => {
@@ -73,18 +78,16 @@ test('manual + PromptModuleAPI', async () => {
7378
choose: 0
7479
},
7580
{
76-
message: 'package manager',
77-
choices: ['Yarn', 'NPM'],
78-
choose: 0
81+
message: 'Save this as a preset',
82+
confirm: true
7983
},
8084
{
81-
message: 'Save the preferences',
82-
confirm: true
85+
message: 'Save preset as',
86+
input: 'test'
8387
}
8488
]
8589

8690
const expectedOptions = {
87-
packageManager: 'yarn',
8891
useConfigFiles: true,
8992
plugins: {
9093
bar: {},
@@ -98,8 +101,8 @@ test('manual + PromptModuleAPI', async () => {
98101
const expectedPromptsForSaved = [
99102
{
100103
choices: [
101-
'Use previously saved',
102-
'Zero-config',
104+
'test',
105+
'default',
103106
'Manually'
104107
],
105108
choose: 0

packages/@vue/cli/__tests__/Generator.spec.js

+1-5
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,7 @@ test('extract config files', async () => {
323323
},
324324
jest: {
325325
foo: 'bar'
326-
},
327-
browserslist: [
328-
'>=ie9'
329-
]
326+
}
330327
}
331328

332329
const generator = new Generator('/', {}, [
@@ -345,6 +342,5 @@ test('extract config files', async () => {
345342
expect(fs.readFileSync('/.babelrc', 'utf-8')).toMatch(json(configs.babel))
346343
expect(fs.readFileSync('/.postcssrc', 'utf-8')).toMatch(json(configs.postcss))
347344
expect(fs.readFileSync('/.eslintrc', 'utf-8')).toMatch(json(configs.eslintConfig))
348-
expect(fs.readFileSync('/.browserslistrc', 'utf-8')).toMatch(configs.browserslist.join('\n'))
349345
expect(fs.readFileSync('/jest.config.js', 'utf-8')).toMatch(`module.exports = {\n foo: 'bar'\n}`)
350346
})

packages/@vue/cli/__tests__/options.spec.js

+26-22
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@ const fs = require('fs')
44
const {
55
rcPath,
66
loadOptions,
7-
saveOptions
7+
saveOptions,
8+
savePreset
89
} = require('../lib/options')
910

1011
test('load options', () => {
1112
expect(loadOptions()).toEqual({})
1213
fs.writeFileSync(rcPath, JSON.stringify({
13-
plugins: {}
14+
presets: {}
1415
}, null, 2))
1516
expect(loadOptions()).toEqual({
16-
plugins: {}
17+
presets: {}
1718
})
1819
})
1920

@@ -22,49 +23,52 @@ test('should not save unknown fields', () => {
2223
foo: 'bar'
2324
})
2425
expect(loadOptions()).toEqual({
25-
plugins: {}
26+
presets: {}
2627
})
2728
})
2829

29-
test('save options (merge)', () => {
30+
test('save options', () => {
31+
// partial
3032
saveOptions({
3133
packageManager: 'yarn'
3234
})
3335
expect(loadOptions()).toEqual({
3436
packageManager: 'yarn',
35-
plugins: {}
37+
presets: {}
3638
})
3739

40+
// replace
3841
saveOptions({
39-
plugins: {
42+
presets: {
4043
foo: { a: 1 }
4144
}
4245
})
4346
expect(loadOptions()).toEqual({
4447
packageManager: 'yarn',
45-
plugins: {
48+
presets: {
4649
foo: { a: 1 }
4750
}
4851
})
52+
})
4953

50-
// shallow save should replace fields
51-
saveOptions({
52-
plugins: {
53-
bar: { b: 2 }
54+
test('save preset', () => {
55+
savePreset('bar', { a: 2 })
56+
expect(loadOptions()).toEqual({
57+
packageManager: 'yarn',
58+
presets: {
59+
foo: { a: 1 },
60+
bar: { a: 2 }
5461
}
5562
})
63+
64+
// should entirely replace presets
65+
savePreset('foo', { c: 3 })
66+
savePreset('bar', { d: 4 })
5667
expect(loadOptions()).toEqual({
5768
packageManager: 'yarn',
58-
plugins: {
59-
bar: { b: 2 }
69+
presets: {
70+
foo: { c: 3 },
71+
bar: { d: 4 }
6072
}
6173
})
6274
})
63-
64-
test('save options (replace)', () => {
65-
const toSave = {
66-
foo: 'bar'
67-
}
68-
saveOptions(toSave, true)
69-
expect(loadOptions()).toEqual(toSave)
70-
})

packages/@vue/cli/bin/vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ program
3737
program
3838
.command('create <app-name>')
3939
.description('create a new project powered by vue-cli-service')
40-
.option('-s, --saved', 'Skip prompts and use saved config')
40+
.option('-p, --preset <presetName>', 'Skip prompts and use saved preset')
4141
.option('-d, --default', 'Skip prompts and use default config')
42-
.option('-c, --config <json>', 'Skip prompts and use inline JSON string as config')
42+
.option('-i, --inlinePreset <json>', 'Skip prompts and use inline JSON string as preset')
4343
.option('-r, --registry <url>', 'Use specified NPM registry when installing dependencies')
4444
.option('-m, --packageManager <command>', 'Use specified NPM client when installing dependencies')
4545
.option('-f, --force', 'Overwrite target directory if it exists')

0 commit comments

Comments
 (0)