Compare commits

...

6 Commits

Author SHA1 Message Date
Chen Asraf
5af283292e update README.md, default output fix 2021-12-06 00:47:10 +02:00
Chen Asraf
dcf0d04b68 fix cmd 2021-12-06 00:27:57 +02:00
Chen Asraf
41076366a6 update workflows [skip publish] 2021-12-06 00:16:12 +02:00
Chen Asraf
f35baebf3a update alpha workflow 2021-12-06 00:09:04 +02:00
Chen Asraf
79f9b33631 helpers fix 2021-12-06 00:08:01 +02:00
Chen Asraf
027f5576ba fix copyright 2021-12-06 00:03:51 +02:00
7 changed files with 115 additions and 108 deletions

View File

@@ -36,6 +36,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
prerelease: true
tag_name: ${{ steps.update_tag.outputs.tagname }}
release_name: Release ${{ steps.update_tag.outputs.tagname }}
- name: Upload Release Asset
@@ -47,5 +48,5 @@ jobs:
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./package.tgz
asset_name: package.tgz
asset_name: simple-scaffold ${{ steps.update_tag.outputs.tagname }}.tgz
asset_content_type: application/tgz

View File

@@ -46,5 +46,5 @@ jobs:
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./package.tgz
asset_name: package.tgz
asset_name: simple-scaffold ${{ steps.update_tag.outputs.tagname }}.tgz
asset_content_type: application/tgz

View File

@@ -47,8 +47,7 @@ Options:
--templates|-t Template files to use as input. You may provide multiple
files, each of which can be a relative or absolute path, or a glob
pattern for multiple file matching easily. (default:
)
pattern for multiple file matching easily. (default: current dir)
--overwrite|-w Enable to override output files, even if they already exist.
(default: false)
@@ -88,13 +87,13 @@ You can also add this as a script in your `package.json`:
## Use in Node.js
You can also build the scaffold yourself, if you want to create more complex arguments or scaffold groups.
Simply pass a config object to the constructor, and invoke `run()` when you are ready to start.
Simply pass a config object to the Scaffold function when you are ready to start.
The config takes similar arguments to the command line:
```typescript
import Scaffold from "simple-scaffold"
const scaffold = SimpleScaffold({
const config = {
name: "component",
templates: [path.join(__dirname, "scaffolds", "component")],
output: path.join(__dirname, "src", "components"),
@@ -105,7 +104,9 @@ const scaffold = SimpleScaffold({
helpers: {
twice: (text) => [text, text].join(" ")
}
})
}
const scaffold = Scaffold(config)
```
### Additional Node.js options

View File

