@npmcli/template-oss 1.0.0 → 2.0.0
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/LICENSE.md +2 -0
- package/bin/npm-template-check.js +29 -0
- package/bin/postinstall.js +15 -13
- package/lib/check.js +95 -0
- package/lib/content/LICENSE.md +2 -0
- package/lib/content/SECURITY.md +1 -0
- package/lib/content/bug.yml +54 -0
- package/lib/content/ci.yml +3 -1
- package/lib/content/config.yml +3 -0
- package/lib/content/eslintrc.js +2 -0
- package/lib/content/gitignore +2 -0
- package/lib/content/index.js +3 -0
- package/lib/package.js +4 -0
- package/package.json +19 -8
- package/lib/install.js +0 -31
package/LICENSE.md
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const check = require('../lib/check.js')
|
|
4
|
+
|
|
5
|
+
const main = async () => {
|
|
6
|
+
const {
|
|
7
|
+
npm_config_local_prefix: root,
|
|
8
|
+
} = process.env
|
|
9
|
+
|
|
10
|
+
if (!root) {
|
|
11
|
+
throw new Error('This package requires npm >7.21.1')
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const problems = await check(root)
|
|
15
|
+
if (problems.length) {
|
|
16
|
+
console.error('Some problems were detected:')
|
|
17
|
+
console.error()
|
|
18
|
+
console.error(problems.map((problem) => problem.message).join('\n'))
|
|
19
|
+
console.error()
|
|
20
|
+
console.error('To correct them:')
|
|
21
|
+
console.error(problems.map((problem) => problem.solution).join('\n'))
|
|
22
|
+
process.exitCode = 1
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = main().catch((err) => {
|
|
27
|
+
console.error(err.stack)
|
|
28
|
+
process.exitCode = 1
|
|
29
|
+
})
|
package/bin/postinstall.js
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const { dirname } = require('path')
|
|
4
|
-
|
|
5
3
|
const copyContent = require('../lib/content/index.js')
|
|
6
|
-
const installPackages = require('../lib/install.js')
|
|
7
4
|
const patchPackage = require('../lib/package.js')
|
|
8
5
|
|
|
9
6
|
const main = async () => {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
7
|
+
const {
|
|
8
|
+
npm_config_global: globalMode,
|
|
9
|
+
npm_config_local_prefix: root,
|
|
10
|
+
} = process.env
|
|
14
11
|
|
|
15
|
-
|
|
12
|
+
// do nothing in global mode or when the local prefix isn't set
|
|
13
|
+
if (globalMode === 'true' || !root) {
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
16
|
|
|
17
17
|
const needsAction = await patchPackage(root)
|
|
18
|
-
if (needsAction) {
|
|
19
|
-
|
|
20
|
-
return installPackages(root)
|
|
18
|
+
if (!needsAction) {
|
|
19
|
+
return
|
|
21
20
|
}
|
|
21
|
+
|
|
22
|
+
return copyContent(root)
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
// we export the promise so it can be awaited in tests
|
|
25
|
-
|
|
25
|
+
// we export the promise so it can be awaited in tests, coverage is disabled
|
|
26
|
+
// for the catch handler because it does so little it's not worth testing
|
|
27
|
+
module.exports = main().catch(/* istanbul ignore next */ (err) => {
|
|
26
28
|
console.error(err.stack)
|
|
27
29
|
process.exitCode = 1
|
|
28
30
|
})
|
package/lib/check.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
const { join } = require('path')
|
|
2
|
+
const fs = require('@npmcli/fs')
|
|
3
|
+
|
|
4
|
+
const patchPackage = require('./package.js')
|
|
5
|
+
|
|
6
|
+
const unwantedPackages = [
|
|
7
|
+
'@npmcli/lint',
|
|
8
|
+
'eslint-plugin-promise',
|
|
9
|
+
'eslint-plugin-standard',
|
|
10
|
+
'eslint-plugin-import',
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
const hasOwn = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key)
|
|
14
|
+
|
|
15
|
+
const check = async (root) => {
|
|
16
|
+
const pkgPath = join(root, 'package.json')
|
|
17
|
+
try {
|
|
18
|
+
var contents = await fs.readFile(pkgPath, { encoding: 'utf8' })
|
|
19
|
+
} catch (err) {
|
|
20
|
+
throw new Error('No package.json found')
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const pkg = JSON.parse(contents)
|
|
24
|
+
|
|
25
|
+
const problems = []
|
|
26
|
+
|
|
27
|
+
const incorrectFields = []
|
|
28
|
+
// 1. ensure package.json changes have been applied
|
|
29
|
+
for (const [key, value] of Object.entries(patchPackage.changes)) {
|
|
30
|
+
if (!hasOwn(pkg, key)) {
|
|
31
|
+
incorrectFields.push({
|
|
32
|
+
name: key,
|
|
33
|
+
found: pkg[key],
|
|
34
|
+
expected: value,
|
|
35
|
+
})
|
|
36
|
+
continue
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (value && typeof value === 'object') {
|
|
40
|
+
for (const [subKey, subValue] of Object.entries(value)) {
|
|
41
|
+
if (!hasOwn(pkg[key], subKey) ||
|
|
42
|
+
pkg[key][subKey] !== subValue) {
|
|
43
|
+
incorrectFields.push({
|
|
44
|
+
name: `${key}.${subKey}`,
|
|
45
|
+
found: pkg[key][subKey],
|
|
46
|
+
expected: subValue,
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
if (pkg[key] !== patchPackage.changes[key]) {
|
|
52
|
+
incorrectFields.push({
|
|
53
|
+
name: key,
|
|
54
|
+
found: pkg[key],
|
|
55
|
+
expected: value,
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (incorrectFields.length) {
|
|
62
|
+
problems.push({
|
|
63
|
+
message: [
|
|
64
|
+
`The following package.json fields are incorrect:`,
|
|
65
|
+
...incorrectFields.map((field) => {
|
|
66
|
+
const { name, found, expected } = field
|
|
67
|
+
return ` Field: "${name}" Expected: "${expected}" Found: "${found}"`
|
|
68
|
+
}),
|
|
69
|
+
].join('\n'),
|
|
70
|
+
solution: 'npm rm @npmcli/template-oss && npm i -D @npmcli/template-oss',
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 2. ensure packages that should not be present are removed
|
|
75
|
+
const mustRemove = unwantedPackages.filter((name) => {
|
|
76
|
+
return hasOwn(pkg.dependencies || {}, name) ||
|
|
77
|
+
hasOwn(pkg.devDependencies || {}, name)
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
if (mustRemove.length) {
|
|
81
|
+
problems.push({
|
|
82
|
+
message: [
|
|
83
|
+
'The following unwanted packages were found:',
|
|
84
|
+
...mustRemove,
|
|
85
|
+
].join(' '),
|
|
86
|
+
solution: `npm rm ${mustRemove.join(' ')}`,
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return problems
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
check.unwantedPackages = unwantedPackages
|
|
94
|
+
|
|
95
|
+
module.exports = check
|
package/lib/content/LICENSE.md
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Please send vulnerability reports through [hackerone](https://hackerone.com/github).
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# This file is automatically added by @npmcli/template-oss. Do not edit.
|
|
2
|
+
|
|
3
|
+
name: Bug
|
|
4
|
+
description: File a bug/issue
|
|
5
|
+
title: "[BUG] <title>"
|
|
6
|
+
labels: [Bug, Needs Triage]
|
|
7
|
+
body:
|
|
8
|
+
- type: checkboxes
|
|
9
|
+
attributes:
|
|
10
|
+
label: Is there an existing issue for this?
|
|
11
|
+
description: Please [search here](./issues) to see if an issue already exists for your problem.
|
|
12
|
+
options:
|
|
13
|
+
- label: I have searched the existing issues
|
|
14
|
+
required: true
|
|
15
|
+
- type: textarea
|
|
16
|
+
attributes:
|
|
17
|
+
label: Current Behavior
|
|
18
|
+
description: A clear & concise description of what you're experiencing.
|
|
19
|
+
validations:
|
|
20
|
+
required: false
|
|
21
|
+
- type: textarea
|
|
22
|
+
attributes:
|
|
23
|
+
label: Expected Behavior
|
|
24
|
+
description: A clear & concise description of what you expected to happen.
|
|
25
|
+
validations:
|
|
26
|
+
required: false
|
|
27
|
+
- type: textarea
|
|
28
|
+
attributes:
|
|
29
|
+
label: Steps To Reproduce
|
|
30
|
+
description: Steps to reproduce the behavior.
|
|
31
|
+
value: |
|
|
32
|
+
1. In this environment...
|
|
33
|
+
2. With this config...
|
|
34
|
+
3. Run '...'
|
|
35
|
+
4. See error...
|
|
36
|
+
validations:
|
|
37
|
+
required: false
|
|
38
|
+
- type: textarea
|
|
39
|
+
attributes:
|
|
40
|
+
label: Environment
|
|
41
|
+
description: |
|
|
42
|
+
examples:
|
|
43
|
+
- **npm**: 7.6.3
|
|
44
|
+
- **Node**: 13.14.0
|
|
45
|
+
- **OS**: Ubuntu 20.04
|
|
46
|
+
- **platform**: Macbook Pro
|
|
47
|
+
value: |
|
|
48
|
+
- npm:
|
|
49
|
+
- Node:
|
|
50
|
+
- OS:
|
|
51
|
+
- platform:
|
|
52
|
+
validations:
|
|
53
|
+
required: false
|
|
54
|
+
|
package/lib/content/ci.yml
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# This file is automatically added by @npmcli/template-oss. Do not edit.
|
|
2
|
+
|
|
1
3
|
name: CI
|
|
2
4
|
|
|
3
5
|
on:
|
|
@@ -24,7 +26,7 @@ jobs:
|
|
|
24
26
|
strategy:
|
|
25
27
|
fail-fast: false
|
|
26
28
|
matrix:
|
|
27
|
-
node-version: [
|
|
29
|
+
node-version: [12.13.0, 12.x, 14.15.0, 14.x, 16.x]
|
|
28
30
|
platform:
|
|
29
31
|
- os: ubuntu-latest
|
|
30
32
|
shell: bash
|
package/lib/content/eslintrc.js
CHANGED
package/lib/content/gitignore
CHANGED
package/lib/content/index.js
CHANGED
|
@@ -6,8 +6,11 @@ const fs = require('@npmcli/fs')
|
|
|
6
6
|
const content = {
|
|
7
7
|
'.eslintrc.js': './eslintrc.js',
|
|
8
8
|
'.github/workflows/ci.yml': './ci.yml',
|
|
9
|
+
'.github/ISSUE_TEMPLATE/bug.yml': './bug.yml',
|
|
10
|
+
'.github/ISSUE_TEMPLATE/config.yml': './config.yml',
|
|
9
11
|
'.gitignore': './gitignore',
|
|
10
12
|
'LICENSE.md': './LICENSE.md',
|
|
13
|
+
'SECURITY.md': './SECURITY.md',
|
|
11
14
|
}
|
|
12
15
|
|
|
13
16
|
// given a root directory, copy all files in the content map
|
package/lib/package.js
CHANGED
|
@@ -9,6 +9,7 @@ const changes = {
|
|
|
9
9
|
templateVersion: TEMPLATE_VERSION,
|
|
10
10
|
scripts: {
|
|
11
11
|
lint: `eslint '**/*.js'`,
|
|
12
|
+
postlint: 'npm-template-check',
|
|
12
13
|
lintfix: 'npm run lint -- --fix',
|
|
13
14
|
preversion: 'npm test',
|
|
14
15
|
postversion: 'npm publish',
|
|
@@ -17,6 +18,9 @@ const changes = {
|
|
|
17
18
|
test: 'tap',
|
|
18
19
|
posttest: 'npm run lint',
|
|
19
20
|
},
|
|
21
|
+
engines: {
|
|
22
|
+
node: '^12.13.0 || ^14.15.0 || >=16',
|
|
23
|
+
},
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
const patchPackage = async (root) => {
|
package/package.json
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@npmcli/template-oss",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "templated files used in npm CLI team oss projects",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"npm-template-check": "bin/npm-template-check.js"
|
|
8
|
+
},
|
|
6
9
|
"scripts": {
|
|
7
10
|
"lint": "eslint '**/*.js'",
|
|
8
11
|
"lintfix": "npm run lint -- --fix",
|
|
9
|
-
"
|
|
12
|
+
"postinstall": "node bin/postinstall.js",
|
|
13
|
+
"postlint": "npm-template-check",
|
|
14
|
+
"posttest": "npm run lint",
|
|
10
15
|
"postversion": "npm publish",
|
|
16
|
+
"prelint": "ln -sf ../../bin/npm-template-check.js node_modules/.bin/npm-template-check",
|
|
11
17
|
"prepublishOnly": "git push origin --follow-tags",
|
|
18
|
+
"preversion": "npm test",
|
|
12
19
|
"snap": "tap",
|
|
13
|
-
"test": "tap"
|
|
14
|
-
"posttest": "npm run lint",
|
|
15
|
-
"postinstall": "node bin/postinstall.js"
|
|
20
|
+
"test": "tap"
|
|
16
21
|
},
|
|
17
22
|
"repository": {
|
|
18
23
|
"type": "git",
|
|
@@ -34,11 +39,17 @@
|
|
|
34
39
|
"lib"
|
|
35
40
|
],
|
|
36
41
|
"devDependencies": {
|
|
37
|
-
"@npmcli/eslint-config": "
|
|
42
|
+
"@npmcli/eslint-config": "*",
|
|
38
43
|
"eslint": "^7.32.0",
|
|
39
44
|
"eslint-plugin-node": "^11.1.0",
|
|
40
|
-
"
|
|
45
|
+
"tap": "*"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"@npmcli/eslint-config": "^1.0.0",
|
|
41
49
|
"tap": "^15.0.9"
|
|
42
50
|
},
|
|
43
|
-
"templateVersion": "1.0.
|
|
51
|
+
"templateVersion": "1.0.3",
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": "^12.13.0 || ^14.15.0 || >=16"
|
|
54
|
+
}
|
|
44
55
|
}
|
package/lib/install.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
const spawn = require('@npmcli/promise-spawn')
|
|
2
|
-
|
|
3
|
-
const removeDeps = [
|
|
4
|
-
'eslint-plugin-import',
|
|
5
|
-
'eslint-plugin-promise',
|
|
6
|
-
'eslint-plugin-standard',
|
|
7
|
-
'@npmcli/lint',
|
|
8
|
-
]
|
|
9
|
-
|
|
10
|
-
const devDeps = [
|
|
11
|
-
'eslint',
|
|
12
|
-
'eslint-plugin-node',
|
|
13
|
-
'@npmcli/eslint-config',
|
|
14
|
-
'tap',
|
|
15
|
-
]
|
|
16
|
-
|
|
17
|
-
const npm = (root, args) => {
|
|
18
|
-
return spawn('npm', args, {
|
|
19
|
-
cwd: root,
|
|
20
|
-
stdioString: true,
|
|
21
|
-
})
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const installPackages = async (root) => {
|
|
25
|
-
await npm(root, ['uninstall', ...removeDeps])
|
|
26
|
-
return npm(root, ['install', '--save-dev', ...devDeps])
|
|
27
|
-
}
|
|
28
|
-
installPackages.removeDeps = removeDeps
|
|
29
|
-
installPackages.devDeps = devDeps
|
|
30
|
-
|
|
31
|
-
module.exports = installPackages
|