├── .circleci └── config.yml ├── .eslintrc.js ├── .github ├── CODE_OF_CONDUCT.md ├── ISSUE_TEMPLATE.md ├── ISSUE_TEMPLATE │ ├── BUG_REPORT.md │ └── FEATURE_REQUEST.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .npmignore ├── .npmrc ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── __tests__ ├── fixtures │ └── filesReplacement │ │ ├── README.md │ │ └── README_EXPECTED.md ├── index.test.js └── integration_result │ └── m.txt ├── babel.config.js ├── bin └── tosin.js ├── docs ├── .vuepress │ ├── config.js │ └── override.styl ├── Guide.md └── README.md ├── jest.config.js ├── lib ├── tosin.cjs.js └── tosin.es.js ├── package.json ├── rollup.config.js ├── scripts └── deploy_docs.sh └── src └── index.js /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Javascript Node CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-javascript/ for more details 4 | # 5 | version: 2 6 | jobs: 7 | build: 8 | docker: 9 | - image: circleci/node:8.9.1 10 | 11 | steps: 12 | - checkout 13 | 14 | # Download and cache dependencies 15 | - restore_cache: 16 | keys: 17 | - v1-dependencies-{{ checksum "package.json" }} 18 | # fallback to using the latest cache if no exact match is found 19 | - v1-dependencies- 20 | 21 | - run: 22 | name: install 23 | command: npm install 24 | 25 | - save_cache: 26 | paths: 27 | - node_modules 28 | key: v1-dependencies-{{ checksum "package.json" }} 29 | 30 | - run: 31 | name: lint 32 | command: npm run lint 33 | 34 | - run: 35 | name: test 36 | command: npm run test -- --coverage 37 | 38 | - run: 39 | name: coverage 40 | command: | 41 | if [ "${CIRCLE_BRANCH}" == "master" ]; then 42 | cat ./coverage/lcov.info | node_modules/.bin/codacy-coverage -p . 43 | fi -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "browser": true, 4 | "node": true, 5 | "es6": true, 6 | "jest": true 7 | }, 8 | "extends": "eslint:recommended", 9 | "globals": { 10 | "Atomics": "readonly", 11 | "SharedArrayBuffer": "readonly" 12 | }, 13 | "parserOptions": { 14 | "ecmaVersion": 2018, 15 | "sourceType": "module" 16 | }, 17 | "rules": {} 18 | }; -------------------------------------------------------------------------------- /.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 contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at florielfedry@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Before you open an issue, please check if a similar issue already exists or has been closed before. 2 | 3 | ### When reporting a bug, please be sure to include the following: 4 | - [ ] A descriptive title 5 | - [ ] An *isolated* way to reproduce the behavior (example: GitHub repository with code isolated to the issue that anyone can clone to observe the problem) 6 | - [ ] What version you are using, and the platform(s) you're running it on 7 | - [ ] The behavior you expect to see, and the actual behavior 8 | 9 | ### When you open an issue for a feature request, please add as much detail as possible: 10 | - [ ] A descriptive title 11 | - [ ] A description of the problem you're trying to solve, including *why* you think this is a problem 12 | - [ ] An overview of the suggested solution 13 | - [ ] If the feature changes current behavior, reasons why your solution is better 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/BUG_REPORT.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | Before you open an issue, please check if a similar issue already exists or has been closed before. 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 | 1. Go to '...' 15 | 2. Click on '....' 16 | 3. Scroll down to '....' 17 | 4. See error 18 | 19 | **Expected behavior** 20 | A clear and concise description of what you expected to happen. 21 | 22 | **Screenshots** 23 | If applicable, add screenshots to help explain your problem. 24 | 25 | **Desktop (please complete the following information):** 26 | - OS: [e.g. Windows] 27 | - Version of Tosin [e.g. 1.4.2] 28 | 29 | **Additional context** 30 | Add any other context about the problem here. 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Proposed changes 2 | 3 | Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. If it fixes a bug or resolves a feature request, be sure to link to that issue. 4 | 5 | ## Types of changes 6 | 7 | What types of changes does your code introduce to Tosin? 8 | _Put an `x` in the boxes that apply_ 9 | 10 | - [ ] Bugfix (non-breaking change which fixes an issue) 11 | - [ ] New feature (non-breaking change which adds functionality) 12 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) 13 | 14 | ## Checklist 15 | 16 | _Put an `x` in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code._ 17 | 18 | - [ ] Lint and unit tests pass locally with my changes 19 | - [ ] I have added tests that prove my fix is effective or that my feature works 20 | - [ ] I have added necessary documentation (if appropriate) 21 | 22 | ## Further comments 23 | 24 | If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did and what alternatives you considered, etc... 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __tests__/fixtures/filesReplacement/test.md 2 | __tests__/integration_result/ 3 | 4 | # Logs 5 | logs 6 | *.log 7 | npm-debug.log* 8 | yarn-debug.log* 9 | yarn-error.log* 10 | 11 | # Runtime data 12 | pids 13 | *.pid 14 | *.seed 15 | *.pid.lock 16 | 17 | # Directory for instrumented libs generated by jscoverage/JSCover 18 | lib-cov 19 | 20 | # Coverage directory used by tools like istanbul 21 | coverage 22 | 23 | # nyc test coverage 24 | .nyc_output 25 | 26 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 27 | .grunt 28 | 29 | # Bower dependency directory (https://bower.io/) 30 | bower_components 31 | 32 | # node-waf configuration 33 | .lock-wscript 34 | 35 | # Compiled binary addons (https://nodejs.org/api/addons.html) 36 | build/Release 37 | 38 | # Dependency directories 39 | node_modules/ 40 | jspm_packages/ 41 | 42 | # TypeScript v1 declaration files 43 | typings/ 44 | 45 | # Optional npm cache directory 46 | .npm 47 | 48 | # Optional eslint cache 49 | .eslintcache 50 | 51 | # Optional REPL history 52 | .node_repl_history 53 | 54 | # Output of 'npm pack' 55 | *.tgz 56 | 57 | # Yarn Integrity file 58 | .yarn-integrity 59 | 60 | # dotenv environment variables file 61 | .env 62 | 63 | # next.js build output 64 | .next 65 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .circleci/ 2 | .travis.yml -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "10" -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | # v1.0.0 - YYYY-MM-DD 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | ## [Code of Conduct](./.github/CODE_OF_CONDUCT.md) 3 | 4 | Please read the text so that you understand how to conduct while contributing to this project. 5 | 6 | ## Semantic Versioning 7 | 8 | tosin use [SemVer](http://semver.org/) for versioning. 9 | 10 | ## Documentation 11 | 12 | The content of the documentation is in the docs repository. 13 | 14 | ## Sending a Pull Request 15 | 16 | **Before submitting a pull request,** please make sure the following is done: 17 | 18 | 1. Fork [the repository](https://github.com/FullHuman/tosin) and create your branch from `master`. 19 | 2. If you've added code that should be tested, add tests! 20 | 3. If you've changed APIs, update the documentation. 21 | 4. Ensure the test suite passes (`npm test`). 22 | 5. Format your code with [prettier](https://github.com/prettier/prettier) (`npm run prettier`). 23 | 6. Make sure your code lints (`npm run lint`). 24 | 25 | ### Development Workflow 26 | 27 | After cloning tosin, run `npm i` to fetch its dependencies. 28 | Then, you can run several commands: 29 | 30 | - `npm run dev` will build cjs and es module of tosin in the `lib` folder and watch for changes. 31 | - `npm run lint` checks the code style. 32 | - `npm test` runs the complete test suite. 33 | - `npm test -- --watch` runs an interactive test watcher. 34 | - `npm test ` runs tests with matching filenames. 35 | - `npm run build` creates the cjs and es module of tosin in the `lib` folder. 36 | 37 | Make sure that your pull request contains unit tests for any new functionality. This way we can ensure that we don't break your code in the future. 38 | 39 | ### License 40 | 41 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. 42 | 43 | ### Acknowledgement 44 | 45 | This CONTRIBUTING.md is based on the [react](https://github.com/facebook/react) [how-to-contribute.md](https://github.com/facebook/react/blob/master/docs/contributing/how-to-contribute.md) file. 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Floriel Fedry 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 | # Tosin 2 | 3 | [![Build Status](https://travis-ci.org/FullHuman/tosin.svg?branch=master)]() 4 | [![CircleCi](https://circleci.com/gh/FullHuman/tosin/tree/master.svg?style=shield)]() 5 | [![dependencies Status](https://david-dm.org/fullhuman/tosin/status.svg)](https://david-dm.org/fullhuman/tosin) 6 | [![devDependencies Status](https://david-dm.org/fullhuman/tosin/dev-status.svg)](https://david-dm.org/fullhuman/tosin?type=dev) 7 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/37bbf49b16c04764bfc26fb41a47aaed)](https://www.codacy.com/app/florielfedry/tosin?utm_source=github.com&utm_medium=referral&utm_content=FullHuman/tosin&utm_campaign=Badge_Grade) 8 | [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/37bbf49b16c04764bfc26fb41a47aaed)](https://www.codacy.com/app/florielfedry/tosin?utm_source=github.com&utm_medium=referral&utm_content=FullHuman/tosin&utm_campaign=Badge_Coverage) 9 | [![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier) 10 | [![npm](https://img.shields.io/npm/v/tosin.svg)](https://www.npmjs.com/package/tosin) 11 | [![license](https://img.shields.io/github/license/fullhuman/tosin.svg)]() 12 | [![dependabot](https://img.shields.io/badge/dependabot-enabled-brightgreen.svg?style=plastic&logo=dependabot)]() 13 | 14 |

