feat(create): allow specifying a git clone strategy (#6610)

* feat(create): allow specifying a git clone strategy

* Update index.ts
This commit is contained in:
Joshua Chen 2022-02-10 11:15:06 +08:00 committed by GitHub
parent 6996ed2f2f
commit b16b394eb6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 19 deletions

View file

@ -11,7 +11,7 @@
const logger = require('@docusaurus/logger').default;
const semver = require('semver');
const path = require('path');
const program = require('commander');
const {program} = require('commander');
const {default: init} = require('../lib');
const requiredVersion = require('../package.json').engines.node;
@ -29,36 +29,41 @@ function wrapCommand(fn) {
});
}
program
.version(require('../package.json').version)
.usage('<command> [options]');
program.version(require('../package.json').version);
program
.command('init [siteName] [template] [rootDir]', {isDefault: true})
.option('--use-npm')
.option('--skip-install')
.option('--typescript')
.arguments('[siteName] [template] [rootDir]')
.option('--use-npm', 'Use NPM as package manage even with Yarn installed')
.option(
'--skip-install',
'Do not run package manager immediately after scaffolding',
)
.option('--typescript', 'Use the TypeScript template variant')
.option(
'--git-strategy <strategy>',
`Only used if the template is a git repository.
\`deep\`: preserve full history
\`shallow\`: clone with --depth=1
\`copy\`: do a shallow clone, but do not create a git repo
\`custom\`: enter your custom git clone command. We will prompt you for it.`,
)
.description('Initialize website.')
.action(
(
siteName,
template,
rootDir = '.',
{useNpm, skipInstall, typescript} = {},
{useNpm, skipInstall, typescript, gitStrategy} = {},
) => {
wrapCommand(init)(path.resolve(rootDir), siteName, template, {
useNpm,
skipInstall,
typescript,
gitStrategy,
});
},
);
program.arguments('<command>').action((cmd) => {
program.outputHelp();
logger.error`Unknown command code=${cmd}.`;
});
program.parse(process.argv);
if (!process.argv.slice(1).length) {

View file

@ -101,6 +101,28 @@ async function copyTemplate(
});
}
const gitStrategies = ['deep', 'shallow', 'copy', 'custom'] as const;
async function getGitCommand(gitStrategy: typeof gitStrategies[number]) {
switch (gitStrategy) {
case 'shallow':
case 'copy':
return 'git clone --recursive --depth 1';
case 'custom': {
const {command} = await prompts({
type: 'text',
name: 'command',
message:
'Write your own git clone command. The repository URL and destination directory will be supplied. E.g. "git clone --depth 10"',
});
return command;
}
case 'deep':
default:
return 'git clone';
}
}
export default async function init(
rootDir: string,
siteName?: string,
@ -109,6 +131,7 @@ export default async function init(
useNpm: boolean;
skipInstall: boolean;
typescript: boolean;
gitStrategy: typeof gitStrategies[number];
}> = {},
): Promise<void> {
const useYarn = cliOptions.useNpm ? false : hasYarn();
@ -166,6 +189,8 @@ export default async function init(
}
}
let gitStrategy = cliOptions.gitStrategy ?? 'deep';
// If user choose Git repository, we'll prompt for the url.
if (template === 'Git repository') {
const repoPrompt = await prompts({
@ -180,6 +205,20 @@ export default async function init(
message: logger.interpolate`Enter a repository URL from GitHub, Bitbucket, GitLab, or any other public repo.
(e.g: path=${'https://github.com/ownerName/repoName.git'})`,
});
({gitStrategy} = await prompts({
type: 'select',
name: 'gitStrategy',
message: 'How should we clone this repo?',
choices: [
{title: 'Deep clone: preserve full history', value: 'deep'},
{title: 'Shallow clone: clone with --depth=1', value: 'shallow'},
{
title: 'Copy: do a shallow clone, but do not create a git repo',
value: 'copy',
},
{title: 'Custom: enter your custom git clone command', value: 'custom'},
],
}));
template = repoPrompt.gitRepoUrl;
} else if (template === 'Local template') {
const dirPrompt = await prompts({
@ -212,13 +251,20 @@ export default async function init(
if (isValidGitRepoUrl(template)) {
logger.info`Cloning Git template path=${template}...`;
if (
shell.exec(`git clone --recursive ${template} ${dest}`, {silent: true})
.code !== 0
) {
if (!gitStrategies.includes(gitStrategy)) {
logger.error`Invalid git strategy: name=${gitStrategy}. Value must be one of ${gitStrategies.join(
', ',
)}.`;
process.exit(1);
}
const command = await getGitCommand(gitStrategy);
if (shell.exec(`${command} ${template} ${dest}`).code !== 0) {
logger.error`Cloning Git template name=${template} failed!`;
process.exit(1);
}
if (gitStrategy === 'copy') {
await fs.remove(path.join(dest, '.git'));
}
} else if (templates.includes(template)) {
// Docusaurus templates.
if (useTS) {