diff --git a/packages/create-docusaurus/bin/index.js b/packages/create-docusaurus/bin/index.js index bd608096f0..8f644944da 100755 --- a/packages/create-docusaurus/bin/index.js +++ b/packages/create-docusaurus/bin/index.js @@ -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(' [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 ', + `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('').action((cmd) => { - program.outputHelp(); - logger.error`Unknown command code=${cmd}.`; -}); - program.parse(process.argv); if (!process.argv.slice(1).length) { diff --git a/packages/create-docusaurus/src/index.ts b/packages/create-docusaurus/src/index.ts index 979516ee8a..b74827ac23 100755 --- a/packages/create-docusaurus/src/index.ts +++ b/packages/create-docusaurus/src/index.ts @@ -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 { 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) { diff --git a/website/docs/installation.md b/website/docs/installation.md index 1189fabdf8..4bd97f1427 100644 --- a/website/docs/installation.md +++ b/website/docs/installation.md @@ -35,7 +35,7 @@ npx create-docusaurus@latest website classic If you do not specify `name` or `template`, it will prompt you for them. We recommend the `classic` template so that you can get started quickly, and it contains features found in Docusaurus 1. The `classic` template contains `@docusaurus/preset-classic` which includes standard documentation, a blog, custom pages, and a CSS framework (with dark mode support). You can get up and running extremely quickly with the classic template and customize things later on when you have gained more familiarity with Docusaurus. -The `template` also accepts a git repo URL or a local file path, with the latter evaluated relative to the current working directory. The repo/folder content will be copied to the site directory. +The `template` also accepts a git repo URL or a local file path, with the latter evaluated relative to the current working directory. The repo/folder content will be copied to the site directory. If it's a git repository, you can also specify a cloning strategy. Run `npx create-docusaurus@latest --help` for more information. :::info FB-Only