create-juisy 2.0.0-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +162 -0
- package/package.json +63 -0
- package/template/.env.example +4 -0
- package/template/CHANGELOG.md +0 -0
- package/template/bin/cli/cli.js +27 -0
- package/template/bin/cli/cmds/index.js +13 -0
- package/template/bin/cli/cmds/private/changelog.js +44 -0
- package/template/bin/cli/cmds/private/docs/generate-api.js +22 -0
- package/template/bin/cli/cmds/private/docs/generate-cli.js +11 -0
- package/template/bin/cli/cmds/private/docs/generate-readme.js +11 -0
- package/template/bin/cli/cmds/private/docs/index.js +20 -0
- package/template/bin/cli/cmds/private/docs/lint.js +42 -0
- package/template/bin/cli/cmds/private/git-hooks/index.js +20 -0
- package/template/bin/cli/cmds/private/git-hooks/reset.js +48 -0
- package/template/bin/cli/cmds/private/git-hooks/sync.js +19 -0
- package/template/bin/cli/cmds/private/release.js +223 -0
- package/template/bin/cli/cmds/private/test.js +33 -0
- package/template/bin/cli/index.js +7 -0
- package/template/bin/cli/lib/docs/generate-api-doc.js +33 -0
- package/template/bin/cli/lib/release/generate-release-note.js +3 -0
- package/template/bin/cli/lib/version/update-version.js +51 -0
- package/template/bin/scripts/commit-msg.js +42 -0
- package/template/bin/scripts/pre-commit.js +32 -0
- package/template/dev.config.js +34 -0
- package/template/dev.config.json +27 -0
- package/template/dev.config.ts +28 -0
- package/template/docs/api/docs.config.js +10 -0
- package/template/docs/readme/config.js +22 -0
- package/template/docs/readme/readme.js +70 -0
- package/template/docs/readme/template.md +53 -0
- package/template/package.json +25 -0
- package/template/project.globals.js +33 -0
package/index.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Create a new Juisy project
|
|
5
|
+
* @author Hervé Perchec
|
|
6
|
+
* @see https://github.com/hperchec/juisy
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import fs from 'node:fs'
|
|
10
|
+
import path, { dirname } from 'node:path'
|
|
11
|
+
import { fileURLToPath } from 'node:url'
|
|
12
|
+
import mri from 'mri'
|
|
13
|
+
import { eject } from 'juisy'
|
|
14
|
+
import { InterfaceUtils, OutputUtils } from 'juisy/cli'
|
|
15
|
+
|
|
16
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
17
|
+
const __dirname = dirname(__filename)
|
|
18
|
+
|
|
19
|
+
const {
|
|
20
|
+
run,
|
|
21
|
+
prompts
|
|
22
|
+
} = InterfaceUtils
|
|
23
|
+
|
|
24
|
+
const {
|
|
25
|
+
$style,
|
|
26
|
+
log,
|
|
27
|
+
step,
|
|
28
|
+
substep
|
|
29
|
+
} = OutputUtils
|
|
30
|
+
|
|
31
|
+
// Use `mri` library to parse command line arguments
|
|
32
|
+
// Usage: npm create juisy <project-name> -- [--template|-t <template>] [--force|-f]
|
|
33
|
+
const argv = mri(process.argv.slice(2), {
|
|
34
|
+
alias: { t: 'template', f: 'force' },
|
|
35
|
+
boolean: [ 'force' ],
|
|
36
|
+
string: [ 'template' ]
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const cwd = process.cwd()
|
|
40
|
+
|
|
41
|
+
// Get juisy version from this package.json file
|
|
42
|
+
const { version: JUISY_VERSION } = JSON.parse(
|
|
43
|
+
fs.readFileSync(path.resolve(__dirname, './package.json'), 'utf-8')
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
const defaultTargetDir = 'juisy-project'
|
|
47
|
+
|
|
48
|
+
const rmTrailingSlashes = str => str.trim().replace(/\/+$/g, '') // remove trailing slashes
|
|
49
|
+
|
|
50
|
+
async function main () {
|
|
51
|
+
// Get target dir argument (optional)
|
|
52
|
+
let targetDir = argv._[0]
|
|
53
|
+
? rmTrailingSlashes(String(argv._[0])) // remove trailing slashes
|
|
54
|
+
: undefined
|
|
55
|
+
|
|
56
|
+
let devConfigFormat = '.ts' // default is typescript config
|
|
57
|
+
|
|
58
|
+
// Project name (& directory name)
|
|
59
|
+
if (!targetDir) {
|
|
60
|
+
const promptsResult = await prompts([
|
|
61
|
+
{
|
|
62
|
+
type: 'text',
|
|
63
|
+
message: 'Project name (directory):',
|
|
64
|
+
initial: defaultTargetDir,
|
|
65
|
+
name: 'projectName'
|
|
66
|
+
}
|
|
67
|
+
])
|
|
68
|
+
targetDir = rmTrailingSlashes(promptsResult.projectName)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Dev config format
|
|
72
|
+
const promptsResult = await prompts([
|
|
73
|
+
{
|
|
74
|
+
type: 'select',
|
|
75
|
+
message: 'Dev config format:',
|
|
76
|
+
choices: [
|
|
77
|
+
{ title: 'TypeScript', description: 'dev.config.ts', value: '.ts' },
|
|
78
|
+
{ title: 'JavaScript', description: 'dev.config.js', value: '.js' },
|
|
79
|
+
{ title: 'JSON', description: 'dev.config.json', value: '.json' }
|
|
80
|
+
],
|
|
81
|
+
initial: 0,
|
|
82
|
+
name: 'devConfigFormat'
|
|
83
|
+
}
|
|
84
|
+
])
|
|
85
|
+
devConfigFormat = promptsResult.devConfigFormat
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Eject files from template
|
|
89
|
+
*/
|
|
90
|
+
step('Copying files')
|
|
91
|
+
|
|
92
|
+
await eject(path.resolve(__dirname, './template'), '**/*', {
|
|
93
|
+
force: argv.force,
|
|
94
|
+
targetDir: path.resolve(cwd, targetDir),
|
|
95
|
+
ignoreFiles: [
|
|
96
|
+
'dev.config.ts',
|
|
97
|
+
'dev.config.js',
|
|
98
|
+
'dev.config.json'
|
|
99
|
+
].filter(identifier => !identifier.endsWith(devConfigFormat)), // don't ignore dev config file of chosen format
|
|
100
|
+
logLevel: 'warn',
|
|
101
|
+
processor: (content, identifier) => {
|
|
102
|
+
if (identifier === 'package.json') {
|
|
103
|
+
return content.replace(/__JUISY_VERSION__/g, JUISY_VERSION)
|
|
104
|
+
} else {
|
|
105
|
+
return content
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
substep($style.green(`✔ Successfuly copied`), { last: true })
|
|
111
|
+
log() // Blank line
|
|
112
|
+
|
|
113
|
+
const targetCliCommand = 'node ./bin/cli'
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Update package.json file
|
|
117
|
+
*/
|
|
118
|
+
const scripts = {
|
|
119
|
+
'docs:api': `${targetCliCommand} docs generate -c ./docs/docs.config.js`,
|
|
120
|
+
'docs:readme': `${targetCliCommand} docs generate:readme`,
|
|
121
|
+
'docs:lint': `${targetCliCommand} docs lint`,
|
|
122
|
+
'docs:lint:fix': 'npm run docs:lint -- --fix',
|
|
123
|
+
'docs': 'npm run docs:readme && npm run docs:api && npm run docs:lint',
|
|
124
|
+
'lint': `${targetCliCommand} lint`,
|
|
125
|
+
'lint:fix': 'npm run lint -- --fix',
|
|
126
|
+
'lint:markdown': 'npm run docs:lint',
|
|
127
|
+
'lint:markdown:fix': 'npm run docs:lint:fix',
|
|
128
|
+
'release': `${targetCliCommand} release`,
|
|
129
|
+
'changelog': `${targetCliCommand} changelog`,
|
|
130
|
+
'git-hooks:reset': `${targetCliCommand} git-hooks reset`,
|
|
131
|
+
'git-hooks:sync': `${targetCliCommand} git-hooks sync`,
|
|
132
|
+
'test': `${targetCliCommand} test`
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
step('Adding scripts to package.json')
|
|
136
|
+
const pkg = JSON.parse(
|
|
137
|
+
fs.readFileSync(path.join(path.resolve(cwd, targetDir), 'package.json'), 'utf-8')
|
|
138
|
+
)
|
|
139
|
+
pkg.scripts = pkg.scripts || {}
|
|
140
|
+
|
|
141
|
+
for (const scriptName of Object.keys(scripts)) {
|
|
142
|
+
// Is script already defined?
|
|
143
|
+
const setScript = pkg.scripts[scriptName]
|
|
144
|
+
? argv.force
|
|
145
|
+
: true
|
|
146
|
+
const isLastStep = scriptName === Object.keys(scripts)[Object.keys(scripts).length - 1]
|
|
147
|
+
if (setScript) {
|
|
148
|
+
await run('npm', [ 'set-script', scriptName, scripts[scriptName] ], { stdio: 'pipe', cwd: path.resolve(cwd, targetDir) })
|
|
149
|
+
substep($style.green(`✔ Script "${scriptName}" successfuly added`), { last: isLastStep })
|
|
150
|
+
} else {
|
|
151
|
+
substep($style.yellow(`Script "${scriptName}" already set. Use --force option to overwrite`), { last: isLastStep })
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
log() // Blank line
|
|
156
|
+
log('You should now move into the created folder and run the following command:\n - npm install')
|
|
157
|
+
log() // Blank line
|
|
158
|
+
log('You can use feature of .env file by copying .env.example:\n - cp .env.example .env')
|
|
159
|
+
log() // Blank line
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
main()
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-juisy",
|
|
3
|
+
"version": "2.0.0-beta.9",
|
|
4
|
+
"description": "Juisy boilerplate for npm init",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"create-juisy": "index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"template",
|
|
11
|
+
"index.js"
|
|
12
|
+
],
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"release": "release-it",
|
|
18
|
+
"test": "echo No test found..."
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://gitlab.com/hperchec/juisy.git"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"js",
|
|
26
|
+
"build",
|
|
27
|
+
"release",
|
|
28
|
+
"changelog",
|
|
29
|
+
"bin",
|
|
30
|
+
"cmd",
|
|
31
|
+
"easy"
|
|
32
|
+
],
|
|
33
|
+
"author": {
|
|
34
|
+
"name": "Hervé Perchec",
|
|
35
|
+
"email": "contact@herve-perchec.com",
|
|
36
|
+
"url": "https://gitlab.com/herveperchec"
|
|
37
|
+
},
|
|
38
|
+
"license": "GPL-3.0-only",
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://gitlab.com/hperchec/juisy/issues"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://gitlab.com/hperchec/juisy#readme",
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"juisy": "2.0.0-beta.9"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"execa": "^8",
|
|
48
|
+
"mri": "^1.2.0"
|
|
49
|
+
},
|
|
50
|
+
"release-it": {
|
|
51
|
+
"git": false,
|
|
52
|
+
"plugins": {
|
|
53
|
+
"@release-it/bumper": {
|
|
54
|
+
"out": {
|
|
55
|
+
"file": "package.json",
|
|
56
|
+
"path": [
|
|
57
|
+
"devDependencies.juisy"
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const { createCli, utils } = require('@hperchec/juisy')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const {
|
|
4
|
+
rootDir,
|
|
5
|
+
$style
|
|
6
|
+
} = utils
|
|
7
|
+
// Get package.json content
|
|
8
|
+
const packageJson = require(path.resolve(rootDir, './package.json'))
|
|
9
|
+
|
|
10
|
+
function getBanner () {
|
|
11
|
+
let str = ''
|
|
12
|
+
const title = $style.bold('CLI: ') + packageJson.name
|
|
13
|
+
const length = title.length - 9 // removes characters generated by $style.bold from length
|
|
14
|
+
str += $style.cyan('-'.repeat(length) + '\n')
|
|
15
|
+
str += $style.cyan(title + '\n')
|
|
16
|
+
str += $style.cyan('-'.repeat(length) + '\n')
|
|
17
|
+
str += $style.italic('Made with') + ' ' + $style.red('❤') + ' ' + $style.italic('by ') + $style.bold('Hervé Perchec <contact@herve-perchec.com') + '\n'
|
|
18
|
+
return str
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// CLI
|
|
22
|
+
module.exports = createCli(cli => cli
|
|
23
|
+
.scriptName('./bin/cli')
|
|
24
|
+
.usage(`${getBanner()}\nUsage: $0 <command> [<options>]`)
|
|
25
|
+
.commandDir('cmds')
|
|
26
|
+
.demandCommand(1, ('Command is missing. See help to learn more.').red)
|
|
27
|
+
)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Private commands
|
|
2
|
+
import docs from './private/docs/index.js'
|
|
3
|
+
import release from './private/release.js'
|
|
4
|
+
import test from './private/test.js'
|
|
5
|
+
|
|
6
|
+
export const commands = [
|
|
7
|
+
// Private commands
|
|
8
|
+
docs,
|
|
9
|
+
release,
|
|
10
|
+
test
|
|
11
|
+
// Public commands
|
|
12
|
+
// ...
|
|
13
|
+
]
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** @type {import('juisy/cli').Command} */
|
|
2
|
+
export default new CLI.Command({
|
|
3
|
+
command: 'changelog',
|
|
4
|
+
describe: 'Generate CHANGELOG file',
|
|
5
|
+
meta: {
|
|
6
|
+
private: true
|
|
7
|
+
},
|
|
8
|
+
builder: function (cli) {
|
|
9
|
+
return cli.option('i', {
|
|
10
|
+
alias: 'infile',
|
|
11
|
+
type: 'string',
|
|
12
|
+
describe: 'Same as conventional-changelog option',
|
|
13
|
+
default: 'CHANGELOG.md',
|
|
14
|
+
requiresArg: true
|
|
15
|
+
})
|
|
16
|
+
},
|
|
17
|
+
async handler (argv) {
|
|
18
|
+
// Utils
|
|
19
|
+
const { $style, step, substep, error } = CLI.OutputUtils
|
|
20
|
+
const { run, wait } = CLI.InterfaceUtils
|
|
21
|
+
/**
|
|
22
|
+
* Generate changelog file
|
|
23
|
+
*/
|
|
24
|
+
step('Generating changelog')
|
|
25
|
+
await wait('Generating', async () => {
|
|
26
|
+
try {
|
|
27
|
+
await run(
|
|
28
|
+
'npx',
|
|
29
|
+
[
|
|
30
|
+
'conventional-changelog',
|
|
31
|
+
'-p', 'angular',
|
|
32
|
+
'-i', argv.infile,
|
|
33
|
+
'-s' // same file to output
|
|
34
|
+
],
|
|
35
|
+
{ stdio: 'pipe' }
|
|
36
|
+
)
|
|
37
|
+
} catch (e) {
|
|
38
|
+
error('Unable to generate changelog', e)
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
substep($style.green('✔ Success'), { last: true })
|
|
42
|
+
this.log() // Blank line
|
|
43
|
+
}
|
|
44
|
+
})
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** @type {import('juisy/cli').Command} */
|
|
2
|
+
export default new CLI.Command({
|
|
3
|
+
command: 'generate:api',
|
|
4
|
+
describe: 'Generate API docs from source code',
|
|
5
|
+
builder (cli) {
|
|
6
|
+
cli
|
|
7
|
+
},
|
|
8
|
+
async handler (argv) {
|
|
9
|
+
// Utils
|
|
10
|
+
const { $style, step, substep } = CLI.OutputUtils
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Generate api documentation
|
|
14
|
+
*/
|
|
15
|
+
step('Generating API documentation')
|
|
16
|
+
|
|
17
|
+
substep($style.yellow('⚠ This command does nothing...'), { last: true })
|
|
18
|
+
this.log() // blank line
|
|
19
|
+
this.log($style.yellow('You can use JSDoc or TypeDoc for example. See documentation'))
|
|
20
|
+
this.log() // blank line
|
|
21
|
+
}
|
|
22
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ReadmeTemplater } from 'juisy/templater'
|
|
2
|
+
|
|
3
|
+
/** @type {import('juisy/cli').Command} */
|
|
4
|
+
export default new CLI.Command({
|
|
5
|
+
command: 'generate:cli',
|
|
6
|
+
describe: 'Generate CLI docs',
|
|
7
|
+
async handler (argv) {
|
|
8
|
+
const templater = new ReadmeTemplater('./docs/cli/config.js')
|
|
9
|
+
await templater.generate()
|
|
10
|
+
}
|
|
11
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ReadmeTemplater } from 'juisy/templater'
|
|
2
|
+
|
|
3
|
+
/** @type {import('juisy/cli').Command} */
|
|
4
|
+
export default new CLI.Command({
|
|
5
|
+
command: 'generate:readme',
|
|
6
|
+
describe: 'Generate README.md',
|
|
7
|
+
async handler (argv) {
|
|
8
|
+
const templater = new ReadmeTemplater('./docs/readme/config.js')
|
|
9
|
+
await templater.generate()
|
|
10
|
+
}
|
|
11
|
+
})
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import generateAPI from './generate-api.js'
|
|
2
|
+
|
|
3
|
+
/** @type {import('juisy/cli').Command} */
|
|
4
|
+
export default new CLI.Command({
|
|
5
|
+
command: 'docs <command>',
|
|
6
|
+
describe: 'Manage project documentation',
|
|
7
|
+
meta: {
|
|
8
|
+
private: true
|
|
9
|
+
},
|
|
10
|
+
builder (cli) {
|
|
11
|
+
return cli
|
|
12
|
+
.command([
|
|
13
|
+
/**
|
|
14
|
+
* Default command are automatically injected here...
|
|
15
|
+
*/
|
|
16
|
+
generateAPI
|
|
17
|
+
])
|
|
18
|
+
},
|
|
19
|
+
handler (argv) {}
|
|
20
|
+
})
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** @type {import('juisy/cli').Command} */
|
|
2
|
+
export default new CLI.Command({
|
|
3
|
+
command: 'lint',
|
|
4
|
+
describe: 'Lint markdown with markdownlint',
|
|
5
|
+
builder: function (cli) {
|
|
6
|
+
cli.option('c', {
|
|
7
|
+
alias: 'config',
|
|
8
|
+
type: 'string',
|
|
9
|
+
describe: 'Path to custom markdownlint config file (relative to root folder)',
|
|
10
|
+
requiresArg: true
|
|
11
|
+
})
|
|
12
|
+
cli.option('f', {
|
|
13
|
+
alias: 'fix',
|
|
14
|
+
type: 'boolean',
|
|
15
|
+
describe: 'Auto fix by passing --fix option to markdownlint-cli2',
|
|
16
|
+
default: false
|
|
17
|
+
})
|
|
18
|
+
return cli
|
|
19
|
+
},
|
|
20
|
+
async handler (argv) {
|
|
21
|
+
const { abort, run } = CLI.InterfaceUtils
|
|
22
|
+
const configPath = argv.config || './docs/.markdownlint-cli2.cjs' // default relative to root folder
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Call markdownlint command
|
|
26
|
+
*/
|
|
27
|
+
try {
|
|
28
|
+
await run(
|
|
29
|
+
'npx',
|
|
30
|
+
[
|
|
31
|
+
'markdownlint-cli2',
|
|
32
|
+
'--config',
|
|
33
|
+
configPath,
|
|
34
|
+
...(argv.fix ? [ '--fix' ] : [])
|
|
35
|
+
],
|
|
36
|
+
{ stdio: 'inherit' }
|
|
37
|
+
)
|
|
38
|
+
} catch (error) {
|
|
39
|
+
abort(error.exitCode)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
})
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import reset from './reset.js'
|
|
2
|
+
import sync from './sync.js'
|
|
3
|
+
|
|
4
|
+
/** @type {import('juisy/cli').Command} */
|
|
5
|
+
export default new CLI.Command({
|
|
6
|
+
command: 'git-hooks <command>',
|
|
7
|
+
describe: 'Git relative commands',
|
|
8
|
+
meta: {
|
|
9
|
+
private: true
|
|
10
|
+
},
|
|
11
|
+
builder: function (cli) {
|
|
12
|
+
return cli
|
|
13
|
+
.command([
|
|
14
|
+
reset,
|
|
15
|
+
sync
|
|
16
|
+
])
|
|
17
|
+
.demandCommand(1, 'Command is missing. See help to learn more.')
|
|
18
|
+
},
|
|
19
|
+
handler: async function (argv) {}
|
|
20
|
+
})
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import fs from 'fs-extra'
|
|
3
|
+
|
|
4
|
+
/** @type {import('juisy/cli').Command} */
|
|
5
|
+
export default new CLI.Command({
|
|
6
|
+
command: 'reset',
|
|
7
|
+
describe: 'Reset git hooks',
|
|
8
|
+
builder (cli) {
|
|
9
|
+
return cli
|
|
10
|
+
},
|
|
11
|
+
async handler (argv) {
|
|
12
|
+
// Utils
|
|
13
|
+
const { $style, step, substep } = CLI.OutputUtils
|
|
14
|
+
const { rootDir, run, abort } = CLI.InterfaceUtils
|
|
15
|
+
/**
|
|
16
|
+
* Reset git hooks
|
|
17
|
+
*/
|
|
18
|
+
step('Reset git hooks')
|
|
19
|
+
|
|
20
|
+
// Create temporary empty configuration file
|
|
21
|
+
const tempConfigFilePath = './__TEMP_SIMPLE_GIT_HOOKS_CONFIG__.json' // relative to project root folder
|
|
22
|
+
fs.writeFileSync(path.resolve(rootDir, tempConfigFilePath), '{}')
|
|
23
|
+
|
|
24
|
+
// Run command with empty configuration
|
|
25
|
+
let commandError = false
|
|
26
|
+
try {
|
|
27
|
+
await run('npx', [
|
|
28
|
+
'simple-git-hooks',
|
|
29
|
+
tempConfigFilePath
|
|
30
|
+
], { stdio: 'pipe', cwd: rootDir })
|
|
31
|
+
} catch (e) {
|
|
32
|
+
commandError = e
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Don't forget to always remove temporary file
|
|
36
|
+
fs.unlinkSync(path.resolve(rootDir, tempConfigFilePath))
|
|
37
|
+
|
|
38
|
+
// If error
|
|
39
|
+
if (commandError) {
|
|
40
|
+
substep($style.red('❌ Unable to reset git hooks.'), { last: true })
|
|
41
|
+
abort(1) // Abort with error
|
|
42
|
+
} else {
|
|
43
|
+
// Everything is okay
|
|
44
|
+
substep($style.green('✔ Git hooks successfuly reset'), { last: true })
|
|
45
|
+
this.log() // blank line
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
})
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** @type {import('juisy/cli').Command} */
|
|
2
|
+
export default new CLI.Command({
|
|
3
|
+
command: 'sync',
|
|
4
|
+
describe: 'Sync git hooks',
|
|
5
|
+
builder (cli) {
|
|
6
|
+
return cli
|
|
7
|
+
},
|
|
8
|
+
async handler (argv) {
|
|
9
|
+
// Utils
|
|
10
|
+
const { step } = CLI.OutputUtils
|
|
11
|
+
const { run } = CLI.InterfaceUtils
|
|
12
|
+
/**
|
|
13
|
+
* Sync git hooks
|
|
14
|
+
*/
|
|
15
|
+
step('Sync git hooks')
|
|
16
|
+
|
|
17
|
+
await run('npx', [ 'simple-git-hooks' ])
|
|
18
|
+
}
|
|
19
|
+
})
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
// const path = require('path')
|
|
2
|
+
// const {
|
|
3
|
+
// $style,
|
|
4
|
+
// log,
|
|
5
|
+
// step,
|
|
6
|
+
// substep,
|
|
7
|
+
// run,
|
|
8
|
+
// error,
|
|
9
|
+
// wait,
|
|
10
|
+
// confirm,
|
|
11
|
+
// prompts
|
|
12
|
+
// } = juisy.utils
|
|
13
|
+
|
|
14
|
+
// const rootDir = path.resolve(__dirname, '../../../')
|
|
15
|
+
|
|
16
|
+
// const updateVersion = require('../lib/version/update-version')
|
|
17
|
+
|
|
18
|
+
import semver from 'semver'
|
|
19
|
+
|
|
20
|
+
import { getPackageInfo } from 'juisy'
|
|
21
|
+
|
|
22
|
+
/** @type {import('juisy/cli').Command} */
|
|
23
|
+
export default new CLI.Command({
|
|
24
|
+
command: 'release',
|
|
25
|
+
describe: 'Make a release',
|
|
26
|
+
meta: {
|
|
27
|
+
private: true
|
|
28
|
+
},
|
|
29
|
+
builder: function (cli) {
|
|
30
|
+
cli.option('p', {
|
|
31
|
+
alias: 'preid',
|
|
32
|
+
type: 'string',
|
|
33
|
+
describe: 'Pre-release id',
|
|
34
|
+
requiresArg: true
|
|
35
|
+
})
|
|
36
|
+
return cli
|
|
37
|
+
},
|
|
38
|
+
async handler (argv) {
|
|
39
|
+
const { step } = CLI.OutputUtils
|
|
40
|
+
const { abort, run } = CLI.InterfaceUtils
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Generate docs
|
|
44
|
+
*/
|
|
45
|
+
step('Release-it')
|
|
46
|
+
await run('npx', [ 'release-it' ], { stdio: 'pipe' })
|
|
47
|
+
|
|
48
|
+
// const packageJson = getPackageInfo()
|
|
49
|
+
// let targetVersion
|
|
50
|
+
// const currentVersion = packageJson.version
|
|
51
|
+
// const packageName = packageJson.name
|
|
52
|
+
// const preId = argv.preid || (semver.prerelease(currentVersion) && semver.prerelease(currentVersion)[0])
|
|
53
|
+
// const inc = i => semver.inc(currentVersion, i, preId)
|
|
54
|
+
// const versionIncrements = [
|
|
55
|
+
// 'patch',
|
|
56
|
+
// 'minor',
|
|
57
|
+
// 'major',
|
|
58
|
+
// ...(preId ? [ 'prepatch', 'preminor', 'premajor', 'prerelease' ] : [])
|
|
59
|
+
// ]
|
|
60
|
+
|
|
61
|
+
// /**
|
|
62
|
+
// * First, check if local repository is clean
|
|
63
|
+
// */
|
|
64
|
+
// step('Checking changes to commit')
|
|
65
|
+
// const { stdout } = await run('git', [ 'diff' ], { stdio: 'pipe', cwd: rootDir })
|
|
66
|
+
// if (stdout) {
|
|
67
|
+
// error('Please commit your changes before creating a new release!', new Error('There are changes to commit'))
|
|
68
|
+
// }
|
|
69
|
+
// substep($style.green('✔ Local repository is clean'), { last: true })
|
|
70
|
+
// log() // Blank line
|
|
71
|
+
|
|
72
|
+
// /**
|
|
73
|
+
// * Release prompt
|
|
74
|
+
// */
|
|
75
|
+
// step('Setup')
|
|
76
|
+
// const { release } = await prompts([
|
|
77
|
+
// {
|
|
78
|
+
// type: 'select',
|
|
79
|
+
// name: 'release',
|
|
80
|
+
// message: 'Release type:',
|
|
81
|
+
// choices: versionIncrements.map(i => ({ title: `${i} (${inc(i)})`, value: inc(i) })).concat([ { title: 'custom', value: 'custom' } ])
|
|
82
|
+
// }
|
|
83
|
+
// ])
|
|
84
|
+
// // If custom release
|
|
85
|
+
// if (release === 'custom') {
|
|
86
|
+
// const { version: customVersion } = await prompts([
|
|
87
|
+
// {
|
|
88
|
+
// type: 'text',
|
|
89
|
+
// name: 'version',
|
|
90
|
+
// message: 'New custom version:',
|
|
91
|
+
// initial: currentVersion,
|
|
92
|
+
// validate: value => Boolean(semver.valid(value))
|
|
93
|
+
// }
|
|
94
|
+
// ])
|
|
95
|
+
// targetVersion = customVersion
|
|
96
|
+
// } else {
|
|
97
|
+
// targetVersion = release
|
|
98
|
+
// }
|
|
99
|
+
|
|
100
|
+
// /**
|
|
101
|
+
// * Demand confirmation
|
|
102
|
+
// */
|
|
103
|
+
// await confirm({ message: `Releasing v${targetVersion}. Confirm?` })
|
|
104
|
+
// log() // Blank line
|
|
105
|
+
|
|
106
|
+
// /**
|
|
107
|
+
// * Run tests
|
|
108
|
+
// */
|
|
109
|
+
// // step(`Running tests`)
|
|
110
|
+
// // ... here run tests
|
|
111
|
+
|
|
112
|
+
// /**
|
|
113
|
+
// * Update version in necessary files
|
|
114
|
+
// */
|
|
115
|
+
// await updateVersion(targetVersion)
|
|
116
|
+
// log() // Blank line
|
|
117
|
+
|
|
118
|
+
// /**
|
|
119
|
+
// * Generate docs
|
|
120
|
+
// */
|
|
121
|
+
// step('Generate docs')
|
|
122
|
+
// await wait('API docs', async () => {
|
|
123
|
+
// await run('node', [ './bin/cli', 'docs', 'generate:api' ], { stdio: 'pipe', cwd: rootDir })
|
|
124
|
+
// })
|
|
125
|
+
// substep($style.green('✔ API docs successfuly generated'))
|
|
126
|
+
// await wait('CLI docs', async () => {
|
|
127
|
+
// await run('node', [ './bin/cli', 'docs', 'generate:cli' ], { stdio: 'pipe', cwd: rootDir })
|
|
128
|
+
// })
|
|
129
|
+
// substep($style.green('✔ CLI docs successfuly generated'))
|
|
130
|
+
// await wait('README', async () => {
|
|
131
|
+
// await run('node', [ './bin/cli', 'docs', 'generate:readme' ], { stdio: 'pipe', cwd: rootDir })
|
|
132
|
+
// })
|
|
133
|
+
// substep($style.green('✔ README successfuly generated'), { last: true })
|
|
134
|
+
// // await wait('Linting', async () => {
|
|
135
|
+
// // await run('node', [ './bin/cli', 'docs', 'lint', '-c', './docs/.markdownlint-cli2.cjs' ], { stdio: 'pipe', cwd: rootDir })
|
|
136
|
+
// // })
|
|
137
|
+
// log() // Blank line
|
|
138
|
+
|
|
139
|
+
// /**
|
|
140
|
+
// * Generate changelog file
|
|
141
|
+
// */
|
|
142
|
+
// step('Generating changelog')
|
|
143
|
+
// await wait('Generating', async () => {
|
|
144
|
+
// await run('node', [ './bin/cli', 'changelog' ], { stdio: 'pipe', cwd: rootDir })
|
|
145
|
+
// })
|
|
146
|
+
// substep($style.green('✔ Success'), { last: true })
|
|
147
|
+
// log() // Blank line
|
|
148
|
+
|
|
149
|
+
// /**
|
|
150
|
+
// * Confirm changes to commit
|
|
151
|
+
// */
|
|
152
|
+
// step('Confirm changes to commit')
|
|
153
|
+
// substep($style.yellow('↓ The following changes will be committed:'))
|
|
154
|
+
// await run('git', [ 'status', '-s' ], { stdio: 'inherit', cwd: rootDir })
|
|
155
|
+
// substep($style.yellow('- The following tag will be created: ') + `v${targetVersion}`, { last: true })
|
|
156
|
+
|
|
157
|
+
// /**
|
|
158
|
+
// * Demand confirmation
|
|
159
|
+
// */
|
|
160
|
+
// await confirm()
|
|
161
|
+
// log() // Blank line
|
|
162
|
+
|
|
163
|
+
// /**
|
|
164
|
+
// * Publish package
|
|
165
|
+
// */
|
|
166
|
+
// step(`Publishing ${packageName}`)
|
|
167
|
+
// const releaseTag = targetVersion.includes('alpha')
|
|
168
|
+
// ? 'alpha'
|
|
169
|
+
// : targetVersion.includes('beta')
|
|
170
|
+
// ? 'beta'
|
|
171
|
+
// : targetVersion.includes('rc')
|
|
172
|
+
// ? 'rc'
|
|
173
|
+
// : null
|
|
174
|
+
// let alreadyPublished = false
|
|
175
|
+
// await wait('Publishing', async () => {
|
|
176
|
+
// try {
|
|
177
|
+
// await run('npm', [ 'publish', ...(releaseTag ? [ '--tag', releaseTag ] : []) ], { stdio: 'pipe', cwd: rootDir })
|
|
178
|
+
// } catch (e) {
|
|
179
|
+
// if (e.stderr.match(/previously published/)) {
|
|
180
|
+
// alreadyPublished = true
|
|
181
|
+
// } else {
|
|
182
|
+
// error('Unknown error during publishing', e)
|
|
183
|
+
// }
|
|
184
|
+
// }
|
|
185
|
+
// })
|
|
186
|
+
// substep(
|
|
187
|
+
// alreadyPublished
|
|
188
|
+
// ? $style.yellow(`Skipping already published: ${packageName}`)
|
|
189
|
+
// : $style.green('✔ Success'),
|
|
190
|
+
// { last: true }
|
|
191
|
+
// )
|
|
192
|
+
// log() // Blank line
|
|
193
|
+
|
|
194
|
+
// /**
|
|
195
|
+
// * Push to git
|
|
196
|
+
// */
|
|
197
|
+
// step('Pushing changes')
|
|
198
|
+
// await wait('Committing', async () => {
|
|
199
|
+
// try {
|
|
200
|
+
// await run('git', [ 'add', '.' ], { stdio: 'pipe', cwd: rootDir })
|
|
201
|
+
// await run('git', [ 'commit', '-m', `chore(release): v${targetVersion}` ], { stdio: 'pipe', cwd: rootDir })
|
|
202
|
+
// } catch (e) {
|
|
203
|
+
// error('Unable to commit', e)
|
|
204
|
+
// }
|
|
205
|
+
// })
|
|
206
|
+
// substep($style.green('✔ Committed'))
|
|
207
|
+
// await wait('Creating tag', async () => {
|
|
208
|
+
// try {
|
|
209
|
+
// await run('git', [ 'tag', '-a', `v${targetVersion}`, '-m', `v${targetVersion}` ], { stdio: 'pipe', cwd: rootDir })
|
|
210
|
+
// } catch (e) {
|
|
211
|
+
// error('Unable to create tag', e)
|
|
212
|
+
// }
|
|
213
|
+
// })
|
|
214
|
+
// substep($style.green('✔ Tagged'))
|
|
215
|
+
// log() // blank line
|
|
216
|
+
|
|
217
|
+
// log($style.green(`✔ Release v${targetVersion} successfuly created`))
|
|
218
|
+
// log()
|
|
219
|
+
|
|
220
|
+
// log($style.yellow('IMPORTANT: You should now run ') + 'git push origin --follow-tags')
|
|
221
|
+
// log()
|
|
222
|
+
}
|
|
223
|
+
})
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** @type {import('juisy/cli').Command} */
|
|
2
|
+
export default new CLI.Command({
|
|
3
|
+
command: 'test',
|
|
4
|
+
describe: 'Run project tests',
|
|
5
|
+
meta: {
|
|
6
|
+
private: true
|
|
7
|
+
},
|
|
8
|
+
builder (cli) {
|
|
9
|
+
cli.option('watch', {
|
|
10
|
+
alias: 'w',
|
|
11
|
+
type: 'boolean',
|
|
12
|
+
default: false,
|
|
13
|
+
describe: 'Run vitest in watch mode'
|
|
14
|
+
})
|
|
15
|
+
cli.option('ui', {
|
|
16
|
+
type: 'boolean',
|
|
17
|
+
default: false,
|
|
18
|
+
describe: 'Launch vitest UI'
|
|
19
|
+
})
|
|
20
|
+
return cli
|
|
21
|
+
},
|
|
22
|
+
async handler (args) {
|
|
23
|
+
const watchMode = args.watch || args.ui
|
|
24
|
+
const { run } = CLI.InterfaceUtils
|
|
25
|
+
/**
|
|
26
|
+
* Run tests
|
|
27
|
+
*/
|
|
28
|
+
await run('vitest', [
|
|
29
|
+
...(watchMode ? [] : [ 'run' ]),
|
|
30
|
+
...(args.ui ? [ '--ui' ] : [])
|
|
31
|
+
], { stdio: 'inherit' })
|
|
32
|
+
}
|
|
33
|
+
})
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const fs = require('fs-extra')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const juisy = require('@hperchec/juisy')
|
|
4
|
+
|
|
5
|
+
const {
|
|
6
|
+
rootDir,
|
|
7
|
+
$style,
|
|
8
|
+
step,
|
|
9
|
+
substep
|
|
10
|
+
} = juisy.utils
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Generate doc function
|
|
14
|
+
* @param {Object} [options = {}] - The options object
|
|
15
|
+
*/
|
|
16
|
+
module.exports = async function generateAPIDoc (options = {}) {
|
|
17
|
+
// Process options
|
|
18
|
+
const distDir = options.distDir
|
|
19
|
+
const outputDir = options.outputDir
|
|
20
|
+
|
|
21
|
+
const outputFullPath = path.resolve(rootDir, distDir, outputDir)
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Generate api documentation
|
|
25
|
+
*/
|
|
26
|
+
step('Generating API documentation')
|
|
27
|
+
|
|
28
|
+
// Here do logic to generate your documentation
|
|
29
|
+
// ex: jsdoc
|
|
30
|
+
fs.writeFileSync(path.resolve(outputFullPath, './api.md'), '# Awesome API !', { encoding: 'utf8' })
|
|
31
|
+
|
|
32
|
+
substep($style.yellow('This command just creates an example file. Let\'s write your logic!'), { last: true })
|
|
33
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const juisy = require('@hperchec/juisy')
|
|
4
|
+
|
|
5
|
+
const {
|
|
6
|
+
rootDir,
|
|
7
|
+
$style,
|
|
8
|
+
error,
|
|
9
|
+
step,
|
|
10
|
+
substep,
|
|
11
|
+
run,
|
|
12
|
+
wait
|
|
13
|
+
} = juisy.utils
|
|
14
|
+
|
|
15
|
+
// File paths
|
|
16
|
+
const filePaths = {
|
|
17
|
+
packageJson: path.resolve(rootDir, './package.json')
|
|
18
|
+
}
|
|
19
|
+
// Get package.json content
|
|
20
|
+
const packageJson = require(filePaths.packageJson)
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Update version in necessary files
|
|
24
|
+
* @param {string} version - The version
|
|
25
|
+
* @return {void}
|
|
26
|
+
*/
|
|
27
|
+
module.exports = async function updateVersion (version) {
|
|
28
|
+
// Update version for each file
|
|
29
|
+
packageJson.version = version
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Update files
|
|
33
|
+
*/
|
|
34
|
+
step('Updating version in necessary files')
|
|
35
|
+
// Update package.json
|
|
36
|
+
try {
|
|
37
|
+
fs.writeFileSync(filePaths.packageJson, JSON.stringify(packageJson, null, 4), 'utf8')
|
|
38
|
+
} catch (e) {
|
|
39
|
+
error('Unable to update package.json file', e)
|
|
40
|
+
}
|
|
41
|
+
substep($style.green('✔ package.json successfuly updated'))
|
|
42
|
+
// Updating package-lock
|
|
43
|
+
await wait('Updating package-lock.json', async () => {
|
|
44
|
+
try {
|
|
45
|
+
await run('npm', [ 'install', '--prefer-offline' ], { stdio: 'pipe' })
|
|
46
|
+
} catch (e) {
|
|
47
|
+
error('Unable to update package-lock.json file', e)
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
substep($style.green('✔ package-lock.json successfuly updated'), { last: true })
|
|
51
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const juisy = require('@hperchec/juisy')
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
$style,
|
|
5
|
+
abort,
|
|
6
|
+
log,
|
|
7
|
+
rootDir,
|
|
8
|
+
step,
|
|
9
|
+
substep,
|
|
10
|
+
run
|
|
11
|
+
} = juisy.utils
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* commit-msg git hook
|
|
15
|
+
*/
|
|
16
|
+
;(async function () {
|
|
17
|
+
step('Git hook: commit-msg')
|
|
18
|
+
|
|
19
|
+
// Get git commit msg path from args
|
|
20
|
+
const args = process.argv.slice(2)
|
|
21
|
+
const gitMsgPath = args[0]
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
// original is: npx --no -- commitlint --edit ${1}
|
|
25
|
+
// we replace "${1}" by gitMsgPath arg
|
|
26
|
+
await run('npx', [
|
|
27
|
+
'--no',
|
|
28
|
+
'--',
|
|
29
|
+
'commitlint',
|
|
30
|
+
'--edit',
|
|
31
|
+
gitMsgPath
|
|
32
|
+
], { cwd: rootDir })
|
|
33
|
+
} catch (e) {
|
|
34
|
+
substep($style.red('❌ Git hook: "commit-msg" failed. Please check ./COMMIT_CONVENTION.md for more informations.'), { last: true })
|
|
35
|
+
abort(1) // Abort with error
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Everything is okay
|
|
39
|
+
substep($style.green('✔ Git hook: "commit-msg" passed'), { last: true })
|
|
40
|
+
|
|
41
|
+
log() // blank line
|
|
42
|
+
})()
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const juisy = require('@hperchec/juisy')
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
$style,
|
|
5
|
+
error,
|
|
6
|
+
log,
|
|
7
|
+
rootDir,
|
|
8
|
+
step,
|
|
9
|
+
substep,
|
|
10
|
+
run
|
|
11
|
+
} = juisy.utils
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Pre commit git hook
|
|
15
|
+
*/
|
|
16
|
+
;(async function () {
|
|
17
|
+
step('Git hook: pre-commit')
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
// npx lint-staged
|
|
21
|
+
await run('npx', [
|
|
22
|
+
'lint-staged'
|
|
23
|
+
], { stdio: 'pipe', cwd: rootDir })
|
|
24
|
+
} catch (e) {
|
|
25
|
+
error('Git hook: "commit-msg" error: ', e)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Everything is okay
|
|
29
|
+
substep($style.green('✔ Git hook: "pre-commit" passed'), { last: true })
|
|
30
|
+
|
|
31
|
+
log() // blank line
|
|
32
|
+
})()
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** @type {import('juisy/cli').GlobalSettings} */
|
|
2
|
+
export default {
|
|
3
|
+
changelog: {
|
|
4
|
+
infile: 'CHANGELOG.md',
|
|
5
|
+
preset: 'angular',
|
|
6
|
+
sameFile: true
|
|
7
|
+
},
|
|
8
|
+
docs: {
|
|
9
|
+
readme: {
|
|
10
|
+
config: './docs/readme/config.js'
|
|
11
|
+
},
|
|
12
|
+
cli: {
|
|
13
|
+
config: './docs/cli/config.js'
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
gitHooks: {
|
|
17
|
+
'pre-commit': 'node ./bin/scripts/pre-commit.js',
|
|
18
|
+
'commit-msg': 'node ./bin/scripts/commit-msg.js ${1}'
|
|
19
|
+
},
|
|
20
|
+
lint: {
|
|
21
|
+
staged: {
|
|
22
|
+
'*.{js,cjs,ts}': [
|
|
23
|
+
'eslint --fix'
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
release: {
|
|
28
|
+
git: {
|
|
29
|
+
commitMessage: 'chore(release): v${version}',
|
|
30
|
+
requireBranch: 'main',
|
|
31
|
+
tagAnnotation: 'v${version}'
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./node_modules/juisy/dist/GlobalSettings.schema.json",
|
|
3
|
+
"changelog": {
|
|
4
|
+
"infile": "CHANGELOG.md",
|
|
5
|
+
"preset": "angular",
|
|
6
|
+
"sameFile": true
|
|
7
|
+
},
|
|
8
|
+
"docs": {
|
|
9
|
+
"readme": {
|
|
10
|
+
"config": "./docs/readme/config.js"
|
|
11
|
+
},
|
|
12
|
+
"cli": {
|
|
13
|
+
"config": "./docs/cli/config.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"gitHooks": {
|
|
17
|
+
"pre-commit": "node ./bin/scripts/pre-commit.js",
|
|
18
|
+
"commit-msg": "node ./bin/scripts/commit-msg.js ${1}"
|
|
19
|
+
},
|
|
20
|
+
"lint": {
|
|
21
|
+
"staged": {
|
|
22
|
+
"*.{js,cjs,ts}": [
|
|
23
|
+
"eslint --fix"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { GlobalSettings } from 'juisy/cli'
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
changelog: {
|
|
5
|
+
infile: 'CHANGELOG.md',
|
|
6
|
+
preset: 'angular',
|
|
7
|
+
sameFile: true
|
|
8
|
+
},
|
|
9
|
+
docs: {
|
|
10
|
+
readme: {
|
|
11
|
+
config: './docs/readme/config.js'
|
|
12
|
+
},
|
|
13
|
+
cli: {
|
|
14
|
+
config: './docs/cli/config.js'
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
gitHooks: {
|
|
18
|
+
'pre-commit': 'node ./bin/scripts/pre-commit.js',
|
|
19
|
+
'commit-msg': 'node ./bin/scripts/commit-msg.js ${1}'
|
|
20
|
+
},
|
|
21
|
+
lint: {
|
|
22
|
+
staged: {
|
|
23
|
+
'*.{js,cjs,ts}': [
|
|
24
|
+
'eslint --fix'
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
} satisfies GlobalSettings
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hperchec/readme-generator Example configuration file
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const path = require('path')
|
|
6
|
+
|
|
7
|
+
// Export configuration
|
|
8
|
+
module.exports = {
|
|
9
|
+
// Template path
|
|
10
|
+
templatePath: path.resolve(__dirname, './template.md'), // Default template file
|
|
11
|
+
// Output path
|
|
12
|
+
outputPath: path.resolve(__dirname, '../../'), // Your project root directory by default
|
|
13
|
+
// Output file name
|
|
14
|
+
outputName: 'README.md', // 'README.md' by default
|
|
15
|
+
// Path to ejs data file
|
|
16
|
+
ejsDataPath: path.resolve(__dirname, './readme.js'), // Default template ejs data file
|
|
17
|
+
// EJS options (see https://www.npmjs.com/package/ejs#options)
|
|
18
|
+
ejsOptions: {
|
|
19
|
+
async: true
|
|
20
|
+
/* your ejs options... */
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hperchec/readme-generator Template EJS data example file
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const markdownTable = require('markdown-table') // ! v3 not compatible, use v2
|
|
6
|
+
|
|
7
|
+
// Based on the package.json file, get some data and informations
|
|
8
|
+
const pkg = require('../../package.json')
|
|
9
|
+
const packageName = pkg.name
|
|
10
|
+
const packageUrl = `https://www.npmjs.com/package/${packageName}`
|
|
11
|
+
const dependencies = pkg.dependencies || {}
|
|
12
|
+
const devDependencies = pkg.devDependencies || {}
|
|
13
|
+
const peerDependencies = pkg.peerDependencies || {}
|
|
14
|
+
const author = pkg.author
|
|
15
|
+
const contributors = pkg.contributors || []
|
|
16
|
+
const license = pkg.license || 'Unknown'
|
|
17
|
+
const homepage = pkg.homepage
|
|
18
|
+
const projectUrl = pkg.repository.url
|
|
19
|
+
const issuesUrl = pkg.bugs.url
|
|
20
|
+
|
|
21
|
+
// Output a markdown formatted table from a js object
|
|
22
|
+
// Like:
|
|
23
|
+
// |name|version|
|
|
24
|
+
// |----|-------|
|
|
25
|
+
// | | |
|
|
26
|
+
function getMdDependencies (deps) {
|
|
27
|
+
return markdownTable([
|
|
28
|
+
[ 'name', 'version' ],
|
|
29
|
+
...(Object.entries(deps))
|
|
30
|
+
])
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Return author link
|
|
35
|
+
* @param {Object} author
|
|
36
|
+
* @return {string}
|
|
37
|
+
*/
|
|
38
|
+
function getMdAuthor (author) {
|
|
39
|
+
return '[' + author.name + '](' + author.url + ')'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Return markdown list of persons
|
|
44
|
+
* @param {Array} contributors
|
|
45
|
+
* @return {String}
|
|
46
|
+
*/
|
|
47
|
+
function getMdContributors (contributors) {
|
|
48
|
+
let mdString = ''
|
|
49
|
+
contributors.forEach((person) => {
|
|
50
|
+
mdString += '- [' + person.name + '](' + person.url + ')\n'
|
|
51
|
+
})
|
|
52
|
+
return mdString
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Export data for readme file templating
|
|
57
|
+
*/
|
|
58
|
+
module.exports = {
|
|
59
|
+
packageName,
|
|
60
|
+
packageUrl,
|
|
61
|
+
projectUrl,
|
|
62
|
+
homepage,
|
|
63
|
+
issuesUrl,
|
|
64
|
+
dependencies: getMdDependencies(dependencies),
|
|
65
|
+
devDependencies: getMdDependencies(devDependencies),
|
|
66
|
+
peerDependencies: getMdDependencies(peerDependencies),
|
|
67
|
+
author: getMdAuthor(author),
|
|
68
|
+
contributors: getMdContributors(contributors),
|
|
69
|
+
license
|
|
70
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Awesome project
|
|
2
|
+
|
|
3
|
+
[]()
|
|
4
|
+
[](http://herve-perchec.com/)
|
|
5
|
+
|
|
6
|
+
**Table of contents**:
|
|
7
|
+
|
|
8
|
+
[[*TOC*]]
|
|
9
|
+
|
|
10
|
+
## 🚀 Get started
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
# Let's go!
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## 📙 Documentation
|
|
17
|
+
|
|
18
|
+
Please check the [documentation](https://www.npmjs.com/package/@hperchec/juisy)
|
|
19
|
+
|
|
20
|
+
## 🧱 Dependencies
|
|
21
|
+
|
|
22
|
+
<details>
|
|
23
|
+
<summary>Global</summary>
|
|
24
|
+
|
|
25
|
+
<%%= dependencies %>
|
|
26
|
+
|
|
27
|
+
</details>
|
|
28
|
+
|
|
29
|
+
<details>
|
|
30
|
+
<summary>Dev</summary>
|
|
31
|
+
|
|
32
|
+
<%%= devDependencies %>
|
|
33
|
+
|
|
34
|
+
</details>
|
|
35
|
+
|
|
36
|
+
<details>
|
|
37
|
+
<summary>Peer</summary>
|
|
38
|
+
|
|
39
|
+
<%%= peerDependencies %>
|
|
40
|
+
|
|
41
|
+
</details>
|
|
42
|
+
|
|
43
|
+
## ✍ Author
|
|
44
|
+
|
|
45
|
+
<%%= author %>
|
|
46
|
+
|
|
47
|
+
## 📄 License
|
|
48
|
+
|
|
49
|
+
<%%= license %>
|
|
50
|
+
|
|
51
|
+
----
|
|
52
|
+
|
|
53
|
+
Made with ❤ by <%%= author %>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "new-project",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "New project based on Juisy template",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://gitlab.com/hperchec/juisy.git"
|
|
12
|
+
},
|
|
13
|
+
"author": {
|
|
14
|
+
"name": "Hervé Perchec",
|
|
15
|
+
"url": "https://gitlab.com/herveperchec"
|
|
16
|
+
},
|
|
17
|
+
"license": "ISC",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://gitlab.com/hperchec/juisy/issues"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://gitlab.com/hperchec/juisy#readme",
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"juisy": "^__JUISY_VERSION__"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import pkg from './package.json' assert { type: 'json' }
|
|
2
|
+
|
|
3
|
+
// Exports globals object
|
|
4
|
+
export default {
|
|
5
|
+
ENV: {
|
|
6
|
+
NODE_ENV: process.env.NODE_ENV
|
|
7
|
+
},
|
|
8
|
+
PACKAGE: {
|
|
9
|
+
NAME: pkg.name,
|
|
10
|
+
URL: `https://www.npmjs.com/package/${pkg.name}`
|
|
11
|
+
},
|
|
12
|
+
VERSION: pkg.version,
|
|
13
|
+
AUTHOR: {
|
|
14
|
+
EMAIL: pkg.author.email,
|
|
15
|
+
NAME: pkg.author.name,
|
|
16
|
+
URL: pkg.author.url
|
|
17
|
+
},
|
|
18
|
+
REPOSITORY: {
|
|
19
|
+
TYPE: pkg.repository.type,
|
|
20
|
+
URL: pkg.repository.url
|
|
21
|
+
},
|
|
22
|
+
ISSUES_URL: pkg.bugs.url,
|
|
23
|
+
HOMEPAGE: pkg.homepage,
|
|
24
|
+
BRAND: {
|
|
25
|
+
COLORS: {
|
|
26
|
+
GERALDINE: '#FF8E92',
|
|
27
|
+
SAND: '#FFC17A',
|
|
28
|
+
COGNAC: '#A04113',
|
|
29
|
+
DARK_PINK: '#E95185',
|
|
30
|
+
PINK_SHERBET: '#F583A3'
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|