├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .github
├── AUTHOR.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── PULL_REQUEST_TEMPLATE
│ └── pull_request_template.md
├── SECURITY.md
├── assets
│ └── example.gif
└── workflows
│ ├── codeql-analysis.yml
│ └── publish.yml
├── .gitignore
├── .npmignore
├── .nvmrc
├── .prettierrc
├── .vscode
└── settings.json
├── CHANGELOG.md
├── EXAMPLE-README.md
├── LICENSE
├── README.md
├── changelog.tpl.hbs
├── jest.config.babel.js
├── package.json
├── rollup.config.babel.js
├── src
├── cli.js
├── index.js
├── readme
│ ├── questions
│ │ ├── managers.js
│ │ ├── prompt.js
│ │ ├── purpose.js
│ │ └── support.js
│ └── templates
│ │ ├── README.hbs
│ │ └── partials
│ │ ├── author.hbs
│ │ ├── badges.hbs
│ │ ├── commands.hbs
│ │ ├── contributing.hbs
│ │ ├── contributors.hbs
│ │ ├── copyright.hbs
│ │ ├── dependencies.hbs
│ │ ├── description.hbs
│ │ ├── dev-instructions.hbs
│ │ ├── engines.hbs
│ │ ├── formatters.hbs
│ │ ├── installation.hbs
│ │ ├── purpose.hbs
│ │ ├── support.hbs
│ │ └── title.hbs
├── settings
│ ├── data.js
│ ├── file.js
│ ├── index.js
│ ├── message.js
│ └── path.js
└── utilities
│ ├── data.js
│ ├── file.js
│ ├── handlebar.js
│ ├── index.js
│ ├── question.js
│ ├── system.js
│ └── yaml.js
└── test
├── settings
├── data.test.js
├── file.test.js
├── message.test.js
└── path.test.js
└── utilities
├── file.test.js
├── handlebar.test.js
├── question.test.js
├── ststem.test.js
└── yaml.test.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env",
5 | {
6 | "useBuiltIns": "usage",
7 | "corejs": 3,
8 | "shippedProposals": true,
9 | "targets": {
10 | "node": "current"
11 | }
12 | }
13 | ]
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 | max_line_length = off
12 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | **/node_modules
2 | **/jspm_packages
3 | **/bower_components
4 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "env": {
4 | "browser": true,
5 | "node": true,
6 | "es6": true,
7 | "jest/globals": true
8 | },
9 | "parserOptions": {
10 | "ecmaVersion": 8,
11 | "sourceType": "module",
12 | "ecmaFeatures": {
13 | "jsx": true
14 | }
15 | },
16 | "rules": {
17 | "no-console": "warn"
18 | },
19 | "extends": [
20 | "eslint:recommended",
21 | "plugin:jest/recommended",
22 | ],
23 | "plugins": [
24 | "import",
25 | "jest",
26 | ],
27 | }
28 |
--------------------------------------------------------------------------------
/.github/AUTHOR.md:
--------------------------------------------------------------------------------
1 | Dev Maurizio Battaghini | maurizio.battaghini+tech@gmail.com
2 | • Developer
3 | — — • Twitter: https://twitter.com/battago
4 | — — • GitHub: https://github.com/ibbatta
5 |
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | - Using welcoming and inclusive language
18 | - Being respectful of differing viewpoints and experiences
19 | - Gracefully accepting constructive criticism
20 | - Focusing on what is best for the community
21 | - Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | - The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | - Trolling, insulting/derogatory comments, and personal or political attacks
28 | - Public or private harassment
29 | - Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | - Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at maurizio.battaghini+github@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | I love your input and I want to make contributing to this project as easy and transparent as possible, whether it's:
4 |
5 | - Reporting a bug
6 | - Discussing the current state of the code
7 | - Submitting a fix
8 | - Proposing new features
9 | - Becoming a maintainer
10 |
11 | ### How to contributing
12 |
13 | - Fork it!
14 | - Create your feature branch: `git checkout -b my-new-feature`
15 | - Commit your changes: `git commit -am 'Add some feature'`
16 | - Push to the branch: `git push origin my-new-feature`
17 | - Submit a pull request
18 |
19 | ## I Develop with Github
20 |
21 | I use github to host code, to track issues and feature requests, as well as accept pull requests.
22 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [ibbatta]
4 | patreon: ibbatta
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: https://www.paypal.me/mauriziobattaghini
13 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 | ---
8 |
9 | **Describe the bug**
10 | A clear and concise description of what the bug is.
11 |
12 | **To Reproduce**
13 | Steps to reproduce the behavior:
14 |
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 |
28 | - OS: [e.g. iOS]
29 | - Browser [e.g. chrome, safari]
30 | - Version [e.g. 22]
31 |
32 | **Smartphone (please complete the following information):**
33 |
34 | - Device: [e.g. iPhone6]
35 | - OS: [e.g. iOS8.1]
36 | - Browser [e.g. stock browser, safari]
37 | - Version [e.g. 22]
38 |
39 | **Additional context**
40 | Add any other context about the problem here.
41 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 | ---
8 |
9 | **Is your feature request related to a problem? Please describe.**
10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
11 |
12 | **Describe the solution you'd like**
13 | A clear and concise description of what you want to happen.
14 |
15 | **Describe alternatives you've considered**
16 | A clear and concise description of any alternative solutions or features you've considered.
17 |
18 | **Additional context**
19 | Add any other context or screenshots about the feature request here.
20 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## Description
2 |
3 | Describe your changes in detail.
4 |
5 | ## Motivation and Context
6 |
7 | Why is this change required? What problem does it solve?
8 | If it fixes an open issue, please link to the issue here.
9 |
10 | ## How Has This Been Tested?
11 |
12 | Please describe in detail how you tested your changes.
13 | Include details of your testing environment, and the tests you ran to see how your change affects other areas of the code, etc.
14 |
15 | ## Screenshots (if appropriate):
16 |
17 | ## Types of changes
18 |
19 | What types of changes does your code introduce? Put an `x` in all the boxes that apply:
20 |
21 | - [ ] Bug fix (non-breaking change which fixes an issue)
22 | - [ ] New feature (non-breaking change which adds functionality)
23 | - [ ] Breaking change (fix or feature that would cause existing functionality to change)
24 |
25 | ## Checklist:
26 |
27 | Go over all the following points, and put an `x` in all the boxes that apply.
28 | If you're unsure about any of these, don't hesitate to ask. We're here to help!
29 |
30 | - [ ] My code follows the code style of this project.
31 | - [ ] My change requires a change to the documentation.
32 | - [ ] I have updated the documentation accordingly.
33 | - [ ] I have read the **CONTRIBUTING** document.
34 | - [ ] I have added tests to cover my changes.
35 | - [ ] All new and existing tests passed.
36 |
--------------------------------------------------------------------------------
/.github/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | Use this section to tell people about which versions of your project are
6 | currently being supported with security updates.
7 |
8 | | Version | Supported |
9 | | ------- | ------------------ |
10 | | 5.1.x | :white_check_mark: |
11 | | 5.0.x | :x: |
12 | | 4.0.x | :white_check_mark: |
13 | | < 4.0 | :x: |
14 |
15 | ## Reporting a Vulnerability
16 |
17 | Use this section to tell people how to report a vulnerability.
18 |
19 | Tell them where to go, how often they can expect to get an update on a
20 | reported vulnerability, what to expect if the vulnerability is accepted or
21 | declined, etc.
22 |
--------------------------------------------------------------------------------
/.github/assets/example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ibbatta/readme-generator/24ace134de20687abfee189bf4ab3d37fdf114fd/.github/assets/example.gif
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ master ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ master ]
20 | schedule:
21 | - cron: '23 18 * * 6'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 |
28 | strategy:
29 | fail-fast: false
30 | matrix:
31 | language: [ 'javascript' ]
32 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
33 | # Learn more:
34 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
35 |
36 | steps:
37 | - name: Checkout repository
38 | uses: actions/checkout@v2
39 |
40 | # Initializes the CodeQL tools for scanning.
41 | - name: Initialize CodeQL
42 | uses: github/codeql-action/init@v1
43 | with:
44 | languages: ${{ matrix.language }}
45 | # If you wish to specify custom queries, you can do so here or in a config file.
46 | # By default, queries listed here will override any specified in a config file.
47 | # Prefix the list here with "+" to use these queries and those in the config file.
48 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
49 |
50 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
51 | # If this step fails, then you should remove it and run the build manually (see below)
52 | - name: Autobuild
53 | uses: github/codeql-action/autobuild@v1
54 |
55 | # ℹ️ Command-line programs to run using the OS shell.
56 | # 📚 https://git.io/JvXDl
57 |
58 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
59 | # and modify them (or add more) to build your code if your project
60 | # uses a compiled language
61 |
62 | #- run: |
63 | # make bootstrap
64 | # make release
65 |
66 | - name: Perform CodeQL Analysis
67 | uses: github/codeql-action/analyze@v1
68 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish pkg (NPM + GITHUB)
2 |
3 | on:
4 | release:
5 | types: [created]
6 |
7 | jobs:
8 | build:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v1
12 | - uses: actions/setup-node@v1
13 | with:
14 | node-version: 12
15 | - run: npm install
16 | - run: npm test
17 |
18 | publish-npm:
19 | needs: build
20 | runs-on: ubuntu-latest
21 | steps:
22 | - uses: actions/checkout@v1
23 | - uses: actions/setup-node@v1
24 | with:
25 | node-version: 12
26 | registry-url: https://registry.npmjs.org/
27 | scope: '@ibbatta'
28 | - run: npm install
29 | - run: npm publish
30 | env:
31 | NODE_AUTH_TOKEN: ${{secrets.npm}}
32 |
33 | publish-gpr:
34 | needs: build
35 | runs-on: ubuntu-latest
36 | steps:
37 | - uses: actions/checkout@v1
38 | - uses: actions/setup-node@v1
39 | with:
40 | node-version: 12
41 | registry-url: https://npm.pkg.github.com/ibbatta
42 | - run: npm install
43 | - run: npm publish
44 | env:
45 | NODE_AUTH_TOKEN: ${{secrets.github}}
46 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### Node ###
2 |
3 | # Logs
4 | logs
5 | npm-debug.log*
6 | yarn-debug.log*
7 | yarn-error.log*
8 |
9 | # Optional npm cache directory
10 | .npm
11 |
12 | # package-lock should be ignored because users should use Yarn
13 | package-lock.json
14 |
15 | # Dependency directories
16 | **/node_modules
17 | **/jspm_packages
18 | **/bower_components
19 |
20 | # Yarn Integrity file
21 | .yarn-integrity
22 |
23 | # Optional eslint cache
24 | .eslintcache
25 |
26 | # dotenv environment variables file(s)
27 | .env
28 | .env.*
29 |
30 | #Build generated
31 | dist/
32 | build/
33 | .tmp/
34 |
35 |
36 | ### SublimeText ###
37 | # cache files for sublime text
38 | *.tmlanguage.cache
39 | *.tmPreferences.cache
40 | *.stTheme.cache
41 |
42 | # workspace files are user-specific
43 | *.sublime-workspace
44 |
45 | # project files should be checked into the repository, unless a significant
46 | # proportion of contributors will probably not be using SublimeText
47 | # *.sublime-project
48 |
49 |
50 | ### VisualStudioCode ###
51 | .vscode/*
52 | !.vscode/settings.json
53 | !.vscode/tasks.json
54 | !.vscode/launch.json
55 | !.vscode/extensions.json
56 |
57 | ### WebStorm/IntelliJ ###
58 | /.idea
59 | modules.xml
60 | *.ipr
61 |
62 |
63 | ### System Files ###
64 | .DS_Store
65 |
66 | # Windows thumbnail cache files
67 | Thumbs.db
68 | ehthumbs.db
69 | ehthumbs_vista.db
70 |
71 | # Folder config file
72 | Desktop.ini
73 |
74 | # Recycle Bin used on file shares
75 | $RECYCLE.BIN/
76 |
77 | # Thumbnails
78 | ._*
79 |
80 | # Files that might appear in the root of a volume
81 | .DocumentRevisions-V100
82 | .fseventsd
83 | .Spotlight-V100
84 | .TemporaryItems
85 | .Trashes
86 | .VolumeIcon.icns
87 | .com.apple.timemachine.donotpresent
88 |
89 | # Tests coverage
90 | **/coverage
91 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | #tests
2 | test
3 | coverage
4 |
5 | #build tools
6 | .travis.yml
7 | .jenkins.yml
8 | .codeclimate.yml
9 |
10 | #linters
11 | .jscsrc
12 | .jshintrc
13 | .eslintrc*
14 |
15 | #editor settings
16 | .idea
17 | .editorconfig
18 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | lts/*
2 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": true,
3 | "singleQuote": true
4 | }
5 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "html.format.indentHandlebars": false
3 | }
4 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## Unreleased
4 |
--------------------------------------------------------------------------------
/EXAMPLE-README.md:
--------------------------------------------------------------------------------
1 | # **:triangular_flag_on_post: @IBBATTA/README-GENERATOR** (version 0.1.9)
2 |
3 | 
4 | 
5 |
6 | > This project was born mainly to satisfy my desire for knowledge and to simplify my workflow. Being a curious (and also lazy) developer I have always wondered how avoid to waste my working time to write README.md files who fits perfectly project by project and that's why I wrote a tool to help me simplify and speed up these processes.
7 |
8 | ---
9 |
10 | ## **:package: Main tools used**
11 |
12 | - [x] boxen
13 | - [x] chalk
14 | - [x] commander
15 | - [x] figlet
16 | - [x] handlebars
17 | - [x] immer
18 | - [x] inquirer
19 | - [x] js-yaml
20 | - [x] lodash
21 |
22 | ---
23 |
24 | ## **:wrench: Developer usage**
25 |
26 | ### **Set up project**
27 |
28 | Before cloning the repo **be sure** you have installed:
29 |
30 | - [**NODE**](https://www.google.com/search?q=how+to+install+node) (version >= 10.16.x)
31 | - [**NPM**](https://www.google.com/search?q=how+to+install+npm) (version >= 6.9.x)
32 |
33 | Then:
34 |
35 | - Choose a folder project in your system and switch in `cd [folder path]`
36 | - Clone the repo in your folder path `git clone git+https://github.com/ibbatta/readme-generator.git`
37 |
38 | ---
39 |
40 | ### **Installation**
41 |
42 | In order to install the project and all dependencies, enter in the project folder and run `npm install`
43 |
44 | ---
45 |
46 | ### Start the project
47 |
48 | ```bash
49 | npm start
50 | ```
51 |
52 | ### Test the project
53 |
54 | ```bash
55 | npm test
56 | ```
57 |
58 | ---
59 |
60 | ### **Editor setup**
61 |
62 | To keep the style of resources consistent, I decided to stick to some shared rules that have to be applied to every
63 | project using some editors plugins. Plese be sure to disable / remove any other js/jsx linters or custom configurations.
64 |
65 | I have chosen to use
66 |
67 | - [ESLINT](https://www.google.com/search?q=eslint)
68 | - [PRETTIER](https://www.google.com/search?q=prettier)
69 | - [EDITORCONFIG](https://www.google.com/search?q=editorconfig)
70 |
71 | This
72 | works including a specific `.dotfile` in the root directory and making sure your editor has the necessary plugin.
73 |
74 | ---
75 |
76 | ## **:handshake: Contributing**
77 |
78 | - Fork it!
79 | - Create your feature branch: `git checkout -b my-new-feature`
80 | - Commit your changes: `git commit -am 'Add some feature'`
81 | - Push to the branch: `git push origin my-new-feature`
82 | - Submit a pull request
83 |
84 | ---
85 |
86 | ### **:busts_in_silhouette: Credits**
87 |
88 | - [Maurizio Battaghini](http://github.com/ibbatta)
89 |
90 | ---
91 |
92 | ### **:anger: Troubleshootings**
93 |
94 | This is just a personal project created for study / demonstration purpose and to simplify my working life, it may or may
95 | not be a good fit for your project(s).
96 |
97 | ---
98 |
99 | ### **:heart: Show your support**
100 |
101 | Please :star: this repository if you like it or this project helped you!\
102 | Feel free to open issues or submit pull-requests to help me improving my work.
103 |
104 |
105 |
106 |
107 |
108 | ---
109 |
110 | ### **:robot: Author**
111 |
112 | _*Maurizio Battaghini*_
113 |
114 | > You can follow me on
115 | [twitter](https://twitter.com/battago) · [github](https://github.com/ibbatta)
116 |
117 | ---
118 |
119 | Copyright © 2020 [Maurizio Battaghini](https://twitter.com/battago).
120 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Maurizio Battaghini
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # **:triangular_flag_on_post: @IBBATTA/README GENERATOR**
2 |
3 | 
4 | 
5 | 
6 | /badge.svg)
7 |
8 | > This project was born to simplify my workflow and satisfy my desire for knowledge. Being a curious (and also lazy) developer, I've always wandered how to avoid wasting time writing README.md files that fit perfectly project after project. That's why I wrote this tool to help simplify and speed up this process!
9 |
10 | 
11 |
12 | ---
13 |
14 | ## **:clipboard: User usage**
15 |
16 | - To install globally: `npm i -g @ibbatta/readme-generator`.
17 | - To install locally: `npm i --save-dev @ibbatta/readme-generator`.
18 |
19 | Just run `readme-generator` (or `npx readme-generator`) at the root of your project and follow the prompts!
20 |
21 | You can add the following options:
22 |
23 | | Option | Description | Default |
24 | | -------------- | -------------------------------------------- | --------------------------- |
25 | | -V, --version | output the version number | |
26 | | -h, --help | output usage information | |
27 | | -E, --entry | specify the entry file | `package.json` |
28 | | -O, --output | specify the output file | `README.md` |
29 | | -T, --template | specify the path for you own README template | `internal default template` |
30 | | -D, --debug | log output readme data | `false` |
31 |
32 | The tools will look for the **name**, **version**, **description**, **respository**, **author**, **engines**, **dependencies** and **contributors** data inside you package.json and then will generate the README.md file based on that information.
33 |
34 | Due to this reason, this tool was create mainly for a node based project as it will take the package.json by default.\
35 | If your project doesn't have a package.json, you can specify another json file.
36 |
37 | _NOTE_: To generate a complete `README.md`, make sure that the structure of your `package.json` (or you entry file) looks like this:
38 |
39 | ```js
40 | {
41 | "name": ...,
42 | "version": ...,
43 | "description": ...,
44 | "repository": {
45 | "url": ...
46 | },
47 | "author": {
48 | "name": ...,
49 | "email": ...,
50 | "url": ...
51 | },
52 | "contributors": [{
53 | "name": ...,
54 | "url": ...
55 | }],
56 | "engines": {
57 | ...
58 | },
59 | "dependencies": {
60 | ...
61 | }
62 | }
63 |
64 | ```
65 |
66 | _If no entry file is specified, and package.json is missing, the tool will prompt you for information instead._
67 |
68 | You can include a custom field for your social accounts simply adding a `readmeGenerator` param inside `package.json`, like in this following example:
69 |
70 | ```js
71 | {
72 | "name": ...,
73 | "version": ...,
74 | "description": ...,
75 | ...,
76 | ...,
77 | ...,
78 | "readmeGenerator": {
79 | "social": {
80 | "github": "http://github.com/...",
81 | "twitter": "http://twitter.com/...",
82 | "ADD MORE SOCIAL ACCOUNTS IF YOU WANT": "..."
83 | }
84 | }
85 | }
86 | ```
87 |
88 | This allows the tool to create a better `README.md` with more information.
89 |
90 | Here is a generated [README example](https://github.com/ibbatta/readme-generator/blob/master/EXAMPLE-README.md).
91 |
92 | ---
93 |
94 | ## **:wrench: Developer usage**
95 |
96 | ### **Set up project**
97 |
98 | Before cloning the repo **make sure** you have installed:
99 |
100 | - [**NODE**](https://www.google.com/search?q=how+to+install+node) (version >= 8.9.x)
101 | - [**YARN**](https://www.google.com/search?q=how+to+install+yarn) (version >= 1.9.x)
102 | - [**NPM**](https://www.google.com/search?q=how+to+install+npm) (version >= 6.3.x)
103 |
104 | Then:
105 |
106 | - Choose a folder project in your system and switch in `cd [folder path]`
107 | - Clone the repo in your folder: `git clone https://github.com/ibbatta/readme-generator.git`
108 |
109 | ---
110 |
111 | ### **Installation**
112 |
113 | First, enter the project folder and run `nvm use` to check you have the right node version, then run `yarn install` to install all the dependencies.
114 |
115 | ---
116 |
117 | #### Start the project
118 |
119 | To run the cli of the project locally:
120 |
121 | ```bash
122 | npm start
123 | # or
124 | yarn start
125 | ```
126 |
127 | #### Build the project for production
128 |
129 | This will create a folder `/lib` and compile the es6 / es7 js syntax:
130 |
131 | ```bash
132 | npm build
133 | #or
134 | yarn build
135 | ```
136 |
137 | You can add the `--watch` flag if you want to keep watching the changes made for test files.
138 |
139 | #### Run the tests
140 |
141 | ```bash
142 | npm test
143 | #or
144 | yarn test
145 | ```
146 |
147 | You can add the `--watch` flag if you to want keep watching the changes made for test files.
148 |
149 | ---
150 |
151 | ## **Editor setup**
152 |
153 | To keep the style of resources consistent, I decided to stick to some shared rules that have to be applied to every
154 | project using some editors plugins. Plese be sure to disable / remove any other js/jsx linters or custom configurations.
155 |
156 | ### Eslint
157 |
158 | I have chosen to use [Eslint](https://eslint.org/) to lint the Javascript / React [.js / .jsx] syntax.
159 | It includes a `.eslintrc` file in the root directory. Make sure your editor has the right plugins.
160 |
161 | ### Auto correction on save
162 |
163 | I have chosen to use [js-beautify](https://github.com/beautify-web/js-beautify/) as the beautifier for the HTML and CSS.
164 | It includes a `.jsbeautifyrc` file in the root directory. Make sure your editor has the right plugins.
165 |
166 | ### Basic Editor Configuration
167 |
168 | I have chosen to use [EditorConfig](https://editorconfig.org/) to share the basic configuration like indentation and
169 | charset.
170 | It includes a `.editorconfig` file in the root directory. Make sure your editor has the right plugins.
171 |
172 | ### Prettier
173 |
174 | I have chosen to use [Prettier](https://prettier.io/) to ensure the codebase has a consistent style.
175 | It includes a `.prettierrc` file in the root directory. Make sure your editor has the right plugin.
176 |
177 | ---
178 |
179 | ## **:handshake: Contributing**
180 |
181 | Contributions, issues and feature requests are welcome.
182 | Feel free to check the issues page if you want to contribute, and follow these simple steps:
183 |
184 | - Fork it!
185 | - Create your feature (or fix) branch: `git checkout -b my-new-feature`
186 | - Commit your changes: `git commit -am 'Add some feature'`
187 | - Push to the branch: `git push origin my-new-feature`
188 | - Submit a pull request!
189 |
190 | ---
191 |
192 | ### **:anger: Troubleshooting**
193 |
194 | This is just a personal project created for study / demonstration purposes and to simplify my working life, it may or may not be a good fit for your project!
195 |
196 | ---
197 |
198 | ### **:heart: Show your support**
199 |
200 | Please :star: this repository if you like it or this project helped you!\
201 | Feel free to open issues or submit pull-requests to help me improve my work.
202 |
203 |
204 |
205 |
206 |
207 | ---
208 |
209 | ### **:robot: Author**
210 |
211 | Maurizio Battaghini
212 |
213 | > GitHub [@ibbatta](https://github.com/ibbatta) ·
214 | > Twitter [@battago](https://twitter.com/battago)
215 |
216 | ---
217 |
218 | Copyright © 2019 [Maurizio Battaghini](https://github.com/ibbatta).\
219 | This project is covered by [MIT](https://github.com/ibbatta/readme-generator/blob/master/LICENSE) license.
220 |
--------------------------------------------------------------------------------
/changelog.tpl.hbs:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | {{#each releases}}
4 | {{#if href}}
5 | ## [{{title}}]({{href}}){{#if tag}} - {{isoDate}}{{/if}}
6 | {{else}}
7 | ## {{title}}{{#if tag}} - {{isoDate}}{{/if}}
8 | {{/if}}
9 |
10 | {{#if summary}}
11 | {{summary}}
12 | {{/if}}
13 |
14 | {{#if merges}}
15 | ### Merged
16 |
17 | {{#each merges}}
18 | - {{{message}}} {{#if href}}[`#{{id}}`]({{href}}){{/if}}
19 | {{/each}}
20 | {{/if}}
21 |
22 | {{#if fixes}}
23 | ### Fixed
24 |
25 | {{#each fixes}}
26 | - {{{commit.subject}}}{{#each fixes}} {{#if href}}[`#{{id}}`]({{href}}){{/if}}{{/each}}
27 | {{/each}}
28 | {{/if}}
29 |
30 | {{#commit-list commits heading='### Commits'}}
31 | - {{#if breaking}}**Breaking change:** {{/if}}{{{subject}}} {{#if href}}[`{{shorthash}}`]({{href}}){{/if}}
32 | {{/commit-list}}
33 |
34 | {{/each}}
35 |
--------------------------------------------------------------------------------
/jest.config.babel.js:
--------------------------------------------------------------------------------
1 | export default {
2 | bail: true,
3 | verbose: true,
4 | testMatch: ['./src/**/*.test.js']
5 | };
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@ibbatta/readme-generator",
3 | "version": "0.1.9",
4 | "description": "This project was born mainly to satisfy my desire for knowledge and to simplify my workflow. Being a curious (and also lazy) developer I have always wondered how avoid to waste my working time to write README.md files who fits perfectly project by project and that's why I wrote a tool to help me simplify and speed up these processes.",
5 | "main": "./src/index.js",
6 | "bin": {
7 | "readme-generator": "./dist/index.js"
8 | },
9 | "homepage": "https://github.com/ibbatta/readme-generator",
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/ibbatta/readme-generator.git"
13 | },
14 | "bugs": {
15 | "url": "https://github.com/ibbatta/readme-generator/issues",
16 | "email": "maurizio.battaghini+tech@gmail.com"
17 | },
18 | "author": "Maurizio Battaghini (https://twitter.com/battago)",
19 | "contributors": [
20 | "Maurizio Battaghini (http://github.com/ibbatta)"
21 | ],
22 | "keywords": [
23 | "readme",
24 | "readme-template",
25 | "readme-generator",
26 | "readme-md",
27 | "generator",
28 | "cli",
29 | "readme-standard",
30 | "readme-quality"
31 | ],
32 | "engines": {
33 | "node": ">= 10.16.x",
34 | "npm": ">= 6.9.x"
35 | },
36 | "license": "MIT",
37 | "private": false,
38 | "scripts": {
39 | "start": "clear && babel-node -- ./src/index.js",
40 | "build": "rm -rf ./dist && rollup --config ./rollup.config.babel.js --environment INCLUDE_DEPS,BUILD:production",
41 | "build:watch": "rm -rf ./dist && rollup --config ./rollup.config.babel.js --watch",
42 | "test": "lint-staged && jest",
43 | "test:watch": "jest --watch",
44 | "prepare": "npm run build",
45 | "changelog": "auto-changelog",
46 | "version": "auto-changelog -p && git add CHANGELOG.md"
47 | },
48 | "publishConfig": {
49 | "registry": "https://npm.pkg.github.com/"
50 | },
51 | "dependencies": {
52 | "boxen": "^4.2.0",
53 | "chalk": "^4.1.0",
54 | "commander": "^5.1.0",
55 | "figlet": "^1.4.0",
56 | "handlebars": "^4.7.6",
57 | "immer": ">=8.0.1",
58 | "inquirer": "^7.1.0",
59 | "js-yaml": "^3.14.0",
60 | "lodash": "^4.17.15"
61 | },
62 | "devDependencies": {
63 | "@babel/cli": "^7.10.1",
64 | "@babel/core": "^7.10.2",
65 | "@babel/node": "^7.10.1",
66 | "@babel/preset-env": "^7.10.2",
67 | "auto-changelog": "^2.0.0",
68 | "babel-eslint": "^10.1.0",
69 | "babel-jest": "^26.0.1",
70 | "babel-loader": "^8.1.0",
71 | "core-js": "^3.6.5",
72 | "eslint": "^7.2.0",
73 | "eslint-config-airbnb": "18.1.0",
74 | "eslint-plugin-import": "^2.21.2",
75 | "eslint-plugin-jest": "^23.13.2",
76 | "eslint-plugin-jsx-a11y": "^6.2.3",
77 | "husky": "^4.2.5",
78 | "jest": "^26.0.1",
79 | "lint-staged": "^10.2.10",
80 | "rollup": "^2.15.0",
81 | "rollup-plugin-babel": "^4.4.0",
82 | "rollup-plugin-copy-assets": "^2.0.1",
83 | "rollup-plugin-node-resolve": "^5.2.0",
84 | "rollup-plugin-terser": "^6.1.0"
85 | },
86 | "husky": {
87 | "hooks": {
88 | "pre-commit": "npm run test && auto-changelog && git add CHANGELOG.md",
89 | "commit-msg": "echo HUSKY_GIT_PARAMS"
90 | }
91 | },
92 | "lint-staged": {
93 | "*.js": [
94 | "eslint --fix",
95 | "git add"
96 | ]
97 | },
98 | "auto-changelog": {
99 | "output": "CHANGELOG.md",
100 | "template": "changelog.tpl.hbs",
101 | "unreleased": true,
102 | "commitLimit": 10,
103 | "includeBranch": [
104 | "master",
105 | "develop",
106 | "*"
107 | ]
108 | },
109 | "readmeGenerator": {
110 | "social": {
111 | "twitter": "https://twitter.com/battago",
112 | "github": "https://github.com/ibbatta"
113 | }
114 | },
115 | "directories": {
116 | "test": "test"
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/rollup.config.babel.js:
--------------------------------------------------------------------------------
1 | import resolve from 'rollup-plugin-node-resolve';
2 | import babel from 'rollup-plugin-babel';
3 | import copy from 'rollup-plugin-copy-assets';
4 | import { terser } from 'rollup-plugin-terser';
5 |
6 | const externalDependencies = Object.keys(
7 | require('./package.json').dependencies
8 | );
9 |
10 | export default {
11 | input: './src/index.js',
12 | output: {
13 | banner: '#!/usr/bin/env node',
14 | name: 'readme-generator',
15 | file: './dist/index.js',
16 | format: 'cjs',
17 | assetFileNames: 'src/readme'
18 | },
19 | plugins: [
20 | resolve({
21 | preferBuiltins: true,
22 | customResolveOptions: {
23 | moduleDirectory: 'node_modules'
24 | }
25 | }),
26 | babel({
27 | exclude: 'node_modules/**' // only transpile our source code
28 | }),
29 | copy({
30 | assets: ['./src/readme']
31 | }),
32 | terser()
33 | ],
34 | external: ['fs', 'path', externalDependencies],
35 | onwarn: warning => {
36 | if (warning.code === 'THIS_IS_UNDEFINED') return;
37 | }
38 | };
39 |
--------------------------------------------------------------------------------
/src/cli.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import produce from 'immer';
3 | const _ = require('lodash');
4 | const inquirer = require('inquirer');
5 |
6 | import {
7 | fileSettings,
8 | dataSettings,
9 | pathSettings,
10 | messageSettings
11 | } from './settings';
12 |
13 | import {
14 | dataUtils,
15 | fileUtils,
16 | questionUtils,
17 | hbsUtils,
18 | systemUtils
19 | } from './utilities';
20 |
21 | const partialDir = path.resolve(__dirname, pathSettings.readme.hbsPartials);
22 | const questionDir = path.resolve(__dirname, pathSettings.readme.questions);
23 |
24 | const readmeFile = `${fileSettings.readme.name}.${fileSettings.readme.ext}`;
25 | const supportFile = `${fileSettings.support.name}.${fileSettings.support.ext}`;
26 |
27 | const parseQuestions = async questionsPath => {
28 | const bulkQuestions = [];
29 | const extraQuestions = [];
30 | const { data } = await fileUtils.readDirectoryFiles(questionsPath);
31 | const formatters = await systemUtils.checkFormatters(fileSettings.formatters);
32 | const supports = await systemUtils.checkSupports(
33 | await fileUtils
34 | .checkExist(pathSettings.github)
35 | .then(() => path.join(pathSettings.github, supportFile))
36 | .catch(() => path.join(pathSettings.root, supportFile))
37 | );
38 |
39 | const hasFormatters = !_.isNil(formatters) && !_.isEmpty(formatters);
40 | const hasSupports = !_.isNil(supports) && !_.isEmpty(supports);
41 |
42 | data.files.forEach(file => {
43 | bulkQuestions.push(...require(path.join(data.directory, file)));
44 | });
45 |
46 | extraQuestions.push(
47 | hasFormatters &&
48 | questionUtils.injectQuestion(
49 | {
50 | name: 'formatters',
51 | type: 'checkbox',
52 | message: 'What kind of formatter / linter are you using?',
53 | choices: formatters,
54 | default: formatters
55 | },
56 | bulkQuestions
57 | ),
58 |
59 | hasSupports &&
60 | questionUtils.injectQuestion(
61 | {
62 | name: 'support',
63 | default: true
64 | },
65 | bulkQuestions
66 | ),
67 |
68 | hasSupports &&
69 | !_.isNil(supports.patreon) &&
70 | questionUtils.injectQuestion(
71 | {
72 | name: 'support.patreon',
73 | default: supports.patreon
74 | },
75 | bulkQuestions
76 | )
77 | );
78 |
79 | messageSettings.questionTitle('\nJust few questions');
80 | return inquirer.prompt(_.unionBy(bulkQuestions, ...extraQuestions, 'name'));
81 | };
82 |
83 | const parseData = packageData => {
84 | const packageDataParsed = produce(packageData, draftState => {
85 | const { author, contributors, readmeGenerator } = draftState;
86 | draftState.author = _.isString(author)
87 | ? dataUtils.convertInfoToObject(author)
88 | : author;
89 |
90 | if (!_.isNil(readmeGenerator) && !_.isNil(readmeGenerator.social)) {
91 | draftState.author.social = readmeGenerator.social;
92 | delete draftState.readmeGenerator;
93 | }
94 |
95 | if (!_.isNil(contributors)) {
96 | contributors.forEach((value, index) => {
97 | contributors[index] = _.isString(value)
98 | ? dataUtils.convertInfoToObject(value)
99 | : value;
100 | });
101 | }
102 | });
103 | return packageDataParsed;
104 | };
105 |
106 | const Run = async ({ entry, output, template, debug }) => {
107 | messageSettings.mainTitle('Readme\nGenerator');
108 |
109 | const buildTemplate = {};
110 |
111 | let entryFile = _.isNil(entry)
112 | ? fileSettings.package.path
113 | : path.resolve(pathSettings.root, entry);
114 | const outputFile = _.isNil(output) ? readmeFile : output;
115 | const templatePath = _.isNil(template)
116 | ? path.resolve(__dirname, fileSettings.template.path)
117 | : path.resolve(pathSettings.root, template);
118 | const showDebugLog = !_.isNil(debug);
119 |
120 | /** REGISTER ALL HANDLEBAR PARTIALS FOUND INSIDE THE FOLDER ./src/readme/templates/partials
121 | *
122 | */
123 | try {
124 | await systemUtils.registerHbsPartials(partialDir);
125 | } catch ({ error }) {
126 | throw new Error(messageSettings.genericError(error));
127 | }
128 |
129 | /** READ HANDLEBAR TEMPLATE FILE
130 | *
131 | */
132 |
133 | try {
134 | const { data } = await fileUtils.readFile(templatePath);
135 | buildTemplate.file = data.file;
136 | } catch ({ error }) {
137 | throw new Error(messageSettings.readFileError(templatePath, error));
138 | }
139 |
140 | let pickedData;
141 | try {
142 | await fileUtils.checkExist(entryFile);
143 | const { data } = await fileUtils.readFile(entryFile);
144 |
145 | pickedData = _.pick(
146 | JSON.parse(data.file),
147 | dataSettings.packageJsonFilterData
148 | );
149 | } catch (error) {
150 | messageSettings.questionTitle('\nMain questions');
151 | pickedData = await inquirer.prompt(dataSettings.fallbackQuestionData);
152 | }
153 |
154 | /** MERGE COLLECTED DATA FROM QUESTIONS AND PACKAGE.JSON
155 | * CREATE THE COLLECTION TO POPULATE HANDLEBAR TEMPLATE
156 | */
157 | try {
158 | buildTemplate.data = _.merge(
159 | {},
160 | parseData(pickedData),
161 | await parseQuestions(questionDir)
162 | );
163 | } catch ({ error }) {
164 | throw new Error(messageSettings.genericError(error));
165 | }
166 |
167 | /** PARSE AND GENERATE THE HANDLEBAR TEMPLATE
168 | * WRITE THE README.MD FILE
169 | */
170 | try {
171 | const { file, data } = buildTemplate;
172 | const outputPath = path.resolve(pathSettings.root, outputFile);
173 | const hbsGenerated = hbsUtils.generateHandlebar(file, data, showDebugLog);
174 | await fileUtils.writeFile(outputPath, hbsGenerated);
175 | messageSettings.writeFileSuccess(outputFile);
176 | } catch ({ error }) {
177 | throw new Error(messageSettings.writeFileError(outputFile, error));
178 | }
179 | };
180 |
181 | export default Run;
182 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | const program = require('commander');
2 | const { version } = require('../package.json');
3 |
4 | import Run from './cli';
5 |
6 | program
7 | .version(version)
8 | .name('readme-generator')
9 | .option('-E, --entry ', 'specify the entry file')
10 | .option('-O, --output ', 'specify the output file')
11 | .option('-T, --template ', 'specity a custom template')
12 | .option('-D, --debug', 'log output readme data');
13 |
14 | program.parse(process.argv);
15 |
16 | Run(program);
17 |
--------------------------------------------------------------------------------
/src/readme/questions/managers.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | {
3 | name: 'manager',
4 | type: 'list',
5 | message: 'What package manager are you using?',
6 | choices: ['npm', 'yarn'],
7 | default: 'npm'
8 | }
9 | ];
10 |
--------------------------------------------------------------------------------
/src/readme/questions/prompt.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | {
3 | name: 'commands.start',
4 | type: 'input',
5 | message: 'What is the command to run the project?',
6 | default: 'start'
7 | },
8 | {
9 | name: 'commands.test',
10 | type: 'input',
11 | message: 'What is the command to test the project?',
12 | default: 'test'
13 | }
14 | ];
15 |
--------------------------------------------------------------------------------
/src/readme/questions/purpose.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | {
3 | name: 'purpose',
4 | type: 'confirm',
5 | message: 'Is this project a demostration / study case?',
6 | default: false
7 | }
8 | ];
9 |
--------------------------------------------------------------------------------
/src/readme/questions/support.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | {
3 | name: 'support',
4 | type: 'confirm',
5 | message: 'Do you have a Patreon account?',
6 | default: false
7 | },
8 | {
9 | name: 'support.patreon',
10 | type: 'input',
11 | message: 'Insert your Patreon username',
12 | when: answer => {
13 | return answer.support;
14 | }
15 | }
16 | ];
17 |
--------------------------------------------------------------------------------
/src/readme/templates/README.hbs:
--------------------------------------------------------------------------------
1 | {{> title}}
2 |
3 | {{> badges}}
4 |
5 | {{> description}}
6 |
7 | ---
8 |
9 | {{> dependencies}}
10 |
11 | {{> dev-instructions}}
12 |
13 | {{> installation}}
14 |
15 | {{> commands}}
16 |
17 | {{> formatters}}
18 |
19 | {{> contributing}}
20 |
21 | {{> contributors}}
22 |
23 | {{> purpose}}
24 |
25 | {{> support}}
26 |
27 | {{> author}}
28 |
29 | {{> copyright}}
30 |
--------------------------------------------------------------------------------
/src/readme/templates/partials/author.hbs:
--------------------------------------------------------------------------------
1 | {{#if author.name}}
2 | ### **:robot: Author**
3 |
4 | _*{{author.name}}*_
5 |
6 | {{#if author.social}}
7 | > You can follow me on
8 | {{#each author.social~}}{{#unless @last}}[{{@key}}]({{{this}}}) · {{/unless}}{{#if @last}}[{{@key}}]({{{this}}}){{/if}}{{~/each}}
9 | {{/if}}
10 |
11 | ---
12 | {{/if}}
13 |
--------------------------------------------------------------------------------
/src/readme/templates/partials/badges.hbs:
--------------------------------------------------------------------------------
1 | {{#if engines}}
2 | {{#each engines}}
3 | 
4 | {{/each}}
5 | {{/if}}
6 |
--------------------------------------------------------------------------------
/src/readme/templates/partials/commands.hbs:
--------------------------------------------------------------------------------
1 | {{#if commands}}
2 | {{#each commands}}
3 | ### {{capitalize @key}} the project
4 |
5 | ```bash
6 | {{../manager}} {{this}}
7 | ```
8 |
9 | {{/each}}
10 | ---
11 | {{/if}}
12 |
--------------------------------------------------------------------------------
/src/readme/templates/partials/contributing.hbs:
--------------------------------------------------------------------------------
1 | ## **:handshake: Contributing**
2 |
3 | - Fork it!
4 | - Create your feature branch: `git checkout -b my-new-feature`
5 | - Commit your changes: `git commit -am 'Add some feature'`
6 | - Push to the branch: `git push origin my-new-feature`
7 | - Submit a pull request
8 |
9 | ---
10 |
--------------------------------------------------------------------------------
/src/readme/templates/partials/contributors.hbs:
--------------------------------------------------------------------------------
1 | {{#if contributors}}
2 | ### **:busts_in_silhouette: Credits**
3 |
4 | {{#each contributors}}
5 | - [{{name}}]({{{url}}})
6 | {{/each}}
7 |
8 | ---
9 | {{/if}}
10 |
--------------------------------------------------------------------------------
/src/readme/templates/partials/copyright.hbs:
--------------------------------------------------------------------------------
1 | Copyright © {{getYear}} {{#if author.url}}[{{author.name}}]({{author.url}}).{{else}}{{author.name}}{{/if}}
2 |
--------------------------------------------------------------------------------
/src/readme/templates/partials/dependencies.hbs:
--------------------------------------------------------------------------------
1 | {{#if dependencies}}
2 | ## **:package: Main tools used**
3 |
4 | {{#each dependencies}}
5 | - [x] {{@key}}
6 | {{/each}}
7 | {{#each frameworks}}
8 | - [x] {{this}}
9 | {{/each}}
10 |
11 | ---
12 | {{/if}}
13 |
--------------------------------------------------------------------------------
/src/readme/templates/partials/description.hbs:
--------------------------------------------------------------------------------
1 | {{#if description}}
2 | > {{{description}}}
3 | {{/if}}
4 |
--------------------------------------------------------------------------------
/src/readme/templates/partials/dev-instructions.hbs:
--------------------------------------------------------------------------------
1 | ## **:wrench: Developer usage**
2 |
3 | ### **Set up project**
4 |
5 | {{#if engines}}
6 | Before cloning the repo **be sure** you have installed:
7 |
8 | {{> engines}}
9 |
10 | Then:
11 |
12 | {{/if}}
13 | - Choose a folder project in your system and switch in `cd [folder path]`
14 | - Clone the repo in your folder path{{#if repository.url}} `git clone {{{repository.url}}}`{{/if}}
15 |
16 | ---
17 |
--------------------------------------------------------------------------------
/src/readme/templates/partials/engines.hbs:
--------------------------------------------------------------------------------
1 | {{#each engines}}
2 | - [**{{uppercase @key}}**](https://www.google.com/search?q=how+to+install+{{lowercase @key}}) (version {{{this}}})
3 | {{/each}}
4 |
--------------------------------------------------------------------------------
/src/readme/templates/partials/formatters.hbs:
--------------------------------------------------------------------------------
1 | {{#if formatters}}
2 | ### **Editor setup**
3 |
4 | To keep the style of resources consistent, I decided to stick to some shared rules that have to be applied to every
5 | project using some editors plugins. Plese be sure to disable / remove any other js/jsx linters or custom configurations.
6 |
7 | I have chosen to use
8 |
9 | {{#each formatters}}
10 | - [{{uppercase this}}](https://www.google.com/search?q={{lowercase this}})
11 | {{/each}}
12 |
13 | This
14 | works including a specific `.dotfile` in the root directory and making sure your editor has the necessary plugin.
15 |
16 | ---
17 | {{/if}}
18 |
--------------------------------------------------------------------------------
/src/readme/templates/partials/installation.hbs:
--------------------------------------------------------------------------------
1 | ### **Installation**
2 |
3 | In order to install the project and all dependencies, enter in the project folder and run `{{manager}} install`
4 |
5 | ---
6 |
--------------------------------------------------------------------------------
/src/readme/templates/partials/purpose.hbs:
--------------------------------------------------------------------------------
1 | {{#if purpose}}
2 | ### **:anger: Troubleshootings**
3 |
4 | This is just a personal project created for study / demonstration purpose and to simplify my working life, it may or may
5 | not be a good fit for your project(s).
6 |
7 | ---
8 | {{/if}}
9 |
--------------------------------------------------------------------------------
/src/readme/templates/partials/support.hbs:
--------------------------------------------------------------------------------
1 | ### **:heart: Show your support**
2 |
3 | Please :star: this repository if you like it or this project helped you!\
4 | Feel free to open issues or submit pull-requests to help me improving my work.
5 |
6 | {{#if support}}
7 |
8 |
9 |
10 | {{/if}}
11 |
12 | ---
13 |
--------------------------------------------------------------------------------
/src/readme/templates/partials/title.hbs:
--------------------------------------------------------------------------------
1 | # **:triangular_flag_on_post: {{uppercase name}}** (version {{version}})
2 |
--------------------------------------------------------------------------------
/src/settings/data.js:
--------------------------------------------------------------------------------
1 | const packageJsonFilterData = [
2 | 'name',
3 | 'version',
4 | 'description',
5 | 'repository',
6 | 'author',
7 | 'engines',
8 | 'dependencies',
9 | 'contributors',
10 | 'readmeGenerator'
11 | ];
12 |
13 | const fallbackQuestionData = [
14 | {
15 | name: 'name',
16 | type: 'input',
17 | message: 'What is the name of the project?',
18 | default: 'Amazing title'
19 | },
20 | {
21 | name: 'version',
22 | type: 'input',
23 | message: 'What is the version?',
24 | default: '0.1.0'
25 | },
26 | {
27 | name: 'description',
28 | type: 'input',
29 | message: 'Describe your project'
30 | },
31 | {
32 | name: 'repository.url',
33 | type: 'input',
34 | message: "Insert the url of your project's repository"
35 | },
36 | {
37 | name: 'author.name',
38 | type: 'input',
39 | message: 'Insert the author name'
40 | }
41 | ];
42 |
43 | export default {
44 | packageJsonFilterData,
45 | fallbackQuestionData
46 | };
47 |
--------------------------------------------------------------------------------
/src/settings/file.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import pathSettings from './path';
3 |
4 | const settings = {
5 | package: {
6 | name: 'package',
7 | ext: 'json'
8 | },
9 | template: {
10 | name: 'README',
11 | ext: 'hbs'
12 | },
13 | readme: {
14 | name: 'README',
15 | ext: 'md'
16 | },
17 | support: {
18 | name: 'FUNDING',
19 | ext: 'yml'
20 | },
21 | formatters: [
22 | { name: 'eslint', ext: 'rc' },
23 | { name: 'jsbeautify', ext: 'rc' },
24 | { name: 'editorconfig', ext: null },
25 | { name: 'prettier', ext: 'rc' }
26 | ]
27 | };
28 |
29 | settings.package.path = path.join(
30 | pathSettings.root,
31 | `${settings.package.name}.${settings.package.ext}`
32 | );
33 |
34 | settings.template.path = path.join(
35 | pathSettings.readme.templates,
36 | `${settings.template.name}.${settings.template.ext}`
37 | );
38 |
39 | settings.formatters.forEach((val, index) => {
40 | settings.formatters[index].path = path.join(
41 | pathSettings.root,
42 | `.${val.name}${val.ext ? val.ext : ''}`
43 | );
44 | });
45 |
46 | export default settings;
47 |
--------------------------------------------------------------------------------
/src/settings/index.js:
--------------------------------------------------------------------------------
1 | export { default as fileSettings } from './file';
2 | export { default as pathSettings } from './path';
3 | export { default as dataSettings } from './data';
4 | export { default as messageSettings } from './message';
5 |
--------------------------------------------------------------------------------
/src/settings/message.js:
--------------------------------------------------------------------------------
1 | const figlet = require('figlet');
2 | const chalk = require('chalk');
3 | const boxen = require('boxen');
4 |
5 | const { log, clear } = console;
6 |
7 | const mainTitle = (data) => {
8 | clear();
9 | log(chalk.magentaBright(figlet.textSync(data)));
10 | };
11 |
12 | const questionTitle = (data) => {
13 | log(chalk.yellow(data));
14 | };
15 |
16 | const debugMessage = (data) => {
17 | log(data);
18 | };
19 |
20 | const genericError = (error) => {
21 | log(chalk.red(error));
22 | };
23 |
24 | const readFileError = (data, error) => {
25 | log(
26 | chalk.red(`ERROR: The ${chalk.bold(data)} file is missing or not readable.`)
27 | );
28 | log(chalk.red(error));
29 | };
30 |
31 | const writeFileError = (data, error) => {
32 | log(chalk.red(`ERROR: Unable to generate the ${chalk.bold(data)} file.`));
33 | log(chalk.red(error));
34 | };
35 |
36 | const readFileSuccess = (data) => {
37 | log(chalk.green(`The ${data} file was successfully read`));
38 | };
39 |
40 | const writeFileSuccess = (data) => {
41 | log(
42 | chalk.green(
43 | boxen(
44 | `The ${chalk.bold.underline(data)} file is generated with success`,
45 | {
46 | padding: 1,
47 | margin: 1,
48 | borderStyle: 'classic',
49 | }
50 | )
51 | )
52 | );
53 | };
54 |
55 | export default {
56 | mainTitle,
57 | questionTitle,
58 | debugMessage,
59 | genericError,
60 | readFileError,
61 | writeFileError,
62 | readFileSuccess,
63 | writeFileSuccess,
64 | };
65 |
--------------------------------------------------------------------------------
/src/settings/path.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 |
3 | const basePath = {
4 | root: path.resolve(process.cwd()),
5 | github: path.resolve(process.cwd(), '.github'),
6 | readme: {
7 | questions: 'readme/questions',
8 | templates: 'readme/templates',
9 | hbsPartials: 'readme/templates/partials'
10 | }
11 | };
12 |
13 | export default basePath;
14 |
--------------------------------------------------------------------------------
/src/utilities/data.js:
--------------------------------------------------------------------------------
1 | const convertInfoToObject = data => {
2 | const infoData = {
3 | name: ''
4 | };
5 |
6 | data.split(' ').forEach(value => {
7 | if (value.includes('<' && '>')) {
8 | infoData.email = data.substring(
9 | data.lastIndexOf('<') + 1,
10 | data.lastIndexOf('>')
11 | );
12 | } else if (value.includes('(' && ')')) {
13 | infoData.url = data.substring(
14 | data.lastIndexOf('(') + 1,
15 | data.lastIndexOf(')')
16 | );
17 | } else {
18 | infoData.name = `${`${infoData.name} ${value}`}`.trim();
19 | }
20 | });
21 |
22 | return infoData;
23 | };
24 |
25 | export default {
26 | convertInfoToObject
27 | };
28 |
--------------------------------------------------------------------------------
/src/utilities/file.js:
--------------------------------------------------------------------------------
1 | import fs, { constants } from 'fs';
2 |
3 | const checkExist = target =>
4 | new Promise((resolve, reject) => {
5 | !target &&
6 | reject({
7 | success: false,
8 | error: new Error('Path must be specified')
9 | });
10 | fs.access(target, constants.F_OK | constants.W_OK, error => {
11 | error ? reject({ success: false, error }) : resolve({ success: true });
12 | });
13 | });
14 |
15 | const readDirectoryFiles = directory =>
16 | new Promise((resolve, reject) => {
17 | !directory &&
18 | reject({
19 | success: false,
20 | error: new Error('Directory must be specified')
21 | });
22 | fs.readdir(directory, (error, files) => {
23 | error
24 | ? reject({ success: false, error })
25 | : resolve({ success: true, data: { directory, files } });
26 | });
27 | });
28 |
29 | const readFile = file =>
30 | new Promise((resolve, reject) => {
31 | !file &&
32 | reject({
33 | success: false,
34 | error: new Error('File must be specified')
35 | });
36 | fs.readFile(file, 'utf8', (error, fileData) => {
37 | error
38 | ? reject({ success: false, error })
39 | : resolve({ success: true, data: { file: fileData } });
40 | });
41 | });
42 |
43 | const writeFile = (file, data) => {
44 | new Promise((resolve, reject) => {
45 | !file &&
46 | reject({
47 | success: false,
48 | error: new Error('File must be specified')
49 | });
50 |
51 | !data &&
52 | reject({
53 | success: false,
54 | error: new Error('Data must be specified')
55 | });
56 |
57 | fs.writeFile(file, data, error => {
58 | error
59 | ? reject({ success: false, error })
60 | : resolve({
61 | success: true,
62 | data: { file }
63 | });
64 | });
65 | });
66 | };
67 |
68 | export default {
69 | checkExist,
70 | readDirectoryFiles,
71 | readFile,
72 | writeFile
73 | };
74 |
--------------------------------------------------------------------------------
/src/utilities/handlebar.js:
--------------------------------------------------------------------------------
1 | const hbs = require('handlebars');
2 | const _ = require('lodash');
3 |
4 | import { messageSettings } from '../settings';
5 |
6 | hbs.registerHelper('removeAllSpaces', text => {
7 | return text.replace(/\s/g, '');
8 | });
9 |
10 | hbs.registerHelper('uppercase', text => {
11 | return text.toUpperCase();
12 | });
13 |
14 | hbs.registerHelper('lowercase', text => {
15 | return text.toLowerCase();
16 | });
17 |
18 | hbs.registerHelper('capitalize', text => {
19 | return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
20 | });
21 |
22 | hbs.registerHelper('getYear', () => {
23 | return new Date().getFullYear();
24 | });
25 |
26 | const registerPartial = (name, partialTemplate) => {
27 | if (!name) throw new Error('Template name must be specified');
28 | if (!partialTemplate) throw new Error('Partial data must be specified');
29 | hbs.registerPartial(name, partialTemplate);
30 | };
31 |
32 | const generateHandlebar = (wrapper, data, debug = false) => {
33 | for (let key of Object.keys(data)) {
34 | if (
35 | (_.isObject(data[key]) || _.isArray(data[key])) &&
36 | _.isEmpty(data[key])
37 | ) {
38 | data[key] = null;
39 | }
40 | }
41 | const template = hbs.compile(wrapper);
42 | debug && messageSettings.debugMessage(data);
43 | return template(data);
44 | };
45 |
46 | export default {
47 | registerPartial,
48 | generateHandlebar
49 | };
50 |
--------------------------------------------------------------------------------
/src/utilities/index.js:
--------------------------------------------------------------------------------
1 | export { default as dataUtils } from './data';
2 | export { default as fileUtils } from './file';
3 | export { default as hbsUtils } from './handlebar';
4 | export { default as questionUtils } from './question';
5 | export { default as systemUtils } from './system';
6 | export { default as yamlUtils } from './yaml';
7 |
--------------------------------------------------------------------------------
/src/utilities/question.js:
--------------------------------------------------------------------------------
1 | const _ = require('lodash');
2 |
3 | const injectQuestion = (question, bulkQuestions = []) => {
4 | let exist = false;
5 |
6 | if (_.isNil(question.name) || _.isEmpty(question.name))
7 | throw new Error('Question name must be specified');
8 |
9 | if (!_.isNil(bulkQuestions) && !_.isEmpty(bulkQuestions)) {
10 | bulkQuestions.map((existingQuestion, index) => {
11 | if (existingQuestion.name === question.name) {
12 | exist = true;
13 | bulkQuestions[index] = _.assign({}, existingQuestion, question);
14 | }
15 | });
16 | }
17 |
18 | return exist ? bulkQuestions : [_.merge({}, question)];
19 | };
20 |
21 | export default {
22 | injectQuestion
23 | };
24 |
--------------------------------------------------------------------------------
/src/utilities/system.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import fileUtils from './file';
3 | import hbsUtils from './handlebar';
4 | import yamlUtils from './yaml';
5 |
6 | const registerHbsPartials = async partialsPath => {
7 | const { data } = await fileUtils.readDirectoryFiles(partialsPath);
8 | await data.files.forEach(async file => {
9 | const partialName = file.split('.')[0];
10 | fileUtils.readFile(path.join(data.directory, file)).then(partialContent => {
11 | const { data } = partialContent;
12 | hbsUtils.registerPartial(partialName, data.file);
13 | });
14 | });
15 | };
16 |
17 | const checkFormatters = async fileArray => {
18 | const formatters = [];
19 | await Promise.all(
20 | fileArray.map(async file => {
21 | await fileUtils
22 | .checkExist(file.path)
23 | .then(({ success }) => {
24 | success && formatters.push(file.name);
25 | })
26 | .catch(() => null);
27 | })
28 | );
29 |
30 | return formatters;
31 | };
32 |
33 | const checkSupports = async supportFile => {
34 | const supports = await yamlUtils.parseData(
35 | await fileUtils
36 | .readFile(supportFile)
37 | .then(({ success, data }) => {
38 | return success && data.file;
39 | })
40 | .catch(() => null)
41 | );
42 | return supports;
43 | };
44 |
45 | export default {
46 | registerHbsPartials,
47 | checkFormatters,
48 | checkSupports
49 | };
50 |
--------------------------------------------------------------------------------
/src/utilities/yaml.js:
--------------------------------------------------------------------------------
1 | const yaml = require('js-yaml');
2 | const _ = require('lodash');
3 |
4 | const parseData = content => {
5 | return new Promise((resolve, reject) => {
6 | try {
7 | resolve(_.omitBy(yaml.safeLoad(content), _.isNil));
8 | } catch (error) {
9 | reject(error);
10 | }
11 | });
12 | };
13 |
14 | export default {
15 | parseData
16 | };
17 |
--------------------------------------------------------------------------------
/test/settings/data.test.js:
--------------------------------------------------------------------------------
1 | import dataSettings from '../../src/settings/data';
2 |
3 | const packagejsonFilterData = [
4 | 'name',
5 | 'version',
6 | 'description',
7 | 'repository',
8 | 'author',
9 | 'engines',
10 | 'dependencies',
11 | 'contributors'
12 | ];
13 |
14 | const fallbackQuestionData = [
15 | {
16 | name: 'name',
17 | type: 'input',
18 | message: 'What is the name of the project?',
19 | default: 'Amazing title'
20 | },
21 | {
22 | name: 'version',
23 | type: 'input',
24 | message: 'What is the version?',
25 | default: '0.1.0'
26 | },
27 | {
28 | name: 'description',
29 | type: 'input',
30 | message: 'Describe your project'
31 | },
32 | {
33 | name: 'repository.url',
34 | type: 'input',
35 | message: "Insert the url of your project's repository"
36 | },
37 | {
38 | name: 'author.name',
39 | type: 'input',
40 | message: 'Insert the author name'
41 | }
42 | ];
43 |
44 | test('check if packageJsonFilterData exists and is not empty', () => {
45 | expect(dataSettings.packageJsonFilterData).not.toBeNull();
46 | expect(dataSettings.packageJsonFilterData).not.toBeUndefined();
47 | expect(dataSettings.packageJsonFilterData.length).toBeGreaterThan(0);
48 | });
49 |
50 | test('check if packageJsonFilterData contain all right values', () => {
51 | expect(dataSettings.packageJsonFilterData).toEqual(
52 | expect.arrayContaining(packagejsonFilterData)
53 | );
54 | });
55 |
56 | test('check if fallbackQuestionData exists and is not empty', () => {
57 | expect(dataSettings.fallbackQuestionData).not.toBeNull();
58 | expect(dataSettings.fallbackQuestionData).not.toBeUndefined();
59 | expect(dataSettings.fallbackQuestionData.length).toBeGreaterThan(0);
60 | });
61 |
62 | test('check if fallbackQuestionData contain all right values', () => {
63 | expect(dataSettings.fallbackQuestionData).toEqual(
64 | expect.arrayContaining(fallbackQuestionData)
65 | );
66 | });
67 |
--------------------------------------------------------------------------------
/test/settings/file.test.js:
--------------------------------------------------------------------------------
1 | import fileSettings from '../../src/settings/file';
2 |
3 | test('check if fileSettings exists and is not empty', () => {
4 | expect(fileSettings).not.toBeNull();
5 | expect(fileSettings).not.toBeUndefined();
6 | expect(Object.keys(fileSettings).length).toBeGreaterThan(0);
7 | });
8 |
9 | test('check if fileSettings has the right properties', () => {
10 | expect(fileSettings).toMatchObject({
11 | package: {
12 | name: 'package',
13 | ext: 'json'
14 | },
15 | template: {
16 | name: 'README',
17 | ext: 'hbs'
18 | },
19 | readme: {
20 | name: 'README',
21 | ext: 'md'
22 | },
23 | support: {
24 | name: 'FUNDING',
25 | ext: 'yml'
26 | },
27 | formatters: [
28 | { name: 'eslint', ext: 'rc' },
29 | { name: 'jsbeautify', ext: 'rc' },
30 | { name: 'editorconfig', ext: null },
31 | { name: 'prettier', ext: 'rc' }
32 | ]
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/test/settings/message.test.js:
--------------------------------------------------------------------------------
1 | import messageSettings from '../../src/settings/message';
2 |
3 | test('check if messageSettings exists and is not empty', () => {
4 | expect(messageSettings).not.toBeNull();
5 | expect(messageSettings).not.toBeUndefined();
6 | expect(Object.keys(messageSettings).length).toBeGreaterThan(0);
7 | });
8 |
--------------------------------------------------------------------------------
/test/settings/path.test.js:
--------------------------------------------------------------------------------
1 | import pathSettings from '../../src/settings/path';
2 | import path from 'path';
3 |
4 | test('check if pathSettings exists and is not empty', () => {
5 | expect(pathSettings).not.toBeNull();
6 | expect(pathSettings).not.toBeUndefined();
7 | expect(Object.keys(pathSettings).length).toBeGreaterThan(0);
8 | });
9 |
10 | test('check if pathSettings has the right properties', () => {
11 | expect(pathSettings).toMatchObject({
12 | root: process.cwd(),
13 | github: path.resolve(process.cwd(), '.github'),
14 | readme: {
15 | questions: 'readme/questions',
16 | templates: 'readme/templates',
17 | hbsPartials: 'readme/templates/partials'
18 | }
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/test/utilities/file.test.js:
--------------------------------------------------------------------------------
1 | import fileUtils from '../../src/utilities/file';
2 |
3 | test('check if fileUtils exists and is not empty', () => {
4 | expect(fileUtils).not.toBeNull();
5 | expect(fileUtils).not.toBeUndefined();
6 | expect(Object.keys(fileUtils).length).toBeGreaterThan(0);
7 | });
8 |
9 | // EXIST FILE TEST
10 | test('check if a file exist correctly', async () => {
11 | expect.assertions(1);
12 | const res = await fileUtils.checkExist('package.json');
13 | expect(res.success).toBe(true);
14 | });
15 |
16 | test('check if empty path throw error', async () => {
17 | expect.assertions(1);
18 | try {
19 | await fileUtils.checkExist();
20 | } catch ({ error }) {
21 | expect(error).toEqual(new Error('Path must be specified'));
22 | }
23 | });
24 |
25 | test('check if throw error with non-existing file', async () => {
26 | expect.assertions(1);
27 | try {
28 | await fileUtils.checkExist('test.json');
29 | } catch ({ success }) {
30 | expect(success).toBe(false);
31 | }
32 | });
33 |
34 | // READ DIRECTORY TEST
35 | test('check if get data from existing directory', async () => {
36 | expect.assertions(4);
37 | const res = await fileUtils.readDirectoryFiles('src/');
38 | expect(res.success).toBe(true);
39 | expect(res.data).not.toBeNull();
40 | expect(res.data).not.toBeUndefined();
41 | expect(Object.keys(res.data).length).toBeGreaterThan(0);
42 | });
43 |
44 | test('check if empty directory path throw error', async () => {
45 | expect.assertions(1);
46 | try {
47 | await fileUtils.readDirectoryFiles();
48 | } catch ({ error }) {
49 | expect(error).toEqual(new Error('Directory must be specified'));
50 | }
51 | });
52 |
53 | test('check if a non existing folder throw error', async () => {
54 | expect.assertions(1);
55 | try {
56 | await fileUtils.checkExist('fake/');
57 | } catch ({ success }) {
58 | expect(success).toBe(false);
59 | }
60 | });
61 |
62 | // READ FILE TEST
63 | test('check if can read data from existing file', async () => {
64 | expect.assertions(4);
65 | const res = await fileUtils.readFile('package.json');
66 | expect(res.success).toBe(true);
67 | expect(res.data).not.toBeNull();
68 | expect(res.data).not.toBeUndefined();
69 | expect(Object.keys(res.data).length).toBeGreaterThan(0);
70 | });
71 |
72 | test('check if empty file path throw error', async () => {
73 | expect.assertions(1);
74 | try {
75 | await fileUtils.readFile();
76 | } catch ({ error }) {
77 | expect(error).toEqual(new Error('File must be specified'));
78 | }
79 | });
80 |
81 | test('check if cannot read data from non existing file', async () => {
82 | expect.assertions(1);
83 | try {
84 | await fileUtils.readFile('test.json');
85 | } catch ({ success }) {
86 | expect(success).toBe(false);
87 | }
88 | });
89 |
--------------------------------------------------------------------------------
/test/utilities/handlebar.test.js:
--------------------------------------------------------------------------------
1 | import hbsUtils from '../../src/utilities/handlebar';
2 |
3 | test('check if fileUtils exists and is not empty', () => {
4 | expect(hbsUtils).not.toBeNull();
5 | expect(hbsUtils).not.toBeUndefined();
6 | expect(Object.keys(hbsUtils).length).toBeGreaterThan(0);
7 | });
8 |
9 | test('should throw error if if try to register partial with missing name', async () => {
10 | expect.assertions(1);
11 | try {
12 | await hbsUtils.registerPartial();
13 | } catch (error) {
14 | expect(error).toEqual(new Error('Template name must be specified'));
15 | }
16 | });
17 |
18 | test('should throw error if try to register partial with missing template', async () => {
19 | expect.assertions(1);
20 | try {
21 | await hbsUtils.registerPartial(
22 | './src/readme/templates/partials/title.hbs'
23 | );
24 | } catch (error) {
25 | expect(error).toEqual(new Error('Partial data must be specified'));
26 | }
27 | });
28 |
29 | test('check if parse a handlebar template correctly', () => {
30 | const name = 'Maurizio';
31 | const data = hbsUtils.generateHandlebar('{{name}}', { name });
32 | expect(data).toEqual(name);
33 | });
34 |
--------------------------------------------------------------------------------
/test/utilities/question.test.js:
--------------------------------------------------------------------------------
1 | import questionUtils from '../../src/utilities/question';
2 |
3 | test('check if fileUtils exists and is not empty', () => {
4 | expect(questionUtils).not.toBeNull();
5 | expect(questionUtils).not.toBeUndefined();
6 | expect(Object.keys(questionUtils).length).toBeGreaterThan(0);
7 | });
8 |
9 | test('throw error if question name is missing', () => {
10 | const updateQuestion = {
11 | message: 'Test message'
12 | };
13 | try {
14 | questionUtils.injectQuestion(updateQuestion);
15 | } catch (error) {
16 | expect(error).toEqual(new Error('Question name must be specified'));
17 | }
18 | });
19 |
20 | test("check if update correctly the question's bulk", () => {
21 | const bulk = [
22 | {
23 | name: 'commands.start',
24 | type: 'input',
25 | message: 'What is the command to run the project?',
26 | default: 'start'
27 | }
28 | ];
29 |
30 | const updateQuestion = {
31 | name: 'commands.start',
32 | message: 'Test message'
33 | };
34 |
35 | const data = questionUtils.injectQuestion(updateQuestion, bulk);
36 | expect(data[0]).toEqual({
37 | name: 'commands.start',
38 | type: 'input',
39 | message: 'Test message',
40 | default: 'start'
41 | });
42 | });
43 |
44 | test("check if create correctly the question's bulk", () => {
45 | const createQuestion = {
46 | name: 'commands.start',
47 | type: 'input',
48 | message: 'What is the command to run the project?',
49 | default: 'start'
50 | };
51 |
52 | const data = questionUtils.injectQuestion(createQuestion);
53 | expect(data[0]).toEqual(createQuestion);
54 | });
55 |
--------------------------------------------------------------------------------
/test/utilities/ststem.test.js:
--------------------------------------------------------------------------------
1 | import systemUtils from '../../src/utilities/system';
2 |
3 | test('check if fileUtils exists and is not empty', () => {
4 | expect(systemUtils).not.toBeNull();
5 | expect(systemUtils).not.toBeUndefined();
6 | expect(Object.keys(systemUtils).length).toBeGreaterThan(0);
7 | });
8 |
--------------------------------------------------------------------------------
/test/utilities/yaml.test.js:
--------------------------------------------------------------------------------
1 | import ymlUtils from '../../src/utilities/yaml';
2 |
3 | test('check if fileUtils exists and is not empty', () => {
4 | expect(ymlUtils).not.toBeNull();
5 | expect(ymlUtils).not.toBeUndefined();
6 | expect(Object.keys(ymlUtils).length).toBeGreaterThan(0);
7 | });
8 |
--------------------------------------------------------------------------------