Skip to content

Commit dee54ed

Browse files
committed
feat(CLI Onboarding): Present default project name if possible
1 parent 225c5ac commit dee54ed

2 files changed

Lines changed: 24 additions & 28 deletions

File tree

lib/cli/interactive-setup/service.js

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ const inquirer = require('@serverless/utils/inquirer');
88
const resolveConfigurationPath = require('../resolve-configuration-path');
99
const readConfiguration = require('../../configuration/read');
1010
const resolveVariables = require('../../configuration/variables');
11-
const { confirm } = require('./utils');
1211
const createFromLocalTemplate = require('../../utils/create-from-local-template');
1312
const npmCommandDeferred = require('../../utils/npm-command-deferred');
1413
const ServerlessError = require('../../serverless-error');
@@ -50,12 +49,13 @@ const INVALID_PROJECT_NAME_MESSAGE =
5049
' - It should start with an alphabetic character.\n' +
5150
" - Shouldn't exceed 128 characters";
5251

53-
const projectNameInput = async (workingDir) =>
52+
const projectNameInput = async (workingDir, projectType) =>
5453
(
5554
await inquirer.prompt({
5655
message: 'What do you want to call this project?',
5756
type: 'input',
5857
name: 'projectName',
58+
default: projectType ? `${projectType}-project` : null,
5959
validate: async (input) => {
6060
input = input.trim();
6161
if (!isValidServiceName(input)) {
@@ -72,7 +72,7 @@ const projectNameInput = async (workingDir) =>
7272
})
7373
).projectName.trim();
7474

75-
const resolveProjectNameInput = async (options, workingDir) => {
75+
const resolveProjectNameInput = async (options, workingDir, projectType = null) => {
7676
if (options.name) {
7777
if (!isValidServiceName(options.name)) {
7878
throw new ServerlessError(INVALID_PROJECT_NAME_MESSAGE, 'INVALID_PROJECT_NAME');
@@ -96,7 +96,7 @@ const resolveProjectNameInput = async (options, workingDir) => {
9696
return options.name;
9797
}
9898

99-
return projectNameInput(workingDir);
99+
return projectNameInput(workingDir, projectType);
100100
};
101101

102102
module.exports = {
@@ -135,10 +135,15 @@ module.exports = {
135135
!context.options.template &&
136136
!context.options['template-url']
137137
) {
138-
const isConfirmed = await confirm('No project detected. Do you want to create a new one?', {
139-
name: 'shouldCreateNewProject',
140-
});
141-
if (!isConfirmed) return;
138+
const isConfirmed = (
139+
await inquirer.prompt({
140+
message: 'No project detected. Do you want to create a new one?',
141+
type: 'list',
142+
name: 'shouldCreateNewProject',
143+
choices: ['Yes', 'No'],
144+
})
145+
).shouldCreateNewProject;
146+
if (isConfirmed !== 'Yes') return;
142147
}
143148

144149
let projectDir;
@@ -180,7 +185,7 @@ module.exports = {
180185
return;
181186
}
182187
}
183-
projectName = await resolveProjectNameInput(context.options, workingDir);
188+
projectName = await resolveProjectNameInput(context.options, workingDir, projectType);
184189
projectDir = join(workingDir, projectName);
185190
const templateUrl = `https://github.com/serverless/examples/tree/master/${projectType}`;
186191
process.stdout.write(`\nDownloading "${projectType}" template...\n`);

test/unit/lib/cli/interactive-setup/service.test.js

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,15 @@ describe('test/unit/lib/cli/interactive-setup/service.test.js', () => {
5454

5555
it("Should abort if user doesn't want setup", async () => {
5656
configureInquirerStub(inquirer, {
57-
confirm: { shouldCreateNewProject: false },
57+
list: { shouldCreateNewProject: 'No' },
5858
});
5959
await step.run({ options: {} });
6060
return confirmEmptyWorkingDir();
6161
});
6262

6363
it("Should abort if user choses 'other' template", async () => {
6464
configureInquirerStub(inquirer, {
65-
confirm: { shouldCreateNewProject: true },
66-
list: { projectType: 'other' },
65+
list: { projectType: 'other', shouldCreateNewProject: 'Yes' },
6766
});
6867
await step.run({ options: {} });
6968
return confirmEmptyWorkingDir();
@@ -90,8 +89,7 @@ describe('test/unit/lib/cli/interactive-setup/service.test.js', () => {
9089
});
9190

9291
configureInquirerStub(inquirer, {
93-
confirm: { shouldCreateNewProject: true },
94-
list: { projectType: 'aws-nodejs' },
92+
list: { projectType: 'aws-nodejs', shouldCreateNewProject: 'Yes' },
9593
input: { projectName: 'test-project' },
9694
});
9795
await mockedStep.run({ options: {} });
@@ -125,8 +123,7 @@ describe('test/unit/lib/cli/interactive-setup/service.test.js', () => {
125123
});
126124

127125
configureInquirerStub(inquirer, {
128-
confirm: { shouldCreateNewProject: true },
129-
list: { projectType: 'aws-nodejs' },
126+
list: { projectType: 'aws-nodejs', shouldCreateNewProject: 'Yes' },
130127
input: { projectName: 'test-project-template' },
131128
});
132129
await mockedStep.run({ options: {} });
@@ -165,8 +162,7 @@ describe('test/unit/lib/cli/interactive-setup/service.test.js', () => {
165162
});
166163

167164
configureInquirerStub(inquirer, {
168-
confirm: { shouldCreateNewProject: true },
169-
list: { projectType: 'aws-nodejs' },
165+
list: { shouldCreateNewProject: 'Yes', projectType: 'aws-nodejs' },
170166
input: { projectName: 'test-project-package-json' },
171167
});
172168
await mockedStep.run({ options: {} });
@@ -204,8 +200,7 @@ describe('test/unit/lib/cli/interactive-setup/service.test.js', () => {
204200
});
205201

206202
configureInquirerStub(inquirer, {
207-
confirm: { shouldCreateNewProject: true },
208-
list: { projectType: 'aws-nodejs' },
203+
list: { projectType: 'aws-nodejs', shouldCreateNewProject: 'Yes' },
209204
input: { projectName: 'test-project-missing-npm' },
210205
});
211206

@@ -242,8 +237,7 @@ describe('test/unit/lib/cli/interactive-setup/service.test.js', () => {
242237
});
243238

244239
configureInquirerStub(inquirer, {
245-
confirm: { shouldCreateNewProject: true },
246-
list: { projectType: 'aws-nodejs' },
240+
list: { projectType: 'aws-nodejs', shouldCreateNewProject: 'Yes' },
247241
input: { projectName: 'test-project-failed-install' },
248242
});
249243

@@ -360,8 +354,7 @@ describe('test/unit/lib/cli/interactive-setup/service.test.js', () => {
360354
},
361355
});
362356
configureInquirerStub(inquirer, {
363-
confirm: { shouldCreateNewProject: true },
364-
list: { projectType: 'aws-nodejs' },
357+
list: { projectType: 'aws-nodejs', shouldCreateNewProject: 'Yes' },
365358
input: { projectName: 'test-error-during-download' },
366359
});
367360
await expect(mockedStep.run({ options: {} })).to.be.eventually.rejected.and.have.property(
@@ -403,8 +396,7 @@ describe('test/unit/lib/cli/interactive-setup/service.test.js', () => {
403396

404397
it('Should not allow project creation in a directory in which already service is configured', async () => {
405398
configureInquirerStub(inquirer, {
406-
confirm: { shouldCreateNewProject: true },
407-
list: { projectType: 'aws-nodejs' },
399+
list: { projectType: 'aws-nodejs', shouldCreateNewProject: 'Yes' },
408400
input: { projectName: 'existing' },
409401
});
410402

@@ -430,8 +422,7 @@ describe('test/unit/lib/cli/interactive-setup/service.test.js', () => {
430422

431423
it('Should not allow project creation using an invalid project name', async () => {
432424
configureInquirerStub(inquirer, {
433-
confirm: { shouldCreateNewProject: true },
434-
list: { projectType: 'aws-nodejs' },
425+
list: { projectType: 'aws-nodejs', shouldCreateNewProject: 'Yes' },
435426
input: { projectName: 'elo grzegżółka' },
436427
});
437428
await expect(step.run({ options: {} })).to.eventually.be.rejected.and.have.property(

0 commit comments

Comments
 (0)