@@ -1,6 +1,6 @@
{
"name": "simple-scaffold",
"version": "1.0.0-alpha.13",
"version": "1.0.0-alpha.17",
"description": "Create files based on templates",
"repository": "https://github.com/chenasraf/simple-scaffold.git",
"author": "Chen Asraf <inbox@casraf.com>",
@@ -9,7 +9,7 @@
"bin": "cmd.js",
"scripts": {
"clean": "rm -rf dist/",
"build": "yarn clean && tsc && chmod -R +x ./dist && cp ./package.json ./dist/ && cp ./README.md ./dist/",
"build": "yarn clean && tsc && chmod -R +x ./dist && cp ./package.json ./README.md ./dist/",
"dev": "tsc --watch",
"start": "node dist/scaffold.js",
"test": "jest --verbose",

View File

@@ -1,2 +1,97 @@
import { parseCliArgs } from "./cmd_util"
#!/usr/bin/env node
import massarg from "massarg"
import chalk from "chalk"
import { LogLevel, ScaffoldCmdConfig } from "./types"
import { Scaffold } from "./scaffold"
export function parseCliArgs(args = process.argv.slice(2)) {
return (
massarg<ScaffoldCmdConfig & { help: boolean; extras: string[] }>()
.main(Scaffold)
.option({
name: "name",
aliases: ["n"],
description:
"Name to be passed to the generated files. {{name}} and {{Name}} inside contents and file names will be replaced accordingly.",
isDefault: true,
required: true,
})
.option({
name: "output",
aliases: ["o"],
description: `Path to output to. If --create-sub-folder is enabled, the subfolder will be created inside this path. ${chalk.reset`${chalk.white`(default: current dir)`}`}`,
required: true,
})
.option({
name: "templates",
aliases: ["t"],
array: true,
description:
"Template files to use as input. You may provide multiple files, each of which can be a relative or absolute path, " +
"or a glob pattern for multiple file matching easily.",
required: true,
})
.option({
name: "overwrite",
aliases: ["w"],
boolean: true,
defaultValue: false,
description: "Enable to override output files, even if they already exist.",
})
.option({
name: "data",
aliases: ["d"],
description: "Add custom data to the templates. By default, only your app name is included.",
parse: (v) => JSON.parse(v),
})
.option({
name: "create-sub-folder",
aliases: ["s"],
boolean: true,
defaultValue: false,
description: "Create subfolder with the input name",
})
.option({
name: "quiet",
aliases: ["q"],
boolean: true,
defaultValue: false,
description: "Suppress output logs (Same as --verbose 0)",
})
.option({
name: "verbose",
aliases: ["v"],
defaultValue: LogLevel.Info,
description: `Determine amount of logs to display. The values are: ${chalk.bold`0 (none) | 1 (debug) | 2 (info) | 3 (warn) | 4 (error)`}. The provided level will display messages of the same level or higher.`,
parse: Number,
})
.option({
name: "dry-run",
aliases: ["dr"],
boolean: true,
defaultValue: false,
description:
"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.",
})
// .example({
// input: `yarn cmd -t examples/test-input/Component -o examples/test-output -d '{"property":"myProp","value":"10"}'`,
// description: "Usage",
// output: "",
// })
.help({
binName: "simple-scaffold",
useGlobalColumns: true,
usageExample: "[options]",
header: "Create structured files based on templates.",
footer: [
`Copyright © Chen Asraf 2021`,
`NPM: ${chalk.underline`https://npmjs.com/package/simple-scaffold`}`,
`GitHub: ${chalk.underline`https://github.com/chenasraf/simple-scaffold`}`,
].join("\n"),
})
.parse(args)
)
}
parseCliArgs()

View File

@@ -1,91 +0,0 @@
import massarg from "massarg"
import chalk from "chalk"
import { LogLevel, ScaffoldCmdConfig } from "./types"
import { Scaffold } from "./scaffold"
export function parseCliArgs(args = process.argv.slice(2)) {
return (
massarg<ScaffoldCmdConfig & { help: boolean; extras: string[] }>()
.main(Scaffold)
.option({
name: "name",
aliases: ["n"],
description:
"Name to be passed to the generated files. {{name}} and {{Name}} inside contents and file names will be replaced accordingly.",
isDefault: true,
required: true,
})
.option({
name: "output",
aliases: ["o"],
description:
"Path to output to. If --create-sub-folder is enabled, the subfolder will be created inside this path.",
required: true,
})
.option({
name: "templates",
aliases: ["t"],
array: true,
description:
"Template files to use as input. You may provide multiple files, each of which can be a relative or absolute path, " +
"or a glob pattern for multiple file matching easily.",
required: true,
})
.option({
name: "overwrite",
aliases: ["w"],
boolean: true,
defaultValue: false,
description: "Enable to override output files, even if they already exist.",
})
.option({
name: "data",
aliases: ["d"],
description: "Add custom data to the templates. By default, only your app name is included.",
parse: (v) => JSON.parse(v),
})
.option({
name: "create-sub-folder",
aliases: ["s"],
boolean: true,
defaultValue: false,
description: "Create subfolder with the input name",
})
.option({
name: "quiet",
aliases: ["q"],
boolean: true,
defaultValue: false,
description: "Suppress output logs (Same as --verbose 0)",
})
.option({
name: "verbose",
aliases: ["v"],
defaultValue: LogLevel.Info,
description: `Determine amount of logs to display. The values are: ${chalk.bold`0 (none) | 1 (debug) | 2 (info) | 3 (warn) | 4 (error)`}. The provided level will display messages of the same level or higher.`,
parse: Number,
})
.option({
name: "dry-run",
aliases: ["dr"],
boolean: true,
defaultValue: false,
description:
"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.",
})
// .example({
// input: `yarn cmd -t examples/test-input/Component -o examples/test-output -d '{"property":"myProp","value":"10"}'`,
// description: "Usage",
// output: "",
// })
.help({
binName: "simple-scaffold",
useGlobalColumns: true,
usageExample: "[options]",
header: "Create structured files based on templates.",
footer: `Copyright © Chen Asraf 2021\nNPM: ${chalk.underline`https://npmjs.com/package/massarg`}\nGitHub: ${chalk.underline`https://github.com/chenasraf/massarg`}`,
})
.parse(args)
)
}

View File

@@ -19,10 +19,12 @@ import {
} from "./utils"
import { LogLevel, ScaffoldConfig } from "./types"
export async function Scaffold(config: ScaffoldConfig) {
const options = { ...config }
export async function Scaffold({ ...options }: ScaffoldConfig) {
options.output ??= process.cwd()
registerHelpers(options)
try {
const data = { name: options.name, Name: pascalCase(options.name), ...options.data }
options.data = { name: options.name, Name: pascalCase(options.name), ...options.data }
log(options, LogLevel.Debug, "Full config:", {
name: options.name,
templates: options.templates,
@@ -36,10 +38,9 @@ export async function Scaffold(config: ScaffoldConfig) {
(k) => (LogLevel[k as any] as unknown as number) === options.verbose!
)})`,
})
log(options, LogLevel.Info, "Data:", data)
for (let template of config.templates) {
log(options, LogLevel.Info, "Data:", options.data)
for (let template of options.templates) {
try {
registerHelpers(options)
const _isGlob = template.includes("*")
if (!_isGlob && !(await pathExists(template))) {
const err: NodeJS.ErrnoException = new Error(`ENOENT, no such file or directory ${template}`)
@@ -89,7 +90,7 @@ export async function Scaffold(config: ScaffoldConfig) {
`\nisGlob: ${_isGlob}`,
`\n`
)
await handleTemplateFile(inputFilePath, basePath, options, data)
await handleTemplateFile(inputFilePath, basePath, options, options.data)
}
}
} catch (e: any) {