Skip to content

Commit

Permalink
feat: enable fork workspace
Browse files Browse the repository at this point in the history
  • Loading branch information
linbudu599 committed Mar 15, 2022
1 parent 8f5b947 commit 6171a4a
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 7 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
"fs-extra": "^10.0.1",
"jsonfile": "^6.1.0",
"minimist": "^1.2.5",
"nanoid": "^3.3.1",
"ora": "^5.0.0",
"preferred-pm": "^3.0.3",
"prettier": "^2.5.1",
"prompts": "^2.4.2",
Expand Down
11 changes: 5 additions & 6 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions scripts/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import useCreateSimplePackage from './create-package';
import useCopyPackage from './copy-package';
import useCachePackage from './cache-package';
import useRenameWorkspacePackage from './rename-package';
import useForkWorkspace from './fork-workspace';

const cli = cac('LinbuduLab-Starter');

Expand All @@ -22,6 +23,7 @@ useCreateSimplePackage(cli);
useCopyPackage(cli);
useCachePackage(cli);
useRenameWorkspacePackage(cli);
useForkWorkspace(cli);

cli.help();
cli.parse();
155 changes: 155 additions & 0 deletions scripts/fork-workspace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import { CAC } from 'cac';
import fs from 'fs-extra';

import chalk from 'chalk';
import { CLIUtils, Constants } from './utils';
import consola from 'consola';
import path from 'path';
import ora from 'ora';

export default function useForkWorkspace(cli: CAC) {
cli
.command('fork [workspaceName] <dir>', 'fork workspace to a new folder')
.option('-f, --force', 'rm workspace dir if exists')
.action(
async (
workspaceName: string,
dir?: string,
options?: {
force: boolean;
}
) => {
const { force = false } = options ?? {};

const defaultBaseDir = path.dirname(process.cwd());

const forkedWorkspaceLocation = path.resolve(
defaultBaseDir,
'tmp',
dir ?? 'forked'
);

consola.info(
`Forked workspace will be created in: ${chalk.green(
forkedWorkspaceLocation
)}`
);

if (fs.existsSync(forkedWorkspaceLocation)) {
if (force) {
// TODO: confirm
consola.warn(`A non-empty dir will be removed.`);

const confirm = await CLIUtils.createConfirmSelector(
'Confirm Operation?'
);

confirm
? fs.rmSync(forkedWorkspaceLocation, {
recursive: true,
})
: consola.info('Operation Cancelled');

!confirm && process.exit(0);
} else {
consola.fatal(
`Target workspace dir: ${chalk.green(
forkedWorkspaceLocation
)} exists, use ${chalk.white('-f, --force')} to overwrite it.`
);

process.exit(0);
}
}

const pickedPackages = await CLIUtils.createPackageMultiSelector(
'picked',
'Pick packages to use in forked workspace',
false
);

consola.info(
`Forking workspace packages: ${chalk.white(
pickedPackages.join(', ')
)}...`
);

for (const pkg of pickedPackages) {
const packageSourcePath = CLIUtils.resolvePackageDir(pkg);
const packageDestPath = path.resolve(
forkedWorkspaceLocation,
'packages',
pkg
);

fs.copySync(packageSourcePath, packageDestPath, {
recursive: true,
filter: (src, dest) => {
const filtered = ['node_modules', 'dist', 'tmp'].every(
(pattern) => !src.includes(pattern)
);

return filtered;
},
});
}

consola.success(`Workspace packages copied.`);

consola.info(`Forking workspace assets...`);

const workspaceBase = fs
.readdirSync(process.cwd())
.filter(
(d) =>
!['node_modules', 'dist', 'tmp', '.git', 'packages'].includes(d)
);

for (const baseAsset of workspaceBase) {
const baseAssetPath = path.resolve(process.cwd(), baseAsset);

const forkedAssetPath = path.resolve(
forkedWorkspaceLocation,
baseAsset
);

fs.copySync(baseAssetPath, forkedAssetPath);
}

consola.success(`Workspace assets copied.`);

consola.success(
`Brand new workspace forked to ${chalk.green(
forkedWorkspaceLocation
)}`
);

console.log('');
consola.info(
`Executing ${chalk.white('Deps Installation')} and ${chalk.white(
'Env Setup'
)}...`
);

const spinner = ora('Installing dependencies...').start();

CLIUtils.useChildProcess(
'pnpm install --registry=https://registry.npmmirror.com',
{
cwd: forkedWorkspaceLocation,
stdio: 'ignore',
}
)
.then(() => {
spinner.succeed('Dependencies installed!');

return Promise.resolve();
})
.then(() => {
consola.success('Openning workspace in VS Code...');
CLIUtils.useChildProcess(`code ${forkedWorkspaceLocation}`);
return Promise.resolve();
});
}
);
}
13 changes: 12 additions & 1 deletion scripts/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,16 @@ export class CLIUtils {
return null;
}

public static async createConfirmSelector(message: string): Promise<boolean> {
const res = await enquirer.prompt<Record<'confirm', boolean>>({
type: 'confirm',
name: 'confirm',
message,
});

return res.confirm;
}

public static async createPackageMultiSelector<T extends string>(
name: T,
message: string,
Expand Down Expand Up @@ -264,7 +274,8 @@ export class CLIUtils {
command: string,
options?: execa.Options
) {
consola.info(`Executing command: ${command} \n`);
console.log('');
consola.info(`Executing command: ${chalk.cyan(command)}`);

await execa(command, {
stdio: 'inherit',
Expand Down

0 comments on commit 6171a4a

Please sign in to comment.