From 4aaca9fa2bbcff806e47be872d58e4a0a1bb08db Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Mon, 20 Mar 2023 17:19:55 -0500 Subject: [PATCH 1/6] fix: default `project_name` --- .tmplr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.tmplr.yml b/.tmplr.yml index f54270e..e242efc 100644 --- a/.tmplr.yml +++ b/.tmplr.yml @@ -8,6 +8,7 @@ steps: - read: project_name prompt: 'Enter project name:' + default: filesystem.rootdir - read: project_description prompt: 'Enter project description:' From b21de0c673510ff67ee24dc72636f6dc38a6c964 Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Thu, 23 Mar 2023 11:02:43 -0500 Subject: [PATCH 2/6] fix(`tmplr`): default `project_name` --- .tmplr.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.tmplr.yml b/.tmplr.yml index e242efc..d95deca 100644 --- a/.tmplr.yml +++ b/.tmplr.yml @@ -8,7 +8,8 @@ steps: - read: project_name prompt: 'Enter project name:' - default: filesystem.rootdir + default: + from: filesystem.rootdir - read: project_description prompt: 'Enter project description:' From 6db6fd131bece264b4c24c29e2c1e6dda093a6dc Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Fri, 7 Jul 2023 20:22:32 -0500 Subject: [PATCH 3/6] feat: use `template` directory --- .npmrc | 1 + .tmplr.yml | 13 +--- license => license.md | 0 package.tmplr.json | 88 --------------------------- readme.md | 2 +- template/.github/workflows/main.yml | 19 ++++++ .gitignore => template/.gitignore | 1 + template/.xo-config.json | 17 ++++++ template/package.json | 60 ++++++++++++++++++ readme.tmplr.md => template/readme.md | 6 +- {src => template/src}/cli.ts | 10 ++- template/test/_utils.ts | 28 +++++++++ template/test/fixtures/.gitkeep | 0 template/test/test.ts | 15 +++++ template/tsconfig.json | 9 +++ template/tsconfig.test.json | 9 +++ test/test.ts | 9 --- tsconfig.json | 10 --- 18 files changed, 173 insertions(+), 124 deletions(-) create mode 100644 .npmrc rename license => license.md (100%) delete mode 100644 package.tmplr.json create mode 100644 template/.github/workflows/main.yml rename .gitignore => template/.gitignore (83%) create mode 100644 template/.xo-config.json create mode 100644 template/package.json rename readme.tmplr.md => template/readme.md (85%) rename {src => template/src}/cli.ts (66%) create mode 100644 template/test/_utils.ts create mode 100644 template/test/fixtures/.gitkeep create mode 100644 template/test/test.ts create mode 100644 template/tsconfig.json create mode 100644 template/tsconfig.test.json delete mode 100644 test/test.ts delete mode 100644 tsconfig.json diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..43c97e7 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/.tmplr.yml b/.tmplr.yml index d95deca..70b675c 100644 --- a/.tmplr.yml +++ b/.tmplr.yml @@ -54,17 +54,10 @@ steps: # setup project - - update: src/cli.ts - - update: test/test.ts - - - copy: package.tmplr.json - to: package.json - - - copy: readme.tmplr.md - to: readme.md + - copy: ./template/**/*.* + to: ./ # finish + - remove: ./template/**/*.* - remove: .tmplr.yml - - remove: package.tmplr.json - - remove: readme.tmplr.md diff --git a/license b/license.md similarity index 100% rename from license rename to license.md diff --git a/package.tmplr.json b/package.tmplr.json deleted file mode 100644 index e8f7468..0000000 --- a/package.tmplr.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "name": "{{ tmplr.project_name }}", - "version": "0.0.0", - "description": "{{ tmplr.project_description }}", - "keywords": [ - "cli", - "cli-app", - "command line" - ], - "license": "MIT", - "repository": "tommy-mitchell/{{ tmplr.project_name | skip: @tommy-mitchell/ }}", - "author": { - "name": "Tommy Mitchell", - "url": "https://tommymitchell.io" - }, - "type": "module", - "bin": { - "{{ tmplr.command_name }}": "dist/cli.js" - }, - "files": [ - "dist" - ], - "scripts": { - "build": "tsc && chmod +x dist/cli.js", - "test": "listr xo tsd 'c8 ava'" - }, - "dependencies": { - "meow": "^11.0.0" - }, - "devDependencies": { - "@tommy-mitchell/tsconfig": "^0.1.0", - "ava": "^5.2.0", - "c8": "^7.13.0", - "execa": "^7.1.1", - "get-bin-path": "^8.0.0", - "listr-cli": "^0.2.0", - "tsd": "^0.28.0", - "tsx": "^3.12.5", - "typescript": "~5.0.2", - "xo": "^0.53.1" - }, - "engines": { - "node": ">=14.8.0" - }, - "ava": { - "files": [ - "test/*.ts" - ], - "extensions": { - "ts": "module" - }, - "nodeArguments": [ - "--loader=tsx" - ] - }, - "xo": { - "rules": { - "@typescript-eslint/quotes": [ - "error", - "double" - ], - "object-shorthand": [ - "error", - "always", - { - "avoidExplicitReturnArrows": false - } - ], - "@typescript-eslint/keyword-spacing": [ - "error", - { - "overrides": { - "if": { - "after": false - }, - "for": { - "after": false - }, - "while": { - "after": false - } - } - } - ], - "arrow-parens": "off" - } - } -} diff --git a/readme.md b/readme.md index c2a87a7..35f312b 100644 --- a/readme.md +++ b/readme.md @@ -9,4 +9,4 @@ npx tmplr tommy-mitchell/cli-template yarn install ``` -Run inside of desired installation directory. +Run inside of desired installation directory. Requires `tmplr` v0.2.3 or higher. diff --git a/template/.github/workflows/main.yml b/template/.github/workflows/main.yml new file mode 100644 index 0000000..86f4abc --- /dev/null +++ b/template/.github/workflows/main.yml @@ -0,0 +1,19 @@ +name: CI +on: + - push + - pull_request +jobs: + test: + name: Node.js ${{ matrix.node-version }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + node-version: [16, 18, 20] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm run ci diff --git a/.gitignore b/template/.gitignore similarity index 83% rename from .gitignore rename to template/.gitignore index 35ce849..02860b1 100644 --- a/.gitignore +++ b/template/.gitignore @@ -1,4 +1,5 @@ node_modules +coverage dist package-lock.json yarn.lock diff --git a/template/.xo-config.json b/template/.xo-config.json new file mode 100644 index 0000000..19b43e4 --- /dev/null +++ b/template/.xo-config.json @@ -0,0 +1,17 @@ +{ + "rules": { + "arrow-parens": "off", + "quotes": "off", + "@typescript-eslint/quotes": ["error", "double"], + "object-curly-spacing": "off", + "@typescript-eslint/object-curly-spacing": ["error", "always"], + "@typescript-eslint/no-confusing-void-expression": ["error", { "ignoreArrowShorthand": true }], + "object-shorthand": ["error", "always", { "avoidExplicitReturnArrows": false }], + "@typescript-eslint/keyword-spacing": ["error", { "overrides": { + "if": { "after": false }, + "for": {"after": false }, + "while": {"after": false }, + "catch": {"after": false } + }}] + } +} diff --git a/template/package.json b/template/package.json new file mode 100644 index 0000000..482f1ce --- /dev/null +++ b/template/package.json @@ -0,0 +1,60 @@ +{ + "name": "{{ tmplr.project_name }}", + "version": "0.0.0", + "description": "{{ tmplr.project_description }}", + "keywords": [ + "cli", + "cli-app", + "command line" + ], + "license": "MIT", + "repository": "tommy-mitchell/{{ tmplr.project_name | skip: @tommy-mitchell/ }}", + "author": { + "name": "Tommy Mitchell", + "url": "https://tommymitchell.io" + }, + "type": "module", + "bin": { + "{{ tmplr.command_name }}": "dist/cli.js" + }, + "files": [ + "dist" + ], + "scripts": { + "prepublishOnly": "npm run build", + "build": "tsc && chmodx --package", + "postbuild": "replace-in-files dist/cli.js --string='#!/usr/bin/env tsx' --replacement='#!/usr/bin/env node'", + "test": "listr xo 'c8 ava'" + }, + "dependencies": { + "meow": "^12.0.1" + }, + "devDependencies": { + "@johnowennixon/chmodx": "1.1.0", + "@tommy-mitchell/tsconfig": "^1.0.0", + "@types/node": "^16", + "ava": "^5.3.1", + "c8": "^8.0.0", + "execa": "^7.1.1", + "get-bin-path": "^10.0.0", + "listr-cli": "^0.3.0", + "replace-in-files-cli": "^2.2.0", + "tsx": "^3.12.7", + "typescript": "~5.1.6", + "xo": "^0.54.2" + }, + "engines": { + "node": ">=16" + }, + "ava": { + "files": [ + "test/*.ts" + ], + "extensions": { + "ts": "module" + }, + "nodeArguments": [ + "--loader=tsx" + ] + } +} diff --git a/readme.tmplr.md b/template/readme.md similarity index 85% rename from readme.tmplr.md rename to template/readme.md index c29962c..b7b27f9 100644 --- a/readme.tmplr.md +++ b/template/readme.md @@ -16,21 +16,19 @@ ``` -*Uses top-level await. Requires Node 14.8 or higher.* - ## Usage ```sh $ {{ tmplr.command_name }} Usage - $ {{ tmplr.command_name }} + $ {{ tmplr.command_name }} […] Options Examples - + $ {{ tmplr.command_name }} ``` ## Related diff --git a/src/cli.ts b/template/src/cli.ts similarity index 66% rename from src/cli.ts rename to template/src/cli.ts index b75c66f..9774759 100644 --- a/src/cli.ts +++ b/template/src/cli.ts @@ -1,17 +1,23 @@ #!/usr/bin/env node +import process from "node:process"; import meow from "meow"; const cli = meow(` Usage - $ {{ tmplr.command_name }} + $ {{ tmplr.command_name }} […] Options Examples - + $ {{ tmplr.command_name }} `, { importMeta: import.meta, + description: false, + help: { + type: "boolean", + shortFlag: "h", + } }); const {input} = cli; diff --git a/template/test/_utils.ts b/template/test/_utils.ts new file mode 100644 index 0000000..77b65e0 --- /dev/null +++ b/template/test/_utils.ts @@ -0,0 +1,28 @@ +import {fileURLToPath} from "node:url"; +import path from "node:path"; +import anyTest, {type TestFn, type ExecutionContext} from "ava"; +import {getBinPath} from "get-bin-path"; +import {type Options as ExecaOptions} from "execa"; + +export const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export const test = anyTest as TestFn<{ + binPath: string; + helpText: string; +}>; + +const getBinPath = async (t: ExecutionContext) => { + const binPath = (await getBinPath()).replace('dist', 'src'); + + t.truthy(binPath, "No bin path found!"); + + t.context.binPath = binPath!; +}; + +export const setupContext = async (t: ExecutionContext) => { + await getBinPath(t); + + t.context.helpText = ""; +}; + +export const atFixture = (name: string): ExecaOptions => ({cwd: `${__dirname}/fixtures/${name}`}); diff --git a/template/test/fixtures/.gitkeep b/template/test/fixtures/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/template/test/test.ts b/template/test/test.ts new file mode 100644 index 0000000..823af6d --- /dev/null +++ b/template/test/test.ts @@ -0,0 +1,15 @@ +import {execa, type ExecaError} from "execa"; +import { + test, + __dirname, + setupContext, + atFixture, +} from "./_utils"; + +test.before("setup context", setupContext); + +test("main", async t => { + const {exitCode} = await execa(t.context.binPath); + + t.is(exitCode, 0); +}); diff --git a/template/tsconfig.json b/template/tsconfig.json new file mode 100644 index 0000000..65907cb --- /dev/null +++ b/template/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@tommy-mitchell/tsconfig", + "exclude": ["node_modules", "coverage", "dist"], + "include": ["src"], + "compilerOptions": { + "outDir": "dist", + "declaration": false + }, +} diff --git a/template/tsconfig.test.json b/template/tsconfig.test.json new file mode 100644 index 0000000..ba54f70 --- /dev/null +++ b/template/tsconfig.test.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["src"], + "include": ["test"], + "compilerOptions": { + "noEmit": true, + "noUnusedLocals": false, + }, +} diff --git a/test/test.ts b/test/test.ts deleted file mode 100644 index 3f6ec01..0000000 --- a/test/test.ts +++ /dev/null @@ -1,9 +0,0 @@ -import test from "ava"; -import {execa} from "execa"; -import {getBinPath} from "get-bin-path"; - -const binPath = await getBinPath(); - -test("main", async t => { - await execa(binPath); -}); diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 2535e5b..0000000 --- a/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "@tommy-mitchell/tsconfig", - "exclude": [ - "node_modules", - "dist", - ], - "compilerOptions": { - "outDir": "dist", - }, -} From b21ce4de918b8927103dd781ac19f72081b45d30 Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Sun, 9 Jul 2023 00:14:05 -0500 Subject: [PATCH 4/6] fix(`tmplr`): add globs for dot files --- .tmplr.yml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/.tmplr.yml b/.tmplr.yml index 70b675c..102931f 100644 --- a/.tmplr.yml +++ b/.tmplr.yml @@ -53,11 +53,25 @@ steps: eval: 'yarn add {{ project_name }}' # setup project + # make sure to copy "hidden"/dot files (loreanvictor/tmplr#14) - - copy: ./template/**/*.* + - copy: ./template/**/* + to: ./ + + - copy: ./template/**/.**/**/* + to: ./ + + - copy: ./template/**/.* + to: ./ + + - copy: ./template/**/.**/**/.* to: ./ # finish - - remove: ./template/**/*.* + - remove: ./template/**/* + - remove: ./template/**/.**/**/* + - remove: ./template/**/.* + - remove: ./template/**/.**/**/.* + - remove: .tmplr.yml From 1c0ade5e0dfc9cd99d21442c23f878717036ce2d Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Mon, 10 Jul 2023 13:24:18 -0500 Subject: [PATCH 5/6] Update template and instructions --- readme.md | 2 +- template/package.json | 1 + template/src/cli.ts | 3 +-- template/test/_utils.ts | 25 ++----------------------- template/test/cli.ts | 26 ++++++++++++++++++++++++++ template/test/test.ts | 15 --------------- template/test/tsconfig.json | 3 +++ 7 files changed, 34 insertions(+), 41 deletions(-) create mode 100644 template/test/cli.ts delete mode 100644 template/test/test.ts create mode 100644 template/test/tsconfig.json diff --git a/readme.md b/readme.md index 35f312b..e77d493 100644 --- a/readme.md +++ b/readme.md @@ -9,4 +9,4 @@ npx tmplr tommy-mitchell/cli-template yarn install ``` -Run inside of desired installation directory. Requires `tmplr` v0.2.3 or higher. +Run inside of desired installation directory, then add `test/tsconfig.json` to git exclude. Requires `tmplr` v0.2.3 or higher. diff --git a/template/package.json b/template/package.json index 482f1ce..f25fa30 100644 --- a/template/package.json +++ b/template/package.json @@ -37,6 +37,7 @@ "c8": "^8.0.0", "execa": "^7.1.1", "get-bin-path": "^10.0.0", + "is-executable": "^2.0.1", "listr-cli": "^0.3.0", "replace-in-files-cli": "^2.2.0", "tsx": "^3.12.7", diff --git a/template/src/cli.ts b/template/src/cli.ts index 9774759..aea1575 100644 --- a/template/src/cli.ts +++ b/template/src/cli.ts @@ -20,8 +20,7 @@ const cli = meow(` } }); -const {input} = cli; -const {help: helpShortFlag} = cli.flags; +const { input, flags: { help: helpShortFlag } } = cli; if(input.length === 0 || helpShortFlag) { cli.showHelp(0); diff --git a/template/test/_utils.ts b/template/test/_utils.ts index 77b65e0..62a12e7 100644 --- a/template/test/_utils.ts +++ b/template/test/_utils.ts @@ -1,28 +1,7 @@ -import {fileURLToPath} from "node:url"; +import { fileURLToPath } from "node:url"; import path from "node:path"; -import anyTest, {type TestFn, type ExecutionContext} from "ava"; -import {getBinPath} from "get-bin-path"; -import {type Options as ExecaOptions} from "execa"; +import { type Options as ExecaOptions } from "execa"; export const __dirname = path.dirname(fileURLToPath(import.meta.url)); -export const test = anyTest as TestFn<{ - binPath: string; - helpText: string; -}>; - -const getBinPath = async (t: ExecutionContext) => { - const binPath = (await getBinPath()).replace('dist', 'src'); - - t.truthy(binPath, "No bin path found!"); - - t.context.binPath = binPath!; -}; - -export const setupContext = async (t: ExecutionContext) => { - await getBinPath(t); - - t.context.helpText = ""; -}; - export const atFixture = (name: string): ExecaOptions => ({cwd: `${__dirname}/fixtures/${name}`}); diff --git a/template/test/cli.ts b/template/test/cli.ts new file mode 100644 index 0000000..1039faa --- /dev/null +++ b/template/test/cli.ts @@ -0,0 +1,26 @@ +import anyTest, { type TestFn } from "ava"; +import { getBinPath } from "get-bin-path"; +import { isExecutable } from "is-executable"; +import {execa, type ExecaError} from "execa"; +import { __dirname, atFixture } from "./_utils.js"; + +const test = anyTest as TestFn<{ + binPath: string; + helpText: string[]; +}>; + +test.before("setup context", async t => { + const binPath = await getBinPath(); + t.truthy(binPath, "No bin path found!"); + + t.context.binPath = binPath!.replace("dist", "src").replace(".js", ".ts"); + t.true(await isExecutable(t.context.binPath), "Source binary not executable!"); + + t.context.helpText = []; +}); + +test("main", async t => { + const {exitCode} = await execa(t.context.binPath); + + t.is(exitCode, 0); +}); diff --git a/template/test/test.ts b/template/test/test.ts deleted file mode 100644 index 823af6d..0000000 --- a/template/test/test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {execa, type ExecaError} from "execa"; -import { - test, - __dirname, - setupContext, - atFixture, -} from "./_utils"; - -test.before("setup context", setupContext); - -test("main", async t => { - const {exitCode} = await execa(t.context.binPath); - - t.is(exitCode, 0); -}); diff --git a/template/test/tsconfig.json b/template/test/tsconfig.json new file mode 100644 index 0000000..ca1253b --- /dev/null +++ b/template/test/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../tsconfig.test.json" +} From 6ac055308d82f41d0301346bb044098dbf28f062 Mon Sep 17 00:00:00 2001 From: tommy-mitchell Date: Mon, 10 Jul 2023 13:26:09 -0500 Subject: [PATCH 6/6] fix(`tmplr`): remove template dirs --- .tmplr.yml | 12 +++++++++--- readme.md | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.tmplr.yml b/.tmplr.yml index 102931f..36f15d0 100644 --- a/.tmplr.yml +++ b/.tmplr.yml @@ -32,7 +32,7 @@ steps: eval: '{{ install_type | matches: dev }}' steps: - read: install_node - eval: 'node install --save-dev {{ project_name }}' + eval: 'npm install --save-dev {{ project_name }}' - read: install_yarn eval: 'yarn add --dev {{ project_name }}' @@ -40,7 +40,7 @@ steps: eval: '{{ install_type | matches: global }}' steps: - read: install_node - eval: 'node install --global {{ project_name }}' + eval: 'npm install --global {{ project_name }}' - read: install_yarn eval: 'yarn global add {{ project_name }}' @@ -48,7 +48,7 @@ steps: eval: '{{ install_type | matches: dep }}' steps: - read: install_node - eval: 'node install {{ project_name }}' + eval: 'npm install {{ project_name }}' - read: install_yarn eval: 'yarn add {{ project_name }}' @@ -68,10 +68,16 @@ steps: to: ./ # finish + # temporaryily specify folders to remove (loreanvictor/tmplr#15) - remove: ./template/**/* - remove: ./template/**/.**/**/* - remove: ./template/**/.* - remove: ./template/**/.**/**/.* + - remove: ./template/.github + - remove: ./template/src + - remove: ./template/test + - remove: ./template + - remove: .tmplr.yml diff --git a/readme.md b/readme.md index e77d493..5c7e56f 100644 --- a/readme.md +++ b/readme.md @@ -9,4 +9,4 @@ npx tmplr tommy-mitchell/cli-template yarn install ``` -Run inside of desired installation directory, then add `test/tsconfig.json` to git exclude. Requires `tmplr` v0.2.3 or higher. +Run inside of desired installation directory, then add `test/tsconfig.json` to git exclude. Requires `tmplr` v0.2.4 or higher.