feat: support CLI arguments for npx quartz create
(#421)
* feat(cli): add new args for content + link resolve * feat(cli): validate cmd args * feat(cli): add chalk + error code to errors * feat(cli): support for setup/link via args * refactor(cli): use yargs choices instead of manual Scrap manual check if arguments are valid, use yargs "choices" field instead. * feat(cli): add in-dir argument+ handle errors add new "in-directory" argument, used if "setup" is "copy" or "symlink" to determine source. add error handling for invalid permutations of arguments or non existent path * feat(cli): dynamically use cli or provided args use "in-directory" arg as `originalFolder` if available, otherwise get it from manual cli process * run format * fix: use process.exit instead of return * refactor: split CommonArgv and CreateArgv * refactor(cli): rename create args, use ${} syntax * fix(cli): fix link resolution strategy arg * format * feat(consistency): allow partial cmd args
This commit is contained in:
parent
74c3ebb7bd
commit
ad4145fb10
@ -43,6 +43,27 @@ const CommonArgv = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CreateArgv = {
|
||||||
|
...CommonArgv,
|
||||||
|
source: {
|
||||||
|
string: true,
|
||||||
|
alias: ["s"],
|
||||||
|
describe: "source directory to copy/create symlink from",
|
||||||
|
},
|
||||||
|
strategy: {
|
||||||
|
string: true,
|
||||||
|
alias: ["X"],
|
||||||
|
choices: ["new", "copy", "symlink"],
|
||||||
|
describe: "strategy for content folder setup",
|
||||||
|
},
|
||||||
|
links: {
|
||||||
|
string: true,
|
||||||
|
alias: ["l"],
|
||||||
|
choices: ["absolute", "shortest", "relative"],
|
||||||
|
describe: "strategy to resolve links",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
const SyncArgv = {
|
const SyncArgv = {
|
||||||
...CommonArgv,
|
...CommonArgv,
|
||||||
commit: {
|
commit: {
|
||||||
@ -147,11 +168,59 @@ yargs(hideBin(process.argv))
|
|||||||
.scriptName("quartz")
|
.scriptName("quartz")
|
||||||
.version(version)
|
.version(version)
|
||||||
.usage("$0 <cmd> [args]")
|
.usage("$0 <cmd> [args]")
|
||||||
.command("create", "Initialize Quartz", CommonArgv, async (argv) => {
|
.command("create", "Initialize Quartz", CreateArgv, async (argv) => {
|
||||||
console.log()
|
console.log()
|
||||||
intro(chalk.bgGreen.black(` Quartz v${version} `))
|
intro(chalk.bgGreen.black(` Quartz v${version} `))
|
||||||
const contentFolder = path.join(cwd, argv.directory)
|
const contentFolder = path.join(cwd, argv.directory)
|
||||||
const setupStrategy = exitIfCancel(
|
let setupStrategy = argv.strategy?.toLowerCase()
|
||||||
|
let linkResolutionStrategy = argv.links?.toLowerCase()
|
||||||
|
const sourceDirectory = argv.source
|
||||||
|
|
||||||
|
// If all cmd arguments were provided, check if theyre valid
|
||||||
|
if (setupStrategy && linkResolutionStrategy) {
|
||||||
|
// If setup isn't, "new", source argument is required
|
||||||
|
if (setupStrategy !== "new") {
|
||||||
|
// Error handling
|
||||||
|
if (!sourceDirectory) {
|
||||||
|
outro(
|
||||||
|
chalk.red(
|
||||||
|
`Setup strategies (arg '${chalk.yellow(
|
||||||
|
`-${CreateArgv.strategy.alias[0]}`,
|
||||||
|
)}') other than '${chalk.yellow(
|
||||||
|
"new",
|
||||||
|
)}' require content folder argument ('${chalk.yellow(
|
||||||
|
`-${CreateArgv.source.alias[0]}`,
|
||||||
|
)}') to be set`,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
process.exit(1)
|
||||||
|
} else {
|
||||||
|
if (!fs.existsSync(sourceDirectory)) {
|
||||||
|
outro(
|
||||||
|
chalk.red(
|
||||||
|
`Input directory to copy/symlink 'content' from not found ('${chalk.yellow(
|
||||||
|
sourceDirectory,
|
||||||
|
)}', invalid argument "${chalk.yellow(`-${CreateArgv.source.alias[0]}`)})`,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
process.exit(1)
|
||||||
|
} else if (!fs.lstatSync(sourceDirectory).isDirectory()) {
|
||||||
|
outro(
|
||||||
|
chalk.red(
|
||||||
|
`Source directory to copy/symlink 'content' from is not a directory (found file at '${chalk.yellow(
|
||||||
|
sourceDirectory,
|
||||||
|
)}', invalid argument ${chalk.yellow(`-${CreateArgv.source.alias[0]}`)}")`,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use cli process if cmd args werent provided
|
||||||
|
if (!setupStrategy) {
|
||||||
|
setupStrategy = exitIfCancel(
|
||||||
await select({
|
await select({
|
||||||
message: `Choose how to initialize the content in \`${contentFolder}\``,
|
message: `Choose how to initialize the content in \`${contentFolder}\``,
|
||||||
options: [
|
options: [
|
||||||
@ -165,6 +234,7 @@ yargs(hideBin(process.argv))
|
|||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
async function rmContentFolder() {
|
async function rmContentFolder() {
|
||||||
const contentStat = await fs.promises.lstat(contentFolder)
|
const contentStat = await fs.promises.lstat(contentFolder)
|
||||||
@ -177,7 +247,11 @@ yargs(hideBin(process.argv))
|
|||||||
|
|
||||||
await fs.promises.unlink(path.join(contentFolder, ".gitkeep"))
|
await fs.promises.unlink(path.join(contentFolder, ".gitkeep"))
|
||||||
if (setupStrategy === "copy" || setupStrategy === "symlink") {
|
if (setupStrategy === "copy" || setupStrategy === "symlink") {
|
||||||
const originalFolder = escapePath(
|
let originalFolder = sourceDirectory
|
||||||
|
|
||||||
|
// If input directory was not passed, use cli
|
||||||
|
if (!sourceDirectory) {
|
||||||
|
originalFolder = escapePath(
|
||||||
exitIfCancel(
|
exitIfCancel(
|
||||||
await text({
|
await text({
|
||||||
message: "Enter the full path to existing content folder",
|
message: "Enter the full path to existing content folder",
|
||||||
@ -194,6 +268,7 @@ yargs(hideBin(process.argv))
|
|||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
await rmContentFolder()
|
await rmContentFolder()
|
||||||
if (setupStrategy === "copy") {
|
if (setupStrategy === "copy") {
|
||||||
@ -217,8 +292,10 @@ See the [documentation](https://quartz.jzhao.xyz) for how to get started.
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use cli process if cmd args werent provided
|
||||||
|
if (!linkResolutionStrategy) {
|
||||||
// get a preferred link resolution strategy
|
// get a preferred link resolution strategy
|
||||||
const linkResolutionStrategy = exitIfCancel(
|
linkResolutionStrategy = exitIfCancel(
|
||||||
await select({
|
await select({
|
||||||
message: `Choose how Quartz should resolve links in your content. You can change this later in \`quartz.config.ts\`.`,
|
message: `Choose how Quartz should resolve links in your content. You can change this later in \`quartz.config.ts\`.`,
|
||||||
options: [
|
options: [
|
||||||
@ -240,6 +317,7 @@ See the [documentation](https://quartz.jzhao.xyz) for how to get started.
|
|||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// now, do config changes
|
// now, do config changes
|
||||||
const configFilePath = path.join(cwd, "quartz.config.ts")
|
const configFilePath = path.join(cwd, "quartz.config.ts")
|
||||||
|
Loading…
Reference in New Issue
Block a user