Skip to content

fix: include base in rerun commands #1301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/create/createRerunSuggestion.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";

import { getExclusions } from "../shared/options/augmentOptionsWithExcludes.js";
import { getExclusions } from "../shared/options/exclusionKeys.js";
import { Options } from "../shared/types.js";
import { createRerunSuggestion } from "./createRerunSuggestion.js";

Expand Down
2 changes: 1 addition & 1 deletion src/create/createRerunSuggestion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { allArgOptions } from "../shared/options/args.js";
import {
ExclusionKey,
getExclusions,
} from "../shared/options/augmentOptionsWithExcludes.js";
} from "../shared/options/exclusionKeys.js";
import { Options } from "../shared/types.js";

function getFirstMatchingArg(key: string) {
Expand Down
65 changes: 62 additions & 3 deletions src/shared/options/augmentOptionsWithExcludes.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
import { describe, expect, it } from "vitest";
import { describe, expect, it, vi } from "vitest";

import { Options } from "../types.js";
import { augmentOptionsWithExcludes } from "./augmentOptionsWithExcludes.js";

const mockMultiselect = vi.fn();
const mockSelect = vi.fn();

vi.mock("@clack/prompts", () => ({
isCancel: () => false,
get multiselect() {
return mockMultiselect;
},
get select() {
return mockSelect;
},
}));

const optionsBase = {
access: "public",
author: undefined,
base: "everything",
base: undefined,
description: "",
directory: ".",
email: {
Expand Down Expand Up @@ -47,7 +60,53 @@ const optionsBase = {
} satisfies Options;

describe("augmentOptionsWithExcludes", () => {
it("returns options without exclusions and skips prompting when exclusions are provided manually", async () => {
it("returns options directly when no exclusions are provided and 'base' is provided for the prompt", async () => {
const base = "everything";

mockSelect.mockResolvedValueOnce(base);

const actual = await augmentOptionsWithExcludes(optionsBase);

expect(actual).toEqual({
...optionsBase,
base,
});
});

it("returns options based on the select when no exclusions are provided and 'prompt' is provided for the prompt", async () => {
const base = "prompt";

mockSelect.mockResolvedValueOnce(base);
mockMultiselect.mockResolvedValue([]);

const actual = await augmentOptionsWithExcludes(optionsBase);

expect(actual).toEqual({
...optionsBase,
base,
excludeAllContributors: true,
excludeCompliance: true,
excludeLintDeprecation: true,
excludeLintESLint: true,
excludeLintJSDoc: true,
excludeLintJson: true,
excludeLintKnip: true,
excludeLintMd: true,
excludeLintPackageJson: true,
excludeLintPackages: true,
excludeLintPerfectionist: true,
excludeLintRegex: true,
excludeLintSpelling: true,
excludeLintStrict: true,
excludeLintStylistic: true,
excludeLintYml: true,
excludeReleases: true,
excludeRenovate: true,
excludeTests: true,
});
});

it("skips prompting returns options directly when exclusions are provided manually", async () => {
const options = {
...optionsBase,
excludeCompliance: true,
Expand Down
152 changes: 8 additions & 144 deletions src/shared/options/augmentOptionsWithExcludes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,150 +3,12 @@ import chalk from "chalk";

import { filterPromptCancel } from "../prompts.js";
import { Options, OptionsBase } from "../types.js";

interface ExclusionDescription {
hint: string;
label: string;
uncommon?: true;
}

export type ExclusionKey = keyof Options & `exclude${string}`;

const exclusionDescriptions: Record<ExclusionKey, ExclusionDescription> = {
excludeAllContributors: {
hint: "--exclude-all-contributors",
label:
"Add all-contributors to track contributions and display them in a README.md table.",
},
excludeCompliance: {
hint: "--exclude-compliance",
label:
"Add a GitHub Actions workflow to verify that PRs match an expected format.",
uncommon: true,
},
excludeLintDeprecation: {
hint: "--exclude-lint-deprecation",
label:
"Include an eslint-plugin-deprecation to reports on usage of code marked as @deprecated.",
uncommon: true,
},
excludeLintESLint: {
hint: "--exclude-lint-eslint",
label:
"Include eslint-plugin-eslint-comment to enforce good practices around ESLint comment directives.",
uncommon: true,
},
excludeLintJSDoc: {
hint: "--exclude-lint-jsdoc",
label:
"Include eslint-plugin-jsdoc to enforce good practices around JSDoc comments.",
uncommon: true,
},
excludeLintJson: {
hint: "--exclude-lint-json",
label: "Apply linting and sorting to *.json and *.jsonc files.",
uncommon: true,
},
excludeLintKnip: {
hint: "--exclude-lint-knip",
label: "Add Knip to detect unused files, dependencies, and code exports.",
},
excludeLintMd: {
hint: "--exclude-lint-md",
label: "Apply linting to *.md files.",
uncommon: true,
},
excludeLintPackageJson: {
hint: "--exclude-lint-package-json",
label:
"Add eslint-plugin-package-json to lint for package.json correctness.",
uncommon: true,
},
excludeLintPackages: {
hint: "--exclude-lint-packages",
label:
"Add a pnpm dedupe workflow to ensure packages aren't duplicated unnecessarily.",
uncommon: true,
},
excludeLintPerfectionist: {
hint: "--exclude-lint-perfectionist",
label:
"Apply eslint-plugin-perfectionist to ensure imports, keys, and so on are in sorted order.",
uncommon: true,
},
excludeLintRegex: {
hint: "--exclude-lint-regex",
label:
"Include eslint-plugin-regex to enforce good practices around regular expressions.",
uncommon: true,
},
excludeLintSpelling: {
hint: "--exclude-lint-spelling",
label: "Add cspell to spell check against dictionaries of known words.",
uncommon: true,
},
excludeLintStrict: {
hint: "--exclude-lint-strict",
label:
"Include strict logical lint rules such as typescript-eslint's strict config. ",
uncommon: true,
},
excludeLintStylistic: {
hint: "--exclude-lint-stylistic",
label:
"Include stylistic lint rules such as typescript-eslint's stylistic config.",
uncommon: true,
},
excludeLintYml: {
hint: "--exclude-lint-yml",
label: "Apply linting and sorting to *.yaml and *.yml files.",
uncommon: true,
},
excludeReleases: {
hint: "--exclude-releases",
label:
"Add release-it to generate changelogs, package bumps, and publishes based on conventional commits.",
},
excludeRenovate: {
hint: "--exclude-renovate",
label: "Add a Renovate config to keep dependencies up-to-date with PRs.",
},
excludeTests: {
hint: "--exclude-tests",
label:
"Add Vitest tooling for fast unit tests, configured with coverage tracking.",
},
};

const exclusionKeys = Object.keys(exclusionDescriptions) as ExclusionKey[];

export function getExclusions(
options: Partial<Options>,
base?: OptionsBase,
): Partial<Options> {
switch (base) {
case "common":
return {
...Object.fromEntries(
exclusionKeys
.filter((exclusion) => exclusionDescriptions[exclusion].uncommon)
.map((exclusion) => [exclusion, options[exclusion] ?? true]),
),
};
case "minimum":
return {
...Object.fromEntries(
exclusionKeys.map((exclusion) => [
exclusion,
options[exclusion] ?? true,
]),
),
};
// We only really care about exclusions on the common and minimum bases
default:
return {};
}
}
import {
ExclusionKey,
exclusionDescriptions,
exclusionKeys,
getExclusions,
} from "./exclusionKeys.js";

export async function augmentOptionsWithExcludes(
options: Options,
Expand Down Expand Up @@ -206,6 +68,7 @@ export async function augmentOptionsWithExcludes(
case "everything":
return {
...options,
base,
...getExclusions(options, base),
};
case "prompt":
Expand All @@ -228,6 +91,7 @@ export async function augmentOptionsWithExcludes(

return {
...options,
base,
...Object.fromEntries(
exclusionKeys.map(
(exclusionKey) =>
Expand Down
Loading