15 | Tosin logo 16 |

17 | 18 | ## What is Tosin? 19 | 20 | Tosin is an opinionated way to start the creation of an npm package. It comes with everything included, from CI to a documentation website. Below is a list of its features. 21 | 22 | ### Continuous Integration 23 | 24 | Continuous integration is useful to keep an eye of the status of your repository. Do your branch build and pass all of the tests? 25 | You can do all of that manually of course but with external contributors and pull requests, you want a way to automate the process. 26 | 27 | Tosin comes with a simple configuration for circleci and one for Travis-ci. 28 | - CircleCi will build the package with npm install, lint to make sure there is no code that is error-prone, and run the test. Take a look at the `Next Steps` section on how to add code coverage on the master branch. 29 | - Travis configuration will only test your package with another version of Nodejs. You can see it as a backup in case CircleCI as a problem preventing it from building your package. You can also easily understand if your build failed the test by looking at the Travis status. Since CircleCI is doing more, it can fail even though your tests pass with success. 30 | 31 | You want to replace all of that with GitHub Actions? Take a look at the section `GitHub Actions` below. 32 | 33 | ### Linter + Prettier 34 | 35 | [Eslint](https://eslint.org/) is used for linting. 36 | > ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, with the goal of making code more consistent and avoiding bugs. 37 | 38 | [Prettier](https://prettier.io/) is used to format the code. 39 | > Prettier is an opinionated code formatter. It enforces a consistent style by parsing your code and re-printing it with its own rules that take the maximum line length into account, wrapping code when necessary. 40 | 41 | ### Testing Framework Jest 42 | 43 | Jest is one of the most popular testing framework for Javascript. Contrary to other testing framework, Jest includes assertions library and mocking inside its framework. 44 | > Jest is a JavaScript testing framework designed to ensure correctness of any JavaScript codebase. It allows you to write tests with an approachable, familiar and feature-rich API that gives you results quickly. 45 | 46 | ### GitHub files for the community 47 | 48 | Be prepared to receive help and issues from the community. A standard Pull Request template is included as well as three issue template: 49 | - A bug report template 50 | - A feature request template 51 | - A standard issue template for everything else 52 | 53 | A [code of conduct](https://www.contributor-covenant.org/) is present to make sure everyone feels welcome to contribute. 54 | 55 | ### Build system with Rollup 56 | 57 | [Rollup](https://rollupjs.org/guide/en/) is used to compile your code. You can use ES modules and compile your code in es and commonjs format. 58 | 59 | > Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application. It uses the new standardized format for code modules included in the ES6 revision of JavaScript, instead of previous idiosyncratic solutions such as CommonJS and AMD. ES modules let you freely and seamlessly combine the most useful individual functions from your favorite libraries. This will eventually be possible natively everywhere, but Rollup lets you do it today. 60 | 61 | ### Ready for autocompletion 62 | 63 | Do you want to provide autocompletion when someone installed your package? If you do, the `types/index.d.ts` is ready to be completed. 64 | It is set in `package.json` as the file containing your types. Most of the IDE and code editor will use this file to provide auto-completion. 65 | It is a great way to improve developer experience. 66 | 67 | ### Documentation website ready to be deployed 68 | 69 | GitHub offers the possibility of hosting a website per repository since a long time now. You can take advantage of that to create a documentation website for your package and hosting it directly on GitHub. 70 | 71 | Tosin comes with [vuepress](https://vuepress.vuejs.org/) and a script to deploy the website to GitHub Pages. The script will deploy the files to the gh-pages branch of your repository. 72 | 73 | ## Getting Started 74 | 75 | Use it the same way you would use `npm init`: 76 | 77 | ``` 78 | npx tosin init 79 | ``` 80 | 81 | Once done, take a look at the documentation to do the [next steps](https://fullhuman.github.io/tosin/Guide.html#next-steps). 82 | 83 | ## Contributing 84 | 85 | Please read [CONTRIBUTING.md](./CONTRIBUTING.md) for details on our code of 86 | conduct, and the process for submitting pull requests to us. 87 | 88 | ## Versioning 89 | 90 | Tosin use [SemVer](http://semver.org/) for versioning. 91 | 92 | ## License 93 | 94 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file 95 | for details. 96 | -------------------------------------------------------------------------------- /__tests__/fixtures/filesReplacement/README.md: -------------------------------------------------------------------------------- 1 | # This file contains every values to be replace by the cli 2 | 3 | - Project Name = {% project name %} 4 | - Human Project Name = {% human project name %} 5 | - Developer Name = {% developer name %} 6 | - Email = {% email %} 7 | - Repository = {% repository %} 8 | - Lowercase Repository = {% lowercase repository %} 9 | 10 | - Project Name = {% project name %} 11 | - Human Project Name = {% human project name %} 12 | - Developer Name = {% developer name %} 13 | - Email = {% email %} 14 | - Repository = {% repository %} 15 | - Lowercase Repository = {% lowercase repository %} -------------------------------------------------------------------------------- /__tests__/fixtures/filesReplacement/README_EXPECTED.md: -------------------------------------------------------------------------------- 1 | # This file contains every values to be replace by the cli 2 | 3 | - Project Name = tosin-cli 4 | - Human Project Name = Awesome Tosin 5 | - Developer Name = Floriel Fedry 6 | - Email = truc@gmail.com 7 | - Repository = FullHuman/tosin 8 | - Lowercase Repository = fullhuman/tosin 9 | 10 | - Project Name = tosin-cli 11 | - Human Project Name = Awesome Tosin 12 | - Developer Name = Floriel Fedry 13 | - Email = truc@gmail.com 14 | - Repository = FullHuman/tosin 15 | - Lowercase Repository = fullhuman/tosin -------------------------------------------------------------------------------- /__tests__/index.test.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs' 2 | import { promisify } from 'util' 3 | import { init, replaceInFile } from './../src/index' 4 | import enquirer from 'enquirer' 5 | 6 | jest.mock('enquirer', () => { 7 | return { 8 | prompt: jest.fn().mockImplementation(() => { 9 | return { 10 | humanProject: 'Awesome Tosin', 11 | projectName: 'tosin', 12 | repository: 'FullHuman/tosin', 13 | developerName: 'Floriel Fedry', 14 | email: 'truc@gmail.com' 15 | } 16 | }) 17 | } 18 | }) 19 | 20 | const readFile = promisify(fs.readFile) 21 | const writeFile = promisify(fs.writeFile) 22 | 23 | describe('test the library', () => { 24 | 25 | const replaceSets = [ 26 | ['{% project name %}', 'tosin-cli'], 27 | ['{% human project name %}', 'Awesome Tosin'], 28 | ['{% developer name %}', 'Floriel Fedry'], 29 | ['{% email %}', 'truc@gmail.com'], 30 | ['{% repository %}', 'FullHuman/tosin'], 31 | ['{% lowercase repository %}', 'fullhuman/tosin'] 32 | ] 33 | 34 | it('replace the text with the values', async () => { 35 | const testFilePath = '__tests__/fixtures/filesReplacement/test.md' 36 | 37 | const fileReadme = await readFile('__tests__/fixtures/filesReplacement/README.md', 'utf-8') 38 | await writeFile(testFilePath, fileReadme, 'utf-8') 39 | 40 | const fileReadmeExpected = await readFile('__tests__/fixtures/filesReplacement/README_EXPECTED.md', 'utf-8') 41 | await replaceInFile(testFilePath, replaceSets) 42 | const actualFile = await readFile(testFilePath, 'utf-8') 43 | 44 | expect(actualFile).toBe(fileReadmeExpected) 45 | }) 46 | 47 | it('initialize a project with tosin successfully', async () => { 48 | enquirer.prompt = jest.fn().mockImplementation(() => { 49 | return { 50 | humanProjectName: 'Awesome Tosin', 51 | projectName: 'tosin', 52 | repository: 'FullHuman/tosin', 53 | developerName: 'Floriel Fedry', 54 | email: 'truc@gmail.com' 55 | } 56 | }) 57 | 58 | // change the directory 59 | process.chdir('__tests__/integration_result/') 60 | 61 | await init() 62 | // check if Readme file exists and does not contain template variable 63 | const readme = await readFile('README.md', 'utf-8') 64 | expect(readme.includes('{%')).toBe(false) 65 | expect(readme.includes('%}')).toBe(false) 66 | expect(readme.includes('Awesome Tosin')).toBe(true) 67 | }) 68 | }) -------------------------------------------------------------------------------- /__tests__/integration_result/m.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FullHuman/tosin/c5bf292b6913c7cb2552746b5bd1073522b0e421/__tests__/integration_result/m.txt -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/preset-env', 5 | { 6 | targets: { 7 | node: 'current' 8 | } 9 | } 10 | ] 11 | ] 12 | }; -------------------------------------------------------------------------------- /bin/tosin.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { init } = require("../lib/tosin.cjs"); 4 | 5 | const program = require('commander'); 6 | 7 | program 8 | .version('1.0.0') 9 | .command('init') 10 | .action(() => { 11 | init() 12 | .then(() => process.exit(0)) 13 | .catch((e) => { 14 | console.log(e) 15 | process.exit(1) 16 | }) 17 | }) 18 | 19 | program.parse(process.argv); 20 | 21 | -------------------------------------------------------------------------------- /docs/.vuepress/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: 'Tosin', 3 | description: 'Initialize a npm package with everything included, from CI to documentation website', 4 | base: '/tosin/', 5 | themeConfig: { 6 | nav: [ 7 | { text: 'Home', link: '/' }, 8 | { text: 'Guide', link: '/Guide.md'}, 9 | ], 10 | sidebar: 'auto', 11 | // Assumes GitHub. Can also be a full GitLab url. 12 | repo: 'FullHuman/tosin', 13 | // if your docs are not at the root of the repo: 14 | docsDir: 'docs', 15 | // if your docs are in a specific branch (defaults to 'master'): 16 | docsBranch: 'master', 17 | // defaults to false, set to true to enable 18 | editLinks: true, 19 | // custom text for edit link. Defaults to "Edit this page" 20 | editLinkText: 'Help us improve this page!' 21 | } 22 | } -------------------------------------------------------------------------------- /docs/.vuepress/override.styl: -------------------------------------------------------------------------------- 1 | $accentColor = #4B39E5 2 | $textColor = #2c3e50 3 | $borderColor = #eaecef 4 | $codeBgColor = #282c34 -------------------------------------------------------------------------------- /docs/Guide.md: -------------------------------------------------------------------------------- 1 | # Guide 2 | 3 | ## Features 4 | 5 | Tosin is an opinionated way to start the creation of an npm package. It comes with everything included, from CI to a documentation website. Below is a list of its features. 6 | 7 | ### Continuous Integration 8 | 9 | Continuous integration is useful to keep an eye of the status of your repository. Do your branch build and pass all of the tests? 10 | You can do all of that manually of course but with external contributors and pull requests, you want a way to automate the process. 11 | 12 | Tosin comes with a simple configuration for circleci and one for Travis-ci. 13 | - CircleCi will build the package with npm install, lint to make sure there is no code that is error-prone and run the test. Take a look at the `Next Steps` section on how to add code coverage on the master branch. 14 | - Travis configuration will only test your package with another version of Nodejs. You can see it as a backup in case of CircleCI as a problem preventing it from building your package. You can also easily understand if your build failed the test by looking at the Travis status. Since CircleCI is doing more, it can fail even though your tests pass with success. 15 | 16 | Do you want to replace all of that with GitHub Actions? Take a look at the section `GitHub Actions` below. 17 | 18 | ### Linter + Prettier 19 | 20 | [Eslint](https://eslint.org/) is used for linting. 21 | > ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, with the goal of making the code more consistent and avoiding bugs. 22 | 23 | [Prettier](https://prettier.io/) is used to format the code. 24 | > Prettier is an opinionated code formatter. It enforces a consistent style by parsing your code and re-printing it with its own rules that take the maximum line length into account, wrapping code when necessary. 25 | 26 | ### Testing Framework Jest 27 | 28 | Jest is one of the most popular testing frameworks for Javascript. Contrary to other testing frameworks, Jest includes assertions library and mocking inside its framework. 29 | > Jest is a JavaScript testing framework designed to ensure the correctness of any JavaScript codebase. It allows you to write tests with an approachable, familiar and feature-rich API that gives you results quickly. 30 | 31 | ### GitHub files for the community 32 | 33 | Be prepared to receive help and issues from the community. A standard Pull Request template is included as well as three issue template: 34 | - A bug report template 35 | - A feature request template 36 | - A standard issue template for everything else 37 | 38 | A [code of conduct](https://www.contributor-covenant.org/) is present to make sure everyone feels welcome to contribute. 39 | 40 | ### Build system with Rollup 41 | 42 | [Rollup](https://rollupjs.org/guide/en/) is used to compile your code. You can use ES modules and compile your code in es and commonjs format. 43 | 44 | > Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application. It uses the new standardized format for code modules included in the ES6 revision of JavaScript, instead of previous idiosyncratic solutions such as CommonJS and AMD. ES modules let you freely and seamlessly combine the most useful individual functions from your favorite libraries. This will eventually be possible natively everywhere, but Rollup lets you do it today. 45 | 46 | ### Ready for autocompletion 47 | 48 | Do you want to provide autocompletion when someone installed your package? If you do, the `types/index.d.ts` is ready to be completed. 49 | It is set in `package.json` as the file containing your types. Most of the IDE and code editor will use this file to provide auto-completion. 50 | It is a great way to improve the developer experience. 51 | 52 | ### Documentation website ready to be deployed 53 | 54 | GitHub offers the possibility of hosting a website per repository for a long time now. You can take advantage of that to create a documentation website for your package and hosting it directly on GitHub. 55 | 56 | Tosin comes with [vuepress](https://vuepress.vuejs.org/) and a script to deploy the website to GitHub Pages. The script will deploy the files to the gh-pages branch of your repository. 57 | 58 | ## Installation 59 | 60 | Tosin doesn't require installation as it is meant to be a simple CLI tool. 61 | 62 | However, you can still choose to install it if you want to use its Javascript API. 63 | 64 | CLI: 65 | 66 | ``` 67 | npm i -g tosin 68 | ``` 69 | 70 | Javascript API: 71 | 72 | ``` 73 | npm i tosin 74 | ``` 75 | 76 | ## Usage 77 | 78 | You can create your repository and inside the directory, run the following command: 79 | 80 | ``` 81 | npx tosin init 82 | ``` 83 | 84 | You will be prompted a series of questions. The answers will be used to generate your project. 85 | 86 | - _What is the name of your project?_ 87 | - _What is the npm project name?_ This should be the name of the package as seen on npm. 88 | - _What is your repository (<\username>/<\repo>)?_ 89 | - _What is your name?_ Your name will be added to the LICENCE. 90 | - _What is your email?_ Your email will be added to the code of conduct. 91 | 92 | ### Next steps 93 | 94 | Once you initialize your project with Tosin, there are still a few steps to take. 95 | 96 | - Go to [circleci website](https://circleci.com) to add your project. 97 | - Go to [travis-ci website](https://travis-ci.org/) to add your project. 98 | - Go to [dependabot website](https://dependabot.com/) to add your project. 99 | - Modify the `package.json` file and add a description, keywords and your GitHub username as the author. 100 | - Choose a code coverage solution and add it to the project. You can find an example with [codacy](https://www.codacy.com/) in the `.circleci/config.yml` file. Add the badges as well to your Readme, they will be fetched by npm to calculate the quality score of your package. 101 | 102 | ## Use GitHub Actions 103 | 104 | You can use GitHub Actions as a Continuous Integration platform. 105 | The configuration file for GitHub Action is located at `.github/main.workflow`. 106 | 107 | Below is the configuration to build, lint, and test on push (similar to what the Circle CI one does). 108 | 109 | ``` 110 | 111 | workflow "Build, Lint, Test" { 112 | resolves = ["Test"] 113 | on = "push" 114 | } 115 | 116 | action "Install" { 117 | uses = "actions/npm@59b64a598378f31e49cb76f27d6f3312b582f680" 118 | args = "install" 119 | } 120 | 121 | action "Lint" { 122 | uses = "actions/npm@59b64a598378f31e49cb76f27d6f3312b582f680" 123 | needs = ["Install"] 124 | args = "run lint" 125 | } 126 | 127 | action "Test" { 128 | uses = "actions/npm@59b64a598378f31e49cb76f27d6f3312b582f680" 129 | needs = ["Lint"] 130 | args = "run test" 131 | } 132 | 133 | ``` 134 | 135 | Below is the configuration to deploy to npm on release, you will need to create an npm authentication token (https://docs.npmjs.com/creating-and-viewing-authentication-tokens). 136 | Add the authentication token to the configuration (`NPM_AUTH_TOKEN`). 137 | 138 | ``` 139 | 140 | action "Tag" { 141 | uses = "actions/bin/filter@3c0b4f0e63ea54ea5df2914b4fabf383368cd0da" 142 | args = "tag" 143 | } 144 | 145 | action "Publish" { 146 | needs = ["Tag"] 147 | uses = "actions/npm@59b64a598378f31e49cb76f27d6f3312b582f680" 148 | env = { 149 | NPM_AUTH_TOKEN = "" 150 | } 151 | args = "publish" 152 | } 153 | ``` 154 | 155 | With the above configuration, you can release your new version by creating a tag and create a new release on GitHub. 156 | Do not forget to update the version number in `package.json`. 157 | 158 | ## FAQ 159 | 160 | ### Why create an npm package? 161 | 162 | There's already a lot of npm packages out there. I would suggest creating one only if what you are looking for does not exist. 163 | Take a look at the npm website, search for what you are looking for. If something similar already exists, contribute to the project instead of creating a similar package. 164 | 165 | Be aware that some packages might not be actively maintained. Open source projects are often not funded and created during the spare time of a developer. It means it might not be the priority for the developer to take care of the project. If you notice that the project you want to contribute to is unmaintained, contact the developer, open an issue or Pull Request and propose to join the project. 166 | 167 | ### Why would I use Tosin? 168 | 169 | Tosin is a template for creating node libraries, npm packages. You can consider it as a more powerful npm init. 170 | 171 | With Tosin, you will start with Continuous Integration setup with CircleCI, Travis-CI. Rollup is configured so you will easily export your library into the different format available for nodejs. A documentation website is ready to be set up and deploy with vuepress. 172 | 173 | Tosin is configured with npm recommendation of what a 100% quality package is in mind. 174 | 175 | ### Is Tosin overkill? 176 | 177 | If you desire to create a small npm package that consists of a little function, then Tosin might not be the right choice. 178 | Take a look at _Why create an npm package?_ -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | home: true 3 | heroImage: https://imgur.com/lVaCXkU.png 4 | actionText: Get Started → 5 | actionLink: /Guide.html 6 | features: 7 | - title: Simple 8 | details: As easy as `npm init`. Just run `npx tosin init`. 9 | - title: Continuous Integration 10 | details: Comes with Continuous Integration setup, take a look at the docs for GitHub Actions. 11 | - title: Documentation website 12 | details: Ready to deploy website with vuepress. 13 | footer: MIT Licensed 14 | --- 15 | 16 | ``` 17 | npx tosin init 18 | ``` 19 | 20 | Once done, take a look at the documentation to do the [next steps](https://fullhuman.github.io/tosin/Guide.html#next-steps). 21 | 22 | ## Features 23 | 24 | Tosin is an opinionated way to start the creation of an npm package. It comes with everything included, from CI to a documentation website. Below is a list of its features. 25 | 26 | ### Continuous Integration 27 | 28 | Continuous integration is useful to keep an eye of the status of your repository. Do your branch build and pass all of the tests? 29 | You can do all of that manually of course but with external contributors and pull requests, you want a way to automate the process. 30 | 31 | Tosin comes with a simple configuration for circleci and one for Travis-ci. 32 | - CircleCi will build the package with npm install, lint to make sure there is no code that is error-prone, and run the test. Take a look at the `Next Steps` section on how to add code coverage on the master branch. 33 | - Travis configuration will only test your package with another version of Nodejs. You can see it as a backup in case CircleCI as a problem preventing it from building your package. You can also easily understand if your build failed the test by looking at the Travis status. Since CircleCI is doing more, it can fail even though your tests pass with success. 34 | 35 | You want to replace all of that with GitHub Actions? Take a look at the section `GitHub Actions` below. 36 | 37 | ### Linter + Prettier 38 | 39 | [Eslint](https://eslint.org/) is used for linting. 40 | > ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, with the goal of making code more consistent and avoiding bugs. 41 | 42 | [Prettier](https://prettier.io/) is used to format the code. 43 | > Prettier is an opinionated code formatter. It enforces a consistent style by parsing your code and re-printing it with its own rules that take the maximum line length into account, wrapping code when necessary. 44 | 45 | ### Testing Framework Jest 46 | 47 | Jest is one of the most popular testing framework for Javascript. Contrary to other testing framework, Jest includes assertions library and mocking inside its framework. 48 | > Jest is a JavaScript testing framework designed to ensure correctness of any JavaScript codebase. It allows you to write tests with an approachable, familiar and feature-rich API that gives you results quickly. 49 | 50 | ### GitHub files for the community 51 | 52 | Be prepared to receive help and issues from the community. A standard Pull Request template is included as well as three issue template: 53 | - A bug report template 54 | - A feature request template 55 | - A standard issue template for everything else 56 | 57 | A [code of conduct](https://www.contributor-covenant.org/) is present to make sure everyone feels welcome to contribute. 58 | 59 | ### Build system with Rollup 60 | 61 | [Rollup](https://rollupjs.org/guide/en/) is used to compile your code. You can use ES modules and compile your code in es and commonjs format. 62 | 63 | > Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application. It uses the new standardized format for code modules included in the ES6 revision of JavaScript, instead of previous idiosyncratic solutions such as CommonJS and AMD. ES modules let you freely and seamlessly combine the most useful individual functions from your favorite libraries. This will eventually be possible natively everywhere, but Rollup lets you do it today. 64 | 65 | ### Ready for autocompletion 66 | 67 | Do you want to provide autocompletion when someone installed your package? If you do, the `types/index.d.ts` is ready to be completed. 68 | It is set in `package.json` as the file containing your types. Most of the IDE and code editor will use this file to provide auto-completion. 69 | It is a great way to improve developer experience. 70 | 71 | ### Documentation website ready to be deployed 72 | 73 | GitHub offers the possibility of hosting a website per repository since a long time now. You can take advantage of that to create a documentation website for your package and hosting it directly on GitHub. 74 | 75 | Tosin comes with [vuepress](https://vuepress.vuejs.org/) and a script to deploy the website to GitHub Pages. The script will deploy the files to the gh-pages branch of your repository. 76 | 77 | 78 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | // For a detailed explanation regarding each configuration property, visit: 2 | // https://jestjs.io/docs/en/configuration.html 3 | 4 | module.exports = { 5 | // All imported modules in your tests should be mocked automatically 6 | // automock: false, 7 | 8 | // Stop running tests after `n` failures 9 | // bail: 0, 10 | 11 | // Respect "browser" field in package.json when resolving modules 12 | // browser: false, 13 | 14 | // The directory where Jest should store its cached dependency information 15 | // cacheDirectory: "/private/var/folders/sk/zystdgkn6bzdyp6f8kcvjdnr0000gn/T/jest_dx", 16 | 17 | // Automatically clear mock calls and instances between every test 18 | clearMocks: true, 19 | 20 | // Indicates whether the coverage information should be collected while executing the test 21 | // collectCoverage: false, 22 | 23 | // An array of glob patterns indicating a set of files for which coverage information should be collected 24 | // collectCoverageFrom: null, 25 | 26 | // The directory where Jest should output its coverage files 27 | coverageDirectory: "coverage", 28 | 29 | // An array of regexp pattern strings used to skip coverage collection 30 | // coveragePathIgnorePatterns: [ 31 | // "/node_modules/" 32 | // ], 33 | 34 | // A list of reporter names that Jest uses when writing coverage reports 35 | // coverageReporters: [ 36 | // "json", 37 | // "text", 38 | // "lcov", 39 | // "clover" 40 | // ], 41 | 42 | // An object that configures minimum threshold enforcement for coverage results 43 | // coverageThreshold: null, 44 | 45 | // A path to a custom dependency extractor 46 | // dependencyExtractor: null, 47 | 48 | // Make calling deprecated APIs throw helpful error messages 49 | // errorOnDeprecated: false, 50 | 51 | // Force coverage collection from ignored files using an array of glob patterns 52 | // forceCoverageMatch: [], 53 | 54 | // A path to a module which exports an async function that is triggered once before all test suites 55 | // globalSetup: null, 56 | 57 | // A path to a module which exports an async function that is triggered once after all test suites 58 | // globalTeardown: null, 59 | 60 | // A set of global variables that need to be available in all test environments 61 | // globals: {}, 62 | 63 | // An array of directory names to be searched recursively up from the requiring module's location 64 | // moduleDirectories: [ 65 | // "node_modules" 66 | // ], 67 | 68 | // An array of file extensions your modules use 69 | // moduleFileExtensions: [ 70 | // "js", 71 | // "json", 72 | // "jsx", 73 | // "ts", 74 | // "tsx", 75 | // "node" 76 | // ], 77 | 78 | // A map from regular expressions to module names that allow to stub out resources with a single module 79 | // moduleNameMapper: {}, 80 | 81 | // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader 82 | // modulePathIgnorePatterns: [], 83 | 84 | // Activates notifications for test results 85 | // notify: false, 86 | 87 | // An enum that specifies notification mode. Requires { notify: true } 88 | // notifyMode: "failure-change", 89 | 90 | // A preset that is used as a base for Jest's configuration 91 | // preset: null, 92 | 93 | // Run tests from one or more projects 94 | // projects: null, 95 | 96 | // Use this configuration option to add custom reporters to Jest 97 | // reporters: undefined, 98 | 99 | // Automatically reset mock state between every test 100 | // resetMocks: false, 101 | 102 | // Reset the module registry before running each individual test 103 | // resetModules: false, 104 | 105 | // A path to a custom resolver 106 | // resolver: null, 107 | 108 | // Automatically restore mock state between every test 109 | // restoreMocks: false, 110 | 111 | // The root directory that Jest should scan for tests and modules within 112 | // rootDir: null, 113 | 114 | // A list of paths to directories that Jest should use to search for files in 115 | // roots: [ 116 | // "" 117 | // ], 118 | 119 | // Allows you to use a custom runner instead of Jest's default test runner 120 | // runner: "jest-runner", 121 | 122 | // The paths to modules that run some code to configure or set up the testing environment before each test 123 | // setupFiles: [], 124 | 125 | // A list of paths to modules that run some code to configure or set up the testing framework before each test 126 | // setupFilesAfterEnv: [], 127 | 128 | // A list of paths to snapshot serializer modules Jest should use for snapshot testing 129 | // snapshotSerializers: [], 130 | 131 | // The test environment that will be used for testing 132 | testEnvironment: "node", 133 | 134 | // Options that will be passed to the testEnvironment 135 | // testEnvironmentOptions: {}, 136 | 137 | // Adds a location field to test results 138 | // testLocationInResults: false, 139 | 140 | // The glob patterns Jest uses to detect test files 141 | testMatch: [ 142 | "**/__tests__/**/*.test.[jt]s?(x)" 143 | ], 144 | 145 | // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped 146 | // testPathIgnorePatterns: [ 147 | // "/node_modules/" 148 | // ], 149 | 150 | // The regexp pattern or array of patterns that Jest uses to detect test files 151 | // testRegex: [], 152 | 153 | // This option allows the use of a custom results processor 154 | // testResultsProcessor: null, 155 | 156 | // This option allows use of a custom test runner 157 | // testRunner: "jasmine2", 158 | 159 | // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href 160 | // testURL: "http://localhost", 161 | 162 | // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout" 163 | // timers: "real", 164 | 165 | // A map from regular expressions to paths to transformers 166 | // transform: null, 167 | 168 | // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation 169 | // transformIgnorePatterns: [ 170 | // "/node_modules/" 171 | // ], 172 | 173 | // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them 174 | // unmockedModulePathPatterns: undefined, 175 | 176 | // Indicates whether each individual test should be reported during the run 177 | // verbose: null, 178 | 179 | // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode 180 | // watchPathIgnorePatterns: [], 181 | 182 | // Whether to use watchman for file crawling 183 | // watchman: true, 184 | }; 185 | -------------------------------------------------------------------------------- /lib/tosin.cjs.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { value: true }); 4 | 5 | function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } 6 | 7 | var fs = _interopDefault(require('fs')); 8 | var util = require('util'); 9 | var enquirer = _interopDefault(require('enquirer')); 10 | var degit = _interopDefault(require('degit')); 11 | 12 | const readFile = util.promisify(fs.readFile); 13 | const writeFile = util.promisify(fs.writeFile); 14 | 15 | const init = async () => { 16 | const response = await enquirer.prompt([ 17 | { 18 | type: 'input', 19 | name: 'humanProjectName', 20 | message: 'What is the name of your project? (e.g. Svelte)' 21 | }, 22 | { 23 | type: 'input', 24 | name: 'projectName', 25 | message: 'What is the npm project name? (e.g. svelte-js)' 26 | }, 27 | { 28 | type: 'input', 29 | name: 'repository', 30 | message: 'What is your repository (/)? (e.g. FullHuman/tosin)' 31 | }, 32 | { 33 | type: 'input', 34 | name: 'developerName', 35 | message: 'What is your name (used for the licence)?' 36 | }, 37 | { 38 | type: 'input', 39 | name: 'email', 40 | message: 'What is the email to be use for the code of conduct?' 41 | } 42 | ]); 43 | // clone the template library 44 | const emitter = degit('FullHuman/tosin-template-library', { 45 | cache: false, 46 | force: true, 47 | verbose: false 48 | }); 49 | 50 | await emitter.clone('.'); 51 | 52 | const replaceSets = [ 53 | ['{% project name %}', response.projectName], 54 | ['{% human project name %}', response.humanProjectName], 55 | ['{% developer name %}', response.developerName], 56 | ['{% email %}', response.email], 57 | ['{% repository %}', response.repository], 58 | ['{% lowercase repository %}', response.repository.toLowerCase()] 59 | ]; 60 | 61 | const filesToModify = [ 62 | '.github/ISSUE_TEMPLATE/BUG_REPORT.md', 63 | '.github/CODE_OF_CONDUCT.md', 64 | '.github/PULL_REQUEST_TEMPLATE.md', 65 | 'scripts/deploy_docs.sh', 66 | 'CONTRIBUTING.md', 67 | 'LICENSE', 68 | 'package.json', 69 | 'README.md', 70 | 'rollup.config.js', 71 | // docs 72 | 'docs/.vuepress/config.js', 73 | 'docs/Guide.md', 74 | 'docs/README.md' 75 | ]; 76 | 77 | for (const file of filesToModify) { 78 | await replaceInFile(file, replaceSets); 79 | } 80 | }; 81 | 82 | const replaceInFile = async (filePath, replaceSets) => { 83 | const fileContent = await readFile(filePath, 'utf-8'); 84 | let result = fileContent; 85 | replaceSets.forEach(([toReplace, value]) => { 86 | result = result.replace(new RegExp(toReplace, 'g'), value); 87 | }); 88 | await writeFile(filePath, result, 'utf8'); 89 | }; 90 | 91 | exports.init = init; 92 | exports.replaceInFile = replaceInFile; 93 | -------------------------------------------------------------------------------- /lib/tosin.es.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import { promisify } from 'util'; 3 | import enquirer from 'enquirer'; 4 | import degit from 'degit'; 5 | 6 | const readFile = promisify(fs.readFile); 7 | const writeFile = promisify(fs.writeFile); 8 | 9 | const init = async () => { 10 | const response = await enquirer.prompt([ 11 | { 12 | type: 'input', 13 | name: 'humanProjectName', 14 | message: 'What is the name of your project? (e.g. Svelte)' 15 | }, 16 | { 17 | type: 'input', 18 | name: 'projectName', 19 | message: 'What is the npm project name? (e.g. svelte-js)' 20 | }, 21 | { 22 | type: 'input', 23 | name: 'repository', 24 | message: 'What is your repository (/)? (e.g. FullHuman/tosin)' 25 | }, 26 | { 27 | type: 'input', 28 | name: 'developerName', 29 | message: 'What is your name (used for the licence)?' 30 | }, 31 | { 32 | type: 'input', 33 | name: 'email', 34 | message: 'What is the email to be use for the code of conduct?' 35 | } 36 | ]); 37 | // clone the template library 38 | const emitter = degit('FullHuman/tosin-template-library', { 39 | cache: false, 40 | force: true, 41 | verbose: false 42 | }); 43 | 44 | await emitter.clone('.'); 45 | 46 | const replaceSets = [ 47 | ['{% project name %}', response.projectName], 48 | ['{% human project name %}', response.humanProjectName], 49 | ['{% developer name %}', response.developerName], 50 | ['{% email %}', response.email], 51 | ['{% repository %}', response.repository], 52 | ['{% lowercase repository %}', response.repository.toLowerCase()] 53 | ]; 54 | 55 | const filesToModify = [ 56 | '.github/ISSUE_TEMPLATE/BUG_REPORT.md', 57 | '.github/CODE_OF_CONDUCT.md', 58 | '.github/PULL_REQUEST_TEMPLATE.md', 59 | 'scripts/deploy_docs.sh', 60 | 'CONTRIBUTING.md', 61 | 'LICENSE', 62 | 'package.json', 63 | 'README.md', 64 | 'rollup.config.js', 65 | // docs 66 | 'docs/.vuepress/config.js', 67 | 'docs/Guide.md', 68 | 'docs/README.md' 69 | ]; 70 | 71 | for (const file of filesToModify) { 72 | await replaceInFile(file, replaceSets); 73 | } 74 | }; 75 | 76 | const replaceInFile = async (filePath, replaceSets) => { 77 | const fileContent = await readFile(filePath, 'utf-8'); 78 | let result = fileContent; 79 | replaceSets.forEach(([toReplace, value]) => { 80 | result = result.replace(new RegExp(toReplace, 'g'), value); 81 | }); 82 | await writeFile(filePath, result, 'utf8'); 83 | }; 84 | 85 | export { init, replaceInFile }; 86 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tosin", 3 | "version": "1.0.2", 4 | "description": "Initialize a npm package with everything included, from CI to documentation website", 5 | "main": "./lib/tosin.js", 6 | "module": "./lib/tosin.es.js", 7 | "jsnext:main": "./lib/tosin.es.js", 8 | "bin": "./bin/tosin.js", 9 | "directories": { 10 | "lib": "lib", 11 | "test": "__tests__", 12 | "doc": "docs" 13 | }, 14 | "files": [ 15 | "lib/", 16 | "bin/" 17 | ], 18 | "scripts": { 19 | "test": "jest", 20 | "dev": "rollup -c rollup.config.js -w", 21 | "build": "rollup -c rollup.config.js", 22 | "prettier": "prettier --no-config --write '{src,__{tests,mocks}__}/**/*.js'", 23 | "lint": "eslint src/", 24 | "docs:dev": "vuepress dev docs", 25 | "docs:build": "vuepress build docs" 26 | }, 27 | "repository": { 28 | "type": "git", 29 | "url": "git+https://github.com/FullHuman/tosin.git" 30 | }, 31 | "keywords": [ 32 | "project", 33 | "scaffolding", 34 | "github", 35 | "npm", 36 | "package", 37 | "library", 38 | "init" 39 | ], 40 | "author": "Ffloriel", 41 | "license": "MIT", 42 | "bugs": { 43 | "url": "https://github.com/FullHuman/tosin/issues" 44 | }, 45 | "homepage": "https://github.com/FullHuman/tosin#readme", 46 | "devDependencies": { 47 | "@babel/core": "^7.4.5", 48 | "@babel/preset-env": "^7.4.5", 49 | "codacy-coverage": "^3.4.0", 50 | "eslint": "^6.5.1", 51 | "jest": "^24.8.0", 52 | "prettier": "^1.17.1", 53 | "rollup": "^1.12.3", 54 | "rollup-plugin-node-builtins": "^2.1.2", 55 | "rollup-plugin-node-resolve": "^5.0.0", 56 | "vuepress": "^0.14.11" 57 | }, 58 | "dependencies": { 59 | "commander": "^3.0.2", 60 | "degit": "^2.1.3", 61 | "enquirer": "^2.3.0" 62 | }, 63 | "engines": { 64 | "node": ">=8.0.0", 65 | "npm": ">=5.2.0" 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import builtins from "rollup-plugin-node-builtins" 2 | import resolve from "rollup-plugin-node-resolve" 3 | 4 | export default { 5 | input: "src/index.js", 6 | output: [ 7 | { 8 | file: "lib/tosin.es.js", 9 | format: "es" 10 | }, 11 | { 12 | file: "lib/tosin.cjs.js", 13 | format: "cjs" 14 | } 15 | ], 16 | plugins: [builtins(), resolve()], 17 | external: ['degit', 'enquirer', 'util', 'fs'] 18 | } 19 | -------------------------------------------------------------------------------- /scripts/deploy_docs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # abort on errors 4 | set -e 5 | 6 | # build 7 | npm run docs:build 8 | 9 | # navigate into the build output directory 10 | cd docs/.vuepress/dist 11 | 12 | # if you are deploying to a custom domain 13 | # echo 'www.example.com' > CNAME 14 | 15 | git init 16 | git add -A 17 | git commit -m 'deploy' 18 | 19 | # if you are deploying to https://.github.io 20 | # git push -f git@github.com:/.github.io.git master 21 | 22 | # if you are deploying to https://.github.io/ 23 | git push -f git@github.com:FullHuman/tosin.git master:gh-pages 24 | 25 | cd - -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs' 2 | import { promisify } from 'util' 3 | import enquirer from 'enquirer' 4 | import degit from 'degit' 5 | 6 | const readFile = promisify(fs.readFile) 7 | const writeFile = promisify(fs.writeFile) 8 | 9 | export const init = async () => { 10 | const response = await enquirer.prompt([ 11 | { 12 | type: 'input', 13 | name: 'humanProjectName', 14 | message: 'What is the name of your project? (e.g. Svelte)' 15 | }, 16 | { 17 | type: 'input', 18 | name: 'projectName', 19 | message: 'What is the npm project name? (e.g. svelte-js)' 20 | }, 21 | { 22 | type: 'input', 23 | name: 'repository', 24 | message: 'What is your repository (/)? (e.g. FullHuman/tosin)' 25 | }, 26 | { 27 | type: 'input', 28 | name: 'developerName', 29 | message: 'What is your name (used for the licence)?' 30 | }, 31 | { 32 | type: 'input', 33 | name: 'email', 34 | message: 'What is the email to be use for the code of conduct?' 35 | } 36 | ]) 37 | // clone the template library 38 | const emitter = degit('FullHuman/tosin-template-library', { 39 | cache: false, 40 | force: true, 41 | verbose: false 42 | }) 43 | 44 | await emitter.clone('.') 45 | 46 | const replaceSets = [ 47 | ['{% project name %}', response.projectName], 48 | ['{% human project name %}', response.humanProjectName], 49 | ['{% developer name %}', response.developerName], 50 | ['{% email %}', response.email], 51 | ['{% repository %}', response.repository], 52 | ['{% lowercase repository %}', response.repository.toLowerCase()] 53 | ] 54 | 55 | const filesToModify = [ 56 | '.github/ISSUE_TEMPLATE/BUG_REPORT.md', 57 | '.github/CODE_OF_CONDUCT.md', 58 | '.github/PULL_REQUEST_TEMPLATE.md', 59 | 'scripts/deploy_docs.sh', 60 | 'CONTRIBUTING.md', 61 | 'LICENSE', 62 | 'package.json', 63 | 'README.md', 64 | 'rollup.config.js', 65 | // docs 66 | 'docs/.vuepress/config.js', 67 | 'docs/Guide.md', 68 | 'docs/README.md' 69 | ] 70 | 71 | for (const file of filesToModify) { 72 | await replaceInFile(file, replaceSets) 73 | } 74 | } 75 | 76 | export const replaceInFile = async (filePath, replaceSets) => { 77 | const fileContent = await readFile(filePath, 'utf-8') 78 | let result = fileContent 79 | replaceSets.forEach(([toReplace, value]) => { 80 | result = result.replace(new RegExp(toReplace, 'g'), value) 81 | }) 82 | await writeFile(filePath, result, 'utf8') 83 | } --------------------------------------------------------------------------------