├── .gitignore
├── LICENSE
├── README.md
├── assets
└── preview.png
├── bin
├── steps
│ ├── log-error.js
│ ├── log-newline.js
│ ├── log-success.js
│ ├── log-welcome.js
│ ├── prompt-author.js
│ ├── prompt-description.js
│ ├── prompt-git-origin.js
│ ├── prompt-git.js
│ ├── prompt-license.js
│ ├── prompt-name.js
│ ├── prompt-private.js
│ ├── prompt-readme.js
│ ├── prompt-version.js
│ ├── update-changelog.js
│ ├── update-git.js
│ ├── update-license.js
│ ├── update-packagejson.js
│ └── update-readme.js
├── unboil.js
└── utils
│ ├── ensure-file.js
│ └── sh-basic.js
├── package.json
└── templates
├── licenses
├── agpl3.txt
├── apache.txt
├── bsd2.txt
├── bsd3.txt
├── gpl2.txt
├── gpl3.txt
├── isc.txt
├── lgpl.txt
├── mit.txt
├── mpl.txt
└── wtfpl.txt
└── readme.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # nyc test coverage
18 | .nyc_output
19 |
20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21 | .grunt
22 |
23 | # node-waf configuration
24 | .lock-wscript
25 |
26 | # Compiled binary addons (http://nodejs.org/api/addons.html)
27 | build/Release
28 |
29 | # Dependency directories
30 | node_modules
31 | jspm_packages
32 |
33 | # Optional npm cache directory
34 | .npm
35 |
36 | # Optional REPL history
37 | .node_repl_history
38 |
39 | *.DS_Store
40 | .AppleDouble
41 | .LSOverride
42 |
43 | # Icon must end with two \r
44 | Icon
45 |
46 |
47 | # Thumbnails
48 | ._*
49 |
50 | # Files that might appear in the root of a volume
51 | .DocumentRevisions-V100
52 | .fseventsd
53 | .Spotlight-V100
54 | .TemporaryItems
55 | .Trashes
56 | .VolumeIcon.icns
57 | .com.apple.timemachine.donotpresent
58 |
59 | # Directories potentially created on remote AFP share
60 | .AppleDB
61 | .AppleDesktop
62 | Network Trash Folder
63 | Temporary Items
64 | .apdisk
65 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 brocessing
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 |
2 |
3 |
4 |
5 | unboil
6 | Boilerplate customiser for lazy people
7 |
21 |
22 |
23 |
24 |
25 |
26 | ## Features
27 | - Fancy CLI interface to generate a new project from a boilerplate
28 | - Update & customize existing `package.json`
29 | - Update existing `LICENSE` accordingly to the updated package.json, create it if none
30 | - Update existing `README`, create it if none
31 | - Clear existing `.git`
32 | - Quickly re-init the git folder and add your git remote repository
33 | - Minimal module: only 4 dependencies
34 |
35 | ## Installation
36 | ```sh
37 | $ npm install -g unboil
38 | ```
39 |
40 | ## Usage
41 | ```sh
42 | $ cd my-project
43 | $ unboil
44 | ```
45 |
46 | ## License
47 | [MIT](https://tldrlegal.com/license/mit-license).
48 |
--------------------------------------------------------------------------------
/assets/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brocessing/unboil/0022484c5f32ae72e43fe7cdb763719ecf4c2c8c/assets/preview.png
--------------------------------------------------------------------------------
/bin/steps/log-error.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const sh = require('kool-shell')()
4 | .use(require('kool-shell/plugins/log'))
5 |
6 | module.exports = function (err, state) {
7 | process.stdout.write('\n')
8 | const msg = (err && err.message) ? err.message : err
9 | sh.error(msg + '\n')
10 | if (err.message && err.stack) sh.log(err.stack)
11 | }
12 |
--------------------------------------------------------------------------------
/bin/steps/log-newline.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const sh = require('../utils/sh-basic')
4 |
5 | module.exports = function (state, next) {
6 | sh.log('')
7 | next(null, state)
8 | }
--------------------------------------------------------------------------------
/bin/steps/log-success.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const sh = require('kool-shell')()
4 | .use(require('kool-shell/plugins/log'))
5 |
6 | module.exports = function (err, state) {
7 | process.stdout.write('\n')
8 | sh.success(sh.colors.yellow(state.package.name) + ' is unboiled !\n')
9 | }
10 |
--------------------------------------------------------------------------------
/bin/steps/log-welcome.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const colors = require('kool-shell/utils/colors')
4 | const sh = require('kool-shell')()
5 | .use(require('kool-shell/plugins/log'))
6 |
7 | module.exports = function (next) {
8 | process.stdout.write('\n')
9 | sh.info(colors.gray('🍳 Unboiling ' + process.cwd()))
10 |
11 | // initialize the state flow
12 | next(null, {
13 | package: {},
14 | tasks: {}
15 | })
16 | }
17 |
--------------------------------------------------------------------------------
/bin/steps/prompt-author.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const sh = require('kool-shell')()
4 | .use(require('kool-shell/plugins/input'))
5 | .use(require('kool-shell/plugins/exec'))
6 |
7 | function ask (author) {
8 | const def = author && author !== '' ? author : false
9 | const label = def ? 'Author: (' + def + ')' : 'Author:'
10 | return sh.input(label, {
11 | onSubmit: answer => def && (!answer || answer === '') ? def : answer
12 | })
13 | }
14 |
15 | module.exports = function (state, next) {
16 | sh.silentExec('git', ['config', 'user.name'])
17 | .then(out => out.stdout)
18 | .catch(out => '')
19 | .then(ask)
20 | .then(author => {
21 | state.package.author = author
22 | next(null, state)
23 | })
24 | .catch(err => next(err, state))
25 | }
26 |
--------------------------------------------------------------------------------
/bin/steps/prompt-description.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const sh = require('kool-shell')()
4 | .use(require('kool-shell/plugins/input'))
5 |
6 | module.exports = function (state, next) {
7 | sh.input('Description:', { onSubmit: answer => answer.trim() })
8 | .then(description => {
9 | state.package.description = description
10 | next(null, state)
11 | })
12 | .catch(err => next(err, state))
13 | }
14 |
--------------------------------------------------------------------------------
/bin/steps/prompt-git-origin.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const sh = require('../utils/sh-basic')
4 |
5 | const REGEX = /^(git@([a-z0-9._~/?#\[\]@!$&'()*+,;=`-]+):|https?:\/\/([a-z0-9._~?#\[\]@!$&'()*+,;=`-]+)\/)([a-z0-9._~:/?#\[\]@!$&'()*+,;=`-]+)\.git$/i
6 |
7 | const GIT_DOMAINS = [
8 | 'www.bitbucket.org',
9 | 'bitbucket.org',
10 | 'www.github.com',
11 | 'github.com',
12 | 'www.gitlab.com',
13 | 'gitlab.com'
14 | ]
15 |
16 |
17 | function validate (answer = '') {
18 | let url = (answer + '').trim()
19 | if (url.substr(-1, 1) === '/') url = url.slice(0, -1)
20 | if (url.substr(-4, 4) !== '.git') url += '.git'
21 |
22 | const result = url.match(REGEX)
23 | if (!result) {
24 | sh.error('Invalid repository origin')
25 | return ask()
26 | }
27 | const host = result[2] || result[3]
28 | const path = result[4]
29 | return { host, path, url }
30 | }
31 |
32 | function ask () {
33 | return sh.input('Repository origin (ssh/https):', { onSubmit: validate })
34 | }
35 |
36 | module.exports = function (state, next) {
37 | if (!state.hasGitRepo) return next(null, state)
38 |
39 | ask()
40 | .then(({ host, path, url }) => {
41 |
42 | state.gitOriginUrl = url
43 |
44 | state.package.repository = {
45 | type: 'git',
46 | url: 'git+' + url
47 | }
48 |
49 | if (~GIT_DOMAINS.indexOf(host)) {
50 | const projectUrl = `https://${host}/${path}`
51 | state.package.homepage = projectUrl + '#readme'
52 | state.package.bugs = { url: projectUrl + '/issues' }
53 | }
54 |
55 | next(null, state)
56 | })
57 | .catch(err => next(err, state))
58 | }
59 |
--------------------------------------------------------------------------------
/bin/steps/prompt-git.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const fs = require('fs-extra')
4 | const path = require('path')
5 | const sh = require('kool-shell')()
6 | .use(require('kool-shell/plugins/log'))
7 | .use(require('kool-shell/plugins/input'))
8 |
9 | const GIT_PATH = path.join(process.cwd(), '.git')
10 |
11 | function ask(name) {
12 | return sh.input(
13 | `Does ${sh.colors.yellow(name)} have a git repository? (yes)`,
14 | { onSubmit: answer => !answer.match(/^no?$/i) }
15 | )
16 | }
17 |
18 | module.exports = function (state, next) {
19 | fs.pathExists(GIT_PATH)
20 | .then(exists => exists ? ask(state.package.name) : false)
21 | .then(answer => {
22 | state.hasGitRepo = !!answer
23 | state.package.homepage = null
24 | state.package.bugs = null
25 | state.package.repository = null
26 | next(null, state)
27 | })
28 | .catch(err => next(err, state))
29 | }
30 |
--------------------------------------------------------------------------------
/bin/steps/prompt-license.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const { license } = require('../../package.json')
4 | const sh = require('kool-shell')()
5 | .use(require('kool-shell/plugins/input'))
6 |
7 | const DEFAULT_LICENSE = license || 'MIT'
8 | const def = val => val === undefined || val === '' ? DEFAULT_LICENSE : val
9 |
10 | function ask() {
11 | return sh.input(`License: (${DEFAULT_LICENSE})`, {
12 | onSubmit: answer => def(answer).trim()
13 | })
14 | }
15 |
16 | module.exports = function (state, next) {
17 | ask()
18 | .then(license => {
19 | // @TODO : if (license !== DEFAULT_LICENSE) update LICENSE file
20 | state.package.license = license
21 | next(null, state)
22 | })
23 | .catch(err => next(err, state))
24 | }
25 |
--------------------------------------------------------------------------------
/bin/steps/prompt-name.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const slug = require('slug')
4 | const path = require('path')
5 | const sh = require('../utils/sh-basic')
6 |
7 | const DEFAULT_NAME = slug(path.basename(process.cwd()))
8 |
9 | const def = val => val === undefined || val === '' ? DEFAULT_NAME : val
10 |
11 | const errors = {
12 | noName: 'You must provide a name to create a module',
13 | tooLong: 'Module name can\'t contain more than 214 characters',
14 | badStartChar: 'Module name can only start with a lowercase alphabetic character',
15 | badChar: 'Module name should contain only lowercase alphanumeric characters, dots, hyphens, and underscores',
16 | badTrimming: 'Module name cannot contain leading or trailing spaces'
17 | }
18 |
19 | function realName (slug) {
20 | return slug
21 | .split('-')
22 | .map(w => w.charAt(0).toUpperCase() + w.substring(1))
23 | .join(' ')
24 | }
25 |
26 | function validateName (name, cb) {
27 | if (name === undefined || typeof name !== 'string' || name.length === 0) { return cb(errors.noName) }
28 | if (name.length > 214) return cb(errors.tooLong)
29 | if (name.trim() !== name) return cb(errors.badTrimming)
30 | if (!name.match(/^[a-z]/)) return cb(errors.badStartChar)
31 | if (!name.match(/^[a-z0-9_\-.]*$/)) return cb(errors.badChar)
32 |
33 | return cb(null, name)
34 | }
35 |
36 | function ask () {
37 | return sh.input(`Name: (${DEFAULT_NAME})`, {
38 | onSubmit: answer => {
39 | return validateName(def(answer.trim()), (err, name) => {
40 | if (err) {
41 | sh.error(err)
42 | return ask()
43 | } else return name
44 | })
45 | }
46 | })
47 | }
48 |
49 | module.exports = function (state, next) {
50 | ask()
51 | .then(name => {
52 | state.package.name = name
53 | state.name = realName(name)
54 | next(null, state)
55 | })
56 | .catch(err => next(err, state))
57 | }
58 |
--------------------------------------------------------------------------------
/bin/steps/prompt-private.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const fs = require('fs-extra')
4 | const path = require('path')
5 | const sh = require('kool-shell')()
6 | .use(require('kool-shell/plugins/log'))
7 | .use(require('kool-shell/plugins/input'))
8 |
9 | function ask(name) {
10 | return sh.input(
11 | `Is ${sh.colors.yellow(name)} a private package? (no)`,
12 | { onSubmit: answer => !!answer.match(/^y(es)?$/i) }
13 | )
14 | }
15 |
16 | module.exports = function (state, next) {
17 | ask(state.package.name)
18 | .then(answer => {
19 | state.package.private = answer
20 | next(null, state)
21 | })
22 | .catch(err => next(err, state))
23 | }
24 |
--------------------------------------------------------------------------------
/bin/steps/prompt-readme.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const sh = require('../utils/sh-basic')
4 |
5 | function ask () {
6 | return sh.input(
7 | `Do you want ${sh.colors.yellow('README')} to be unboiled ? (yes)`,
8 | { onSubmit: answer => answer === '' || !!answer.match(/^y(es)?$/i) }
9 | )
10 | }
11 |
12 | module.exports = function (state, next) {
13 | ask()
14 | .then(answer => {
15 | state.clearReadme = answer
16 | next(null, state)
17 | })
18 | .catch(err => next(err, state))
19 | }
20 |
--------------------------------------------------------------------------------
/bin/steps/prompt-version.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const sh = require('../utils/sh-basic')
4 |
5 | const DEFAULT_VERSION = '0.0.1'
6 | const REGEX = /^((\w{1}|[1-9]{1}\w+)\.){2}(\w{1}|[1-9]{1}\w+)$/g
7 |
8 | const isValid = val => REGEX.test(val)
9 | const def = val => val === undefined || val === '' ? DEFAULT_VERSION : val
10 |
11 | function ask () {
12 | return sh.input('Version: (' + DEFAULT_VERSION + ')', {
13 | onSubmit: answer => {
14 | answer = def(answer)
15 | if (isValid(answer)) return answer
16 | sh.error('Invalid version: "' + answer + '"')
17 | return ask()
18 | }
19 | })
20 | }
21 |
22 | module.exports = function (state, next) {
23 | ask()
24 | .then(version => {
25 | state.package.version = version
26 | next(null, state)
27 | })
28 | .catch(err => next(err, state))
29 | }
30 |
--------------------------------------------------------------------------------
/bin/steps/update-changelog.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const fs = require('fs-extra')
4 | const path = require('path')
5 | const sh = require('../utils/sh-basic')
6 |
7 | const CHANGELOGMD_PATH = path.join(process.cwd(), 'CHANGELOG.md')
8 | const CHANGELOG_PATH = path.join(process.cwd(), 'CHANGELOG')
9 |
10 | function ensureChangelogFile() {
11 | return new Promise((resolve, reject) => {
12 | fs.pathExists(CHANGELOG_PATH)
13 | .then(exists => {
14 | if (exists) resolve(CHANGELOG_PATH)
15 | else fs.ensureFile(CHANGELOGMD_PATH)
16 | .then(() => resolve(CHANGELOGMD_PATH))
17 | .catch(reject)
18 | })
19 | .catch(reject)
20 | })
21 | }
22 |
23 | module.exports = function (state, next) {
24 | let changelogPath = null
25 | return ensureChangelogFile()
26 | .then(file => { changelogPath = file })
27 | .then(output => fs.writeFile(changelogPath, ''))
28 | .then(() => sh.debug(`CHANGELOG file updated`))
29 | .then(() => next(null, state))
30 | .catch(err => next(err, state))
31 | }
32 |
--------------------------------------------------------------------------------
/bin/steps/update-git.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const fs = require('fs-extra')
4 | const path = require('path')
5 | const sh = require('../utils/sh-basic')
6 |
7 | const GIT_PATH = path.join(process.cwd(), '.git')
8 |
9 | module.exports = function (state, next) {
10 | fs.remove(GIT_PATH)
11 | .then(() => state.hasGitRepo ? sh.silentExec('git', ['init']) : { code: 0 })
12 | .then(res => {
13 | if (!state.hasGitRepo) return sh.debug(`.git folder removed`)
14 | if (res.code !== 0) return Promise.reject(res.stderr)
15 | sh.debug(`.git folder (re)created`)
16 | })
17 | .then(() => {
18 | const repoUrl = state.gitOriginUrl
19 | if (state.hasGitRepo && repoUrl) return new Promise((resolve, reject) => {
20 | sh.silentExec('git', ['remote', 'add', 'origin', repoUrl])
21 | .then(res => res.code !== 0 ? Promise.reject(res.stderr) : '')
22 | .then(() => sh.debug(`${repoUrl} added as remote origin`))
23 | .then(resolve)
24 | .catch(reject)
25 | })
26 | })
27 | .then(() => next(null, state))
28 | .catch(err => next(err, state))
29 | }
30 |
--------------------------------------------------------------------------------
/bin/steps/update-license.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const fs = require('fs-extra')
4 | const path = require('path')
5 | const sh = require('../utils/sh-basic')
6 | const ensureFile = require('../utils/ensure-file')
7 |
8 | const LICENSEMD_PATH = path.join(process.cwd(), 'LICENSE.md')
9 | const LICENSE_PATH = path.join(process.cwd(), 'LICENSE')
10 | const CURRENT_YEAR = (new Date()).getFullYear()
11 |
12 | module.exports = function (state, next) {
13 | const license = state.package.license.toLowerCase()
14 | const templatePath = path.join(__dirname, '..', '..', 'templates', 'licenses', license + '.txt')
15 | let licensePath = null
16 | return ensureFile(LICENSEMD_PATH, LICENSE_PATH)
17 | .then(file => { licensePath = file })
18 | .then(() => fs.pathExists(templatePath))
19 | .then(exists => exists ? fs.readFile(templatePath, 'utf8') : '')
20 | .then(template => template
21 | .replace(/\{\{ project \}\}/g, state.package.name)
22 | .replace(/\{\{ author \}\}/g, state.package.author)
23 | .replace(/\{\{ year \}\}/g, CURRENT_YEAR))
24 | .then(output => fs.writeFile(licensePath, output))
25 | .then(() => sh.debug(`LICENSE file updated`))
26 | .then(() => next(null, state))
27 | .catch(err => next(err, state))
28 | }
29 |
--------------------------------------------------------------------------------
/bin/steps/update-packagejson.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const fs = require('fs-extra')
4 | const path = require('path')
5 | const sh = require('../utils/sh-basic')
6 |
7 | const PACKAGE_PATH = path.join(process.cwd(), 'package.json')
8 |
9 | function loadPackageJson () {
10 | return new Promise((resolve, reject) => {
11 | fs.pathExists(PACKAGE_PATH)
12 | .then(exists => {
13 | if (!exists) return resolve({})
14 | else fs.readJson(PACKAGE_PATH)
15 | .then(resolve)
16 | .catch(reject)
17 | })
18 | .catch(reject)
19 | })
20 | }
21 |
22 | module.exports = function (state, next) {
23 | loadPackageJson()
24 | .then(oldPackage => {
25 | const newPackage = Object.assign({}, oldPackage, state.package)
26 |
27 | for (let k in state.package) {
28 | if (state.package[k] === null) delete newPackage[k]
29 | }
30 |
31 | if (!newPackage.dependencies) newPackage.dependencies = {}
32 | if (!newPackage.devDependencies) newPackage.devDependencies = {}
33 |
34 | fs.writeJson(PACKAGE_PATH, newPackage, {spaces: 2})
35 | .then(() => sh.debug(`package.json updated`))
36 | .then(() => next(null, state))
37 | .catch(err => next(err, state))
38 | })
39 | .catch(err => next(err, state))
40 | }
41 |
--------------------------------------------------------------------------------
/bin/steps/update-readme.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const fs = require('fs-extra')
4 | const path = require('path')
5 | const sh = require('../utils/sh-basic')
6 | const ensureFile = require('../utils/ensure-file')
7 |
8 | const READMEMD_PATH = path.join(process.cwd(), 'README.md')
9 | const README_PATH = path.join(process.cwd(), 'README')
10 | const TEMPLATE_PATH = path.join(__dirname, '..', '..', 'templates', 'readme.txt')
11 |
12 | module.exports = function (state, next) {
13 | let readmePath = null
14 | if (state.clearReadme) {
15 | ensureFile(README_PATH, READMEMD_PATH)
16 | .then(file => { readmePath = file })
17 | .then(() => fs.readFile(TEMPLATE_PATH, 'utf8'))
18 | .then(template => template
19 | .replace(/\{\{ project \}\}/g, state.package.name)
20 | .replace(/\{\{ description \}\}/g, state.package.description))
21 | .then(output => fs.writeFile(readmePath, output))
22 | .then(() => sh.debug(`README file updated`))
23 | .then(() => next(null, state))
24 | .catch(err => next(err, state))
25 | } else next(null, state)
26 | }
27 |
--------------------------------------------------------------------------------
/bin/unboil.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | 'use strict'
4 |
5 | const waterfall = require('run-waterfall')
6 |
7 | waterfall(
8 | [
9 | require('./steps/log-welcome'),
10 |
11 | require('./steps/log-newline'),
12 |
13 | require('./steps/prompt-name'),
14 | require('./steps/prompt-version'),
15 | require('./steps/prompt-description'),
16 | require('./steps/prompt-author'),
17 | require('./steps/prompt-license'),
18 | require('./steps/prompt-private'),
19 | require('./steps/prompt-readme'),
20 | require('./steps/prompt-git'),
21 | require('./steps/prompt-git-origin'),
22 |
23 | require('./steps/log-newline'),
24 |
25 | require('./steps/update-packagejson'),
26 | require('./steps/update-license'),
27 | require('./steps/update-readme'),
28 | require('./steps/update-changelog'),
29 | require('./steps/update-git'),
30 | ],
31 | (err, state) => err
32 | ? require('./steps/log-error')(err, state)
33 | : require('./steps/log-success')(err, state)
34 | )
35 |
--------------------------------------------------------------------------------
/bin/utils/ensure-file.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const fs = require('fs-extra')
4 | const path = require('path')
5 |
6 | function ensureFile (preferedPath, fallbackPath) {
7 | return new Promise((resolve, reject) => {
8 | fs.pathExists(preferedPath)
9 | .then(exists => {
10 | if (exists) resolve(preferedPath)
11 | else fs.ensureFile(fallbackPath)
12 | .then(() => resolve(fallbackPath))
13 | .catch(reject)
14 | })
15 | .catch(reject)
16 | })
17 | }
18 |
19 | module.exports = ensureFile
20 |
--------------------------------------------------------------------------------
/bin/utils/sh-basic.js:
--------------------------------------------------------------------------------
1 | const colors = require('kool-shell/utils/colors')
2 |
3 | module.exports = require('kool-shell')()
4 | .use(require('kool-shell/plugins/exec'))
5 | .use(require('kool-shell/plugins/input'))
6 | .use(require('kool-shell/plugins/log'), {
7 | level: 'debug',
8 | color: true,
9 | debugPrefix: colors.gray(' → '),
10 | errorPrefix: colors.red(' × '),
11 | warnPrefix: colors.red(' ! ')
12 | })
13 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "unboil",
3 | "version": "0.1.3",
4 | "description": "Boilerplate customiser for lazy people",
5 | "main": "bin/unboil.js",
6 | "bin": {
7 | "unboil": "bin/unboil.js"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/brocessing/unboil.git"
12 | },
13 | "author": "Brocessing",
14 | "license": "MIT",
15 | "bugs": {
16 | "url": "https://github.com/brocessing/unboil/issues"
17 | },
18 | "homepage": "https://github.com/brocessing/unboil#readme",
19 | "dependencies": {
20 | "fs-extra": "^4.0.1",
21 | "kool-shell": "^1.5.0",
22 | "run-waterfall": "^1.1.3",
23 | "slug": "^0.9.1"
24 | },
25 | "devDependencies": {},
26 | "scripts": {
27 | "test": "echo \"Error: no test specified\" && exit 1"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/templates/licenses/agpl3.txt:
--------------------------------------------------------------------------------
1 | {{ project }}
2 | Copyright (C) {{ year }} {{ author }}
3 |
4 | This program is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU Affero General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Affero General Public License for more details.
13 |
14 | You should have received a copy of the GNU Affero General Public License
15 | along with this program. If not, see .
16 |
--------------------------------------------------------------------------------
/templates/licenses/apache.txt:
--------------------------------------------------------------------------------
1 | Copyright {{ year }} {{ author }}
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12 | or implied. See the License for the specific language governing
13 | permissions and limitations under the License.
14 |
--------------------------------------------------------------------------------
/templates/licenses/bsd2.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) {{ year }}, {{ author }}
2 |
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without modification,
6 | are permitted provided that the following conditions are met:
7 |
8 | * Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
18 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 |
--------------------------------------------------------------------------------
/templates/licenses/bsd3.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) {{ year }}, {{ author }}
2 |
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without modification,
6 | are permitted provided that the following conditions are met:
7 |
8 | * Redistributions of source code must retain the above copyright notice,
9 | this list of conditions and the following disclaimer.
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 | * Neither the name of {{ project }} nor the names of its contributors
14 | may be used to endorse or promote products derived from this software
15 | without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/templates/licenses/gpl2.txt:
--------------------------------------------------------------------------------
1 | {{ project }}
2 | Copyright (C) {{ year }} {{ author }}
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License along
15 | with this program; if not, write to the Free Software Foundation, Inc.,
16 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--------------------------------------------------------------------------------
/templates/licenses/gpl3.txt:
--------------------------------------------------------------------------------
1 | {{ project }}
2 | Copyright (C) {{ year }} {{ author }}
3 |
4 | This program is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see .
16 |
--------------------------------------------------------------------------------
/templates/licenses/isc.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) {{ year }} {{ author }}
2 |
3 | Permission to use, copy, modify, and distribute this software for any
4 | purpose with or without fee is hereby granted, provided that the above
5 | copyright notice and this permission notice appear in all copies.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--------------------------------------------------------------------------------
/templates/licenses/lgpl.txt:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 |
6 | Everyone is permitted to copy and distribute verbatim copies of this license
7 | document, but changing it is not allowed.
8 |
9 | This version of the GNU Lesser General Public License incorporates the terms
10 | and conditions of version 3 of the GNU General Public License, supplemented
11 | by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, “this License” refers to version 3 of the GNU Lesser General
16 | Public License, and the “GNU GPL” refers to version 3 of the
17 | GNU General Public License.
18 |
19 | “The Library” refers to a covered work governed by this License, other than
20 | an Application or a Combined Work as defined below.
21 |
22 | An “Application” is any work that makes use of an interface provided by the
23 | Library, but which is not otherwise based on the Library. Defining a subclass
24 | of a class defined by the Library is deemed a mode of using an interface
25 | provided by the Library.
26 |
27 | A “Combined Work” is a work produced by combining or linking an Application
28 | with the Library. The particular version of the Library with which the
29 | Combined Work was made is also called the “Linked Version”.
30 |
31 | The “Minimal Corresponding Source” for a Combined Work means the Corresponding
32 | Source for the Combined Work, excluding any source code for portions of the
33 | Combined Work that, considered in isolation, are based on the Application,
34 | and not on the Linked Version.
35 |
36 | The “Corresponding Application Code” for a Combined Work means the object code
37 | and/or source code for the Application, including any data and utility programs
38 | needed for reproducing the Combined Work from the Application, but excluding
39 | the System Libraries of the Combined Work.
40 |
41 | 1. Exception to Section 3 of the GNU GPL.
42 |
43 | You may convey a covered work under sections 3 and 4 of this License without
44 | being bound by section 3 of the GNU GPL.
45 |
46 | 2. Conveying Modified Versions.
47 |
48 | If you modify a copy of the Library, and, in your modifications, a facility
49 | refers to a function or data to be supplied by an Application that uses the
50 | facility (other than as an argument passed when the facility is invoked),
51 | then you may convey a copy of the modified version:
52 |
53 | a) under this License, provided that you make a good faith effort to
54 | ensure that, in the event an Application does not supply the function or
55 | data, the facility still operates, and performs whatever part of its
56 | purpose remains meaningful, or
57 |
58 | b) under the GNU GPL, with none of the additional permissions of this
59 | License applicable to that copy.
60 |
61 | 3. Object Code Incorporating Material from Library Header Files.
62 |
63 | The object code form of an Application may incorporate material from a header
64 | file that is part of the Library. You may convey such object code under terms
65 | of your choice, provided that, if the incorporated material is not limited to
66 | numerical parameters, data structure layouts and accessors, or small macros,
67 | inline functions and templates (ten or fewer lines in length),
68 | you do both of the following:
69 |
70 | a) Give prominent notice with each copy of the object code that the Library
71 | is used in it and that the Library and its use are covered by this License.
72 |
73 | b) Accompany the object code with a copy of the GNU GPL
74 | and this license document.
75 |
76 | 4. Combined Works.
77 |
78 | You may convey a Combined Work under terms of your choice that, taken together,
79 | effectively do not restrict modification of the portions of the Library
80 | contained in the Combined Work and reverse engineering for debugging such
81 | modifications, if you also do each of the following:
82 |
83 | a) Give prominent notice with each copy of the Combined Work that the
84 | Library is used in it and that the Library and its use are covered
85 | by this License.
86 |
87 | b) Accompany the Combined Work with a copy of the GNU GPL and
88 | this license document.
89 |
90 | c) For a Combined Work that displays copyright notices during execution,
91 | include the copyright notice for the Library among these notices, as well
92 | as a reference directing the user to the copies of the GNU GPL
93 | and this license document.
94 |
95 | d) Do one of the following:
96 |
97 | 0) Convey the Minimal Corresponding Source under the terms of this
98 | License, and the Corresponding Application Code in a form suitable
99 | for, and under terms that permit, the user to recombine or relink
100 | the Application with a modified version of the Linked Version to
101 | produce a modified Combined Work, in the manner specified by section 6
102 | of the GNU GPL for conveying Corresponding Source.
103 |
104 | 1) Use a suitable shared library mechanism for linking with the
105 | Library. A suitable mechanism is one that (a) uses at run time a
106 | copy of the Library already present on the user's computer system,
107 | and (b) will operate properly with a modified version of the Library
108 | that is interface-compatible with the Linked Version.
109 |
110 | e) Provide Installation Information, but only if you would otherwise be
111 | required to provide such information under section 6 of the GNU GPL, and
112 | only to the extent that such information is necessary to install and
113 | execute a modified version of the Combined Work produced by recombining
114 | or relinking the Application with a modified version of the Linked Version.
115 | (If you use option 4d0, the Installation Information must accompany the
116 | Minimal Corresponding Source and Corresponding Application Code. If you
117 | use option 4d1, you must provide the Installation Information in the
118 | manner specified by section 6 of the GNU GPL for
119 | conveying Corresponding Source.)
120 |
121 | 5. Combined Libraries.
122 |
123 | You may place library facilities that are a work based on the Library side by
124 | side in a single library together with other library facilities that are not
125 | Applications and are not covered by this License, and convey such a combined
126 | library under terms of your choice, if you do both of the following:
127 |
128 | a) Accompany the combined library with a copy of the same work based on
129 | the Library, uncombined with any other library facilities, conveyed under
130 | the terms of this License.
131 |
132 | b) Give prominent notice with the combined library that part of it is a
133 | work based on the Library, and explaining where to find the accompanying
134 | uncombined form of the same work.
135 |
136 | 6. Revised Versions of the GNU Lesser General Public License.
137 |
138 | The Free Software Foundation may publish revised and/or new versions of the
139 | GNU Lesser General Public License from time to time. Such new versions will
140 | be similar in spirit to the present version, but may differ in detail to
141 | address new problems or concerns.
142 |
143 | Each version is given a distinguishing version number. If the Library as you
144 | received it specifies that a certain numbered version of the GNU Lesser
145 | General Public License “or any later version” applies to it, you have the
146 | option of following the terms and conditions either of that published version
147 | or of any later version published by the Free Software Foundation. If the
148 | Library as you received it does not specify a version number of the GNU Lesser
149 | General Public License, you may choose any version of the GNU Lesser General
150 | Public License ever published by the Free Software Foundation.
151 |
152 | If the Library as you received it specifies that a proxy can decide whether
153 | future versions of the GNU Lesser General Public License shall apply, that
154 | proxy's public statement of acceptance of any version is permanent
155 | authorization for you to choose that version for the Library.
156 |
--------------------------------------------------------------------------------
/templates/licenses/mit.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) {{ year }} {{ author }}
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy
5 | of this software and associated documentation files (the "Software"), to deal
6 | in the Software without restriction, including without limitation the rights
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/templates/licenses/mpl.txt:
--------------------------------------------------------------------------------
1 | This Source Code Form is subject to the terms of the
2 | Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed
3 | with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 |
--------------------------------------------------------------------------------
/templates/licenses/wtfpl.txt:
--------------------------------------------------------------------------------
1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2 | Version 2, December 2004
3 |
4 | Copyright (C) {{ year }} {{ author }}
5 |
6 | Everyone is permitted to copy and distribute verbatim or modified
7 | copies of this license document, and changing it is allowed as long
8 | as the name is changed.
9 |
10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12 |
13 | 0. You just DO WHAT THE FUCK YOU WANT TO.
14 |
15 |
--------------------------------------------------------------------------------
/templates/readme.txt:
--------------------------------------------------------------------------------
1 | # {{ project }}
2 | > {{ description }}
3 |
--------------------------------------------------------------------------------