Skip to content

Commit

Permalink
feat(vcs): expect vcs details as results from scaffolding the vcs host
Browse files Browse the repository at this point in the history
since the details are truly about the hosted repository rather than the local repository

BREAKING CHANGE: vcs-host scaffolder is expected to return `host`, `name`, and `owner` details in a
`vcs` object in results
  • Loading branch information
travi committed Jul 30, 2024
1 parent 1a1ae41 commit 9d52a53
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 110 deletions.
37 changes: 15 additions & 22 deletions src/scaffolder.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {info} from '@travi/cli-messages';
import {prompt as promptForLanguageDetails, scaffold as scaffoldLanguage} from './language/index.js';
import {initialize as scaffoldGit, scaffold as liftGit} from './vcs/git/git.js';
import {scaffold as scaffoldLicense} from './license/index.js';
import {scaffold as scaffoldVcsHost} from './vcs/host/index.js';
import scaffoldDependencyUpdater from './dependency-updater/scaffolder.js';
import {promptForBaseDetails} from './prompts/questions.js';
import {validate} from './options-validator.js';
Expand All @@ -32,39 +31,28 @@ export async function scaffold(options) {
} = await promptForBaseDetails(projectRoot, decisions);
const copyright = {year: copyrightYear, holder: copyHolder};

