@form8ion/project 21.1.1 → 22.0.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,32 +1,28 @@
1
- import {afterEach, describe, expect, it, vi} from 'vitest';
1
+ import {describe, expect, it, vi} from 'vitest';
2
2
  import any from '@travi/any';
3
3
  import {when} from 'vitest-when';
4
4
 
5
- import * as prompt from './prompt.js';
5
+ import {promptForDependencyUpdaterChoice} from './prompt.js';
6
6
  import scaffoldUpdater from './scaffolder.js';
7
7
  import {questionNames} from '../index.js';
8
- import {promptForDependencyUpdaterChoice} from './prompt.js';
9
8
 
10
- vi.mock('./prompt');
9
+ vi.mock('./prompt.js');
11
10
 
12
11
  describe('dependency-updater scaffolder', () => {
13
- afterEach(() => {
14
- vi.clearAllMocks();
15
- });
12
+ const prompt = () => undefined;
16
13
 
17
14
  it('should execute the chosen scaffolder with the appropriate options', async () => {
18
- const decisions = any.simpleObject();
19
15
  const options = any.simpleObject();
20
16
  const chosenUpdater = any.word();
21
17
  const chosenUpdaterScaffolder = vi.fn();
22
18
  const plugins = {...any.simpleObject(), [chosenUpdater]: {scaffold: chosenUpdaterScaffolder}};
23
19
  const scaffolderResult = any.simpleObject();
24
- when(prompt.promptForDependencyUpdaterChoice)
25
- .calledWith(plugins, decisions)
20
+ when(promptForDependencyUpdaterChoice)
21
+ .calledWith(plugins, {prompt})
26
22
  .thenResolve({[questionNames.DEPENDENCY_UPDATER]: chosenUpdater});
27
23
  when(chosenUpdaterScaffolder).calledWith(options).thenResolve(scaffolderResult);
28
24
 
29
- expect(await scaffoldUpdater(plugins, decisions, options)).toEqual(scaffolderResult);
25
+ expect(await scaffoldUpdater(plugins, options, {prompt})).toEqual(scaffolderResult);
30
26
  });
31
27
 
32
28
  it('should not present a prompt if no updaters are registered', async () => {
package/src/index.js CHANGED
@@ -1,9 +1,7 @@
1
- import {questionNames as coreQuestionNames} from '@form8ion/core';
2
- import {questionNames as projectScaffolderQuestionNames} from './prompts/question-names.js';
1
+ import {ids} from './prompts/index.js';
3
2
 
4
3
  export * from './scaffolder.js';
5
4
  export {default as lift} from './lift.js';
6
- export const questionNames = {
7
- ...coreQuestionNames,
8
- ...projectScaffolderQuestionNames
9
- };
5
+ export const promptConstants = {ids};
6
+
7
+ export {questionNames} from './prompts/index.js';
@@ -1,12 +1,15 @@
1
- import {prompt} from '@form8ion/overridable-prompts';
2
-
3
1
  import {questionNames} from '../prompts/question-names.js';
4
2
 
5
- export default function (languages, decisions) {
6
- return prompt([{
7
- name: questionNames.PROJECT_LANGUAGE,
8
- type: 'list',
9
- message: 'What type of project is this?',
10
- choices: [...Object.keys(languages), 'Other']
11
- }], decisions);
3
+ export const PROJECT_LANGUAGE_PROMPT_ID = 'PROJECT_LANGUAGE';
4
+
5
+ export default function promptForProjectLanguage(languages, {prompt}) {
6
+ return prompt({
7
+ id: PROJECT_LANGUAGE_PROMPT_ID,
8
+ questions: [{
9
+ name: questionNames.PROJECT_LANGUAGE,
10
+ type: 'list',
11
+ message: 'What type of project is this?',
12
+ choices: [...Object.keys(languages), 'Other']
13
+ }]
14
+ });
12
15
  }
@@ -1,30 +1,27 @@
1
- import {prompt} from '@form8ion/overridable-prompts';
2
-
3
- import {afterEach, describe, expect, it, vi} from 'vitest';
1
+ import {describe, expect, it, vi} from 'vitest';
4
2
  import any from '@travi/any';
5
3
  import {when} from 'vitest-when';
6
4
 
7
5
  import {questionNames} from '../prompts/question-names.js';
8
- import promptForLanguageDetails from './prompt.js';
6
+ import promptForLanguageDetails, {PROJECT_LANGUAGE_PROMPT_ID} from './prompt.js';
9
7
 
10
8
  vi.mock('@form8ion/overridable-prompts');
11
9
 
12
10
  describe('language prompt', () => {
13
- afterEach(() => {
14
- vi.clearAllMocks();
15
- });
16
-
17
11
  it('should prompt for the language details', async () => {
12
+ const prompt = vi.fn();
18
13
  const answers = any.simpleObject();
19
- const decisions = any.simpleObject();
20
14
  const languages = any.simpleObject();
21
- when(prompt).calledWith([{
22
- name: questionNames.PROJECT_LANGUAGE,
23
- type: 'list',
24
- message: 'What type of project is this?',
25
- choices: [...Object.keys(languages), 'Other']
26
- }], decisions).thenResolve(answers);
15
+ when(prompt).calledWith({
16
+ id: PROJECT_LANGUAGE_PROMPT_ID,
17
+ questions: [{
18
+ name: questionNames.PROJECT_LANGUAGE,
19
+ type: 'list',
20
+ message: 'What type of project is this?',
21
+ choices: [...Object.keys(languages), 'Other']
22
+ }]
23
+ }).thenResolve(answers);
27
24
 
28
- expect(await promptForLanguageDetails(languages, decisions)).toEqual(answers);
25
+ expect(await promptForLanguageDetails(languages, {prompt})).toEqual(answers);
29
26
  });
30
27
  });
@@ -1,8 +1,8 @@
1
1
  import {questionNames} from '../prompts/question-names.js';
2
2
  import promptForLanguageDetails from './prompt.js';
3
3
 
4
- export default async function (languagePlugins, decisions, options) {
5
- const {[questionNames.PROJECT_LANGUAGE]: chosenLanguage} = await promptForLanguageDetails(languagePlugins, decisions);
4
+ export default async function (languagePlugins, options, {prompt}) {
5
+ const {[questionNames.PROJECT_LANGUAGE]: chosenLanguage} = await promptForLanguageDetails(languagePlugins, {prompt});
6
6
 
7
7
  const plugin = languagePlugins[chosenLanguage];
8
8
 
@@ -13,15 +13,15 @@ describe('language scaffolder', () => {
13
13
  const options = any.simpleObject();
14
14
  const chosenLanguage = any.word();
15
15
  const scaffolderResult = any.simpleObject();
16
- const decisions = any.simpleObject();
16
+ const prompt = () => undefined;
17
17
  const chosenLanguageScaffolder = vi.fn();
18
18
  const plugins = {...any.simpleObject(), [chosenLanguage]: {scaffold: chosenLanguageScaffolder}};
19
19
  when(languagePrompt.default)
20
- .calledWith(plugins, decisions)
20
+ .calledWith(plugins, {prompt})
21
21
  .thenResolve({[questionNames.PROJECT_LANGUAGE]: chosenLanguage});
22
22
  when(chosenLanguageScaffolder).calledWith(options).thenResolve(scaffolderResult);
23
23
 
24
- expect(await scaffold(plugins, decisions, options)).toEqual(scaffolderResult);
24
+ expect(await scaffold(plugins, options, {prompt})).toEqual(scaffolderResult);
25
25
  });
26
26
 
27
27
  it('should not result in an error when choosing a language without a defined scaffolder', async () => {
@@ -4,11 +4,9 @@ import joi from 'joi';
4
4
  import languagePluginsSchema from './language/schema.js';
5
5
  import vcsHostPluginsSchema from './vcs/host/schema.js';
6
6
  import dependencyUpdaterPluginsSchema from './dependency-updater/schema.js';
7
- import {decisionsSchema} from './options-schemas.js';
8
7
 
9
8
  export function validate(options) {
10
9
  return validateOptions(joi.object({
11
- decisions: decisionsSchema,
12
10
  plugins: joi.object({
13
11
  dependencyUpdaters: dependencyUpdaterPluginsSchema,
14
12
  languages: languagePluginsSchema,
@@ -6,7 +6,6 @@ import any from '@travi/any';
6
6
  import {when} from 'vitest-when';
7
7
 
8
8
  import languagePluginsSchema from './language/schema.js';
9
- import {decisionsSchema} from './options-schemas.js';
10
9
  import vcsHostPluginsSchema from './vcs/host/schema.js';
11
10
  import dependencyUpdaterPluginsSchema from './dependency-updater/schema.js';
12
11
  import {validate} from './options-validator.js';
@@ -39,10 +38,7 @@ describe('options validator', () => {
39
38
  vcsHosts: vcsHostPluginsSchema
40
39
  })
41
40
  .thenReturn(pluginsSchema);
42
- when(joi.object).calledWith({
43
- decisions: decisionsSchema,
44
- plugins: pluginsSchema
45
- }).thenReturn(fullSchema);
41
+ when(joi.object).calledWith({plugins: pluginsSchema}).thenReturn(fullSchema);
46
42
  when(core.validateOptions).calledWith(fullSchema, options).thenReturn(validatedOptions);
47
43
 
48
44
  expect(validate(options)).toEqual(validatedOptions);
@@ -0,0 +1,21 @@
1
+ import {questionNames as coreQuestionNames} from '@form8ion/core';
2
+
3
+ import {BASE_DETAILS_PROMPT_ID} from './questions.js';
4
+ import {GIT_REPOSITORY_PROMPT_ID} from '../vcs/prompt.js';
5
+ import {PROJECT_LANGUAGE_PROMPT_ID} from '../language/prompt.js';
6
+ import {REPOSITORY_HOST_PROMPT_ID} from '../vcs/host/prompt.js';
7
+ import {DEPENDENCY_UPDATER_PROMPT_ID} from '../dependency-updater/prompt.js';
8
+ import {questionNames as projectScaffolderQuestionNames} from './question-names.js';
9
+
10
+ export const ids = {
11
+ BASE_DETAILS: BASE_DETAILS_PROMPT_ID,
12
+ GIT_REPOSITORY: GIT_REPOSITORY_PROMPT_ID,
13
+ REPOSITORY_HOST: REPOSITORY_HOST_PROMPT_ID,
14
+ PROJECT_LANGUAGE: PROJECT_LANGUAGE_PROMPT_ID,
15
+ DEPENDENCY_UPDATER: DEPENDENCY_UPDATER_PROMPT_ID
16
+ };
17
+
18
+ export const questionNames = {
19
+ ...coreQuestionNames,
20
+ ...projectScaffolderQuestionNames
21
+ };
@@ -1,6 +1,10 @@
1
1
  import {questionsForBaseDetails} from '@form8ion/core';
2
- import {prompt} from '@form8ion/overridable-prompts';
3
2
 
4
- export function promptForBaseDetails(projectRoot, decisions) {
5
- return prompt(questionsForBaseDetails(decisions, projectRoot), decisions);
3
+ export const BASE_DETAILS_PROMPT_ID = 'BASE_DETAILS';
4
+
5
+ export function promptForBaseDetails(projectRoot, {prompt}) {
6
+ return prompt({
7
+ id: BASE_DETAILS_PROMPT_ID,
8
+ questions: questionsForBaseDetails(projectRoot)
9
+ });
6
10
  }
@@ -1,11 +1,10 @@
1
1
  import * as core from '@form8ion/core';
2
- import * as prompts from '@form8ion/overridable-prompts';
3
2
 
4
3
  import {describe, expect, it, vi} from 'vitest';
5
4
  import any from '@travi/any';
6
5
  import {when} from 'vitest-when';
7
6
 
8
- import {promptForBaseDetails} from './questions.js';
7
+ import {promptForBaseDetails, BASE_DETAILS_PROMPT_ID} from './questions.js';
9
8
 
10
9
  vi.mock('@form8ion/core');
11
10
  vi.mock('@form8ion/overridable-prompts');
@@ -13,13 +12,13 @@ vi.mock('@form8ion/overridable-prompts');
13
12
  describe('base details prompt', () => {
14
13
  const projectPath = any.string();
15
14
  const answers = any.simpleObject();
16
- const decisions = any.simpleObject();
17
15
  const questions = any.listOf(any.simpleObject);
16
+ const prompt = vi.fn();
18
17
 
19
18
  it('should prompt for the necessary details', async () => {
20
- when(core.questionsForBaseDetails).calledWith(decisions, projectPath).thenReturn(questions);
21
- when(prompts.prompt).calledWith(questions, decisions).thenResolve(answers);
19
+ when(core.questionsForBaseDetails).calledWith(projectPath).thenReturn(questions);
20
+ when(prompt).calledWith({id: BASE_DETAILS_PROMPT_ID, questions}).thenResolve(answers);
22
21
 
23
- expect(await promptForBaseDetails(projectPath, decisions)).toEqual(answers);
22
+ expect(await promptForBaseDetails(projectPath, {prompt})).toEqual(answers);
24
23
  });
25
24
  });
package/src/scaffolder.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import deepmerge from 'deepmerge';
2
2
  import {execa} from 'execa';
3
3
  import {questionNames as coreQuestionNames} from '@form8ion/core';
4
- import {reportResults} from '@form8ion/results-reporter';
5
4
  import {scaffold as scaffoldReadme} from '@form8ion/readme';
6
5
  import {info} from '@travi/cli-messages';
7
6
 
@@ -15,9 +14,9 @@ import {scaffold as scaffoldEditorConfig} from './editorconfig/index.js';
15
14
  import {scaffold as scaffoldContributing} from './contributing/index.js';
16
15
  import lift from './lift.js';
17
16
 
18
- export async function scaffold(options) {
17
+ export async function scaffold(options, {prompt}) {
19
18
  const projectRoot = process.cwd();
20
- const {decisions, plugins: {dependencyUpdaters, languages, vcsHosts = {}}} = validate(options);
19
+ const {plugins: {dependencyUpdaters, languages, vcsHosts = {}}} = validate(options);
21
20
 
22
21
  const {
23
22
  [coreQuestionNames.PROJECT_NAME]: projectName,
@@ -26,11 +25,11 @@ export async function scaffold(options) {
26
25
  [coreQuestionNames.DESCRIPTION]: description,
27
26
  [coreQuestionNames.COPYRIGHT_YEAR]: copyrightYear,
28
27
  [coreQuestionNames.COPYRIGHT_HOLDER]: copyHolder
29
- } = await promptForBaseDetails(projectRoot, decisions);
28
+ } = await promptForBaseDetails(projectRoot, {prompt});
30
29
  const copyright = {year: copyrightYear, holder: copyHolder};
31
30
 
32
31
  const [vcsResults, contributing, license] = await Promise.all([
33
- scaffoldVcs({projectRoot, projectName, decisions, vcsHosts, visibility, description}),
32
+ scaffoldVcs({projectRoot, projectName, vcsHosts, visibility, description}, {prompt}),
34
33
  scaffoldContributing({visibility}),
35
34
  scaffoldLicense({projectRoot, license: chosenLicense, copyright}),
36
35
  scaffoldReadme({projectName, projectRoot, description}),
@@ -39,14 +38,14 @@ export async function scaffold(options) {
39
38
 
40
39
  const dependencyUpdaterResults = vcsResults.vcs && await scaffoldDependencyUpdater(
41
40
  dependencyUpdaters,
42
- decisions,
43
- {projectRoot, vcs: vcsResults.vcs}
41
+ {projectRoot},
42
+ {prompt}
44
43
  );
45
44
 
46
45
  const language = await scaffoldLanguage(
47
46
  languages,
48
- decisions,
49
- {projectRoot, projectName, vcs: vcsResults.vcs, visibility, license: chosenLicense || 'UNLICENSED', description}
47
+ {projectRoot, projectName, vcs: vcsResults.vcs, visibility, license: chosenLicense || 'UNLICENSED', description},
48
+ {prompt}
50
49
  );
51
50
 
52
51
  const mergedResults = deepmerge.all([
@@ -72,5 +71,5 @@ export async function scaffold(options) {
72
71
  await subprocess;
73
72
  }
74
73
 
75
- reportResults(mergedResults);
74
+ return mergedResults;
76
75
  }
@@ -2,7 +2,6 @@ import deepmerge from 'deepmerge';
2
2
  import {execa} from 'execa';
3
3
  import {questionNames as coreQuestionNames} from '@form8ion/core';
4
4
  import {scaffold as scaffoldReadme} from '@form8ion/readme';
5
- import * as resultsReporter from '@form8ion/results-reporter';
6
5
 
7
6
  import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
8
7
  import any from '@travi/any';
@@ -52,7 +51,7 @@ describe('project scaffolder', () => {
52
51
  const tags = any.listOf(any.word);
53
52
  const visibility = any.word();
54
53
  const vcsIgnore = any.simpleObject();
55
- const decisions = any.simpleObject();
54
+ const prompt = () => undefined;
56
55
 
57
56
  beforeEach(() => {
58
57
  process.cwd = vi.fn();
@@ -95,9 +94,9 @@ describe('project scaffolder', () => {
95
94
  ]);
96
95
  when(optionsValidator.validate)
97
96
  .calledWith(options)
98
- .thenReturn({decisions, plugins: {dependencyUpdaters, languages, vcsHosts}});
97
+ .thenReturn({plugins: {dependencyUpdaters, languages, vcsHosts}});
99
98
  when(prompts.promptForBaseDetails)
100
- .calledWith(projectPath, decisions)
99
+ .calledWith(projectPath, {prompt})
101
100
  .thenResolve({
102
101
  [coreQuestionNames.PROJECT_NAME]: projectName,
103
102
  [coreQuestionNames.LICENSE]: license,
@@ -107,25 +106,20 @@ describe('project scaffolder', () => {
107
106
  [coreQuestionNames.VISIBILITY]: visibility
108
107
  });
109
108
  when(scaffoldVcs)
110
- .calledWith({projectRoot: projectPath, projectName, decisions, vcsHosts, visibility, description})
109
+ .calledWith({projectRoot: projectPath, projectName, vcsHosts, visibility, description}, {prompt})
111
110
  .thenResolve(vcsResults);
112
111
  when(licenseScaffolder.default)
113
112
  .calledWith({projectRoot: projectPath, license, copyright})
114
113
  .thenResolve(licenseResults);
115
114
  scaffoldLanguage.mockResolvedValue(languageResults);
116
115
  when(dependencyUpdaterScaffolder.default)
117
- .calledWith(dependencyUpdaters, decisions, {projectRoot: projectPath, vcs})
116
+ .calledWith(dependencyUpdaters, {projectRoot: projectPath}, {prompt})
118
117
  .thenResolve(dependencyUpdaterResults);
119
118
  when(scaffoldContributing).calledWith({visibility}).thenReturn(contributingResults);
120
119
 
121
- await scaffold(options);
120
+ expect(await scaffold(options, {prompt})).toEqual(mergedResults);
122
121
 
123
122
  expect(scaffoldReadme).toHaveBeenCalledWith({projectName, projectRoot: projectPath, description});
124
- expect(dependencyUpdaterScaffolder.default).toHaveBeenCalledWith(
125
- dependencyUpdaters,
126
- decisions,
127
- {projectRoot: projectPath, vcs}
128
- );
129
123
  expect(scaffoldEditorconfig).toHaveBeenCalledWith({projectRoot: projectPath});
130
124
  expect(lift).toHaveBeenCalledWith({
131
125
  projectRoot: projectPath,
@@ -133,7 +127,6 @@ describe('project scaffolder', () => {
133
127
  results: mergedResults,
134
128
  enhancers: {...dependencyUpdaters, ...vcsHosts, ...languages}
135
129
  });
136
- expect(resultsReporter.reportResults).toHaveBeenCalledWith(mergedResults);
137
130
  });
138
131
 
139
132
  it('should pass the lists of badges from contributors to the readme', async () => {
@@ -160,7 +153,7 @@ describe('project scaffolder', () => {
160
153
  const languageResults = {badges: languageBadges, vcsIgnore, documentation};
161
154
  when(optionsValidator.validate).calledWith(options).thenReturn({plugins: {vcsHosts}});
162
155
  when(prompts.promptForBaseDetails)
163
- .calledWith(projectPath, undefined)
156
+ .calledWith(projectPath, {prompt})
164
157
  .thenResolve({
165
158
  [coreQuestionNames.DESCRIPTION]: description,
166
159
  [questionNames.GIT_REPO]: true,
@@ -173,7 +166,7 @@ describe('project scaffolder', () => {
173
166
  licenseScaffolder.default.mockResolvedValue({badges: licenseBadges});
174
167
  scaffoldVcs.mockResolvedValue(vcsResults);
175
168
 
176
- await scaffold(options);
169
+ await scaffold(options, {prompt});
177
170
 
178
171
  expect(scaffoldReadme).toHaveBeenCalledWith({projectName, projectRoot: projectPath, description});
179
172
  });
@@ -184,7 +177,7 @@ describe('project scaffolder', () => {
184
177
  scaffoldReadme.mockResolvedValue();
185
178
  scaffoldVcs.mockResolvedValue({});
186
179
 
187
- await scaffold(options);
180
+ await scaffold(options, {prompt});
188
181
 
189
182
  expect(dependencyUpdaterScaffolder.default).not.toHaveBeenCalled();
190
183
  });
@@ -209,9 +202,7 @@ describe('project scaffolder', () => {
209
202
  nextSteps: languageNextSteps,
210
203
  tags
211
204
  };
212
- when(optionsValidator.validate)
213
- .calledWith(options)
214
- .thenReturn({decisions, plugins: {languages, vcsHosts}});
205
+ when(optionsValidator.validate).calledWith(options).thenReturn({plugins: {languages, vcsHosts}});
215
206
  scaffoldVcs.mockResolvedValue(vcsResults);
216
207
  prompts.promptForBaseDetails.mockResolvedValue({
217
208
  [coreQuestionNames.PROJECT_NAME]: projectName,
@@ -220,30 +211,29 @@ describe('project scaffolder', () => {
220
211
  [coreQuestionNames.LICENSE]: license,
221
212
  [coreQuestionNames.DESCRIPTION]: description
222
213
  });
223
- when(scaffoldLanguage).calledWith(languages, decisions, {
214
+ when(scaffoldLanguage).calledWith(languages, {
224
215
  projectName,
225
216
  projectRoot: projectPath,
226
217
  visibility,
227
218
  license,
228
219
  vcs,
229
220
  description
230
- }).thenResolve(languageResults);
221
+ }, {prompt}).thenResolve(languageResults);
231
222
  when(execa).calledWith(verificationCommand, {shell: true}).thenReturn({stdout: {pipe: execaPipe}});
232
223
  dependencyUpdaterScaffolder.default.mockResolvedValue({});
233
224
  licenseScaffolder.default.mockResolvedValue({});
234
225
  scaffoldContributing.mockResolvedValue({});
235
226
 
236
- await scaffold(options);
227
+ await scaffold(options, {prompt});
237
228
 
238
229
  expect(scaffoldReadme).toHaveBeenCalledWith({projectName, projectRoot: projectPath, description});
239
230
  expect(execaPipe).toHaveBeenCalledWith(process.stdout);
240
- expect(resultsReporter.reportResults).toHaveBeenCalledWith(deepmerge.all([languageResults, vcsResults]));
241
231
  });
242
232
 
243
233
  it('should consider the language details to be optional', async () => {
244
234
  when(optionsValidator.validate)
245
235
  .calledWith(options)
246
- .thenReturn({vcsHosts, decisions, plugins: {languages}});
236
+ .thenReturn({vcsHosts, plugins: {languages}});
247
237
  scaffoldVcs.mockResolvedValue(vcsResults);
248
238
  prompts.promptForBaseDetails.mockResolvedValue({
249
239
  [coreQuestionNames.PROJECT_NAME]: projectName,
@@ -257,22 +247,21 @@ describe('project scaffolder', () => {
257
247
  licenseScaffolder.default.mockResolvedValue({});
258
248
  scaffoldContributing.mockResolvedValue({});
259
249
 
260
- await scaffold(options);
250
+ await scaffold(options, {prompt});
261
251
 
262
252
  expect(scaffoldReadme).toHaveBeenCalledWith({projectName, projectRoot: projectPath, description});
263
253
  expect(execa).not.toHaveBeenCalled();
264
254
  });
265
255
 
266
256
  it('should pass the license to the language scaffolder as `UNLICENSED` when no license was chosen', async () => {
267
- when(optionsValidator.validate).calledWith(options).thenReturn({plugins: {languages}, decisions});
257
+ when(optionsValidator.validate).calledWith(options).thenReturn({plugins: {languages}});
268
258
  prompts.promptForBaseDetails.mockResolvedValue({});
269
259
  scaffoldVcs.mockResolvedValue(vcsResults);
270
260
 
271
- await scaffold(options);
261
+ await scaffold(options, {prompt});
272
262
 
273
263
  expect(scaffoldLanguage).toHaveBeenCalledWith(
274
264
  languages,
275
- decisions,
276
265
  {
277
266
  license: 'UNLICENSED',
278
267
  description: undefined,
@@ -280,7 +269,8 @@ describe('project scaffolder', () => {
280
269
  projectRoot: projectPath,
281
270
  vcs,
282
271
  visibility: undefined
283
- }
272
+ },
273
+ {prompt}
284
274
  );
285
275
  });
286
276
 
@@ -290,7 +280,7 @@ describe('project scaffolder', () => {
290
280
  scaffoldVcs.mockResolvedValue({});
291
281
  scaffoldLanguage.mockResolvedValue({badges: {}, projectDetails: {}});
292
282
 
293
- await scaffold(options);
283
+ await scaffold(options, {prompt});
294
284
 
295
285
  expect(execa).not.toHaveBeenCalled();
296
286
  });
@@ -1,14 +1,17 @@
1
- import {prompt} from '@form8ion/overridable-prompts';
2
-
3
1
  import {questionNames} from '../../prompts/question-names.js';
4
2
 
5
- export default async function (hosts, decisions) {
6
- const answers = await prompt([{
7
- name: questionNames.REPO_HOST,
8
- type: 'list',
9
- message: 'Where will the repository be hosted?',
10
- choices: Object.keys(hosts)
11
- }], decisions);
3
+ export const REPOSITORY_HOST_PROMPT_ID = 'REPOSITORY_HOST';
4
+
5
+ export default async function promptForVcsHostChoice(hosts, {prompt}) {
6
+ const answers = await prompt({
7
+ id: REPOSITORY_HOST_PROMPT_ID,
8
+ questions: [{
9
+ name: questionNames.REPO_HOST,
10
+ type: 'list',
11
+ message: 'Where will the repository be hosted?',
12
+ choices: Object.keys(hosts)
13
+ }]
14
+ });
12
15
  const host = hosts[answers[questionNames.REPO_HOST]];
13
16
 
14
17
  return {...answers, ...host};
@@ -1,21 +1,19 @@
1
- import * as prompts from '@form8ion/overridable-prompts';
2
-
3
- import {afterEach, describe, expect, it, vi} from 'vitest';
1
+ import {beforeEach, describe, expect, it, vi} from 'vitest';
4
2
  import any from '@travi/any';
5
3
  import {when} from 'vitest-when';
6
4
 
7
5
  import {questionNames} from '../../prompts/question-names.js';
8
- import promptForVcsHostDetails from './prompt.js';
6
+ import promptForVcsHostDetails, {REPOSITORY_HOST_PROMPT_ID} from './prompt.js';
9
7
 
10
8
  vi.mock('@form8ion/overridable-prompts');
11
9
  vi.mock('../../prompts/conditionals');
12
10
 
13
11
  describe('vcs host details prompt', () => {
12
+ let prompt;
14
13
  const answers = any.simpleObject();
15
- const decisions = any.simpleObject();
16
14
 
17
- afterEach(() => {
18
- vi.clearAllMocks();
15
+ beforeEach(() => {
16
+ prompt = vi.fn();
19
17
  });
20
18
 
21
19
  it('should prompt for the vcs hosting details', async () => {
@@ -23,25 +21,31 @@ describe('vcs host details prompt', () => {
23
21
  const hostNames = [...any.listOf(any.string), host];
24
22
  const hosts = any.objectWithKeys(hostNames, {factory: () => ({})});
25
23
  const answersWithHostChoice = {...answers, [questionNames.REPO_HOST]: host};
26
- when(prompts.prompt).calledWith([{
27
- name: questionNames.REPO_HOST,
28
- type: 'list',
29
- message: 'Where will the repository be hosted?',
30
- choices: hostNames
31
- }], decisions).thenResolve(answersWithHostChoice);
32
-
33
- expect(await promptForVcsHostDetails(hosts, decisions)).toEqual(answersWithHostChoice);
24
+ when(prompt).calledWith({
25
+ id: REPOSITORY_HOST_PROMPT_ID,
26
+ questions: [{
27
+ name: questionNames.REPO_HOST,
28
+ type: 'list',
29
+ message: 'Where will the repository be hosted?',
30
+ choices: hostNames
31
+ }]
32
+ }).thenResolve(answersWithHostChoice);
33
+
34
+ expect(await promptForVcsHostDetails(hosts, {prompt})).toEqual(answersWithHostChoice);
34
35
  });
35
36
 
36
37
  it('should not throw an error when `Other` is chosen as the host', async () => {
37
38
  const answersWithHostChoice = {...answers, [questionNames.REPO_HOST]: 'Other'};
38
- when(prompts.prompt).calledWith([{
39
- name: questionNames.REPO_HOST,
40
- type: 'list',
41
- message: 'Where will the repository be hosted?',
42
- choices: []
43
- }], decisions).thenResolve(answersWithHostChoice);
44
-
45
- expect(await promptForVcsHostDetails({}, decisions)).toEqual(answersWithHostChoice);
39
+ when(prompt).calledWith({
40
+ id: REPOSITORY_HOST_PROMPT_ID,
41
+ questions: [{
42
+ name: questionNames.REPO_HOST,
43
+ type: 'list',
44
+ message: 'Where will the repository be hosted?',
45
+ choices: []
46
+ }]
47
+ }).thenResolve(answersWithHostChoice);
48
+
49
+ expect(await promptForVcsHostDetails({}, {prompt})).toEqual(answersWithHostChoice);
46
50
  });
47
51
  });
@@ -1,16 +1,15 @@
1
1
  import {questionNames} from '../../prompts/question-names.js';
2
- import terminalPromptFactory from '../../prompts/terminal-prompt.js';
3
2
  import promptForVcsHostDetails from './prompt.js';
4
3
 
5
- export default async function scaffoldVcsHost(hosts, decisions, options) {
6
- const {[questionNames.REPO_HOST]: chosenHost} = await promptForVcsHostDetails(hosts, decisions);
4
+ export default async function scaffoldVcsHost(hosts, options, {prompt}) {
5
+ const {[questionNames.REPO_HOST]: chosenHost} = await promptForVcsHostDetails(hosts, {prompt});
7
6
 
8
7
  const lowercasedHosts = Object.fromEntries(
9
8
  Object.entries(hosts).map(([name, details]) => [name.toLowerCase(), details])
10
9
  );
11
10
  const host = lowercasedHosts[chosenHost.toLowerCase()];
12
11
 
13
- if (host) return host.scaffold(options, {prompt: terminalPromptFactory(decisions)});
12
+ if (host) return host.scaffold(options);
14
13
 
15
14
  return {vcs: {}};
16
15
  }