diff --git a/CITATION.cff b/CITATION.cff index 6ec27b4e..9f2b12e2 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -6,17 +6,21 @@ authors: orcid: https://orcid.org/0009-0001-1641-9397 identifiers: - type: url - value: https://github.com/caffeine-addictt/template/releases/tag/v1.12.3 - description: The GitHub release URL of tag v1.12.3. + value: https://github.com/caffeine-addictt/template/releases/tag/v1.14.0 + description: The GitHub release URL of tag v1.14.0. cff-version: 1.2.0 -date-released: 2024-05-12 +date-released: 2024-08-09 keywords: - template - - bash + - node + - nodejs + - setup + - script + - typescript - github license: MIT message: If you use this software, please cite it using these metadata. repository-code: https://github.com/caffeine-addictt/template title: template type: software -version: 1.12.3 +version: 1.14.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 01832652..0650df9e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,10 +12,11 @@ please follow it in all your interactions with the project. -1. [Pull Request Process](#pull-request-process) -2. [Issue Report Process](#issue-report-process) -3. [Commit Message Guidelines](#commit-message-guidelines) -4. [Code Quality](#code-quality) +1. [Getting started](#getting-started) +2. [Pull Request Process](#pull-request-process) +3. [Issue Report Process](#issue-report-process) +4. [Commit Message Guidelines](#commit-message-guidelines) +5. [Code Quality](#code-quality) - [Testing](#testing) - [Linting](#linting) - [Building](#building) @@ -23,6 +24,23 @@ please follow it in all your interactions with the project. +## Getting started + +Contributions are what make the open source community +such an amazing place to learn, inspire, and create. +Any contributions you make are **greatly appreciated**. ( ˶ˆᗜˆ˵ ) + +If you have a suggestion that would make this better, +please fork the repo and create a pull request. +You can also simply open an issue with the tag "enhancement". +Don't forget to give the project a star! Thanks again! + +1. Fork the Project +2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) +3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) +4. Push to the Branch (`git push origin feature/AmazingFeature`) +5. Open a Pull Request + ## Pull Request Process 1. Ensure any install or build dependencies are removed before the end of the layer diff --git a/README.md b/README.md index 251918ff..d8cbf35b 100644 --- a/README.md +++ b/README.md @@ -1,57 +1,75 @@ - - +###### _
// made with <3
_ - - +
- + - -
+ + + -[![Forks][forks-shield]][forks-url] -[![Stargazers][stars-shield]][stars-url] -[![MIT License][license-shield]][license-url] +
-
+ - -
-
-

Repository Template

- -

- Simple repository template to get started with GitHub. -
-
- Report Bug - · - Request Feature -

-
+![badge-workflow] +[![badge-license]][license] +![badge-language] +[![badge-pr]][prs] +[![badge-issues]][issues] - +

-## About The Project + A simple repository template to get started with GitHub. - -Starting a new project? Say goodbye to repetitive setup tasks and configuration headaches! Simplify your workflow, save time, and ensure consistency across projects. -Let's make starting new projects feel like a _breeze_ again. +Let's make starting new projects feel like a **_breeze_** again. + +

+ +--- -

(back to top)

+ -## Getting Started +**[
 Features 
](#features)** +**[
 Quick Start 
](#quick-start)** +**[
 Contribute 
][contribute]** + +--- + +
+ +
+ +# Features + +- Beautiful README +- Matrix testing CI +- Draft Releasing CI +- Pull Request Labeler CI +- Code of Conduct +- Code Style Documentation +- Security Policy Documentation +- 7 Issue Templates +- Pull Request Template +- And more... + +
+
+
 🡅 
+
+ +# Quick Start ### 1. Creating a repository Click the green "Use this template" button in the top right corner of the page or the button below to create your new repository. -[![Use Template][use-shield]][use-url] +[![Use Template][badge-use]][use-url] ### 2. Run the setup script @@ -85,67 +103,45 @@ Just a few more steps and you're ready to go! Want to support this project? **✨ Star it on GitHub** and help us spread the word! -

