feat!: rename createSubFolder and subFolderNameHelper

This commit is contained in:
2024-01-30 02:11:45 +02:00
committed by Chen Asraf
parent 09d330af63
commit 90ba9f72f2
12 changed files with 92 additions and 52 deletions

View File

@@ -31,14 +31,17 @@ interface ScaffoldConfig {
name: string
templates: string[]
output: FileResponse<string>
createSubFolder?: boolean
subdir?: boolean
git?: string
config?: string
key?: string
data?: Record<string, any>
overwrite?: FileResponse<boolean>
quiet?: boolean
verbose?: LogLevel
dryRun?: boolean
helpers?: Record<string, Helper>
subFolderNameHelper?: DefaultHelpers | string
subdirHelper?: DefaultHelpers | string
beforeWrite?(
content: Buffer,
rawContent: Buffer,

View File

@@ -32,19 +32,19 @@ title: Examples
- Output file path:
- With `createSubFolder = false` (default):
- With `subdir = false` (default):
```text
project → src → components → MyComponent.js
```
- With `createSubFolder = true`:
- With `subdir = true`:
```text
project → src → components → MyComponent → MyComponent.js
```
- With `createSubFolder = true` and `subFolderNameHelper = 'upperCase'`:
- With `subdir = true` and `subdirHelper = 'upperCase'`:
```text
project → src → components → MYCOMPONENT → MyComponent.js

View File

@@ -6,9 +6,9 @@ title: Migration
### CLI option changes
- The `:template_key` syntax has been removed. You can still use `-k template_key` to achieve the
same result.
- Several changes to how remote configs are loaded via CLI:
- The `:template_key` syntax has been removed. You can still use `-k template_key` to achieve the
same result.
- The `--github` (`-gh`) flag has been replaced by a generic `--git` (`-g`) one, which handles any
git URL. Providing a partial GitHub path will default to trying to find the project on GitHub,
e.g. `-g username/project`
@@ -17,6 +17,10 @@ title: Migration
which can find the file for you if it is in one of the supported filenames.
- `verbose` can now take the names `debug`, `info`, `warn`, `error` or `none` (case insensitive) or
as usual by using the numbering from before.
- `--create-sub-folder` (`-s`) has been renamed to `--subdir` (`-s`) in the CLI. The Node.js names
have been changed as well.
- `--sub-folder-name-helper` (`-sh`) has been renamed to `--subdir-helper` (`-sh`). The Node.js
names have been changed as well.
- All boolean flags no longer take a value. `-q` instead of `-q 1` or `-q true`, `-s` instead of
`-s 1`, `-w` instead of `-w 1`, etc.

View File

@@ -125,7 +125,7 @@ config.helpers = {
```
All of the above helpers (built in and custom) will also be available to you when using
`subFolderNameHelper` (`--sub-folder-name-helper`/`-sh`) as a possible value.
`subdirHelper` (`--sub-dir-helper`/`-H`) as a possible value.
> To see more information on how helpers work and more features, see
> [Handlebars.js docs](https://handlebarsjs.com/guide/#custom-helpers).

View File

@@ -24,11 +24,9 @@
"clean": "rm -rf dist/",
"build": "pnpm clean && tsc && chmod -R +x ./dist && cp ./package.json ./README.md ./dist/",
"dev": "tsc --watch",
"start": "node dist/scaffold.js",
"start": "ts-node src/scaffold.ts",
"test": "jest",
"cmd": "node --trace-warnings dist/cmd.js",
"build-test": "pnpm build && pnpm test",
"build-cmd": "pnpm build && pnpm cmd",
"cmd": "ts-node src/cmd.ts",
"docs:build": "cd docs && pnpm build",
"docs:watch": "cd docs && pnpm start",
"audit-fix": "pnpm audit --fix",
@@ -39,7 +37,7 @@
"date-fns": "^3.3.1",
"glob": "^10.3.10",
"handlebars": "^4.7.8",
"massarg": "2.0.0-pre.11"
"massarg": "2.0.0-pre.12"
},
"devDependencies": {
"@semantic-release/changelog": "^6.0.3",

8
pnpm-lock.yaml generated
View File

@@ -18,8 +18,8 @@ dependencies:
specifier: ^4.7.8
version: 4.7.8
massarg:
specifier: 2.0.0-pre.11
version: 2.0.0-pre.11
specifier: 2.0.0-pre.12
version: 2.0.0-pre.12
devDependencies:
'@semantic-release/changelog':
@@ -3164,8 +3164,8 @@ packages:
hasBin: true
dev: true
/massarg@2.0.0-pre.11:
resolution: {integrity: sha512-MrN5ZllZyGI8DPSA8o164WgeEhfpDYnFvtA0xRoWrGJ2eCDUeyyCItUk3EB55tV3kwysqi6AAOei49xUQ5BG4w==}
/massarg@2.0.0-pre.12:
resolution: {integrity: sha512-ncD9mXRQh4y8IIi5qcNEzh0qsqXyVq0FH0/v2vdMy/+WJCdAIuKG3TqlWML1SWMH4QdqZ/XJnbDfp8u2i91NNg==}
dependencies:
zod: 3.22.4
dev: false

View File

@@ -8,7 +8,8 @@ import fs from "node:fs/promises"
import { parseAppendData, parseConfigFile } from "./config"
export async function parseCliArgs(args = process.argv.slice(2)) {
const pkgFile = await fs.readFile(path.join(__dirname, "package.json"))
const isProjectRoot = Boolean(await fs.stat(path.join(__dirname, "package.json")).catch(() => false))
const pkgFile = await fs.readFile(path.resolve(__dirname, isProjectRoot ? "." : "..", "package.json"))
const pkg = JSON.parse(pkgFile.toString())
const isConfigProvided =
args.includes("--config") || args.includes("-c") || args.includes("--git") || args.includes("-g")
@@ -56,7 +57,7 @@ export async function parseCliArgs(args = process.argv.slice(2)) {
name: "output",
aliases: ["o"],
description:
"Path to output to. If `--create-sub-folder` is enabled, the subfolder will be created inside " +
"Path to output to. If `--subdir` is enabled, the subfolder will be created inside " +
"this path. Default is current working directory.",
required: !isConfigProvided,
})
@@ -75,6 +76,7 @@ export async function parseCliArgs(args = process.argv.slice(2)) {
aliases: ["w"],
defaultValue: false,
description: "Enable to override output files, even if they already exist.",
negatable: true,
})
.option({
name: "data",
@@ -91,15 +93,17 @@ export async function parseCliArgs(args = process.argv.slice(2)) {
parse: parseAppendData,
})
.flag({
name: "create-sub-folder",
name: "subdir",
aliases: ["s"],
defaultValue: false,
description: "Create subfolder with the input name",
description: "Create a parent directory with the input name (and possibly `--subdir-helper`",
negatable: true,
negationName: "no-subdir",
})
.option({
name: "sub-folder-name-helper",
aliases: ["sh"],
description: "Default helper to apply to subfolder name when using `--create-sub-folder true`.",
name: "subdir-helper",
aliases: ["H"],
description: "Default helper to apply to subfolder name when using `--subdir`.",
})
.flag({
name: "quiet",
@@ -150,16 +154,17 @@ export async function parseCliArgs(args = process.argv.slice(2)) {
bindOption: true,
lineLength: 100,
useGlobalTableColumns: true,
// optionOptions: {
// displayNegations: true,
// },
usageText: [chalk.yellow`simple-scaffold`, chalk.gray`[options]`, chalk.cyan`<name>`].join(" "),
optionOptions: {
displayNegations: true,
},
footerText: [
`Version: ${pkg.version}`,
`Copyright © Chen Asraf 2017-${new Date().getFullYear()}`,
``,
`Documentation:\n ${chalk.underline`https://chenasraf.github.io/simple-scaffold`}`,
`NPM:\n ${chalk.underline`https://npmjs.com/package/simple-scaffold`}`,
`GitHub:\n ${chalk.underline`https://github.com/chenasraf/simple-scaffold`}`,
`Documentation: ${chalk.underline`https://chenasraf.github.io/simple-scaffold`}`,
`NPM: ${chalk.underline`https://npmjs.com/package/simple-scaffold`}`,
`GitHub: ${chalk.underline`https://github.com/chenasraf/simple-scaffold`}`,
].join("\n"),
})
.parse(args)

View File

@@ -165,9 +165,9 @@ export function getOutputDir(config: ScaffoldConfig, outputPathOpt: string, base
...([
outputPathOpt,
basePath,
config.createSubFolder
? config.subFolderNameHelper
? handlebarsParse(config, `{{ ${config.subFolderNameHelper} name }}`).toString()
config.subdir
? config.subdirHelper
? handlebarsParse(config, `{{ ${config.subdirHelper} name }}`).toString()
: config.name
: undefined,
].filter(Boolean) as string[]),

View File

@@ -2,7 +2,15 @@ import { LogConfig, LogLevel, ScaffoldConfig } from "./types"
import chalk from "chalk"
export function log(config: LogConfig, level: LogLevel, ...obj: any[]): void {
if (config.logLevel === LogLevel.none || level < (config.logLevel ?? LogLevel.info)) {
const priority: Record<LogLevel, number> = {
[LogLevel.none]: 0,
[LogLevel.debug]: 1,
[LogLevel.info]: 2,
[LogLevel.warning]: 3,
[LogLevel.error]: 4,
}
if (config.logLevel === LogLevel.none || priority[level] < priority[config.logLevel ?? LogLevel.info]) {
return
}
@@ -49,10 +57,10 @@ export function logInitStep(config: ScaffoldConfig): void {
name: config.name,
templates: config.templates,
output: config.output,
createSubFolder: config.createSubFolder,
subdir: config.subdir,
data: config.data,
overwrite: config.overwrite,
subFolderNameHelper: config.subFolderNameHelper,
subdirHelper: config.subdirHelper,
helpers: Object.keys(config.helpers ?? {}),
logLevel: config.logLevel,
dryRun: config.dryRun,

View File

@@ -123,7 +123,7 @@ Scaffold.fromConfig = async function (
logLevel: LogLevel.info,
overwrite: false,
templates: [],
createSubFolder: false,
subdir: false,
quiet: false,
config: pathOrUrl,
...config,

View File

@@ -27,7 +27,7 @@ export interface ScaffoldConfig {
templates: string[]
/**
* Path to output to. If `createSubFolder` is `true`, the subfolder will be created inside this path.
* Path to output to. If `subdir` is `true`, the subfolder will be created inside this path.
*
* May also be a {@link FileResponseHandler} which returns a new output path to override the default one.
*
@@ -39,12 +39,12 @@ export interface ScaffoldConfig {
/**
* Whether to create subfolder with the input name.
*
* When `true`, you may also use {@link subFolderNameHelper} to determine a pre-process helper on
* When `true`, you may also use {@link subdirHelper} to determine a pre-process helper on
* the directory name.
*
* @default `false`
*/
createSubFolder?: boolean
subdir?: boolean
/**
* Add custom data to the templates. By default, only your app name is included as `{{name}}` and `{{Name}}`.
@@ -131,15 +131,15 @@ export interface ScaffoldConfig {
helpers?: Record<string, Helper>
/**
* Default transformer to apply to subfolder name when using `createSubFolder: true`. Can be one of the default
* Default transformer to apply to subfolder name when using `subdir: true`. Can be one of the default
* capitalization helpers, or a custom one you provide to `helpers`. Defaults to `undefined`, which means no
* transformation is done.
*
* @see {@link createSubFolder}
* @see {@link subdir}
* @see {@link CaseHelpers}
* @see {@link DefaultHelpers}
*/
subFolderNameHelper?: DefaultHelpers | string
subdirHelper?: DefaultHelpers | string
/**
* This callback runs right before content is being written to the disk. If you supply this function, you may return
@@ -182,7 +182,7 @@ export interface ScaffoldConfig {
* @see {@link DefaultHelpers}
* @see {@link DateHelpers}
* @see {@link ScaffoldConfig}
* @see {@link ScaffoldConfig.subFolderNameHelper}
* @see {@link ScaffoldConfig.subdirHelper}
*
* @category Helpers
*/
@@ -320,20 +320,42 @@ export type FileResponseHandler<T> = (fullPath: string, basedir: string, basenam
* */
export type FileResponse<T> = T | FileResponseHandler<T>
/** @internal */
/**
* The Scaffold config for CLI
* Contains less and more specific options than {@link ScaffoldConfig}
*/
export interface ScaffoldCmdConfig {
/** The name of the scaffold template to use. */
name: string
/** The templates to use for generation */
templates: string[]
/** The output path to write to */
output: string
createSubFolder: boolean
/** Whether to create subfolder with the input name */
subdir: boolean
/** Default transformer to apply to subfolder name when using `subdir: true` */
subdirHelper?: string
/** Add custom data to the templates */
data?: Record<string, string>
/** Add custom data to the template in a CLI-friendly syntax (and not JSON) */
appendData?: Record<string, string>
/** Enable to override output files, even if they already exist */
overwrite: boolean
/** Silence logs, same as `logLevel: "none"` */
quiet: boolean
/**
* Determine amount of logs to display.
*
* @see {@link LogLevel}
*/
logLevel: LogLevel
/** Don't emit files. This is good for testing your scaffolds and making sure they don't fail, without having to write actual file contents or create directories. */
dryRun: boolean
/** Config file path to use */
config?: string
/** The key of the template to use */
key?: string
/** The git repository to use to fetch the config file */
git?: string
}

View File

@@ -110,7 +110,7 @@ describe("Scaffold", () => {
name: "app_name",
output: "output",
templates: ["input"],
createSubFolder: true,
subdir: true,
logLevel: "none",
})
@@ -402,7 +402,7 @@ describe("Scaffold", () => {
name: "app_name",
output: "output",
templates: ["input"],
createSubFolder: true,
subdir: true,
logLevel: "none",
})
@@ -415,9 +415,9 @@ describe("Scaffold", () => {
name: "app_name",
output: "output",
templates: ["input"],
createSubFolder: true,
subdir: true,
logLevel: "none",
subFolderNameHelper: "upperCase",
subdirHelper: "upperCase",
})
const data = readFileSync(join(process.cwd(), "output", "APP_NAME", "app_name.txt"))
@@ -429,9 +429,9 @@ describe("Scaffold", () => {
name: "app_name",
output: "output",
templates: ["input"],
createSubFolder: true,
subdir: true,
logLevel: "none",
subFolderNameHelper: "test",
subdirHelper: "test",
helpers: {
test: () => "REPLACED",
},