aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/packages/turbo-workspaces/src/commands
diff options
context:
space:
mode:
Diffstat (limited to 'packages/turbo-workspaces/src/commands')
-rw-r--r--packages/turbo-workspaces/src/commands/convert/index.ts109
-rw-r--r--packages/turbo-workspaces/src/commands/convert/types.ts6
-rw-r--r--packages/turbo-workspaces/src/commands/index.ts8
-rw-r--r--packages/turbo-workspaces/src/commands/summary/index.ts98
-rw-r--r--packages/turbo-workspaces/src/commands/summary/types.ts1
5 files changed, 222 insertions, 0 deletions
diff --git a/packages/turbo-workspaces/src/commands/convert/index.ts b/packages/turbo-workspaces/src/commands/convert/index.ts
new file mode 100644
index 0000000..6cc82fc
--- /dev/null
+++ b/packages/turbo-workspaces/src/commands/convert/index.ts
@@ -0,0 +1,109 @@
+import { ConvertCommandArgument, ConvertCommandOptions } from "./types";
+import inquirer from "inquirer";
+import { Logger } from "../../logger";
+import chalk from "chalk";
+import { getAvailablePackageManagers } from "@turbo/utils";
+import { directoryInfo } from "../../utils";
+import getWorkspaceDetails from "../../getWorkspaceDetails";
+import { PackageManager } from "../../types";
+import { convertProject } from "../../convert";
+
+function isPackageManagerDisabled({
+ packageManager,
+ currentWorkspaceManger,
+ availablePackageManagers,
+}: {
+ packageManager: PackageManager;
+ currentWorkspaceManger: PackageManager;
+ availablePackageManagers: Record<PackageManager, { available: boolean }>;
+}) {
+ if (currentWorkspaceManger === packageManager) {
+ return "already in use";
+ }
+
+ if (!availablePackageManagers[packageManager].available) {
+ return "not installed";
+ }
+
+ return false;
+}
+
+export default async function convertCommand(
+ directory: ConvertCommandArgument,
+ packageManager: ConvertCommandArgument,
+ options: ConvertCommandOptions
+) {
+ const logger = new Logger(options);
+
+ logger.hero();
+ logger.header("Welcome, let's convert your project.");
+ logger.blankLine();
+
+ const directoryAnswer = await inquirer.prompt<{
+ directoryInput: string;
+ }>({
+ type: "input",
+ name: "directoryInput",
+ message: "Where is the root of your repo?",
+ when: !directory,
+ default: ".",
+ validate: (directory: string) => {
+ const { exists, absolute } = directoryInfo({ directory });
+ if (exists) {
+ return true;
+ } else {
+ return `Directory ${chalk.dim(`(${absolute})`)} does not exist`;
+ }
+ },
+ filter: (directory: string) => directory.trim(),
+ });
+
+ const { directoryInput: selectedDirectory = directory } = directoryAnswer;
+ const { exists, absolute: root } = directoryInfo({
+ directory: selectedDirectory,
+ });
+ if (!exists) {
+ console.error(`Directory ${chalk.dim(`(${root})`)} does not exist`);
+ return process.exit(1);
+ }
+
+ const [project, availablePackageManagers] = await Promise.all([
+ getWorkspaceDetails({ root }),
+ getAvailablePackageManagers(),
+ ]);
+
+ const packageManagerAnswer = await inquirer.prompt<{
+ packageManagerInput?: PackageManager;
+ }>({
+ name: "packageManagerInput",
+ type: "list",
+ message: `Convert from ${project.packageManager} workspaces to:`,
+ when:
+ !packageManager ||
+ !Object.keys(availablePackageManagers).includes(packageManager),
+ choices: ["npm", "pnpm", "yarn"].map((p) => ({
+ name: `${p} workspaces`,
+ value: p,
+ disabled: isPackageManagerDisabled({
+ packageManager: p as PackageManager,
+ currentWorkspaceManger: project.packageManager,
+ availablePackageManagers,
+ }),
+ })),
+ });
+ const {
+ packageManagerInput:
+ selectedPackageManager = packageManager as PackageManager,
+ } = packageManagerAnswer;
+
+ await convertProject({
+ project,
+ to: {
+ name: selectedPackageManager,
+ version: availablePackageManagers[selectedPackageManager]
+ .version as string,
+ },
+ logger,
+ options,
+ });
+}
diff --git a/packages/turbo-workspaces/src/commands/convert/types.ts b/packages/turbo-workspaces/src/commands/convert/types.ts
new file mode 100644
index 0000000..a7b9deb
--- /dev/null
+++ b/packages/turbo-workspaces/src/commands/convert/types.ts
@@ -0,0 +1,6 @@
+export type ConvertCommandArgument = string;
+export type ConvertCommandOptions = {
+ dry: boolean;
+ force: boolean;
+ skipInstall: boolean;
+};
diff --git a/packages/turbo-workspaces/src/commands/index.ts b/packages/turbo-workspaces/src/commands/index.ts
new file mode 100644
index 0000000..423e959
--- /dev/null
+++ b/packages/turbo-workspaces/src/commands/index.ts
@@ -0,0 +1,8 @@
+export { default as summary } from "./summary";
+export { default as convert } from "./convert";
+
+export type { SummaryCommandArgument } from "./summary/types";
+export type {
+ ConvertCommandArgument,
+ ConvertCommandOptions,
+} from "./convert/types";
diff --git a/packages/turbo-workspaces/src/commands/summary/index.ts b/packages/turbo-workspaces/src/commands/summary/index.ts
new file mode 100644
index 0000000..9696a14
--- /dev/null
+++ b/packages/turbo-workspaces/src/commands/summary/index.ts
@@ -0,0 +1,98 @@
+import inquirer from "inquirer";
+import path from "path";
+import { Logger } from "../../logger";
+import chalk from "chalk";
+import { SummaryCommandArgument } from "./types";
+import { directoryInfo } from "../../utils";
+import getWorkspaceDetails from "../../getWorkspaceDetails";
+import { Workspace } from "../../types";
+
+export default async function summary(directory: SummaryCommandArgument) {
+ const logger = new Logger();
+ logger.hero();
+
+ const answer = await inquirer.prompt<{
+ directoryInput?: string;
+ }>({
+ type: "input",
+ name: "directoryInput",
+ message: "Where is the root of the repo?",
+ when: !directory,
+ default: ".",
+ validate: (directory: string) => {
+ const { exists, absolute } = directoryInfo({ directory });
+ if (exists) {
+ return true;
+ } else {
+ return `Directory ${chalk.dim(`(${absolute})`)} does not exist`;
+ }
+ },
+ filter: (directory: string) => directory.trim(),
+ });
+
+ const { directoryInput: selectedDirectory = directory as string } = answer;
+ const { exists, absolute: root } = directoryInfo({
+ directory: selectedDirectory,
+ });
+ if (!exists) {
+ console.error(`Directory ${chalk.dim(`(${root})`)} does not exist`);
+ return process.exit(1);
+ }
+
+ const project = await getWorkspaceDetails({ root });
+
+ const numWorkspaces = project.workspaceData.workspaces.length;
+ const hasWorkspaces = numWorkspaces > 0;
+ // group workspaces
+ const workspacesByDirectory: Record<string, Array<Workspace>> = {};
+ project.workspaceData.workspaces.forEach((workspace) => {
+ const workspacePath = path.relative(root, workspace.paths.root);
+ const rootDirectory = workspacePath.split(path.sep)[0];
+ if (!workspacesByDirectory[rootDirectory]) {
+ workspacesByDirectory[rootDirectory] = [];
+ }
+ workspacesByDirectory[rootDirectory].push(workspace);
+ });
+
+ const renderWorkspace = (w: Workspace) => {
+ return `${w.name} (${chalk.italic(
+ `./${path.relative(root, w.paths.root)}`
+ )})`;
+ };
+
+ const renderDirectory = ({
+ number,
+ directory,
+ workspaces,
+ }: {
+ number: number;
+ directory: string;
+ workspaces: Array<Workspace>;
+ }) => {
+ logger.indented(2, `${number}. ${chalk.bold(directory)}`);
+ workspaces.forEach((workspace, idx) => {
+ logger.indented(3, `${idx + 1}. ${renderWorkspace(workspace)}`);
+ });
+ };
+
+ // repo header
+ logger.header(`Repository Summary`);
+ logger.indented(1, `${chalk.underline(project.name)}:`);
+ // workspace manager header
+ logger.indented(
+ 1,
+ `Package Manager: ${chalk.bold(chalk.italic(project.packageManager))}`
+ );
+ if (hasWorkspaces) {
+ // workspaces header
+ logger.indented(1, `Workspaces (${chalk.bold(numWorkspaces.toString())}):`);
+ Object.keys(workspacesByDirectory).forEach((directory, idx) => {
+ renderDirectory({
+ number: idx + 1,
+ directory,
+ workspaces: workspacesByDirectory[directory],
+ });
+ });
+ logger.blankLine();
+ }
+}
diff --git a/packages/turbo-workspaces/src/commands/summary/types.ts b/packages/turbo-workspaces/src/commands/summary/types.ts
new file mode 100644
index 0000000..0cc5830
--- /dev/null
+++ b/packages/turbo-workspaces/src/commands/summary/types.ts
@@ -0,0 +1 @@
+export type SummaryCommandArgument = string;