(back to top)

- - - -## Contributing - -Contributions are what make the open source community -such an amazing place to learn, inspire, and create. -Any contributions you make are **greatly appreciated**. ( ˶ˆᗜˆ˵ ) - -If you have a suggestion that would make this better, -please fork the repo and create a pull request. -You can also simply open an issue with the tag "enhancement". -Don't forget to give the project a star! Thanks again! - -1. Fork the Project -2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) -3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) -4. Push to the Branch (`git push origin feature/AmazingFeature`) -5. Open a Pull Request - -Read our [contributing guide](./CONTRIBUTING.md) for more information. - -

(back to top)

- - - -## License +
+
+
 🡅 
+
-Distributed under the MIT License. See [LICENSE.txt](./LICENSE.txt) for more information. +## Special Thanks -

(back to top)

+- **[Img Shields][img-shields]** - _For the awesome README badges_ +- **[Hyprland][hyprland]** - _For showing how to make beautiful READMEs_ +- **[Hyprdots][hyprdots]** - _For showing how to make beautiful READMEs_ - +--- -## Contact +![stars-graph] -Alex - [contact@ngjx.org](mailto:contact@ngjx.org) + + -

(back to top)

+[stars-graph]: https://starchart.cc/caffeine-addictt/template.svg?variant=adaptive +[prs]: https://github.com/caffeine-addictt/template/pulls +[issues]: https://github.com/caffeine-addictt/template/issues +[license]: https://github.com/caffeine-addictt/template/blob/main/LICENSE - + -## Acknowledgments +[use-url]: https://github.com/new?template_name=template&template_owner=caffeine-addictt +[contribute]: https://github.com/caffeine-addictt/template/blob/main/CONTRIBUTING.md -- [Choose an Open Source License](https://choosealicense.com) -- [GitHub Emoji Cheat Sheet](https://www.webpagefx.com/tools/emoji-cheat-sheet) -- [Malven's Flexbox Cheatsheet](https://flexbox.malven.co/) -- [Malven's Grid Cheatsheet](https://grid.malven.co/) -- [Img Shields](https://shields.io) + -

(back to top)

