monorepo-next 8.4.1 → 8.6.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/package.json +6 -3
- package/src/build-change-graph.js +7 -12
- package/src/build-dep-graph.js +2 -2
- package/src/get-workspaces-paths.js +161 -16
- package/src/json.js +5 -0
- package/src/releasable.js +32 -4
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "monorepo-next",
|
3
|
-
"version": "8.
|
3
|
+
"version": "8.6.0",
|
4
4
|
"description": "Detach monorepo packages from normal linking",
|
5
5
|
"bin": {
|
6
6
|
"next": "bin/next.js"
|
@@ -62,7 +62,9 @@
|
|
62
62
|
"conventional-recommended-bump": "6.1.0",
|
63
63
|
"debug": "^4.3.1",
|
64
64
|
"execa": "^5.0.0",
|
65
|
+
"glob": "^8.0.0",
|
65
66
|
"inquirer": "^8.0.0",
|
67
|
+
"js-yaml": "^4.0.0",
|
66
68
|
"minimatch": "^5.0.0",
|
67
69
|
"npm-packlist": "^5.0.0",
|
68
70
|
"rfc6902": "^5.0.0",
|
@@ -76,8 +78,9 @@
|
|
76
78
|
"@crowdstrike/commitlint": "^5.0.0",
|
77
79
|
"chai": "^4.2.0",
|
78
80
|
"chai-as-promised": "^7.1.1",
|
81
|
+
"common-tags": "^1.8.2",
|
79
82
|
"eslint": "^8.0.0",
|
80
|
-
"eslint-config-crowdstrike": "^
|
83
|
+
"eslint-config-crowdstrike": "^7.0.0",
|
81
84
|
"eslint-config-crowdstrike-node": "^3.0.0",
|
82
85
|
"eslint-plugin-json-files": "^1.0.0",
|
83
86
|
"eslint-plugin-mocha": "^10.0.0",
|
@@ -86,7 +89,7 @@
|
|
86
89
|
"git-fixtures": "^4.0.0",
|
87
90
|
"mocha": "^10.0.0",
|
88
91
|
"mocha-helpers": "^6.2.1",
|
89
|
-
"remark-cli": "^
|
92
|
+
"remark-cli": "^11.0.0",
|
90
93
|
"remark-preset-lint-crowdstrike": "^2.0.0",
|
91
94
|
"renovate-config-standard": "^2.0.0",
|
92
95
|
"sinon": "^14.0.0",
|
@@ -21,22 +21,17 @@ async function getPackageChangedFiles({
|
|
21
21
|
packageCwd,
|
22
22
|
options,
|
23
23
|
}) {
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
let
|
28
|
-
if (isAncestor) {
|
29
|
-
olderCommit = fromCommit;
|
30
|
-
newerCommit = toCommit;
|
31
|
-
} else {
|
32
|
-
olderCommit = toCommit;
|
33
|
-
newerCommit = fromCommit;
|
34
|
-
}
|
24
|
+
// Be careful you don't accidentally use `...` instead of `..`.
|
25
|
+
// `...` finds the merge-base and uses that instead of `fromCommit`.
|
26
|
+
// https://stackoverflow.com/a/60496462
|
27
|
+
let committedChanges = await git(['diff', '--name-only', `${fromCommit}..${toCommit}`, packageCwd], options);
|
35
28
|
|
36
|
-
let committedChanges = await git(['diff', '--name-only', `${olderCommit}...${newerCommit}`, packageCwd], options);
|
37
29
|
committedChanges = getLinesFromOutput(committedChanges);
|
30
|
+
|
38
31
|
let dirtyChanges = await git(['status', '--porcelain', packageCwd, '-u'], options);
|
32
|
+
|
39
33
|
dirtyChanges = getLinesFromOutput(dirtyChanges).map(line => line.substr(3));
|
34
|
+
|
40
35
|
let changedFiles = Array.from(new Set(committedChanges).union(dirtyChanges));
|
41
36
|
|
42
37
|
return changedFiles;
|
package/src/build-dep-graph.js
CHANGED
@@ -4,7 +4,7 @@ const path = require('path');
|
|
4
4
|
const semver = require('semver');
|
5
5
|
const dependencyTypes = require('./dependency-types');
|
6
6
|
const readJson = require('./json').read;
|
7
|
-
const getWorkspacesPaths = require('./get-workspaces-paths');
|
7
|
+
const { getWorkspacesPaths } = require('./get-workspaces-paths');
|
8
8
|
|
9
9
|
function copyDeps(left, right) {
|
10
10
|
for (let dependencyType of dependencyTypes) {
|
@@ -77,7 +77,7 @@ async function buildDepGraph({
|
|
77
77
|
}) {
|
78
78
|
let workspacePackageJson = await readJson(path.join(workspaceCwd, 'package.json'));
|
79
79
|
|
80
|
-
let workspaces = await getWorkspacesPaths({ workspaceCwd });
|
80
|
+
let workspaces = await getWorkspacesPaths({ cwd: workspaceCwd });
|
81
81
|
|
82
82
|
let packageDirs = workspaces.map(dir => path.join(workspaceCwd, dir));
|
83
83
|
|
@@ -1,33 +1,178 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
3
|
const execa = require('execa');
|
4
|
+
const fs = { ...require('fs'), ...require('fs').promises };
|
5
|
+
const { promisify } = require('util');
|
6
|
+
const glob = promisify(require('glob'));
|
7
|
+
const jsYaml = require('js-yaml');
|
4
8
|
const path = require('path');
|
5
9
|
const readJson = require('./json').read;
|
10
|
+
const readJsonSync = require('./json').readSync;
|
11
|
+
|
12
|
+
function processPnpm({ stdout }, cwd) {
|
13
|
+
let workspaces = stdout.split(/\r?\n/).reduce((workspaces, workspace) => {
|
14
|
+
if (!workspace.startsWith('No projects matched the filters')) {
|
15
|
+
if (process.platform === 'darwin' && workspace.startsWith(`${path.sep}private${path.sep}`)) {
|
16
|
+
workspace = `${path.sep}${path.relative(`${path.sep}private`, workspace)}`;
|
17
|
+
}
|
18
|
+
|
19
|
+
let relative = path.relative(cwd, workspace);
|
20
|
+
|
21
|
+
workspaces.push(relative);
|
22
|
+
}
|
23
|
+
|
24
|
+
return workspaces;
|
25
|
+
}, []);
|
26
|
+
|
27
|
+
return workspaces;
|
28
|
+
}
|
29
|
+
|
30
|
+
function processYarn({ stdout }) {
|
31
|
+
let json = JSON.parse(stdout);
|
32
|
+
|
33
|
+
let workspaces = Object.values(json).map(({ location }) => location);
|
34
|
+
|
35
|
+
return workspaces;
|
36
|
+
}
|
37
|
+
|
38
|
+
function processPnpmYaml(buffer) {
|
39
|
+
// read packagesGlobs excluding packagesGLobs starting with !
|
40
|
+
// https://pnpm.io/pnpm-workspace_yaml
|
41
|
+
let packagesGlobs = jsYaml.load(buffer).packages.filter((packagesGlob) => !packagesGlob.startsWith('!'));
|
42
|
+
|
43
|
+
return packagesGlobs;
|
44
|
+
}
|
45
|
+
|
46
|
+
function processGlobs({ cwd, _2dFilesArray, isPnpm }) {
|
47
|
+
let _1dFilesArray = Array.prototype.concat.apply([], _2dFilesArray);
|
48
|
+
|
49
|
+
let packagePaths = [...new Set(_1dFilesArray)];
|
50
|
+
|
51
|
+
let neededYarnKeys = ['name', 'version'];
|
52
|
+
|
53
|
+
let workspaces = packagePaths.filter(packagePath => {
|
54
|
+
let packageJson;
|
55
|
+
|
56
|
+
try {
|
57
|
+
packageJson = readJsonSync(path.join(cwd, packagePath, 'package.json'));
|
58
|
+
} catch (err) {
|
59
|
+
if (err.code === 'ENOENT') {
|
60
|
+
return;
|
61
|
+
}
|
62
|
+
|
63
|
+
throw err;
|
64
|
+
}
|
65
|
+
|
66
|
+
if (isPnpm) {
|
67
|
+
return true;
|
68
|
+
}
|
69
|
+
|
70
|
+
// for yarn, not a valid package if name and version are missing in package.json
|
71
|
+
if (neededYarnKeys.every(key => key in packageJson)) {
|
72
|
+
return true;
|
73
|
+
}
|
74
|
+
});
|
75
|
+
|
76
|
+
return workspaces;
|
77
|
+
}
|
6
78
|
|
7
79
|
async function getWorkspacesPaths({
|
8
|
-
|
80
|
+
cwd,
|
81
|
+
shouldSpawn = false,
|
82
|
+
}) {
|
83
|
+
let workspacePackageJson = await readJson(path.join(cwd, 'package.json'));
|
84
|
+
|
85
|
+
let { workspaces } = workspacePackageJson;
|
86
|
+
|
87
|
+
let isPnpm = !workspaces;
|
88
|
+
|
89
|
+
if (shouldSpawn) {
|
90
|
+
if (isPnpm) {
|
91
|
+
workspaces = processPnpm(
|
92
|
+
await execa('pnpm', ['recursive', 'exec', '--', 'node', '-e', 'console.log(process.cwd())'], {
|
93
|
+
cwd,
|
94
|
+
}),
|
95
|
+
cwd,
|
96
|
+
);
|
97
|
+
} else {
|
98
|
+
workspaces = processYarn(
|
99
|
+
await execa('yarn', ['--silent', 'workspaces', 'info'], {
|
100
|
+
cwd,
|
101
|
+
}),
|
102
|
+
);
|
103
|
+
}
|
104
|
+
} else {
|
105
|
+
let packagesGlobs;
|
106
|
+
|
107
|
+
if (isPnpm) {
|
108
|
+
packagesGlobs = processPnpmYaml(
|
109
|
+
await fs.readFile(path.join(cwd, 'pnpm-workspace.yaml')),
|
110
|
+
);
|
111
|
+
} else {
|
112
|
+
packagesGlobs = workspaces.packages || workspaces;
|
113
|
+
}
|
114
|
+
|
115
|
+
let _2dFilesArray = await Promise.all(packagesGlobs.map(packagesGlob => {
|
116
|
+
return glob(packagesGlob, {
|
117
|
+
cwd,
|
118
|
+
});
|
119
|
+
}));
|
120
|
+
|
121
|
+
workspaces = processGlobs({ cwd, _2dFilesArray, isPnpm });
|
122
|
+
}
|
123
|
+
|
124
|
+
return workspaces;
|
125
|
+
}
|
126
|
+
|
127
|
+
function getWorkspacesPathsSync({
|
128
|
+
cwd,
|
129
|
+
shouldSpawn = false,
|
9
130
|
}) {
|
10
|
-
let workspacePackageJson =
|
131
|
+
let workspacePackageJson = readJsonSync(path.join(cwd, 'package.json'));
|
11
132
|
|
12
133
|
let { workspaces } = workspacePackageJson;
|
13
134
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
135
|
+
let isPnpm = !workspaces;
|
136
|
+
|
137
|
+
if (shouldSpawn) {
|
138
|
+
if (isPnpm) {
|
139
|
+
workspaces = processPnpm(
|
140
|
+
execa.sync('pnpm', ['recursive', 'exec', '--', 'node', '-e', 'console.log(process.cwd())'], {
|
141
|
+
cwd,
|
142
|
+
}),
|
143
|
+
cwd,
|
144
|
+
);
|
145
|
+
} else {
|
146
|
+
workspaces = processYarn(
|
147
|
+
execa.sync('yarn', ['--silent', 'workspaces', 'info'], {
|
148
|
+
cwd,
|
149
|
+
}),
|
150
|
+
);
|
151
|
+
}
|
18
152
|
} else {
|
19
|
-
let
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
153
|
+
let packagesGlobs;
|
154
|
+
|
155
|
+
if (isPnpm) {
|
156
|
+
packagesGlobs = processPnpmYaml(
|
157
|
+
fs.readFileSync(path.join(cwd, 'pnpm-workspace.yaml')),
|
158
|
+
);
|
159
|
+
} else {
|
160
|
+
packagesGlobs = workspaces.packages || workspaces;
|
161
|
+
}
|
162
|
+
|
163
|
+
let _2dFilesArray = packagesGlobs.map(packagesGlob => {
|
164
|
+
return glob.sync(packagesGlob, {
|
165
|
+
cwd,
|
166
|
+
});
|
167
|
+
});
|
168
|
+
|
169
|
+
workspaces = processGlobs({ cwd, _2dFilesArray, isPnpm });
|
28
170
|
}
|
29
171
|
|
30
172
|
return workspaces;
|
31
173
|
}
|
32
174
|
|
33
|
-
module.exports =
|
175
|
+
module.exports = {
|
176
|
+
getWorkspacesPaths,
|
177
|
+
getWorkspacesPathsSync,
|
178
|
+
};
|
package/src/json.js
CHANGED
@@ -11,6 +11,10 @@ async function read(path) {
|
|
11
11
|
return JSON.parse(await fs.readFile(path, 'utf8'));
|
12
12
|
}
|
13
13
|
|
14
|
+
function readSync(path) {
|
15
|
+
return JSON.parse(fs.readFileSync(path, 'utf8'));
|
16
|
+
}
|
17
|
+
|
14
18
|
async function write(path, json) {
|
15
19
|
await fs.writeFile(path, stringify(json));
|
16
20
|
}
|
@@ -18,5 +22,6 @@ async function write(path, json) {
|
|
18
22
|
module.exports = {
|
19
23
|
stringify,
|
20
24
|
read,
|
25
|
+
readSync,
|
21
26
|
write,
|
22
27
|
};
|
package/src/releasable.js
CHANGED
@@ -18,6 +18,32 @@ const filesContributingToReleasability = new Set([
|
|
18
18
|
|
19
19
|
const packageJsonDevChangeRegex = /^\/(?:devDependencies|publishConfig)(?:\/|$)/m;
|
20
20
|
|
21
|
+
const relativePathRegex = /^\.{2}(?:\/|\\|$)/;
|
22
|
+
|
23
|
+
function removeSubDirs(files) {
|
24
|
+
let remainingFiles = new Set(files);
|
25
|
+
|
26
|
+
for (let file of remainingFiles) {
|
27
|
+
let isSubDir = remainingFiles.some(nextFile => {
|
28
|
+
if (file === nextFile) {
|
29
|
+
return false;
|
30
|
+
}
|
31
|
+
|
32
|
+
let relative = path.relative(file, nextFile);
|
33
|
+
|
34
|
+
let isSubDir = !relativePathRegex.test(relative);
|
35
|
+
|
36
|
+
return isSubDir;
|
37
|
+
});
|
38
|
+
|
39
|
+
if (isSubDir) {
|
40
|
+
remainingFiles.delete(file);
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
return remainingFiles;
|
45
|
+
}
|
46
|
+
|
21
47
|
async function prepareTmpPackage({
|
22
48
|
cwd,
|
23
49
|
tmpDir,
|
@@ -38,11 +64,11 @@ async function prepareTmpPackage({
|
|
38
64
|
}
|
39
65
|
}
|
40
66
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
}
|
67
|
+
let remainingFiles = changedFiles.diff(filesContributingToReleasability);
|
68
|
+
|
69
|
+
remainingFiles = removeSubDirs(remainingFiles);
|
45
70
|
|
71
|
+
for (let file of remainingFiles) {
|
46
72
|
let filePath = path.join(tmpDir, file);
|
47
73
|
|
48
74
|
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
@@ -161,4 +187,6 @@ async function getChangedReleasableFiles({
|
|
161
187
|
module.exports = {
|
162
188
|
getChangedReleasableFiles,
|
163
189
|
packageJsonDevChangeRegex,
|
190
|
+
removeSubDirs,
|
191
|
+
relativePathRegex,
|
164
192
|
};
|