@w5s/mrm-preset 1.0.0-alpha.2 → 1.0.0-alpha.21
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/.turbo/turbo-build.log +11 -0
- package/.turbo/turbo-docs.log +43 -0
- package/.turbo/turbo-format.log +7 -0
- package/.turbo/turbo-lint.log +7 -0
- package/.turbo/turbo-prepare.log +2 -0
- package/.turbo/turbo-test.log +19 -0
- package/CHANGELOG.md +237 -0
- package/README.md +1 -1
- package/bootstrap/index.js +43 -42
- package/ci/_gitlab/AutoDevopsInclude.gitlab-ci.yml +2 -0
- package/ci/github.js +47 -0
- package/ci/gitlab.js +1 -1
- package/ci/index.js +7 -2
- package/commitlint/index.js +5 -2
- package/config.json +1 -0
- package/contributing/index.js +1 -1
- package/contributing/templates/CODE_OF_CONDUCT.md +3 -4
- package/core/block.js +2 -3
- package/core/commitlint.js +3 -3
- package/core/cspell.js +1 -10
- package/core/eslint.js +25 -6
- package/{gitignore/template.js → core/git.ignore.js} +32 -6
- package/core/git.js +21 -18
- package/core/githooks.js +8 -7
- package/core/githubCI.js +56 -0
- package/core/jest.js +50 -69
- package/core/jsonFile.js +8 -7
- package/core/lintStaged.js +3 -3
- package/core/npm.js +52 -15
- package/core/pkg.js +92 -14
- package/core/project.js +6 -0
- package/core/semanticRelease.js +4 -4
- package/core/turbo.js +57 -0
- package/core/typedoc.js +7 -20
- package/core/vscode.js +1 -1
- package/cspell/index.js +20 -10
- package/editorconfig/index.js +3 -1
- package/eslint/index.js +81 -32
- package/githooks/index.js +47 -56
- package/gitignore/index.js +5 -22
- package/jest/index.js +13 -17
- package/lang/.eslintrc.json +4 -1
- package/lang/index.js +22 -19
- package/licenses/index.js +26 -0
- package/package.json +17 -12
- package/postconfigure/index.js +3 -3
- package/project/index.js +217 -156
- package/release/index.js +5 -5
- package/renovate/index.js +7 -5
- package/tsconfig.json +2 -1
- package/core/workspace.js +0 -6
package/core/cspell.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const { json } = require('mrm-core');
|
|
2
|
-
const
|
|
3
|
-
const npm = require('./npm');
|
|
2
|
+
const npm = require('./npm.js');
|
|
4
3
|
/**
|
|
5
4
|
* @typedef {{
|
|
6
5
|
* version: '0.2',
|
|
@@ -22,14 +21,6 @@ const npm = require('./npm');
|
|
|
22
21
|
function cspell({ state, update }) {
|
|
23
22
|
const hasCSpell = state === 'present';
|
|
24
23
|
|
|
25
|
-
pkg.withPackageJson((packageFile) => {
|
|
26
|
-
pkg.script(packageFile, {
|
|
27
|
-
name: 'cspell',
|
|
28
|
-
script: 'cspell',
|
|
29
|
-
state,
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
|
|
33
24
|
const cSpellFile = json('cSpell.json', {
|
|
34
25
|
version: '0.2',
|
|
35
26
|
language: 'en',
|
package/core/eslint.js
CHANGED
|
@@ -1,14 +1,29 @@
|
|
|
1
1
|
const { packageJson } = require('mrm-core');
|
|
2
|
-
|
|
2
|
+
const jsonFile = require('./jsonFile.js');
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import('eslint').Linter.Config} ESLintConfig
|
|
5
|
+
*/
|
|
3
6
|
/**
|
|
4
|
-
* @param {
|
|
7
|
+
* @param {{
|
|
8
|
+
* state: 'present'|'absent',
|
|
9
|
+
* update: (config: ESLintConfig) => ESLintConfig
|
|
10
|
+
* }} config
|
|
5
11
|
*/
|
|
6
|
-
function eslintConfig(
|
|
12
|
+
function eslintConfig({ state, update }) {
|
|
7
13
|
const packageFile = packageJson();
|
|
8
|
-
|
|
14
|
+
|
|
15
|
+
jsonFile.value(packageFile, {
|
|
16
|
+
path: 'eslintConfig',
|
|
17
|
+
state,
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
update,
|
|
20
|
+
/** @type {ESLintConfig} */
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
default: {},
|
|
23
|
+
});
|
|
24
|
+
|
|
9
25
|
packageFile.save();
|
|
10
26
|
}
|
|
11
|
-
exports.eslintConfig = eslintConfig;
|
|
12
27
|
|
|
13
28
|
/**
|
|
14
29
|
*
|
|
@@ -19,4 +34,8 @@ function eslintIgnore(ignorePatterns) {
|
|
|
19
34
|
packageFile.merge({ eslintIgnore: ignorePatterns });
|
|
20
35
|
packageFile.save();
|
|
21
36
|
}
|
|
22
|
-
|
|
37
|
+
|
|
38
|
+
module.exports = {
|
|
39
|
+
eslintConfig,
|
|
40
|
+
eslintIgnore,
|
|
41
|
+
};
|
|
@@ -11,6 +11,7 @@ module.exports = {
|
|
|
11
11
|
yarn-debug.log*
|
|
12
12
|
yarn-error.log*
|
|
13
13
|
lerna-debug.log*
|
|
14
|
+
.pnpm-debug.log*
|
|
14
15
|
|
|
15
16
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
|
16
17
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
|
@@ -47,8 +48,8 @@ module.exports = {
|
|
|
47
48
|
node_modules/
|
|
48
49
|
jspm_packages/
|
|
49
50
|
|
|
50
|
-
#
|
|
51
|
-
|
|
51
|
+
# Snowpack dependency directory (https://snowpack.dev/)
|
|
52
|
+
web_modules/
|
|
52
53
|
|
|
53
54
|
# TypeScript cache
|
|
54
55
|
*.tsbuildinfo
|
|
@@ -59,6 +60,9 @@ module.exports = {
|
|
|
59
60
|
# Optional eslint cache
|
|
60
61
|
.eslintcache
|
|
61
62
|
|
|
63
|
+
# Optional stylelint cache
|
|
64
|
+
.stylelintcache
|
|
65
|
+
|
|
62
66
|
# Microbundle cache
|
|
63
67
|
.rpt2_cache/
|
|
64
68
|
.rts2_cache_cjs/
|
|
@@ -74,15 +78,20 @@ module.exports = {
|
|
|
74
78
|
# Yarn Integrity file
|
|
75
79
|
.yarn-integrity
|
|
76
80
|
|
|
77
|
-
# dotenv environment
|
|
81
|
+
# dotenv environment variable files
|
|
78
82
|
.env
|
|
79
|
-
.env.
|
|
83
|
+
.env.development.local
|
|
84
|
+
.env.test.local
|
|
85
|
+
.env.production.local
|
|
86
|
+
.env.local
|
|
80
87
|
|
|
81
88
|
# parcel-bundler cache (https://parceljs.org/)
|
|
82
89
|
.cache
|
|
90
|
+
.parcel-cache
|
|
83
91
|
|
|
84
92
|
# Next.js build output
|
|
85
93
|
.next
|
|
94
|
+
out
|
|
86
95
|
|
|
87
96
|
# Nuxt.js build / generate output
|
|
88
97
|
.nuxt
|
|
@@ -92,11 +101,18 @@ module.exports = {
|
|
|
92
101
|
.cache/
|
|
93
102
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
|
94
103
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
|
95
|
-
public
|
|
104
|
+
# public
|
|
96
105
|
|
|
97
106
|
# vuepress build output
|
|
98
107
|
.vuepress/dist
|
|
99
108
|
|
|
109
|
+
# vuepress v2.x temp and cache directory
|
|
110
|
+
.temp
|
|
111
|
+
.cache
|
|
112
|
+
|
|
113
|
+
# Docusaurus cache and generated files
|
|
114
|
+
.docusaurus
|
|
115
|
+
|
|
100
116
|
# Serverless directories
|
|
101
117
|
.serverless/
|
|
102
118
|
|
|
@@ -107,7 +123,17 @@ module.exports = {
|
|
|
107
123
|
.dynamodb/
|
|
108
124
|
|
|
109
125
|
# TernJS port file
|
|
110
|
-
.tern-port
|
|
126
|
+
.tern-port
|
|
127
|
+
|
|
128
|
+
# Stores VSCode versions used for testing VSCode extensions
|
|
129
|
+
.vscode-test
|
|
130
|
+
|
|
131
|
+
# yarn v2
|
|
132
|
+
.yarn/cache
|
|
133
|
+
.yarn/unplugged
|
|
134
|
+
.yarn/build-state.yml
|
|
135
|
+
.yarn/install-state.gz
|
|
136
|
+
.pnp.*`,
|
|
111
137
|
VisualStudioCode: `
|
|
112
138
|
.vscode/*
|
|
113
139
|
!.vscode/settings.json
|
package/core/git.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const { file, ini } = require('mrm-core');
|
|
2
|
-
const block = require('./block');
|
|
2
|
+
const block = require('./block.js');
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
*
|
|
@@ -7,23 +7,9 @@ const block = require('./block');
|
|
|
7
7
|
function remoteSync() {
|
|
8
8
|
try {
|
|
9
9
|
const gitConfig = ini('.git/config');
|
|
10
|
-
const remoteURL = gitConfig.get('
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
? [
|
|
14
|
-
/**
|
|
15
|
-
* 1. filter github URL
|
|
16
|
-
* @param {string} returnValue
|
|
17
|
-
*/
|
|
18
|
-
(returnValue) => returnValue.replace(/^git@github.com:/, 'https://github.com/'),
|
|
19
|
-
/**
|
|
20
|
-
* 2. filter gitlab URL
|
|
21
|
-
* @param {string} returnValue
|
|
22
|
-
*/
|
|
23
|
-
(returnValue) => returnValue.replace(/^git@gitlab.com:/, 'https://gitlab.com/'),
|
|
24
|
-
].reduce((returnValue, filter) => filter(returnValue), remoteURL)
|
|
25
|
-
: remoteURL;
|
|
26
|
-
} catch (error) {
|
|
10
|
+
const remoteURL = gitConfig.get('remote "origin"').url.trim();
|
|
11
|
+
return remoteURL;
|
|
12
|
+
} catch {
|
|
27
13
|
// ignore error
|
|
28
14
|
}
|
|
29
15
|
|
|
@@ -61,3 +47,20 @@ function gitIgnore(section, sectionContent) {
|
|
|
61
47
|
});
|
|
62
48
|
}
|
|
63
49
|
exports.gitIgnore = gitIgnore;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @param {string[]} flags
|
|
53
|
+
*/
|
|
54
|
+
function gitIgnoreTemplate(flags) {
|
|
55
|
+
// eslint-disable-next-line global-require, import/no-dynamic-require
|
|
56
|
+
const templateMap = require('./git.ignore.js');
|
|
57
|
+
|
|
58
|
+
flags.forEach((flag) => {
|
|
59
|
+
// @ts-ignore
|
|
60
|
+
if (templateMap[flag]) {
|
|
61
|
+
// @ts-ignore
|
|
62
|
+
gitIgnore(flag, templateMap[flag]);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
exports.gitIgnoreTemplate = gitIgnoreTemplate;
|
package/core/githooks.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
const { execSync } = require('child_process');
|
|
2
|
-
const path = require('path');
|
|
1
|
+
const { execSync } = require('node:child_process');
|
|
2
|
+
const path = require('node:path');
|
|
3
3
|
const { file, packageJson, makeDirs } = require('mrm-core');
|
|
4
|
-
const project = require('./project');
|
|
5
|
-
const npm = require('./npm');
|
|
6
|
-
const pkg = require('./pkg');
|
|
7
|
-
const block = require('./block');
|
|
4
|
+
const project = require('./project.js');
|
|
5
|
+
const npm = require('./npm.js');
|
|
6
|
+
const pkg = require('./pkg.js');
|
|
7
|
+
const block = require('./block.js');
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @param {{
|
|
@@ -44,7 +44,8 @@ function husky({ state }) {
|
|
|
44
44
|
* }} options
|
|
45
45
|
*/
|
|
46
46
|
function gitHook({ name, state, content }) {
|
|
47
|
-
const
|
|
47
|
+
const packageFileDefault = packageJson();
|
|
48
|
+
const hasHusky = pkg.hasDependency(packageFileDefault, 'husky', 'dev');
|
|
48
49
|
const hasGitHook = hasHusky && state === 'present';
|
|
49
50
|
const hookDirectory = '.husky';
|
|
50
51
|
const hookFileName = path.join(hookDirectory, name);
|
package/core/githubCI.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const { yaml } = require('mrm-core');
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
|
|
5
|
+
const FILE_PATH = '.github/workflows';
|
|
6
|
+
|
|
7
|
+
function isSupported() {
|
|
8
|
+
return fs.existsSync(FILE_PATH);
|
|
9
|
+
}
|
|
10
|
+
exports.isSupported = isSupported;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @typedef { string | {
|
|
14
|
+
* group: string,
|
|
15
|
+
* 'cancel-in-progress': boolean,
|
|
16
|
+
* }} GithubWorkflowConcurrency
|
|
17
|
+
*/
|
|
18
|
+
// TODO: add strict typing
|
|
19
|
+
/**
|
|
20
|
+
* @typedef {{
|
|
21
|
+
* name?: string,
|
|
22
|
+
* jobs?: Record<string, any>
|
|
23
|
+
* on?: any,
|
|
24
|
+
* env?: Record<string, string>,
|
|
25
|
+
* permissions?: any,
|
|
26
|
+
* defaults?: Record<string, any>,
|
|
27
|
+
* concurrency?: GithubWorkflowConcurrency,
|
|
28
|
+
* }} GithubWorkflowConfig
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @param {{
|
|
33
|
+
* state: 'present'|'absent',
|
|
34
|
+
* name: string,
|
|
35
|
+
* update?: (config: GithubWorkflowConfig) => GithubWorkflowConfig
|
|
36
|
+
* }} options
|
|
37
|
+
*/
|
|
38
|
+
function workflow({ name, state, update }) {
|
|
39
|
+
const workflowFile = yaml(path.join(FILE_PATH, name));
|
|
40
|
+
if (state === 'present') {
|
|
41
|
+
/** @type {GithubWorkflowConfig} */
|
|
42
|
+
let value = workflowFile.get() || {
|
|
43
|
+
jobs: {},
|
|
44
|
+
};
|
|
45
|
+
if (update) {
|
|
46
|
+
value = update(value);
|
|
47
|
+
// @ts-ignore
|
|
48
|
+
workflowFile.set(value);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
workflowFile.save();
|
|
52
|
+
} else {
|
|
53
|
+
workflowFile.delete();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.workflow = workflow;
|
package/core/jest.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/* eslint-disable no-template-curly-in-string */
|
|
2
2
|
const { packageJson } = require('mrm-core');
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const project = require('./project');
|
|
3
|
+
const pkg = require('./pkg.js');
|
|
4
|
+
const npm = require('./npm.js');
|
|
5
|
+
const project = require('./project.js');
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* @param {{
|
|
@@ -13,38 +12,29 @@ const project = require('./project');
|
|
|
13
12
|
function jest({ state }) {
|
|
14
13
|
const packageFileDefault = packageJson();
|
|
15
14
|
const hasJest = state === 'present';
|
|
16
|
-
const
|
|
17
|
-
const hasWorkspaces = Boolean(packageFileDefault.get('workspaces'));
|
|
15
|
+
const hasWorkspaces = pkg.hasWorkspaces(packageFileDefault);
|
|
18
16
|
|
|
19
17
|
pkg.withPackageJson((packageFile) => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
} else {
|
|
43
|
-
packageFile.unset('jest.globals.ts-jest').unset('jest.transform.^.+\\.tsx?$');
|
|
44
|
-
}
|
|
45
|
-
} else {
|
|
46
|
-
packageFile.unset('jest');
|
|
47
|
-
}
|
|
18
|
+
const ignorePatterns = ['/node_modules/', '/docs/', '/lib/', '/build/', '/.cache/', '/public/'];
|
|
19
|
+
|
|
20
|
+
pkg.value(packageFile, {
|
|
21
|
+
path: 'jest',
|
|
22
|
+
state: hasJest ? 'present' : 'absent',
|
|
23
|
+
update: hasWorkspaces
|
|
24
|
+
? () => ({
|
|
25
|
+
preset: 'es-jest',
|
|
26
|
+
projects: packageFile
|
|
27
|
+
.get('workspaces.packages', packageFile.get('workspaces', []))
|
|
28
|
+
.map((/** @type {string} */ workspace) => `<rootDir>/${workspace}`),
|
|
29
|
+
})
|
|
30
|
+
: (config) => ({
|
|
31
|
+
...config,
|
|
32
|
+
preset: 'es-jest',
|
|
33
|
+
coveragePathIgnorePatterns: ignorePatterns,
|
|
34
|
+
testPathIgnorePatterns: ignorePatterns,
|
|
35
|
+
}),
|
|
36
|
+
default: {},
|
|
37
|
+
});
|
|
48
38
|
|
|
49
39
|
pkg.script(packageFile, {
|
|
50
40
|
name: project.coverage,
|
|
@@ -56,48 +46,39 @@ function jest({ state }) {
|
|
|
56
46
|
script: hasWorkspaces ? pkg.emptyScript : 'jest',
|
|
57
47
|
state: !hasJest || hasWorkspaces ? 'default' : 'present',
|
|
58
48
|
});
|
|
59
|
-
pkg.script(packageFile, {
|
|
60
|
-
name: `${project.test}:watch`,
|
|
61
|
-
script: pkg.emptyScript,
|
|
62
|
-
state: 'absent',
|
|
63
|
-
});
|
|
64
49
|
});
|
|
50
|
+
|
|
65
51
|
// Dependencies
|
|
66
52
|
npm.dependency({
|
|
67
53
|
dev: true,
|
|
68
|
-
name: ['jest', '
|
|
54
|
+
name: ['jest', 'es-jest'],
|
|
69
55
|
state: hasJest ? 'present' : 'absent',
|
|
70
56
|
});
|
|
71
|
-
npm.dependency({
|
|
72
|
-
dev: true,
|
|
73
|
-
name: ['ts-jest', '@types/jest'],
|
|
74
|
-
state: hasJest && hasTypescript ? 'present' : 'absent',
|
|
75
|
-
});
|
|
76
57
|
|
|
77
|
-
vscodeSnippets({
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
});
|
|
58
|
+
// vscodeSnippets({
|
|
59
|
+
// name: 'jest',
|
|
60
|
+
// snippets: {
|
|
61
|
+
// 'Jest Describe Block': {
|
|
62
|
+
// body: ["describe('${1:description}', () => {", '\t$0', '});'],
|
|
63
|
+
// description: 'Jest describe block',
|
|
64
|
+
// prefix: 'describe',
|
|
65
|
+
// scope: 'javascript,typescript',
|
|
66
|
+
// },
|
|
67
|
+
// 'Jest Expect': {
|
|
68
|
+
// body: 'expect($0)',
|
|
69
|
+
// description: 'Jest expect assertion',
|
|
70
|
+
// prefix: 'expect',
|
|
71
|
+
// scope: 'javascript,typescript',
|
|
72
|
+
// },
|
|
73
|
+
// 'Jest Test Block': {
|
|
74
|
+
// body: ["test('${1:description}', () => {", '\t$0', '});'],
|
|
75
|
+
// description: 'Jest test block',
|
|
76
|
+
// prefix: 'test',
|
|
77
|
+
// scope: 'javascript,typescript',
|
|
78
|
+
// },
|
|
79
|
+
// },
|
|
80
|
+
// state: hasJest ? 'present' : 'absent',
|
|
81
|
+
// });
|
|
101
82
|
}
|
|
102
83
|
|
|
103
84
|
module.exports = {
|
package/core/jsonFile.js
CHANGED
|
@@ -41,16 +41,17 @@ function setValue(jsonFile, path, pathValue) {
|
|
|
41
41
|
*/
|
|
42
42
|
function value(jsonFile, { state, path, default: defaultValue, update: nextValue }) {
|
|
43
43
|
if (state === 'present') {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
let currentValue = getValue(jsonFile, path);
|
|
45
|
+
|
|
46
|
+
if (currentValue == null) {
|
|
47
|
+
currentValue = typeof defaultValue === 'function' ? defaultValue() : defaultValue;
|
|
48
|
+
if (currentValue != null) {
|
|
49
|
+
setValue(jsonFile, path, currentValue);
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const resolvedValue = typeof defaultValue === 'function' ? defaultValue() : defaultValue;
|
|
53
|
+
if (nextValue != null) {
|
|
54
|
+
const resolvedValue = typeof nextValue === 'function' ? nextValue(getValue(jsonFile, path)) : nextValue;
|
|
54
55
|
if (resolvedValue != null) {
|
|
55
56
|
setValue(jsonFile, path, resolvedValue);
|
|
56
57
|
}
|
package/core/lintStaged.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const pkg = require('./pkg');
|
|
2
|
-
const npm = require('./npm');
|
|
3
|
-
const jsonFile = require('./jsonFile');
|
|
1
|
+
const pkg = require('./pkg.js');
|
|
2
|
+
const npm = require('./npm.js');
|
|
3
|
+
const jsonFile = require('./jsonFile.js');
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @typedef {Record<string, string|string[]>} LintStagedConfig
|
package/core/npm.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* eslint-disable default-param-last */
|
|
2
|
+
/* eslint-disable no-use-before-define */
|
|
1
3
|
/* eslint-disable import/no-extraneous-dependencies */
|
|
2
4
|
/* cSpell: disable */
|
|
3
5
|
// @ts-check
|
|
@@ -16,25 +18,26 @@ const log = require('mrm-core/src/util/log');
|
|
|
16
18
|
// @ts-ignore
|
|
17
19
|
const execCommand = require('mrm-core/src/util/execCommand');
|
|
18
20
|
// @ts-ignore
|
|
19
|
-
const json = require('mrm-core/src/formats/json');
|
|
20
|
-
// @ts-ignore
|
|
21
21
|
const packageJson = require('mrm-core/src/files/packageJson');
|
|
22
22
|
// @ts-ignore
|
|
23
23
|
const MrmError = require('mrm-core/src/error');
|
|
24
|
+
const { yaml, json } = require('mrm-core');
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
|
-
* @typedef
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
27
|
+
* @typedef {{
|
|
28
|
+
* dev?: boolean,
|
|
29
|
+
* yarn?: boolean,
|
|
30
|
+
* versions?: Record<string, string>,
|
|
31
|
+
* }} Options
|
|
30
32
|
*/
|
|
31
33
|
|
|
32
34
|
/**
|
|
33
|
-
* @typedef
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
35
|
+
* @typedef {{
|
|
36
|
+
* dev?: boolean,
|
|
37
|
+
* remove?: boolean,
|
|
38
|
+
* stdio?: boolean,
|
|
39
|
+
* cwd?: string,
|
|
40
|
+
* }} RunOptions
|
|
38
41
|
*/
|
|
39
42
|
|
|
40
43
|
/**
|
|
@@ -132,7 +135,7 @@ function runNpm(deps, options = {}, exec) {
|
|
|
132
135
|
function runYarn(deps, options = {}, exec) {
|
|
133
136
|
const add = options.dev ? ['add', '--dev'] : ['add'];
|
|
134
137
|
const remove = ['remove'];
|
|
135
|
-
const args = (options.remove ? remove : add).concat(isUsingWorkspaces() ? ['-W'] : []).concat(deps);
|
|
138
|
+
const args = (options.remove ? remove : add).concat(isUsingWorkspaces() && !isYarnBerry() ? ['-W'] : []).concat(deps);
|
|
136
139
|
|
|
137
140
|
return execCommand(exec, 'yarn', args, {
|
|
138
141
|
cwd: options.cwd,
|
|
@@ -165,7 +168,7 @@ function getVersionedDep(dep, versions) {
|
|
|
165
168
|
/**
|
|
166
169
|
*
|
|
167
170
|
* @param {Options} options
|
|
168
|
-
* @returns {Record<string, string>}
|
|
171
|
+
* @returns {Record<string, string>} - map of package names to versions
|
|
169
172
|
*/
|
|
170
173
|
function getOwnDependencies(options) {
|
|
171
174
|
const pkg = packageJson({
|
|
@@ -180,7 +183,7 @@ function getOwnDependencies(options) {
|
|
|
180
183
|
* Return version of installed npm package
|
|
181
184
|
*
|
|
182
185
|
* @param {string} name
|
|
183
|
-
* @returns {string}
|
|
186
|
+
* @returns {string} - version
|
|
184
187
|
*/
|
|
185
188
|
function getInstalledVersion(name) {
|
|
186
189
|
return json(`./node_modules/${name}/package.json`).get('version');
|
|
@@ -193,7 +196,7 @@ function getInstalledVersion(name) {
|
|
|
193
196
|
* @param {string[]} deps
|
|
194
197
|
* @param {Record<string, string>} versions
|
|
195
198
|
* @param {Options} options
|
|
196
|
-
* @returns {string[]}
|
|
199
|
+
* @returns {string[]} - list of not installed dependencies
|
|
197
200
|
*/
|
|
198
201
|
function getUnsatisfiedDeps(deps, versions, options) {
|
|
199
202
|
const ownDependencies = getOwnDependencies(options);
|
|
@@ -246,6 +249,39 @@ function isUsingWorkspaces() {
|
|
|
246
249
|
return Boolean(packageJson().get('workspaces'));
|
|
247
250
|
}
|
|
248
251
|
|
|
252
|
+
function isYarnBerry() {
|
|
253
|
+
const yamlRC = yaml('.yarnrc.yml');
|
|
254
|
+
return yamlRC.exists() && !(yamlRC.get('yarnPath') || '').includes('.yarn/releases/yarn-1.');
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* @param {'npm'|`yarn@${'classic'|'berry'}`} defaultPackageManager
|
|
259
|
+
*/
|
|
260
|
+
function bootstrap(defaultPackageManager) {
|
|
261
|
+
const packageFile = json(`./package.json`);
|
|
262
|
+
const isYarn = isUsingYarn() || defaultPackageManager.startsWith('yarn@');
|
|
263
|
+
if (!packageFile.get('packageManager') && isYarn) {
|
|
264
|
+
execCommand(undefined, 'yarn', ['set', 'version', 'berry']);
|
|
265
|
+
yaml('.yarnrc.yml')
|
|
266
|
+
.merge({
|
|
267
|
+
nodeLinker: 'node-modules',
|
|
268
|
+
})
|
|
269
|
+
.save();
|
|
270
|
+
// Downgrade
|
|
271
|
+
if (defaultPackageManager.endsWith('@classic')) {
|
|
272
|
+
execCommand(undefined, 'yarn', ['set', 'version', 'classic']);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// lock files
|
|
277
|
+
if (isYarn && !fs.existsSync('yarn.lock')) {
|
|
278
|
+
execCommand(undefined, 'yarn', ['install']);
|
|
279
|
+
}
|
|
280
|
+
if (!isYarn && !fs.existsSync('package-lock.json')) {
|
|
281
|
+
execCommand(undefined, 'npm', ['install']);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
249
285
|
/**
|
|
250
286
|
* @param {{
|
|
251
287
|
* name: string|string[]|Record<string, string>,
|
|
@@ -263,5 +299,6 @@ function dependency({ name, state, ...options }) {
|
|
|
263
299
|
}
|
|
264
300
|
|
|
265
301
|
module.exports = {
|
|
302
|
+
bootstrap,
|
|
266
303
|
dependency,
|
|
267
304
|
};
|