Skip to content
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

refactor: inject curried runPkgManagerInstall to package installers #202

Merged
merged 6 commits into from
Jul 17, 2022
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
23 changes: 21 additions & 2 deletions src/helpers/createProject.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { PkgInstallerMap } from "../installers/index.js";
import path from "path";
import { getUserPkgManager } from "../utils/getUserPkgManager.js";
import { curryRunPkgManagerInstall } from "../utils/runPkgManagerInstall.js";
import { installPackages } from "./installPackages.js";
import { scaffoldProject } from "./scaffoldProject.js";
import { selectAppFile, selectIndexFile } from "./selectBoilerplate.js";
Expand All @@ -18,12 +19,30 @@ export const createProject = async ({
}: CreateProjectOptions) => {
const pkgManager = getUserPkgManager();
const projectDir = path.resolve(process.cwd(), projectName);
const runPkgManagerInstall = curryRunPkgManagerInstall({
projectDir,
pkgManager,
devMode: false,
noInstallMode: noInstall,
});

// Bootstraps the base Next.js application
await scaffoldProject({ projectName, projectDir, pkgManager, noInstall });
await scaffoldProject({
projectName,
projectDir,
pkgManager,
noInstall,
runPkgManagerInstall,
});

// Install the selected packages
await installPackages({ projectDir, pkgManager, packages, noInstall });
await installPackages({
projectDir,
pkgManager,
packages,
noInstall,
runPkgManagerInstall,
});

// TODO: Look into using handlebars or other templating engine to scaffold without needing to maintain multiple copies of the same file
await selectAppFile({ projectDir, packages });
Expand Down
10 changes: 3 additions & 7 deletions src/helpers/installPackages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,16 @@ type InstallPackagesOptions = {
packages: PkgInstallerMap;
} & InstallerOptions;
// This runs the installer for all the packages that the user has selected
export const installPackages = async ({
projectDir,
pkgManager,
packages,
noInstall,
}: InstallPackagesOptions) => {
export const installPackages = async (options: InstallPackagesOptions) => {
const { packages, noInstall } = options;
logger.info(`${noInstall ? "Adding" : "Installing"} packages...`);

for (const [name, pkgOpts] of Object.entries(packages)) {
if (pkgOpts.inUse) {
const spinner = ora(
`${noInstall ? "Adding" : "Installing"} ${name}...`,
).start();
await pkgOpts.installer({ projectDir, pkgManager, packages, noInstall });
await pkgOpts.installer(options);
spinner.succeed(
chalk.green(
`Successfully ${noInstall ? "added" : "installed"} ${chalk.green.bold(
Expand Down
4 changes: 4 additions & 0 deletions src/installers/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { PackageManager } from "../utils/getUserPkgManager.js";
import type { CurriedRunPkgManagerInstallOptions } from "../utils/runPkgManagerInstall.js";
import { envVariblesInstaller } from "./envVars.js";
import { nextAuthInstaller } from "./next-auth.js";
import { prismaInstaller } from "./prisma.js";
Expand All @@ -23,6 +24,9 @@ export interface InstallerOptions {
noInstall: boolean;
packages?: PkgInstallerMap;
projectName?: string;
runPkgManagerInstall: (
opts: CurriedRunPkgManagerInstallOptions,
) => Promise<void>;
}

export type Installer = (opts: InstallerOptions) => Promise<void>;
Expand Down
8 changes: 1 addition & 7 deletions src/installers/next-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,17 @@ import type { Installer } from "./index.js";
import path from "path";
import fs from "fs-extra";
import { PKG_ROOT } from "../consts.js";
import { runPkgManagerInstall } from "../utils/runPkgManagerInstall.js";

export const nextAuthInstaller: Installer = async ({
pkgManager,
projectDir,
runPkgManagerInstall,
packages,
noInstall,
}) => {
await runPkgManagerInstall({
pkgManager,
projectDir,
packages: [
"next-auth",
packages?.prisma.inUse ? "@next-auth/prisma-adapter" : "",
],
devMode: false,
noInstallMode: noInstall,
});

const nextAuthAssetDir = path.join(PKG_ROOT, "template/addons/next-auth");
Expand Down
9 changes: 1 addition & 8 deletions src/installers/prisma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,20 @@ import path from "path";
import fs from "fs-extra";
import { PKG_ROOT } from "../consts.js";
import { execa } from "../utils/execAsync.js";
import { runPkgManagerInstall } from "../utils/runPkgManagerInstall.js";

export const prismaInstaller: Installer = async ({
projectDir,
runPkgManagerInstall,
pkgManager,
packages,
noInstall,
}) => {
await runPkgManagerInstall({
pkgManager,
projectDir,
packages: ["prisma"],
devMode: true,
ochicf marked this conversation as resolved.
Show resolved Hide resolved
noInstallMode: noInstall,
});
await runPkgManagerInstall({
pkgManager,
projectDir,
packages: ["@prisma/client"],
devMode: false,
noInstallMode: noInstall,
});

const prismaAssetDir = path.join(PKG_ROOT, "template/addons/prisma");
Expand Down
7 changes: 1 addition & 6 deletions src/installers/tailwind.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,14 @@ import type { Installer } from "./index.js";
import path from "path";
import fs from "fs-extra";
import { PKG_ROOT } from "../consts.js";
import { runPkgManagerInstall } from "../utils/runPkgManagerInstall.js";

export const tailwindInstaller: Installer = async ({
projectDir,
pkgManager,
noInstall,
runPkgManagerInstall,
}) => {
await runPkgManagerInstall({
pkgManager,
projectDir,
packages: ["tailwindcss", "postcss", "autoprefixer"],
devMode: true,
ochicf marked this conversation as resolved.
Show resolved Hide resolved
noInstallMode: noInstall,
});

const twAssetDir = path.join(PKG_ROOT, "template/addons/tailwind");
Expand Down
8 changes: 1 addition & 7 deletions src/installers/trpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,13 @@ import type { Installer } from "./index.js";
import path from "path";
import fs from "fs-extra";
import { PKG_ROOT } from "../consts.js";
import { runPkgManagerInstall } from "../utils/runPkgManagerInstall.js";

export const trpcInstaller: Installer = async ({
projectDir,
pkgManager,
packages,
noInstall,
runPkgManagerInstall,
}) => {
await runPkgManagerInstall({
pkgManager,
projectDir,
packages: [
"react-query",
"superjson",
Expand All @@ -21,8 +17,6 @@ export const trpcInstaller: Installer = async ({
"@trpc/next",
"@trpc/react",
],
devMode: false,
noInstallMode: noInstall,
});
const usingAuth = packages?.nextAuth.inUse;
const usingPrisma = packages?.prisma.inUse;
Expand Down
31 changes: 29 additions & 2 deletions src/utils/runPkgManagerInstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ import { type PackageJson } from "type-fest";
import { execa } from "./execAsync.js";
import { logger } from "./logger.js";

export const runPkgManagerInstall = async (opts: {
export interface RunPkgManagerInstallOptions {
pkgManager: PackageManager;
devMode: boolean;
projectDir: string;
packages: string[];
noInstallMode: boolean;
}) => {
}

export const runPkgManagerInstall = async (
opts: RunPkgManagerInstallOptions,
) => {
const { pkgManager, devMode, projectDir, packages, noInstallMode } = opts;

if (noInstallMode) {
Expand Down Expand Up @@ -50,3 +54,26 @@ export const runPkgManagerInstall = async (opts: {
const fullCmd = `${installCmd} ${flag} ${packages.join(" ")}`;
await execa(fullCmd, { cwd: projectDir });
};

export type CurryRunPkgManagerInstallOptions = Omit<
RunPkgManagerInstallOptions,
"packages"
>;

export type CurriedRunPkgManagerInstallOptions =
Partial<CurryRunPkgManagerInstallOptions> &
Omit<RunPkgManagerInstallOptions, keyof CurryRunPkgManagerInstallOptions>;

export const curryRunPkgManagerInstall = (
baseOptions: CurryRunPkgManagerInstallOptions,
) => {
const curriedRunPkgManagerInstall = async (
options: CurriedRunPkgManagerInstallOptions,
) =>
runPkgManagerInstall({
...baseOptions,
...options,
});

return curriedRunPkgManagerInstall;
};