const [vcs, contributing, license] = await Promise.all([
scaffoldGit(gitRepo, projectRoot, projectName, vcsHosts, visibility, decisions),
const [vcsResults, contributing, license] = await Promise.all([
scaffoldGit(gitRepo, projectRoot, projectName, description, vcsHosts, visibility, decisions),
scaffoldContributing({visibility}),
scaffoldLicense({projectRoot, license: chosenLicense, copyright}),
scaffoldReadme({projectName, projectRoot, description}),
scaffoldEditorConfig({projectRoot})
]);

const [vcsHostResults, dependencyUpdaterResults] = vcs
? await Promise.all([
scaffoldVcsHost(vcsHosts, {
...vcs,
projectName,
projectRoot,
description,
visibility
}),
scaffoldDependencyUpdater(
dependencyUpdaters,
decisions,
{projectRoot, vcs}
)
])
: [];
const dependencyUpdaterResults = vcsResults.vcs && await scaffoldDependencyUpdater(
dependencyUpdaters,
decisions,
{projectRoot, vcs: vcsResults.vcs}
);

const gitResults = gitRepo && await liftGit({projectRoot, vcs: vcsHostResults.vcs});
const gitResults = gitRepo && await liftGit({projectRoot, vcs: vcsResults.vcs});

const {[questionNames.PROJECT_LANGUAGE]: projectLanguage} = await promptForLanguageDetails(languages, decisions);

const language = await scaffoldLanguage(
languages,
projectLanguage,
{projectRoot, projectName, vcs, visibility, license: chosenLicense || 'UNLICENSED', description}
{projectRoot, projectName, vcs: vcsResults.vcs, visibility, license: chosenLicense || 'UNLICENSED', description}
);

const mergedResults = deepmerge.all([
Expand All @@ -75,7 +63,12 @@ export async function scaffold(options) {
gitResults
].filter(Boolean));

await lift({projectRoot, vcs, results: mergedResults, enhancers: {...dependencyUpdaters, ...vcsHosts}});
await lift({
projectRoot,
vcs: vcsResults.vcs,
results: mergedResults,
enhancers: {...dependencyUpdaters, ...vcsHosts}
});

if (language && language.verificationCommand) {
info('Verifying the generated project');
Expand Down
86 changes: 15 additions & 71 deletions src/scaffolder.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import any from '@travi/any';
import {when} from 'jest-when';

import {scaffold as liftGit, initialize as scaffoldGit} from './vcs/git/git.js';
import {scaffold as scaffoldVcsHost} from './vcs/host/index.js';
import * as licenseScaffolder from './license/scaffolder.js';
import scaffoldLanguage from './language/scaffolder.js';
import * as languagePrompt from './language/prompt.js';
Expand All @@ -27,7 +26,6 @@ vi.mock('@form8ion/execa-wrapper');
vi.mock('@form8ion/results-reporter');
vi.mock('./readme');
vi.mock('./vcs/git/git.js');
vi.mock('./vcs/host/index.js');
vi.mock('./license/scaffolder');
vi.mock('./language/scaffolder');
vi.mock('./language/prompt');
Expand All @@ -52,8 +50,7 @@ describe('project scaffolder', () => {
const vcsHosts = any.simpleObject();
const documentation = any.simpleObject();
const vcs = any.simpleObject();
const vcsOriginDetails = any.simpleObject();
const vcsHostResults = {...any.simpleObject(), vcs: vcsOriginDetails};
const vcsResults = {...any.simpleObject(), vcs};
const tags = any.listOf(any.word);
const visibility = any.word();
const vcsIgnore = any.simpleObject();
Expand Down Expand Up @@ -112,24 +109,12 @@ describe('project scaffolder', () => {
.calledWith(languages, decisions)
.mockResolvedValue({[questionNames.PROJECT_LANGUAGE]: projectLanguage});
when(scaffoldGit)
.calledWith(gitRepoShouldBeInitialized, projectPath, projectName, vcsHosts, visibility, decisions)
.mockResolvedValue(vcs);
.calledWith(gitRepoShouldBeInitialized, projectPath, projectName, description, vcsHosts, visibility, decisions)
.mockResolvedValue(vcsResults);
liftGit.mockResolvedValue(gitResults);
when(licenseScaffolder.default)
.calledWith({projectRoot: projectPath, license, copyright})
.mockResolvedValue(licenseResults);
when(scaffoldVcsHost)
.calledWith(
vcsHosts,
{
...vcs,
projectRoot: projectPath,
projectName,
description,
visibility
}
)
.mockResolvedValue(vcsHostResults);
scaffoldLanguage.mockResolvedValue(languageResults);
when(dependencyUpdaterScaffolder.default)
.calledWith(dependencyUpdaters, decisions, {projectRoot: projectPath, vcs})
Expand All @@ -138,10 +123,7 @@ describe('project scaffolder', () => {

await scaffold(options);

expect(liftGit).toHaveBeenCalledWith({
projectRoot: projectPath,
vcs: vcsOriginDetails
});
expect(liftGit).toHaveBeenCalledWith({projectRoot: projectPath, vcs});
expect(scaffoldReadme).toHaveBeenCalledWith({projectName, projectRoot: projectPath, description});
expect(dependencyUpdaterScaffolder.default).toHaveBeenCalledWith(
dependencyUpdaters,
Expand Down Expand Up @@ -175,26 +157,13 @@ describe('project scaffolder', () => {
[coreQuestionNames.PROJECT_NAME]: projectName,
[questionNames.GIT_REPO]: gitRepoShouldBeInitialized
});

when(scaffoldGit).mockResolvedValue(vcs);
when(scaffoldGit).mockResolvedValue(vcsResults);
languagePrompt.default.mockResolvedValue({});
when(scaffoldVcsHost)
.calledWith(
{},
{
...vcs,
projectRoot: projectPath,
projectName,
description: undefined,
visibility: undefined
}
)
.mockResolvedValue(vcsHostResults);

await scaffold();

expect(scaffoldGit)
.toHaveBeenCalledWith(gitRepoShouldBeInitialized, projectPath, projectName, {}, undefined, undefined);
.toHaveBeenCalledWith(gitRepoShouldBeInitialized, projectPath, projectName, undefined, {}, undefined, undefined);
});

it('should consider each option except the plugins map optional', async () => {
Expand All @@ -203,7 +172,6 @@ describe('project scaffolder', () => {
when(prompts.promptForBaseDetails).calledWith(projectPath, undefined).mockResolvedValue({});
languagePrompt.default.mockResolvedValue({});
scaffoldGit.mockResolvedValue({});
scaffoldVcsHost.mockResolvedValue(vcsHostResults);

await scaffold(emptyOptions);
});
Expand Down Expand Up @@ -241,26 +209,14 @@ describe('project scaffolder', () => {
});
when(scaffoldContributing).calledWith({visibility}).mockReturnValue({badges: contributingBadges});
scaffoldLanguage.mockResolvedValue(languageResults);
when(scaffoldVcsHost)
.calledWith(
vcsHosts,
{
...vcs,
projectRoot: projectPath,
projectName,
description,
visibility
}
)
.mockResolvedValue(vcsHostResults);
dependencyUpdaterScaffolder.default.mockResolvedValue({badges: dependencyUpdaterBadges});
licenseScaffolder.default.mockResolvedValue({badges: licenseBadges});
languagePrompt.default.mockResolvedValue({});
when(scaffoldGit).mockResolvedValue(vcs);
when(scaffoldGit).mockResolvedValue(vcsResults);

await scaffold(options);

expect(liftGit).toHaveBeenCalledWith({projectRoot: projectPath, vcs: vcsOriginDetails});
expect(liftGit).toHaveBeenCalledWith({projectRoot: projectPath, vcs});
expect(scaffoldReadme).toHaveBeenCalledWith({projectName, projectRoot: projectPath, description});
});

Expand All @@ -269,12 +225,11 @@ describe('project scaffolder', () => {
prompts.promptForBaseDetails.mockResolvedValue({[questionNames.GIT_REPO]: false});
languagePrompt.default.mockResolvedValue({});
scaffoldReadme.mockResolvedValue();
scaffoldGit.mockResolvedValue(undefined);
scaffoldGit.mockResolvedValue({});

await scaffold(options);

expect(liftGit).not.toHaveBeenCalled();
expect(scaffoldVcsHost).not.toHaveBeenCalled();
expect(dependencyUpdaterScaffolder.default).not.toHaveBeenCalled();
});

Expand Down Expand Up @@ -303,7 +258,7 @@ describe('project scaffolder', () => {
when(optionsValidator.validate)
.calledWith(options)
.mockReturnValue({decisions, plugins: {languages, vcsHosts}});
scaffoldGit.mockResolvedValue(vcs);
scaffoldGit.mockResolvedValue(vcsResults);
liftGit.mockResolvedValue(gitResults);
prompts.promptForBaseDetails.mockResolvedValue({
[coreQuestionNames.PROJECT_NAME]: projectName,
Expand All @@ -323,24 +278,14 @@ describe('project scaffolder', () => {
vcs,
description
}).mockResolvedValue(languageResults);
when(scaffoldVcsHost).calledWith(
vcsHosts,
{
...vcs,
projectRoot: projectPath,
projectName,
description,
visibility
}
).mockResolvedValue(vcsHostResults);
when(execa).calledWith(verificationCommand, {shell: true}).mockReturnValue({stdout: {pipe: execaPipe}});
dependencyUpdaterScaffolder.default.mockResolvedValue({});
licenseScaffolder.default.mockResolvedValue({});
scaffoldContributing.mockResolvedValue({});

await scaffold(options);

expect(liftGit).toHaveBeenCalledWith({projectRoot: projectPath, vcs: vcsOriginDetails});
expect(liftGit).toHaveBeenCalledWith({projectRoot: projectPath, vcs});
expect(scaffoldReadme).toHaveBeenCalledWith({projectName, projectRoot: projectPath, description});
expect(execaPipe).toHaveBeenCalledWith(process.stdout);
expect(resultsReporter.reportResults).toHaveBeenCalledWith({nextSteps: [...languageNextSteps, ...gitNextSteps]});
Expand All @@ -350,7 +295,7 @@ describe('project scaffolder', () => {
when(optionsValidator.validate)
.calledWith(options)
.mockReturnValue({vcsHosts, decisions, plugins: {languages}});
scaffoldGit.mockResolvedValue(vcs);
scaffoldGit.mockResolvedValue(vcsResults);
prompts.promptForBaseDetails.mockResolvedValue({
[coreQuestionNames.PROJECT_NAME]: projectName,
[coreQuestionNames.VISIBILITY]: visibility,
Expand All @@ -361,15 +306,14 @@ describe('project scaffolder', () => {
when(languagePrompt.default)
.calledWith(languages, decisions)
.mockResolvedValue({[questionNames.PROJECT_LANGUAGE]: projectLanguage});
scaffoldVcsHost.mockResolvedValue(vcsHostResults);
scaffoldLanguage.mockResolvedValue({});
dependencyUpdaterScaffolder.default.mockResolvedValue({});
licenseScaffolder.default.mockResolvedValue({});
scaffoldContributing.mockResolvedValue({});

await scaffold(options);

expect(liftGit).toHaveBeenCalledWith({projectRoot: projectPath, vcs: vcsOriginDetails});
expect(liftGit).toHaveBeenCalledWith({projectRoot: projectPath, vcs});
expect(scaffoldReadme).toHaveBeenCalledWith({projectName, projectRoot: projectPath, description});
expect(execa).not.toHaveBeenCalled();
});
Expand All @@ -378,7 +322,7 @@ describe('project scaffolder', () => {
when(optionsValidator.validate).calledWith(options).mockReturnValue({plugins: {languages}});
prompts.promptForBaseDetails.mockResolvedValue({});
languagePrompt.default.mockResolvedValue({[questionNames.PROJECT_LANGUAGE]: projectLanguage});
scaffoldGit.mockResolvedValue({});
scaffoldGit.mockResolvedValue(vcsResults);

await scaffold(options);

Expand All @@ -390,7 +334,7 @@ describe('project scaffolder', () => {
description: undefined,
projectName: undefined,
projectRoot: projectPath,
vcs: {},
vcs,
visibility: undefined
}
);
Expand Down
15 changes: 10 additions & 5 deletions src/vcs/git/git.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {scaffold as scaffoldGit} from '@form8ion/git';

import promptForVcsHostDetails from '../host/prompt.js';
import {questionNames} from '../../prompts/question-names.js';
import {scaffold as scaffoldVcsHost} from '../host/index.js';

async function getExistingRemotes(git) {
try {
Expand Down Expand Up @@ -52,6 +53,7 @@ export async function initialize(
gitRepoShouldBeInitialized,
projectRoot,
projectName,
description,
vcsHosts,
visibility,
decisions
Expand All @@ -72,14 +74,17 @@ export async function initialize(
scaffoldGit({projectRoot})
]);

return {
host: answers[questionNames.REPO_HOST].toLowerCase(),
return scaffoldVcsHost(vcsHosts, {
chosenHost: answers[questionNames.REPO_HOST].toLowerCase(),
owner: answers[questionNames.REPO_OWNER],
name: projectName
};
projectName,
projectRoot,
description,
visibility
});
}

return undefined;
return {};
}

export async function scaffold({projectRoot, vcs}) {
Expand Down
Loading

0 comments on commit 9d52a53

Please sign in to comment.