From 03b41d0860d068bbdd934d334454eb80717b3a45 Mon Sep 17 00:00:00 2001 From: Eunchurn Park/ Date: Thu, 15 Dec 2022 01:52:30 +0900 Subject: [PATCH 1/4] feat(raw-helper): raw blocks to handle unprocessed blocks --- README.md | 103 ++++++++++-------- src/template.ts | 7 +- .../default/.github/workflows/unit-test.yml | 83 ++++++++++++++ tests/index.test.ts | 82 ++++++++++++++ 4 files changed, 230 insertions(+), 45 deletions(-) create mode 100644 templates/default/.github/workflows/unit-test.yml diff --git a/README.md b/README.md index 51567d3..2887235 100644 --- a/README.md +++ b/README.md @@ -20,50 +20,50 @@ -- [✨ Create Create App](#-create-create-app) - - [Why?](#why) - - [Table of contents](#table-of-contents) - - [Quick Start](#quick-start) - - [1. Bootstrap your project](#1-bootstrap-your-project) - - [2. Add and edit template files](#2-add-and-edit-template-files) - - [3. Build the app (TypeScript only)](#3-build-the-app-typescript-only) - - [4. Publish package to npm](#4-publish-package-to-npm) - - [5. PROFIT](#5-profit) - - [Template](#template) - - [Advanced: Multiple templates](#advanced-multiple-templates) - - [Helper functions](#helper-functions) - - [`upper`](#upper) - - [`lower`](#lower) - - [`capital`](#capital) - - [`camel`](#camel) - - [`snake`](#snake) - - [`kebab`](#kebab) - - [`space`](#space) - - [`uuid`](#uuid) - - [Config](#config) - - [templateRoot (required)](#templateroot-required) - - [modifyName (default: `undefined`)](#modifyname-default-undefined) - - [extra (default: `undefined`)](#extra-default-undefined) - - [defaultDescription (default: `description`)](#defaultdescription-default-description) - - [defaultAuthor (default: `user.name` in `~/.gitconfig` otherwise `Your name`)](#defaultauthor-default-username-in-gitconfig-otherwise-your-name) - - [defaultEmail (default: `user.email` in `~/.gitconfig` otherwise `Your email`)](#defaultemail-default-useremail-in-gitconfig-otherwise-your-email) - - [defaultTemplate (default: `default`)](#defaulttemplate-default-default) - - [defaultLicense (default: `MIT`)](#defaultlicense-default-mit) - - [defaultPackageManager (default: `undefined`)](#defaultpackagemanager-default-undefined) - - [promptForDescription (default: `true`)](#promptfordescription-default-true) - - [promptForAuthor (default: `true`)](#promptforauthor-default-true) - - [promptForEmail (default: `true`)](#promptforemail-default-true) - - [promptForTemplate (default: `false`)](#promptfortemplate-default-false) - - [promptForLicense (default: `true`)](#promptforlicense-default-true) - - [promptForPackageManager (default: `false`)](#promptforpackagemanager-default-false) - - [skipGitInit (default: `false`)](#skipgitinit-default-false) - - [skipNpmInstall (default: `false`)](#skipnpminstall-default-false) - - [after (default: `undefined`)](#after-default-undefined) - - [caveat (default: `undefined`)](#caveat-default-undefined) - - [`AfterHookOptions`](#afterhookoptions) - - [Showcase](#showcase) - - [Contribution](#contribution) - - [Contributors ✨](#contributors-) +- [Why?](#why) +- [Table of contents](#table-of-contents) +- [Quick Start](#quick-start) + - [1. Bootstrap your project](#1-bootstrap-your-project) + - [2. Add and edit template files](#2-add-and-edit-template-files) + - [3. Build the app (TypeScript only)](#3-build-the-app-typescript-only) + - [4. Publish package to npm](#4-publish-package-to-npm) + - [5. PROFIT](#5-profit) +- [Template](#template) + - [Advanced: Multiple templates](#advanced-multiple-templates) + - [Helper functions](#helper-functions) + - [`upper`](#upper) + - [`lower`](#lower) + - [`capital`](#capital) + - [`camel`](#camel) + - [`snake`](#snake) + - [`kebab`](#kebab) + - [`space`](#space) + - [`uuid`](#uuid) + - [`raw-helper`](#raw-helper) +- [Config](#config) + - [templateRoot (required)](#templateroot-required) + - [modifyName (default: `undefined`)](#modifyname-default-undefined) + - [extra (default: `undefined`)](#extra-default-undefined) + - [defaultDescription (default: `description`)](#defaultdescription-default-description) + - [defaultAuthor (default: `user.name` in `~/.gitconfig` otherwise `Your name`)](#defaultauthor-default-username-in-gitconfig-otherwise-your-name) + - [defaultEmail (default: `user.email` in `~/.gitconfig` otherwise `Your email`)](#defaultemail-default-useremail-in-gitconfig-otherwise-your-email) + - [defaultTemplate (default: `default`)](#defaulttemplate-default-default) + - [defaultLicense (default: `MIT`)](#defaultlicense-default-mit) + - [defaultPackageManager (default: `undefined`)](#defaultpackagemanager-default-undefined) + - [promptForDescription (default: `true`)](#promptfordescription-default-true) + - [promptForAuthor (default: `true`)](#promptforauthor-default-true) + - [promptForEmail (default: `true`)](#promptforemail-default-true) + - [promptForTemplate (default: `false`)](#promptfortemplate-default-false) + - [promptForLicense (default: `true`)](#promptforlicense-default-true) + - [promptForPackageManager (default: `false`)](#promptforpackagemanager-default-false) + - [skipGitInit (default: `false`)](#skipgitinit-default-false) + - [skipNpmInstall (default: `false`)](#skipnpminstall-default-false) + - [after (default: `undefined`)](#after-default-undefined) + - [caveat (default: `undefined`)](#caveat-default-undefined) + - [`AfterHookOptions`](#afterhookoptions) +- [Showcase](#showcase) +- [Contribution](#contribution) + - [Contributors ✨](#contributors-) @@ -188,6 +188,21 @@ Generates unique UUID string. {{upper (uuid)}} // => A5DF7100-DA46-47A6-907E-AFE861F48B39 ``` +#### `raw-helper` + +Raw blocks to handle unprocessed blocks. + +``` +{{{{raw-helper}}}} + {{bar}} +{{{{/raw-helper}}}} +``` +will render + +``` +{{bar}} +``` + ## Config The app configuration can be found in `src/cli.js` (or `src/cli.ts` if you choose the `typescript` template). diff --git a/src/template.ts b/src/template.ts index 151b7f1..8bf9e0b 100644 --- a/src/template.ts +++ b/src/template.ts @@ -62,6 +62,11 @@ function uuid() { } Handlebars.registerHelper('uuid', uuid); +function rawHelper(options: Handlebars.HelperDeclareSpec) { + return options.fn(); +} +Handlebars.registerHelper('raw-helper', rawHelper); + function format(text: Buffer | string, view: T) { const template = Handlebars.compile(text.toString(), { noEscape: true }); return template(view); @@ -71,7 +76,7 @@ function prepareDirectory(filePath: string) { try { const target = path.dirname(filePath); fs.mkdirSync(target, { recursive: true }); - } catch {} + } catch { } } export function getAvailableTemplates(root: string) { diff --git a/templates/default/.github/workflows/unit-test.yml b/templates/default/.github/workflows/unit-test.yml new file mode 100644 index 0000000..93c0267 --- /dev/null +++ b/templates/default/.github/workflows/unit-test.yml @@ -0,0 +1,83 @@ +{{{{raw-helper}}}} +name: Unit Test +on: + push: + branches: ["main"] + pull_request: + branches: ["main"] +jobs: + build: + environment: dev + runs-on: ubuntu-latest + env: + MY_KEY: hello_ci # ${{ secrets.MY_KEY }} + strategy: + matrix: + node-version: [16.x] + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Detect package manager + id: detect-package-manager + run: | + if [ -f "${{ github.workspace }}/yarn.lock" ]; then + echo "manager=yarn" >> $GITHUB_OUTPUT + echo "command=install" >> $GITHUB_OUTPUT + echo "runner=yarn" >> $GITHUB_OUTPUT + exit 0 + elif [ -f "${{ github.workspace }}/package.json" ]; then + echo "manager=npm" >> $GITHUB_OUTPUT + echo "command=ci" >> $GITHUB_OUTPUT + echo "runner=npx --no-install" >> $GITHUB_OUTPUT + exit 0 + else + echo "Unable to determine packager manager" + exit 1 + fi + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + cache: ${{ steps.detect-package-manager.outputs.manager }} + - name: Restore cache + uses: actions/cache@v3 + with: + path: | + node_modules + key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }} + restore-keys: | + ${{ runner.os }}-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}- + - name: Install dependencies + run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }} + - name: Type Check + env: + NODE_OPTIONS: "--max_old_space_size=4096" + run: ${{ steps.detect-package-manager.outputs.runner }} typecheck + - name: Unit Test + env: + NODE_OPTIONS: "--max_old_space_size=4096" + run: ${{ steps.detect-package-manager.outputs.runner }} test --collectCoverage + - name: Code Coverage Summary + uses: irongut/CodeCoverageSummary@v1.3.0 + with: + filename: coverage/cobertura-coverage.xml + badge: true + fail_below_min: true + format: markdown + hide_branch_rate: false + hide_complexity: true + indicators: true + output: both + thresholds: "60 80" + - name: Build + env: + CI: false + run: ${{ steps.detect-package-manager.outputs.runner }} build + - name: Add Coverage PR Comment + uses: marocchino/sticky-pull-request-comment@v2 + if: github.event_name == 'pull_request' + with: + recreate: true + append: true + path: code-coverage-results.md +{{{{/raw-helper}}}} \ No newline at end of file diff --git a/tests/index.test.ts b/tests/index.test.ts index 2bee7a4..9a91f76 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -152,6 +152,88 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. `); + const newRawHelper = readFileSync(`${tmpDir}/create-greet/.github/workflows/unit-test.yml`, 'utf-8'); + expect(newRawHelper).toBe('name: Unit Test\n' + + 'on:\n' + + ' push:\n' + + ' branches: ["main"]\n' + + ' pull_request:\n' + + ' branches: ["main"]\n' + + 'jobs:\n' + + ' build:\n' + + ' environment: dev\n' + + ' runs-on: ubuntu-latest\n' + + ' env:\n' + + ' MY_KEY: hello_ci # ${{ secrets.MY_KEY }}\n' + + ' strategy:\n' + + ' matrix:\n' + + ' node-version: [16.x]\n' + + ' steps:\n' + + ' - name: Checkout\n' + + ' uses: actions/checkout@v3\n' + + ' - name: Detect package manager\n' + + ' id: detect-package-manager\n' + + ' run: |\n' + + ' if [ -f "${{ github.workspace }}/yarn.lock" ]; then\n' + + ' echo "manager=yarn" >> $GITHUB_OUTPUT\n' + + ' echo "command=install" >> $GITHUB_OUTPUT\n' + + ' echo "runner=yarn" >> $GITHUB_OUTPUT\n' + + ' exit 0\n' + + ' elif [ -f "${{ github.workspace }}/package.json" ]; then\n' + + ' echo "manager=npm" >> $GITHUB_OUTPUT\n' + + ' echo "command=ci" >> $GITHUB_OUTPUT\n' + + ' echo "runner=npx --no-install" >> $GITHUB_OUTPUT\n' + + ' exit 0\n' + + ' else\n' + + ' echo "Unable to determine packager manager"\n' + + ' exit 1\n' + + ' fi\n' + + ' - name: Use Node.js ${{ matrix.node-version }}\n' + + ' uses: actions/setup-node@v3\n' + + ' with:\n' + + ' node-version: ${{ matrix.node-version }}\n' + + ' cache: ${{ steps.detect-package-manager.outputs.manager }}\n' + + ' - name: Restore cache\n' + + ' uses: actions/cache@v3\n' + + ' with:\n' + + ' path: |\n' + + ' node_modules\n' + + " key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }}\n" + + ' restore-keys: |\n' + + " ${{ runner.os }}-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-\n" + + ' - name: Install dependencies\n' + + ' run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }}\n' + + ' - name: Type Check\n' + + ' env:\n' + + ' NODE_OPTIONS: "--max_old_space_size=4096"\n' + + ' run: ${{ steps.detect-package-manager.outputs.runner }} typecheck\n' + + ' - name: Unit Test\n' + + ' env:\n' + + ' NODE_OPTIONS: "--max_old_space_size=4096"\n' + + ' run: ${{ steps.detect-package-manager.outputs.runner }} test --collectCoverage\n' + + ' - name: Code Coverage Summary\n' + + ' uses: irongut/CodeCoverageSummary@v1.3.0\n' + + ' with:\n' + + ' filename: coverage/cobertura-coverage.xml\n' + + ' badge: true\n' + + ' fail_below_min: true\n' + + ' format: markdown\n' + + ' hide_branch_rate: false\n' + + ' hide_complexity: true\n' + + ' indicators: true\n' + + ' output: both\n' + + ' thresholds: "60 80"\n' + + ' - name: Build\n' + + ' env:\n' + + ' CI: false\n' + + ' run: ${{ steps.detect-package-manager.outputs.runner }} build\n' + + ' - name: Add Coverage PR Comment\n' + + ' uses: marocchino/sticky-pull-request-comment@v2\n' + + " if: github.event_name == 'pull_request'\n" + + ' with:\n' + + ' recreate: true\n' + + ' append: true\n' + + ' path: code-coverage-results.md\n') }, 300000); test('create typescript project', async () => { From fd64e24d81ec9c23c731a354ea332973230972ea Mon Sep 17 00:00:00 2001 From: Eunchurn Park/ Date: Thu, 15 Dec 2022 02:00:21 +0900 Subject: [PATCH 2/4] fix(readme:toc): restore space --- README.md | 89 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 2887235..d55a9de 100644 --- a/README.md +++ b/README.md @@ -20,50 +20,51 @@ -- [Why?](#why) -- [Table of contents](#table-of-contents) -- [Quick Start](#quick-start) - - [1. Bootstrap your project](#1-bootstrap-your-project) - - [2. Add and edit template files](#2-add-and-edit-template-files) - - [3. Build the app (TypeScript only)](#3-build-the-app-typescript-only) - - [4. Publish package to npm](#4-publish-package-to-npm) - - [5. PROFIT](#5-profit) -- [Template](#template) - - [Advanced: Multiple templates](#advanced-multiple-templates) - - [Helper functions](#helper-functions) - - [`upper`](#upper) - - [`lower`](#lower) - - [`capital`](#capital) - - [`camel`](#camel) - - [`snake`](#snake) - - [`kebab`](#kebab) - - [`space`](#space) - - [`uuid`](#uuid) - - [`raw-helper`](#raw-helper) -- [Config](#config) - - [templateRoot (required)](#templateroot-required) - - [modifyName (default: `undefined`)](#modifyname-default-undefined) - - [extra (default: `undefined`)](#extra-default-undefined) - - [defaultDescription (default: `description`)](#defaultdescription-default-description) - - [defaultAuthor (default: `user.name` in `~/.gitconfig` otherwise `Your name`)](#defaultauthor-default-username-in-gitconfig-otherwise-your-name) - - [defaultEmail (default: `user.email` in `~/.gitconfig` otherwise `Your email`)](#defaultemail-default-useremail-in-gitconfig-otherwise-your-email) - - [defaultTemplate (default: `default`)](#defaulttemplate-default-default) - - [defaultLicense (default: `MIT`)](#defaultlicense-default-mit) - - [defaultPackageManager (default: `undefined`)](#defaultpackagemanager-default-undefined) - - [promptForDescription (default: `true`)](#promptfordescription-default-true) - - [promptForAuthor (default: `true`)](#promptforauthor-default-true) - - [promptForEmail (default: `true`)](#promptforemail-default-true) - - [promptForTemplate (default: `false`)](#promptfortemplate-default-false) - - [promptForLicense (default: `true`)](#promptforlicense-default-true) - - [promptForPackageManager (default: `false`)](#promptforpackagemanager-default-false) - - [skipGitInit (default: `false`)](#skipgitinit-default-false) - - [skipNpmInstall (default: `false`)](#skipnpminstall-default-false) - - [after (default: `undefined`)](#after-default-undefined) - - [caveat (default: `undefined`)](#caveat-default-undefined) - - [`AfterHookOptions`](#afterhookoptions) -- [Showcase](#showcase) -- [Contribution](#contribution) - - [Contributors ✨](#contributors-) +- [✨ Create Create App](#-create-create-app) + - [Why?](#why) + - [Table of contents](#table-of-contents) + - [Quick Start](#quick-start) + - [1. Bootstrap your project](#1-bootstrap-your-project) + - [2. Add and edit template files](#2-add-and-edit-template-files) + - [3. Build the app (TypeScript only)](#3-build-the-app-typescript-only) + - [4. Publish package to npm](#4-publish-package-to-npm) + - [5. PROFIT](#5-profit) + - [Template](#template) + - [Advanced: Multiple templates](#advanced-multiple-templates) + - [Helper functions](#helper-functions) + - [`upper`](#upper) + - [`lower`](#lower) + - [`capital`](#capital) + - [`camel`](#camel) + - [`snake`](#snake) + - [`kebab`](#kebab) + - [`space`](#space) + - [`uuid`](#uuid) + - [`raw-helper`](#raw-helper) + - [Config](#config) + - [templateRoot (required)](#templateroot-required) + - [modifyName (default: `undefined`)](#modifyname-default-undefined) + - [extra (default: `undefined`)](#extra-default-undefined) + - [defaultDescription (default: `description`)](#defaultdescription-default-description) + - [defaultAuthor (default: `user.name` in `~/.gitconfig` otherwise `Your name`)](#defaultauthor-default-username-in-gitconfig-otherwise-your-name) + - [defaultEmail (default: `user.email` in `~/.gitconfig` otherwise `Your email`)](#defaultemail-default-useremail-in-gitconfig-otherwise-your-email) + - [defaultTemplate (default: `default`)](#defaulttemplate-default-default) + - [defaultLicense (default: `MIT`)](#defaultlicense-default-mit) + - [defaultPackageManager (default: `undefined`)](#defaultpackagemanager-default-undefined) + - [promptForDescription (default: `true`)](#promptfordescription-default-true) + - [promptForAuthor (default: `true`)](#promptforauthor-default-true) + - [promptForEmail (default: `true`)](#promptforemail-default-true) + - [promptForTemplate (default: `false`)](#promptfortemplate-default-false) + - [promptForLicense (default: `true`)](#promptforlicense-default-true) + - [promptForPackageManager (default: `false`)](#promptforpackagemanager-default-false) + - [skipGitInit (default: `false`)](#skipgitinit-default-false) + - [skipNpmInstall (default: `false`)](#skipnpminstall-default-false) + - [after (default: `undefined`)](#after-default-undefined) + - [caveat (default: `undefined`)](#caveat-default-undefined) + - [`AfterHookOptions`](#afterhookoptions) + - [Showcase](#showcase) + - [Contribution](#contribution) + - [Contributors ✨](#contributors-) From 5d8097b452b77ebb86d91e837691ceec448519d9 Mon Sep 17 00:00:00 2001 From: Eunchurn Park/ Date: Thu, 15 Dec 2022 02:03:05 +0900 Subject: [PATCH 3/4] fix(template.ts): unexpected space by formatter --- src/template.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/template.ts b/src/template.ts index 8bf9e0b..280ea6c 100644 --- a/src/template.ts +++ b/src/template.ts @@ -76,7 +76,7 @@ function prepareDirectory(filePath: string) { try { const target = path.dirname(filePath); fs.mkdirSync(target, { recursive: true }); - } catch { } + } catch {} } export function getAvailableTemplates(root: string) { From 4b9b1f96182ac8c22d8280d147f7c95f548dd4b2 Mon Sep 17 00:00:00 2001 From: Eunchurn Park Date: Mon, 30 Jan 2023 15:40:17 +0900 Subject: [PATCH 4/4] feat(raw-helper, raw): added Helper functions --- README.md | 8 ++++---- src/template.ts | 5 +++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d55a9de..3f6f7cc 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,6 @@ - - [✨ Create Create App](#-create-create-app) - [Why?](#why) - [Table of contents](#table-of-contents) @@ -189,15 +188,16 @@ Generates unique UUID string. {{upper (uuid)}} // => A5DF7100-DA46-47A6-907E-AFE861F48B39 ``` -#### `raw-helper` +#### `raw` Raw blocks to handle unprocessed blocks. ``` -{{{{raw-helper}}}} +{{{{raw}}}} {{bar}} -{{{{/raw-helper}}}} +{{{{/raw}}}} ``` + will render ``` diff --git a/src/template.ts b/src/template.ts index 280ea6c..14f9d35 100644 --- a/src/template.ts +++ b/src/template.ts @@ -67,6 +67,11 @@ function rawHelper(options: Handlebars.HelperDeclareSpec) { } Handlebars.registerHelper('raw-helper', rawHelper); +function raw(option: Handlebars.HelperDeclareSpec) { + return option.fn(); +} +Handlebars.registerHelper('raw', raw); + function format(text: Buffer | string, view: T) { const template = Handlebars.compile(text.toString(), { noEscape: true }); return template(view);