+[hyprland]: https://github.com/hyprwm/Hyprland +[hyprdots]: https://github.com/prasanthrangan/hyprdots +[img-shields]: https://shields.io - - + -[forks-shield]: https://img.shields.io/github/forks/caffeine-addictt/template.svg?style=for-the-badge -[forks-url]: https://github.com/caffeine-addictt/template/network/members -[stars-shield]: https://img.shields.io/github/stars/caffeine-addictt/template.svg?style=for-the-badge&color=yellow -[stars-url]: https://github.com/caffeine-addictt/template/stargazers -[license-shield]: https://img.shields.io/github/license/caffeine-addictt/template.svg?style=for-the-badge -[license-url]: https://github.com/caffeine-addictt/template/blob/master/LICENSE.txt -[use-shield]: https://img.shields.io/badge/Use%20template-FFFFFF?style=for-the-badge -[use-url]: https://github.com/new?template_name=template&template_owner=caffeine-addictt +[badge-workflow]: https://github.com/caffeine-addictt/template/actions/workflows/test-worker.yml/badge.svg +[badge-issues]: https://img.shields.io/github/issues/caffeine-addictt/template +[badge-pr]: https://img.shields.io/github/issues-pr/caffeine-addictt/template +[badge-language]: https://img.shields.io/github/languages/top/caffeine-addictt/template +[badge-license]: https://img.shields.io/github/license/caffeine-addictt/template +[badge-use]: https://img.shields.io/badge/Use%20template-FFFFFF?style=for-the-badge diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 00000000..e1e91940 Binary files /dev/null and b/assets/logo.png differ diff --git a/assets/transparent-logo.svg b/assets/transparent-logo.svg new file mode 100644 index 00000000..17dc4f5d --- /dev/null +++ b/assets/transparent-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dist/io-util.js b/dist/io-util.js index e049a53d..0e3b6af0 100644 --- a/dist/io-util.js +++ b/dist/io-util.js @@ -25,7 +25,7 @@ const replaceInFile = (filePath, _tempDir, data) => new Promise((resolve) => { // Revert to legacy let fileContent = fs_1.default.readFileSync(filePath, 'utf8'); fileContent = fileContent - .replace(/{{REPOSITORY}}/g, data.repository) + .replace(/{{REPOSITORY}}/g, `${data.username}/${data.repository}`) .replace(/{{PROJECT_NAME}}/g, data.proj_name) .replace(/{{PROJECT_SHORT_DESCRIPTION}}/g, data.proj_short_desc) .replace(/{{PROJECT_LONG_DESCRIPTION}}/g, data.proj_long_desc) diff --git a/dist/parser.js b/dist/parser.js new file mode 100644 index 00000000..3d7e7d8e --- /dev/null +++ b/dist/parser.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.extractRepoInfo = void 0; +/** Extract username/org and repo from url */ +const extractRepoInfo = (url) => { + const originUrl = url.trim(); + const match = /^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?$/.exec(originUrl); + if (!match || !match[1] || !match[2]) + throw new AggregateError(`Could not extract user and repo from git remote: ${originUrl}`); + return { + url: originUrl, + org: match[1], + repo: match[2], + }; +}; +exports.extractRepoInfo = extractRepoInfo; diff --git a/dist/resolver.js b/dist/resolver.js new file mode 100644 index 00000000..80db13b4 --- /dev/null +++ b/dist/resolver.js @@ -0,0 +1,35 @@ +"use strict"; +/** + * This file will hold the configuration options to make the setup script not so annoying + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.resolveUserInfo = exports.resolveRepoInfo = void 0; +const parser_1 = require("./parser"); +const term_1 = require("./term"); +const resolveRepoInfo = () => (0, term_1.execute)('git', ['remote', 'get-url', 'origin']) + .then((_originUrl) => (0, parser_1.extractRepoInfo)(_originUrl.toString())) + .catch(() => ({})); +exports.resolveRepoInfo = resolveRepoInfo; +const resolveUserInfo = async () => { + const promises = await Promise.all([ + (0, term_1.execute)('git', ['config', '--global', 'user.name']) + .then((r) => r.toString().trim()) + .catch(() => undefined), + (0, term_1.execute)('git', ['config', '--global', 'user.email']) + .then((r) => r.toString().trim()) + .catch(() => undefined), + ]); + return { + name: promises[0], + email: promises[1], + }; +}; +exports.resolveUserInfo = resolveUserInfo; +const resolveGitInfo = async () => { + const promises = await Promise.all([(0, exports.resolveRepoInfo)(), (0, exports.resolveUserInfo)()]); + return { + ...promises[0], + ...promises[1], + }; +}; +exports.default = resolveGitInfo; diff --git a/dist/setup.js b/dist/setup.js index 045aba85..17f11fe1 100644 --- a/dist/setup.js +++ b/dist/setup.js @@ -7,6 +7,7 @@ const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const readline_1 = __importDefault(require("readline")); const io_util_1 = require("./io-util"); +const resolver_1 = __importDefault(require("./resolver")); /** * For interacting with stdin/stdout */ @@ -28,15 +29,25 @@ const question = (query, validator = [], trimWhitespace = true) => new Promise(( })); /** Ask for project information */ const fetchInfo = async (cleanup) => { - const name = await question('Name? (This will go on the LICENSE)\n=> '); - const email = await question('Email?\n=> ', [ + const resolved = await (0, resolver_1.default)(); + // Ask user + const name = await question(`Name? (This will go on the LICENSE)${resolved.name ? ` [Resolved: ${resolved.name}]` : ''}\n=> `) + .then((val) => val.trim()) + .then((val) => (val.length ? val : resolved.name ?? '')); + const email = await question(`Email?${resolved.email ? ` [Resolved: ${resolved.email}]` : ''}\n=> `, [ { - validate: (s) => /.+@.+\..+/.test(s), + validate: (s) => !!resolved.email || /.+@.+\..+/.test(s), onError: () => console.log('Invalid email!'), }, - ]); - const username = await question('Username? (https://github.com/)\n=> '); - const repository = await question('Repository? ((https://github.com/$username/\n=> '); + ]) + .then((val) => val.trim()) + .then((val) => (val.length ? val : resolved.email ?? '')); + const username = await question(`Username? (https://github.com/)${resolved.org ? ` [Resolved: ${resolved.org}]` : ''}\n=> `) + .then((val) => val.trim()) + .then((val) => (val.length ? val : resolved.org ?? '')); + const repository = await question(`Repository? (https://github.com/${username}/)${resolved.repo ? ` [Resolved: ${resolved.repo}]` : ''}\n=> `) + .then((val) => val.trim()) + .then((val) => (val.length ? val : resolved.repo ?? '')); const proj_name = await question('Project name?\n=> '); const proj_short_desc = await question('Short description?\n=> '); const proj_long_desc = await question('Long description?\n=> '); @@ -90,14 +101,14 @@ const { func: main } = (0, io_util_1.withTempDir)('caffeine-addictt-template-', recursive: true, }); // Use async - await Promise.all(filesToUpdate.map((filename) => async () => { + await Promise.all(filesToUpdate.map((filename) => (async () => { const filePath = path_1.default.join('./template', filename); const fileInfo = fs_1.default.statSync(filePath); if (fileInfo.isDirectory()) { return; } await (0, io_util_1.replaceInFile)(filePath, tempDir, data); - })); + })())); // Write CODEOWNERS fs_1.default.appendFileSync('./template/.github/CODEOWNERS', `* @${data.username}`); // ########################################## // @@ -122,6 +133,9 @@ const { func: main } = (0, io_util_1.withTempDir)('caffeine-addictt-template-', // ################# // // Stage 3: Clean up // // ################# // + // Only add `force: true` for files or directories that + // will only exist if some development task was carried out + // like eslintcache console.log('Cleaning up...'); // Js fs_1.default.unlinkSync('package.json'); @@ -133,19 +147,21 @@ const { func: main } = (0, io_util_1.withTempDir)('caffeine-addictt-template-', fs_1.default.unlinkSync('babel.config.cjs'); fs_1.default.rmSync('tests', { recursive: true }); // Linting - fs_1.default.unlinkSync('.eslintcache'); fs_1.default.unlinkSync('.eslintignore'); fs_1.default.unlinkSync('.prettierignore'); fs_1.default.unlinkSync('eslint.config.mjs'); + fs_1.default.rmSync('.eslintcache', { force: true }); // Syncing fs_1.default.unlinkSync('.templatesyncignore'); // Git fs_1.default.unlinkSync('.gitignore'); // Node - fs_1.default.rmSync('node_modules', { recursive: true }); + fs_1.default.rmSync('node_modules', { recursive: true, force: true }); // Clean up dist fs_1.default.unlinkSync(__filename); fs_1.default.rmSync('dist', { recursive: true }); + // Assets + fs_1.default.rmSync('assets', { recursive: true }); // Generate src and test fs_1.default.mkdirSync('src'); fs_1.default.mkdirSync('tests'); diff --git a/dist/term.js b/dist/term.js new file mode 100644 index 00000000..29ff8f2a --- /dev/null +++ b/dist/term.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.execute = void 0; +const child_process_1 = require("child_process"); +const execute = (command, args, spawnOptions) => new Promise((resolve, reject) => { + const cmd = (0, child_process_1.spawn)(command, args, spawnOptions); + cmd.stdout.on('data', resolve); + cmd.stderr.on('data', reject); +}); +exports.execute = execute; diff --git a/package-lock.json b/package-lock.json index 2afe8a63..a5b5caaa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3255,12 +3255,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -4015,9 +4015,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" diff --git a/src/io-util.ts b/src/io-util.ts index da384456..70580dbe 100644 --- a/src/io-util.ts +++ b/src/io-util.ts @@ -42,7 +42,7 @@ export const replaceInFile = ( let fileContent = fs.readFileSync(filePath, 'utf8'); fileContent = fileContent - .replace(/{{REPOSITORY}}/g, data.repository) + .replace(/{{REPOSITORY}}/g, `${data.username}/${data.repository}`) .replace(/{{PROJECT_NAME}}/g, data.proj_name) .replace(/{{PROJECT_SHORT_DESCRIPTION}}/g, data.proj_short_desc) .replace(/{{PROJECT_LONG_DESCRIPTION}}/g, data.proj_long_desc) diff --git a/src/parser.ts b/src/parser.ts new file mode 100644 index 00000000..97ae7e7b --- /dev/null +++ b/src/parser.ts @@ -0,0 +1,20 @@ +import type { RepoInfo } from './types'; + +/** Extract username/org and repo from url */ +export const extractRepoInfo = (url: string): RepoInfo => { + const originUrl = url.trim(); + const match = /^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?$/.exec( + originUrl, + ); + + if (!match || !match[1] || !match[2]) + throw new AggregateError( + `Could not extract user and repo from git remote: ${originUrl}`, + ); + + return { + url: originUrl, + org: match[1], + repo: match[2], + } satisfies RepoInfo; +}; diff --git a/src/resolver.ts b/src/resolver.ts new file mode 100644 index 00000000..e99a82b3 --- /dev/null +++ b/src/resolver.ts @@ -0,0 +1,37 @@ +/** + * This file will hold the configuration options to make the setup script not so annoying + */ + +import { extractRepoInfo } from './parser'; +import { execute } from './term'; +import type { GitInfo, RepoInfo, UserInfo } from './types'; + +export const resolveRepoInfo = (): Promise => + execute('git', ['remote', 'get-url', 'origin']) + .then((_originUrl) => extractRepoInfo(_originUrl.toString())) + .catch(() => ({})); + +export const resolveUserInfo = async (): Promise => { + const promises = await Promise.all([ + execute('git', ['config', '--global', 'user.name']) + .then((r) => r.toString().trim()) + .catch(() => undefined), + execute('git', ['config', '--global', 'user.email']) + .then((r) => r.toString().trim()) + .catch(() => undefined), + ]); + + return { + name: promises[0], + email: promises[1], + } satisfies UserInfo; +}; + +const resolveGitInfo = async (): Promise => { + const promises = await Promise.all([resolveRepoInfo(), resolveUserInfo()]); + return { + ...promises[0], + ...promises[1], + } as GitInfo; +}; +export default resolveGitInfo; diff --git a/src/setup.ts b/src/setup.ts index 71050a88..66a54b8f 100644 --- a/src/setup.ts +++ b/src/setup.ts @@ -4,6 +4,7 @@ import readline from 'readline'; import type { ProjectInfo } from './types'; import { replaceInFile, withTempDir } from './io-util'; +import resolveGitInfo from './resolver'; /** * For interacting with stdin/stdout @@ -41,19 +42,39 @@ const question = ( const fetchInfo = async ( cleanup: () => void | unknown, ): Promise => { - const name = await question('Name? (This will go on the LICENSE)\n=> '); - const email = await question('Email?\n=> ', [ - { - validate: (s: string) => /.+@.+\..+/.test(s), - onError: () => console.log('Invalid email!'), - }, - ]); + const resolved = await resolveGitInfo(); + + // Ask user + const name = await question( + `Name? (This will go on the LICENSE)${resolved.name ? ` [Resolved: ${resolved.name}]` : ''}\n=> `, + ) + .then((val) => val.trim()) + .then((val) => (val.length ? val : resolved.name ?? '')); + + const email = await question( + `Email?${resolved.email ? ` [Resolved: ${resolved.email}]` : ''}\n=> `, + [ + { + validate: (s: string) => !!resolved.email || /.+@.+\..+/.test(s), + onError: () => console.log('Invalid email!'), + }, + ], + ) + .then((val) => val.trim()) + .then((val) => (val.length ? val : resolved.email ?? '')); + const username = await question( - 'Username? (https://github.com/)\n=> ', - ); + `Username? (https://github.com/)${resolved.org ? ` [Resolved: ${resolved.org}]` : ''}\n=> `, + ) + .then((val) => val.trim()) + .then((val) => (val.length ? val : resolved.org ?? '')); + const repository = await question( - 'Repository? ((https://github.com/$username/\n=> ', - ); + `Repository? (https://github.com/${username}/)${resolved.repo ? ` [Resolved: ${resolved.repo}]` : ''}\n=> `, + ) + .then((val) => val.trim()) + .then((val) => (val.length ? val : resolved.repo ?? '')); + const proj_name = await question('Project name?\n=> '); const proj_short_desc = await question('Short description?\n=> '); const proj_long_desc = await question('Long description?\n=> '); @@ -126,16 +147,18 @@ const { func: main } = withTempDir( // Use async await Promise.all( - filesToUpdate.map((filename) => async () => { - const filePath = path.join('./template', filename); - - const fileInfo = fs.statSync(filePath); - if (fileInfo.isDirectory()) { - return; - } - - await replaceInFile(filePath, tempDir, data); - }), + filesToUpdate.map((filename) => + (async () => { + const filePath = path.join('./template', filename); + + const fileInfo = fs.statSync(filePath); + if (fileInfo.isDirectory()) { + return; + } + + await replaceInFile(filePath, tempDir, data); + })(), + ), ); // Write CODEOWNERS @@ -167,6 +190,9 @@ const { func: main } = withTempDir( // ################# // // Stage 3: Clean up // // ################# // + // Only add `force: true` for files or directories that + // will only exist if some development task was carried out + // like eslintcache console.log('Cleaning up...'); // Js @@ -182,10 +208,10 @@ const { func: main } = withTempDir( fs.rmSync('tests', { recursive: true }); // Linting - fs.unlinkSync('.eslintcache'); fs.unlinkSync('.eslintignore'); fs.unlinkSync('.prettierignore'); fs.unlinkSync('eslint.config.mjs'); + fs.rmSync('.eslintcache', { force: true }); // Syncing fs.unlinkSync('.templatesyncignore'); @@ -194,12 +220,15 @@ const { func: main } = withTempDir( fs.unlinkSync('.gitignore'); // Node - fs.rmSync('node_modules', { recursive: true }); + fs.rmSync('node_modules', { recursive: true, force: true }); // Clean up dist fs.unlinkSync(__filename); fs.rmSync('dist', { recursive: true }); + // Assets + fs.rmSync('assets', { recursive: true }); + // Generate src and test fs.mkdirSync('src'); fs.mkdirSync('tests'); diff --git a/src/term.ts b/src/term.ts new file mode 100644 index 00000000..53478fb1 --- /dev/null +++ b/src/term.ts @@ -0,0 +1,13 @@ +import { SpawnOptionsWithoutStdio, spawn } from 'child_process'; + +export const execute = ( + command: string, + args?: string[], + spawnOptions?: SpawnOptionsWithoutStdio, +): Promise => + new Promise((resolve, reject): void => { + const cmd = spawn(command, args, spawnOptions); + + cmd.stdout.on('data', resolve); + cmd.stderr.on('data', reject); + }); diff --git a/src/types.ts b/src/types.ts index 47037077..51150e4e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -11,3 +11,16 @@ export interface ProjectInfo { docs_url: string; assignees: string; } + +export interface RepoInfo { + url?: string; + org?: string; + repo?: string; +} + +export interface UserInfo { + name?: string; + email?: string; +} + +export type GitInfo = RepoInfo & UserInfo; diff --git a/template/CONTRIBUTING.md b/template/CONTRIBUTING.md index 4725d3ff..cd8906c1 100644 --- a/template/CONTRIBUTING.md +++ b/template/CONTRIBUTING.md @@ -12,16 +12,35 @@ please follow it in all your interactions with the project. -1. [Pull Request Process](#pull-request-process) -2. [Issue Report Process](#issue-report-process) -3. [Commit Message Guidelines](#commit-message-guidelines) -4. [Code Quality](#code-quality) +1. [Getting started](#getting-started) +2. [Pull Request Process](#pull-request-process) +3. [Issue Report Process](#issue-report-process) +4. [Commit Message Guidelines](#commit-message-guidelines) +5. [Code Quality](#code-quality) - [Testing](#testing) - [Linting](#linting) + - [Building](#building) +## Getting started + +Contributions are what make the open source community +such an amazing place to learn, inspire, and create. +Any contributions you make are **greatly appreciated**. ( ˶ˆᗜˆ˵ ) + +If you have a suggestion that would make this better, +please fork the repo and create a pull request. +You can also simply open an issue with the tag "enhancement". +Don't forget to give the project a star! Thanks again! + +1. Fork the Project +2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) +3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) +4. Push to the Branch (`git push origin feature/AmazingFeature`) +5. Open a Pull Request + ## Pull Request Process 1. Ensure any install or build dependencies are removed before the end of the layer diff --git a/template/README.md b/template/README.md index 76b4c5da..b63af7c7 100644 --- a/template/README.md +++ b/template/README.md @@ -1,140 +1,103 @@ - - +###### _
// made with <3
_ - - - - - - - - - -
- - Logo - - -

