@form8ion/project 22.0.0-beta.2 → 22.0.0-beta.3

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,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
@@ -15,9 +15,9 @@ import {scaffold as scaffoldEditorConfig} from './editorconfig/index.js';
15
15
  import {scaffold as scaffoldContributing} from './contributing/index.js';
16
16
  import lift from './lift.js';
17
17
 
18
- export async function scaffold(options) {
18
+ export async function scaffold(options, {prompt}) {
19
19
  const projectRoot = process.cwd();
20
- const {decisions, plugins: {dependencyUpdaters, languages, vcsHosts = {}}} = validate(options);
20
+ const {plugins: {dependencyUpdaters, languages, vcsHosts = {}}} = validate(options);
21
21
 
22
22
  const {
23
23
  [coreQuestionNames.PROJECT_NAME]: projectName,
@@ -26,11 +26,11 @@ export async function scaffold(options) {
26
26
  [coreQuestionNames.DESCRIPTION]: description,
27
27
  [coreQuestionNames.COPYRIGHT_YEAR]: copyrightYear,
28
28
  [coreQuestionNames.COPYRIGHT_HOLDER]: copyHolder
29
- } = await promptForBaseDetails(projectRoot, decisions);
29
+ } = await promptForBaseDetails(projectRoot, {prompt});
30
30
  const copyright = {year: copyrightYear, holder: copyHolder};
31
31
 
32
32
  const [vcsResults, contributing, license] = await Promise.all([
33
- scaffoldVcs({projectRoot, projectName, decisions, vcsHosts, visibility, description}),
33
+ scaffoldVcs({projectRoot, projectName, vcsHosts, visibility, description}, {prompt}),
34
34
  scaffoldContributing({visibility}),
35
35
  scaffoldLicense({projectRoot, license: chosenLicense, copyright}),
36
36
  scaffoldReadme({projectName, projectRoot, description}),
@@ -39,14 +39,14 @@ export async function scaffold(options) {
39
39
 
40
40
  const dependencyUpdaterResults = vcsResults.vcs && await scaffoldDependencyUpdater(
41
41
  dependencyUpdaters,
42
- decisions,
43
- {projectRoot}
42
+ {projectRoot},
43
+ {prompt}
44
44
  );
45
45
 
46
46
  const language = await scaffoldLanguage(
47
47
  languages,
48
- decisions,
49
- {projectRoot, projectName, vcs: vcsResults.vcs, visibility, license: chosenLicense || 'UNLICENSED', description}
48
+ {projectRoot, projectName, vcs: vcsResults.vcs, visibility, license: chosenLicense || 'UNLICENSED', description},
49
+ {prompt}
50
50
  );
51
51
 
52
52
  const mergedResults = deepmerge.all([
@@ -52,7 +52,7 @@ describe('project scaffolder', () => {
52
52
  const tags = any.listOf(any.word);
53
53
  const visibility = any.word();
54
54
  const vcsIgnore = any.simpleObject();
55
- const decisions = any.simpleObject();
55
+ const prompt = () => undefined;
56
56
 
57
57
  beforeEach(() => {
58
58
  process.cwd = vi.fn();
@@ -95,9 +95,9 @@ describe('project scaffolder', () => {
95
95
  ]);
96
96
  when(optionsValidator.validate)
97
97
  .calledWith(options)
98
- .thenReturn({decisions, plugins: {dependencyUpdaters, languages, vcsHosts}});
98
+ .thenReturn({plugins: {dependencyUpdaters, languages, vcsHosts}});
99
99
  when(prompts.promptForBaseDetails)
100
- .calledWith(projectPath, decisions)
100
+ .calledWith(projectPath, {prompt})
101
101
  .thenResolve({
102
102
  [coreQuestionNames.PROJECT_NAME]: projectName,
103
103
  [coreQuestionNames.LICENSE]: license,
@@ -107,18 +107,18 @@ describe('project scaffolder', () => {
107
107
  [coreQuestionNames.VISIBILITY]: visibility
108
108
  });
109
109
  when(scaffoldVcs)
110
- .calledWith({projectRoot: projectPath, projectName, decisions, vcsHosts, visibility, description})
110
+ .calledWith({projectRoot: projectPath, projectName, vcsHosts, visibility, description}, {prompt})
111
111
  .thenResolve(vcsResults);
112
112
  when(licenseScaffolder.default)
113
113
  .calledWith({projectRoot: projectPath, license, copyright})
114
114
  .thenResolve(licenseResults);
115
115
  scaffoldLanguage.mockResolvedValue(languageResults);
116
116
  when(dependencyUpdaterScaffolder.default)
117
- .calledWith(dependencyUpdaters, decisions, {projectRoot: projectPath})
117
+ .calledWith(dependencyUpdaters, {projectRoot: projectPath}, {prompt})
118
118
  .thenResolve(dependencyUpdaterResults);
119
119
  when(scaffoldContributing).calledWith({visibility}).thenReturn(contributingResults);
120
120
 
121
- await scaffold(options);
121
+ await scaffold(options, {prompt});
122
122
 
123
123
  expect(scaffoldReadme).toHaveBeenCalledWith({projectName, projectRoot: projectPath, description});
124
124
  expect(scaffoldEditorconfig).toHaveBeenCalledWith({projectRoot: projectPath});
@@ -155,7 +155,7 @@ describe('project scaffolder', () => {
155
155
  const languageResults = {badges: languageBadges, vcsIgnore, documentation};
156
156
  when(optionsValidator.validate).calledWith(options).thenReturn({plugins: {vcsHosts}});
157
157
  when(prompts.promptForBaseDetails)
158
- .calledWith(projectPath, undefined)
158
+ .calledWith(projectPath, {prompt})
159
159
  .thenResolve({
160
160
  [coreQuestionNames.DESCRIPTION]: description,
161
161
  [questionNames.GIT_REPO]: true,
@@ -168,7 +168,7 @@ describe('project scaffolder', () => {
168
168
  licenseScaffolder.default.mockResolvedValue({badges: licenseBadges});
169
169
  scaffoldVcs.mockResolvedValue(vcsResults);
170
170
 
171
- await scaffold(options);
171
+ await scaffold(options, {prompt});
172
172
 
173
173
  expect(scaffoldReadme).toHaveBeenCalledWith({projectName, projectRoot: projectPath, description});
174
174
  });
@@ -179,7 +179,7 @@ describe('project scaffolder', () => {
179
179
  scaffoldReadme.mockResolvedValue();
180
180
  scaffoldVcs.mockResolvedValue({});
181
181
 
182
- await scaffold(options);
182
+ await scaffold(options, {prompt});
183
183
 
184
184
  expect(dependencyUpdaterScaffolder.default).not.toHaveBeenCalled();
185
185
  });
@@ -204,9 +204,7 @@ describe('project scaffolder', () => {
204
204
  nextSteps: languageNextSteps,
205
205
  tags
206
206
  };
207
- when(optionsValidator.validate)
208
- .calledWith(options)
209
- .thenReturn({decisions, plugins: {languages, vcsHosts}});
207
+ when(optionsValidator.validate).calledWith(options).thenReturn({plugins: {languages, vcsHosts}});
210
208
  scaffoldVcs.mockResolvedValue(vcsResults);
211
209
  prompts.promptForBaseDetails.mockResolvedValue({
212
210
  [coreQuestionNames.PROJECT_NAME]: projectName,
@@ -215,20 +213,20 @@ describe('project scaffolder', () => {
215
213
  [coreQuestionNames.LICENSE]: license,
216
214
  [coreQuestionNames.DESCRIPTION]: description
217
215
  });
218
- when(scaffoldLanguage).calledWith(languages, decisions, {
216
+ when(scaffoldLanguage).calledWith(languages, {
219
217
  projectName,
220
218
  projectRoot: projectPath,
221
219
  visibility,
222
220
  license,
223
221
  vcs,
224
222
  description
225
- }).thenResolve(languageResults);
223
+ }, {prompt}).thenResolve(languageResults);
226
224
  when(execa).calledWith(verificationCommand, {shell: true}).thenReturn({stdout: {pipe: execaPipe}});
227
225
  dependencyUpdaterScaffolder.default.mockResolvedValue({});
228
226
  licenseScaffolder.default.mockResolvedValue({});
229
227
  scaffoldContributing.mockResolvedValue({});
230
228
 
231
- await scaffold(options);
229
+ await scaffold(options, {prompt});
232
230
 
233
231
  expect(scaffoldReadme).toHaveBeenCalledWith({projectName, projectRoot: projectPath, description});
234
232
  expect(execaPipe).toHaveBeenCalledWith(process.stdout);
@@ -238,7 +236,7 @@ describe('project scaffolder', () => {
238
236
  it('should consider the language details to be optional', async () => {
239
237
  when(optionsValidator.validate)
240
238
  .calledWith(options)
241
- .thenReturn({vcsHosts, decisions, plugins: {languages}});
239
+ .thenReturn({vcsHosts, plugins: {languages}});
242
240
  scaffoldVcs.mockResolvedValue(vcsResults);
243
241
  prompts.promptForBaseDetails.mockResolvedValue({
244
242
  [coreQuestionNames.PROJECT_NAME]: projectName,
@@ -252,22 +250,21 @@ describe('project scaffolder', () => {
252
250
  licenseScaffolder.default.mockResolvedValue({});
253
251
  scaffoldContributing.mockResolvedValue({});
254
252
 
255
- await scaffold(options);
253
+ await scaffold(options, {prompt});
256
254
 
257
255
  expect(scaffoldReadme).toHaveBeenCalledWith({projectName, projectRoot: projectPath, description});
258
256
  expect(execa).not.toHaveBeenCalled();
259
257
  });
260
258
 
261
259
  it('should pass the license to the language scaffolder as `UNLICENSED` when no license was chosen', async () => {
262
- when(optionsValidator.validate).calledWith(options).thenReturn({plugins: {languages}, decisions});
260
+ when(optionsValidator.validate).calledWith(options).thenReturn({plugins: {languages}});
263
261
  prompts.promptForBaseDetails.mockResolvedValue({});
264
262
  scaffoldVcs.mockResolvedValue(vcsResults);
265
263
 
266
- await scaffold(options);
264
+ await scaffold(options, {prompt});
267
265
 
268
266
  expect(scaffoldLanguage).toHaveBeenCalledWith(
269
267
  languages,
270
- decisions,
271
268
  {
272
269
  license: 'UNLICENSED',
273
270
  description: undefined,
@@ -275,7 +272,8 @@ describe('project scaffolder', () => {
275
272
  projectRoot: projectPath,
276
273
  vcs,
277
274
  visibility: undefined
278
- }
275
+ },
276
+ {prompt}
279
277
  );
280
278
  });
281
279
 
@@ -285,7 +283,7 @@ describe('project scaffolder', () => {
285
283
  scaffoldVcs.mockResolvedValue({});
286
284
  scaffoldLanguage.mockResolvedValue({badges: {}, projectDetails: {}});
287
285
 
288
- await scaffold(options);
286
+ await scaffold(options, {prompt});
289
287
 
290
288
  expect(execa).not.toHaveBeenCalled();
291
289
  });
@@ -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,8 +1,8 @@
1
1
  import {questionNames} from '../../prompts/question-names.js';
2
2
  import promptForVcsHostDetails from './prompt.js';
3
3
 
4
- export default async function scaffoldVcsHost(hosts, decisions, options) {
5
- 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});
6
6
 
7
7
  const lowercasedHosts = Object.fromEntries(
8
8
  Object.entries(hosts).map(([name, details]) => [name.toLowerCase(), details])
@@ -10,7 +10,7 @@ vi.mock('./prompt');
10
10
 
11
11
  describe('vcs host scaffolder', () => {
12
12
  const options = any.simpleObject();
13
- const decisions = any.simpleObject();
13
+ const prompt = () => undefined;
14
14
 
15
15
  it('should scaffold the chosen vcs host', async () => {
16
16
  const chosenHost = `${any.word()}CAPITAL${any.word()}`;
@@ -19,19 +19,19 @@ describe('vcs host scaffolder', () => {
19
19
  const hostPlugins = {...any.simpleObject(), [chosenHost.toLowerCase()]: {scaffold: chosenHostScaffolder}};
20
20
  const owner = any.word;
21
21
  when(promptForVcsHostDetails)
22
- .calledWith(hostPlugins, decisions)
22
+ .calledWith(hostPlugins, {prompt})
23
23
  .thenResolve({[questionNames.REPO_HOST]: chosenHost, [questionNames.REPO_OWNER]: owner});
24
24
  when(chosenHostScaffolder).calledWith(options).thenResolve(results);
25
25
 
26
- expect(await scaffoldVcsHost(hostPlugins, decisions, options)).toEqual(results);
26
+ expect(await scaffoldVcsHost(hostPlugins, options, {prompt})).toEqual(results);
27
27
  });
28
28
 
29
29
  it('should return empty `vcs` results when no matching host is available', async () => {
30
30
  const hostPlugins = any.simpleObject();
31
31
  when(promptForVcsHostDetails)
32
- .calledWith(hostPlugins, decisions)
32
+ .calledWith(hostPlugins, {prompt})
33
33
  .thenResolve({[questionNames.REPO_HOST]: any.word()});
34
34
 
35
- expect(await scaffoldVcsHost(hostPlugins, decisions, options)).toEqual({vcs: {}});
35
+ expect(await scaffoldVcsHost(hostPlugins, options, {prompt})).toEqual({vcs: {}});
36
36
  });
37
37
  });
package/src/vcs/prompt.js CHANGED
@@ -1,17 +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 promptForRepoCreation(decisions) {
6
- const {[questionNames.GIT_REPO]: gitRepoShouldBeCreated} = await prompt(
7
- [{
3
+ export const GIT_REPOSITORY_PROMPT_ID = 'GIT_REPOSITORY';
4
+
5
+ export default async function promptForRepoCreation({prompt}) {
6
+ const {[questionNames.GIT_REPO]: gitRepoShouldBeCreated} = await prompt({
7
+ id: GIT_REPOSITORY_PROMPT_ID,
8
+ questions: [{
8
9
  name: questionNames.GIT_REPO,
9
10
  type: 'confirm',
10
11
  default: true,
11
12
  message: 'Should a git repository be initialized?'
12
- }],
13
- decisions
14
- );
13
+ }]
14
+ });
15
15
 
16
16
  return gitRepoShouldBeCreated;
17
17
  }
@@ -1,27 +1,28 @@
1
- import {prompt} from '@form8ion/overridable-prompts';
2
-
3
1
  import {describe, vi, it, expect} from 'vitest';
4
2
  import {when} from 'vitest-when';
5
3
  import any from '@travi/any';
6
4
 
7
5
  import {questionNames} from '../prompts/question-names.js';
8
- import promptForRepoCreation from './prompt.js';
6
+ import promptForRepoCreation, {GIT_REPOSITORY_PROMPT_ID} from './prompt.js';
9
7
 
10
8
  vi.mock('@form8ion/overridable-prompts');
11
9
 
12
10
  describe('git prompt', () => {
13
11
  it('should ask whether a repository should be created', async () => {
14
- const decisions = any.simpleObject();
12
+ const prompt = vi.fn();
15
13
  const repoShouldBeCreated = any.boolean();
16
14
  when(prompt)
17
- .calledWith([{
18
- name: questionNames.GIT_REPO,
19
- type: 'confirm',
20
- default: true,
21
- message: 'Should a git repository be initialized?'
22
- }], decisions)
15
+ .calledWith({
16
+ id: GIT_REPOSITORY_PROMPT_ID,
17
+ questions: [{
18
+ name: questionNames.GIT_REPO,
19
+ type: 'confirm',
20
+ default: true,
21
+ message: 'Should a git repository be initialized?'
22
+ }]
23
+ })
23
24
  .thenResolve({[questionNames.GIT_REPO]: repoShouldBeCreated});
24
25
 
25
- expect(await promptForRepoCreation(decisions)).toBe(repoShouldBeCreated);
26
+ expect(await promptForRepoCreation({prompt})).toBe(repoShouldBeCreated);
26
27
  });
27
28
  });
@@ -5,8 +5,8 @@ import repositoryShouldBeCreated from './prompt.js';
5
5
  import {determineExistingVcsDetails, defineRemoteOrigin} from './git/index.js';
6
6
  import {scaffold as scaffoldVcsHost} from './host/index.js';
7
7
 
8
- export default async function scaffoldVcs({projectRoot, projectName, decisions, vcsHosts, visibility, description}) {
9
- if (await repositoryShouldBeCreated(decisions)) {
8
+ export default async function scaffoldVcs({projectRoot, projectName, vcsHosts, visibility, description}, {prompt}) {
9
+ if (await repositoryShouldBeCreated({prompt})) {
10
10
  if (await alreadyVersionedByGit({projectRoot})) {
11
11
  info('Git repository already exists');
12
12
 
@@ -14,11 +14,7 @@ export default async function scaffoldVcs({projectRoot, projectName, decisions,
14
14
  }
15
15
 
16
16
  const [{vcs: {host, owner, name, sshUrl}}] = await Promise.all([
17
- scaffoldVcsHost(
18
- vcsHosts,
19
- decisions,
20
- {projectName, projectRoot, description, visibility}
21
- ),
17
+ scaffoldVcsHost(vcsHosts, {projectName, projectRoot, description, visibility}, {prompt}),
22
18
  scaffoldGit({projectRoot})
23
19
  ]);
24
20