{{PROJECT_NAME}}

- -

- {{PROJECT_SHORT_DESCRIPTION}} -
- Explore the docs » -
-
- Report Bug - · - Request Feature -

-
- - - -## About The Project -![Social Card](images/socialcard.png) + -{{PROJECT_LONG_DESCRIPTION}} - -

(back to top)

- - + + + -## Getting Started +
-This is an example of how you can set up your project locally. -To get a local copy up and running follow these simple example steps. + -### Prerequisites +![badge-workflow] +[![badge-license]][license] +![badge-language] +[![badge-pr]][prs] +[![badge-issues]][issues] -- +

-### Installation + -_Below is an example of how you can install and use {{PROJECT_NAME}}._ +{{PROJECT_LONG_DESCRIPTION}} -1. -2. +{{PROJECT_SHORT_DESCRIPTION}} -

(back to top)

+

- +--- -## Documentation + -Our docs are [here]({{DOCS_URL}})! +**[
 Quick Start 
](#quick-start)** +**[
 Documentation 
]({{DOCS_URL}})** +**[
 Thanks 
](#special-thanks)** +**[
 Contribute 
][contribute]** -See the [open issues](https://github.com/{{REPOSITORY}}/issues) -for a full list of proposed features (and known issues). +--- -

(back to top)

+
- + -## Contributing +# Quick Start -Contributions are what make the open source community -such an amazing place to learn, inspire, and create. -Any contributions you make are **greatly appreciated**. ( ˶ˆᗜˆ˵ ) +_This is an example of how you can set up your project locally. +To get a local copy up and running, follow these simple steps._ -If you have a suggestion that would make this better, -please fork the repo and create a pull request. -You can also simply open an issue with the tag "enhancement". -Don't forget to give the project a star! Thanks again! +## Prerequisites -1. Fork the Project -2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) -3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) -4. Push to the Branch (`git push origin feature/AmazingFeature`) -5. Open a Pull Request +- Language 1 -Read our [contributing guide](./CONTRIBUTING.md) for more information. +## Installation -

(back to top)

+_Below is an example of how you can install and use {{PROJECT_NAME}}_ - +1. Step 1 +2. Step 2 -## License + -Distributed under the MIT License. See [LICENSE.txt](./LICENSE.txt) for more information. +## Special Thanks -

(back to top)

+- **[Caffeine-addictt][template-repo]** - _For the repository template_ +- **[Img Shields][img-shields]** - _For the awesome README badges_ +- **[Hyprland][hyprland]** - _For showing how to make beautiful READMEs_ +- **[Hyprdots][hyprdots]** - _For showing how to make beautiful READMEs_ - +--- -## Contact +![stars-graph] -{{NAME}} - [{{EMAIL}}](mailto:{{EMAIL}}) + + -

(back to top)

+[stars-graph]: https://starchart.cc/{{REPOSITORY}}.svg?variant=adaptive +[prs]: https://github.com/{{REPOSITORY}}/pulls +[issues]: https://github.com/{{REPOSITORY}}/issues +[license]: https://github.com/{{REPOSITORY}}/blob/main/LICENSE - + -## Acknowledgments +[contribute]: https://github.com/{{REPOSITORY}}/blob/main/CONTRIBUTING.md -- [Repository Template](https://github.com/caffeine-addictt/template) -- [Choose an Open Source License](https://choosealicense.com) -- [GitHub Emoji Cheat Sheet](https://www.webpagefx.com/tools/emoji-cheat-sheet) -- [Malven's Flexbox Cheatsheet](https://flexbox.malven.co/) -- [Malven's Grid Cheatsheet](https://grid.malven.co/) -- [Img Shields](https://shields.io) + -

(back to top)

+[template-repo]: https://github.com/caffeine-addictt/template +[hyprland]: https://github.com/hyprwm/Hyprland +[hyprdots]: https://github.com/prasanthrangan/hyprdots +[img-shields]: https://shields.io - - + -[forks-shield]: https://img.shields.io/github/forks/{{REPOSITORY}}.svg?style=for-the-badge -[forks-url]: https://github.com/{{REPOSITORY}}/network/members -[stars-shield]: https://img.shields.io/github/stars/{{REPOSITORY}}.svg?style=for-the-badge&color=yellow -[stars-url]: https://github.com/{{REPOSITORY}}/stargazers -[license-shield]: https://img.shields.io/github/license/{{REPOSITORY}}.svg?style=for-the-badge -[license-url]: https://github.com/{{REPOSITORY}}/blob/master/LICENSE.txt +[badge-workflow]: https://github.com/{{REPOSITORY}}/actions/workflows/test-worker.yml/badge.svg +[badge-issues]: https://img.shields.io/github/issues/{{REPOSITORY}} +[badge-pr]: https://img.shields.io/github/issues-pr/{{REPOSITORY}} +[badge-language]: https://img.shields.io/github/languages/top/{{REPOSITORY}} +[badge-license]: https://img.shields.io/github/license/{{REPOSITORY}} diff --git a/tests/io-util.test.ts b/tests/io-util.test.ts index deed0b9e..17462490 100644 --- a/tests/io-util.test.ts +++ b/tests/io-util.test.ts @@ -23,7 +23,7 @@ assignees: ['{{ASSIGNEES}}'] const replaced = ` My name is: John -The repo is https://github.com/username/repo +The repo is johnny/repo HbVYf@example.com https://example.com/docs Project with some description @@ -65,7 +65,7 @@ describe('replace the correct content', () => { name: 'John', email: 'HbVYf@example.com', username: 'johnny', - repository: 'https://github.com/username/repo', + repository: 'repo', proj_name: 'My Project', proj_short_desc: 'Project with some description', proj_long_desc: 'Project with some description that is really long',