monorepo-next 11.2.0 → 11.4.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/README.md +6 -0
- package/bin/commands/changed-files.js +2 -0
- package/bin/commands/changed.js +2 -0
- package/bin/commands/run.js +2 -0
- package/bin/common-args.js +5 -0
- package/package.json +4 -1
- package/src/build-change-graph.js +30 -6
- package/src/changed-files.js +2 -0
- package/src/changed.js +2 -0
- package/src/fs.js +36 -0
- package/src/git.js +61 -11
- package/src/run.js +2 -0
package/README.md
CHANGED
@@ -58,6 +58,8 @@ Options:
|
|
58
58
|
monorepo dev dep change or manually bumping an
|
59
59
|
external dev dep, don't count it towards a package
|
60
60
|
change. [boolean] [default: false]
|
61
|
+
--exclude-deleted Excluded deleted files from the changeset.
|
62
|
+
[boolean] [default: false]
|
61
63
|
|
62
64
|
next changed
|
63
65
|
|
@@ -73,6 +75,8 @@ Options:
|
|
73
75
|
monorepo dev dep change or manually bumping an
|
74
76
|
external dev dep, don't count it towards a package
|
75
77
|
change. [boolean] [default: false]
|
78
|
+
--exclude-deleted Excluded deleted files from the changeset.
|
79
|
+
[boolean] [default: false]
|
76
80
|
|
77
81
|
next cycles
|
78
82
|
|
@@ -158,6 +162,8 @@ Options:
|
|
158
162
|
monorepo dev dep change or manually bumping an
|
159
163
|
external dev dep, don't count it towards a package
|
160
164
|
change. [boolean] [default: false]
|
165
|
+
--exclude-deleted Excluded deleted files from the changeset.
|
166
|
+
[boolean] [default: false]
|
161
167
|
--silent Don't print logs and errors
|
162
168
|
[boolean] [default: false]
|
163
169
|
```
|
@@ -13,6 +13,7 @@ module.exports = {
|
|
13
13
|
},
|
14
14
|
'only-include-releasable': commonArgs['only-include-releasable'],
|
15
15
|
'exclude-dev-changes': commonArgs['exclude-dev-changes'],
|
16
|
+
'exclude-deleted': commonArgs['exclude-deleted'],
|
16
17
|
},
|
17
18
|
async handler(argv) {
|
18
19
|
const changedFiles = require('../../src/changed-files');
|
@@ -21,6 +22,7 @@ module.exports = {
|
|
21
22
|
...argv,
|
22
23
|
shouldOnlyIncludeReleasable: argv['only-include-releasable'],
|
23
24
|
shouldExcludeDevChanges: argv['exclude-dev-changes'],
|
25
|
+
shouldExcludeDeleted: argv['exclude-deleted'],
|
24
26
|
});
|
25
27
|
|
26
28
|
for (let file of _changedFiles) {
|
package/bin/commands/changed.js
CHANGED
@@ -9,6 +9,7 @@ module.exports = {
|
|
9
9
|
builder: {
|
10
10
|
'only-include-releasable': commonArgs['only-include-releasable'],
|
11
11
|
'exclude-dev-changes': commonArgs['exclude-dev-changes'],
|
12
|
+
'exclude-deleted': commonArgs['exclude-deleted'],
|
12
13
|
},
|
13
14
|
async handler(argv) {
|
14
15
|
const changed = require('../../src/changed');
|
@@ -17,6 +18,7 @@ module.exports = {
|
|
17
18
|
...argv,
|
18
19
|
shouldOnlyIncludeReleasable: argv['only-include-releasable'],
|
19
20
|
shouldExcludeDevChanges: argv['exclude-dev-changes'],
|
21
|
+
shouldExcludeDeleted: argv['exclude-deleted'],
|
20
22
|
});
|
21
23
|
|
22
24
|
for (let name of _changed) {
|
package/bin/commands/run.js
CHANGED
@@ -8,6 +8,7 @@ module.exports = {
|
|
8
8
|
builder: {
|
9
9
|
'only-include-releasable': commonArgs['only-include-releasable'],
|
10
10
|
'exclude-dev-changes': commonArgs['exclude-dev-changes'],
|
11
|
+
'exclude-deleted': commonArgs['exclude-deleted'],
|
11
12
|
'silent': commonArgs['silent'],
|
12
13
|
},
|
13
14
|
async handler(argv) {
|
@@ -17,6 +18,7 @@ module.exports = {
|
|
17
18
|
...argv,
|
18
19
|
shouldOnlyIncludeReleasable: argv['only-include-releasable'],
|
19
20
|
shouldExcludeDevChanges: argv['exclude-dev-changes'],
|
21
|
+
shouldExcludeDeleted: argv['exclude-deleted'],
|
20
22
|
args: process.argv.slice(3),
|
21
23
|
});
|
22
24
|
},
|
package/bin/common-args.js
CHANGED
@@ -13,6 +13,11 @@ module.exports = {
|
|
13
13
|
type: 'boolean',
|
14
14
|
default: false,
|
15
15
|
},
|
16
|
+
'exclude-deleted': {
|
17
|
+
describe: 'Excluded deleted files from the changeset.',
|
18
|
+
type: 'boolean',
|
19
|
+
default: false,
|
20
|
+
},
|
16
21
|
'silent': {
|
17
22
|
describe: 'Don\'t print logs and errors',
|
18
23
|
type: 'boolean',
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "monorepo-next",
|
3
|
-
"version": "11.
|
3
|
+
"version": "11.4.0",
|
4
4
|
"description": "Detach monorepo packages from normal linking",
|
5
5
|
"bin": {
|
6
6
|
"next": "bin/next.js"
|
@@ -66,9 +66,11 @@
|
|
66
66
|
"glob": "^8.0.0",
|
67
67
|
"inquirer": "^9.0.0",
|
68
68
|
"js-yaml": "^4.0.0",
|
69
|
+
"lockfile": "^1.0.4",
|
69
70
|
"minimatch": "^9.0.0",
|
70
71
|
"npm-packlist": "^8.0.0",
|
71
72
|
"rfc6902": "^5.0.0",
|
73
|
+
"sanitize-filename": "^1.6.3",
|
72
74
|
"semver": "^7.5.3",
|
73
75
|
"standard-version": "9.5.0",
|
74
76
|
"superset": "^2.0.1",
|
@@ -79,6 +81,7 @@
|
|
79
81
|
"@crowdstrike/commitlint": "^7.0.0",
|
80
82
|
"chai": "^4.2.0",
|
81
83
|
"chai-as-promised": "^7.1.1",
|
84
|
+
"chai-fs": "^2.0.0",
|
82
85
|
"common-tags": "^1.8.2",
|
83
86
|
"eslint": "^8.0.0",
|
84
87
|
"eslint-config-crowdstrike": "10.1.0",
|
@@ -27,6 +27,8 @@ async function getPackageChangedFiles({
|
|
27
27
|
// down to 25 seconds from 39 seconds.
|
28
28
|
shouldRunPerPackage = true,
|
29
29
|
|
30
|
+
shouldExcludeDeleted,
|
31
|
+
|
30
32
|
options,
|
31
33
|
}) {
|
32
34
|
// Be careful you don't accidentally use `...` instead of `..`.
|
@@ -35,23 +37,43 @@ async function getPackageChangedFiles({
|
|
35
37
|
//
|
36
38
|
// I tried using ls-tree instead of diff when it is a new package (fromCommit is first commit in repo),
|
37
39
|
// but it took the same amount of time.
|
38
|
-
let committedChanges = await git(['diff', '--name-
|
40
|
+
let committedChanges = await git(['diff', '--name-status', `${fromCommit}..${toCommit}`, ...shouldRunPerPackage ? [packageCwd] : []], options);
|
41
|
+
|
42
|
+
committedChanges = getLinesFromOutput(committedChanges).reduce((committedChanges, line) => {
|
43
|
+
let isDeleted = line[0] === 'D';
|
44
|
+
let shouldExclude = shouldExcludeDeleted && isDeleted;
|
45
|
+
|
46
|
+
if (!shouldExclude) {
|
47
|
+
line = line.substr(2);
|
48
|
+
|
49
|
+
committedChanges.add(line);
|
50
|
+
}
|
39
51
|
|
40
|
-
|
52
|
+
return committedChanges;
|
53
|
+
}, new Set());
|
41
54
|
|
42
55
|
let dirtyChanges = await git(['status', '--porcelain', '--untracked-files', ...shouldRunPerPackage ? [packageCwd] : []], options);
|
43
56
|
|
44
|
-
dirtyChanges = getLinesFromOutput(dirtyChanges).
|
57
|
+
dirtyChanges = getLinesFromOutput(dirtyChanges).reduce((dirtyChanges, line) => {
|
58
|
+
let isDeleted = line[1] === 'D';
|
59
|
+
let shouldExclude = shouldExcludeDeleted && isDeleted;
|
60
|
+
|
45
61
|
line = line.substr(3);
|
46
62
|
|
47
63
|
// if filename has space like `sample index.js`, if its modified and uncommited, that file will have double quotes in git status
|
48
64
|
// example: '"packages/package-a/sample index.js"'. We need to strip `"` for that reason.
|
49
65
|
line = line.replaceAll('"', '');
|
50
66
|
|
51
|
-
|
52
|
-
|
67
|
+
if (shouldExclude) {
|
68
|
+
committedChanges.delete(line);
|
69
|
+
} else {
|
70
|
+
dirtyChanges.add(line);
|
71
|
+
}
|
72
|
+
|
73
|
+
return dirtyChanges;
|
74
|
+
}, new Set());
|
53
75
|
|
54
|
-
let changedFiles =
|
76
|
+
let changedFiles = committedChanges.union(dirtyChanges);
|
55
77
|
|
56
78
|
if (!shouldRunPerPackage) {
|
57
79
|
let packageChangedFiles = new Set();
|
@@ -94,6 +116,7 @@ async function buildChangeGraph({
|
|
94
116
|
workspaceMeta,
|
95
117
|
shouldOnlyIncludeReleasable,
|
96
118
|
shouldExcludeDevChanges,
|
119
|
+
shouldExcludeDeleted,
|
97
120
|
fromCommit,
|
98
121
|
fromCommitIfNewer,
|
99
122
|
toCommit = 'HEAD',
|
@@ -161,6 +184,7 @@ async function buildChangeGraph({
|
|
161
184
|
toCommit,
|
162
185
|
packageCwd: _package.cwd,
|
163
186
|
shouldRunPerPackage: false,
|
187
|
+
shouldExcludeDeleted,
|
164
188
|
options: {
|
165
189
|
cwd: workspaceMeta.cwd,
|
166
190
|
cached,
|
package/src/changed-files.js
CHANGED
@@ -19,6 +19,7 @@ async function changedFiles({
|
|
19
19
|
cwd = process.cwd(),
|
20
20
|
shouldOnlyIncludeReleasable = builder['only-include-releasable'].default,
|
21
21
|
shouldExcludeDevChanges = builder['exclude-dev-changes'].default,
|
22
|
+
shouldExcludeDeleted = builder['exclude-deleted'].default,
|
22
23
|
fromCommit,
|
23
24
|
fromCommitIfNewer,
|
24
25
|
toCommit,
|
@@ -38,6 +39,7 @@ async function changedFiles({
|
|
38
39
|
workspaceMeta,
|
39
40
|
shouldOnlyIncludeReleasable,
|
40
41
|
shouldExcludeDevChanges,
|
42
|
+
shouldExcludeDeleted,
|
41
43
|
fromCommit,
|
42
44
|
fromCommitIfNewer,
|
43
45
|
toCommit,
|
package/src/changed.js
CHANGED
@@ -12,6 +12,7 @@ async function changed({
|
|
12
12
|
cwd = process.cwd(),
|
13
13
|
shouldOnlyIncludeReleasable = builder['only-include-releasable'].default,
|
14
14
|
shouldExcludeDevChanges = builder['exclude-dev-changes'].default,
|
15
|
+
shouldExcludeDeleted = builder['exclude-deleted'].default,
|
15
16
|
fromCommit,
|
16
17
|
fromCommitIfNewer,
|
17
18
|
toCommit,
|
@@ -26,6 +27,7 @@ async function changed({
|
|
26
27
|
workspaceMeta,
|
27
28
|
shouldOnlyIncludeReleasable,
|
28
29
|
shouldExcludeDevChanges,
|
30
|
+
shouldExcludeDeleted,
|
29
31
|
fromCommit,
|
30
32
|
fromCommitIfNewer,
|
31
33
|
toCommit,
|
package/src/fs.js
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
const fs = { ...require('fs'), ...require('fs').promises };
|
4
4
|
const { EOL } = require('os');
|
5
|
+
const { dirname } = require('path');
|
5
6
|
|
6
7
|
async function replaceFile(path, callback) {
|
7
8
|
let oldContents = await fs.readFile(path, 'utf8');
|
@@ -30,7 +31,42 @@ async function replaceJsonFile(path, callback) {
|
|
30
31
|
});
|
31
32
|
}
|
32
33
|
|
34
|
+
/**
|
35
|
+
* @param {string} path
|
36
|
+
*/
|
37
|
+
async function safeReadFile(path) {
|
38
|
+
try {
|
39
|
+
return await fs.readFile(path, 'utf8');
|
40
|
+
} catch (err) {
|
41
|
+
if (err.code !== 'ENOENT') {
|
42
|
+
throw err;
|
43
|
+
}
|
44
|
+
|
45
|
+
return null;
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
/**
|
50
|
+
* @param {string} path
|
51
|
+
*/
|
52
|
+
async function ensureDir(path) {
|
53
|
+
await fs.mkdir(path, { recursive: true });
|
54
|
+
}
|
55
|
+
|
56
|
+
/**
|
57
|
+
* @param {string} path
|
58
|
+
* @param {string} data
|
59
|
+
*/
|
60
|
+
async function ensureWriteFile(path, data) {
|
61
|
+
await ensureDir(dirname(path));
|
62
|
+
|
63
|
+
await fs.writeFile(path, data);
|
64
|
+
}
|
65
|
+
|
33
66
|
module.exports = {
|
34
67
|
replaceFile,
|
35
68
|
replaceJsonFile,
|
69
|
+
safeReadFile,
|
70
|
+
ensureDir,
|
71
|
+
ensureWriteFile,
|
36
72
|
};
|
package/src/git.js
CHANGED
@@ -2,11 +2,18 @@
|
|
2
2
|
|
3
3
|
const execa = require('execa');
|
4
4
|
const debug = require('./debug').extend('git');
|
5
|
+
const sanitize = require('sanitize-filename');
|
6
|
+
const path = require('path');
|
7
|
+
const { safeReadFile, ensureDir, ensureWriteFile } = require('./fs');
|
8
|
+
const { promisify } = require('util');
|
9
|
+
const lockfile = require('lockfile');
|
10
|
+
const lock = promisify(lockfile.lock);
|
11
|
+
const unlock = promisify(lockfile.unlock);
|
5
12
|
|
6
13
|
let cache = {};
|
7
14
|
|
8
15
|
function getCacheKey(args, cwd) {
|
9
|
-
return [cwd, ...args].join();
|
16
|
+
return sanitize([cwd, ...args].join());
|
10
17
|
}
|
11
18
|
|
12
19
|
async function git(args, options) {
|
@@ -16,6 +23,7 @@ async function git(args, options) {
|
|
16
23
|
} = options;
|
17
24
|
|
18
25
|
let cacheKey;
|
26
|
+
let lockFilePath;
|
19
27
|
|
20
28
|
if (cached) {
|
21
29
|
cacheKey = getCacheKey(args, cwd);
|
@@ -26,22 +34,64 @@ async function git(args, options) {
|
|
26
34
|
return cache[cacheKey];
|
27
35
|
}
|
28
36
|
|
29
|
-
|
30
|
-
|
37
|
+
if (cached !== true) {
|
38
|
+
lockFilePath = path.join(cached, `${cacheKey}.lock`);
|
31
39
|
|
32
|
-
|
40
|
+
await ensureDir(cached);
|
33
41
|
|
34
|
-
|
35
|
-
cwd,
|
36
|
-
})).stdout;
|
42
|
+
debug(`Waiting for git lock at ${lockFilePath}.`);
|
37
43
|
|
38
|
-
|
39
|
-
|
44
|
+
await lock(lockFilePath, { wait: 10 * 60e3 });
|
45
|
+
|
46
|
+
debug(`Acquired git lock at ${lockFilePath}.`);
|
47
|
+
}
|
40
48
|
}
|
41
49
|
|
42
|
-
|
50
|
+
try {
|
51
|
+
let cachedFilePath;
|
52
|
+
|
53
|
+
if (cached) {
|
54
|
+
if (cached !== true) {
|
55
|
+
cachedFilePath = path.join(cached, cacheKey);
|
56
|
+
|
57
|
+
let _cache = await safeReadFile(cachedFilePath);
|
58
|
+
|
59
|
+
if (_cache !== null) {
|
60
|
+
debug('Git cache hit.');
|
61
|
+
|
62
|
+
cache[cacheKey] = _cache;
|
63
|
+
|
64
|
+
return _cache;
|
65
|
+
}
|
66
|
+
}
|
43
67
|
|
44
|
-
|
68
|
+
debug('Git cache miss.');
|
69
|
+
}
|
70
|
+
|
71
|
+
debug(args, options);
|
72
|
+
|
73
|
+
let { stdout } = await execa('git', args, {
|
74
|
+
cwd,
|
75
|
+
});
|
76
|
+
|
77
|
+
if (cached) {
|
78
|
+
cache[cacheKey] = stdout;
|
79
|
+
|
80
|
+
if (cached !== true) {
|
81
|
+
await ensureWriteFile(cachedFilePath, stdout);
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
debug(stdout);
|
86
|
+
|
87
|
+
return stdout;
|
88
|
+
} finally {
|
89
|
+
if (lockFilePath) {
|
90
|
+
await unlock(lockFilePath);
|
91
|
+
|
92
|
+
debug(`Released git lock at ${lockFilePath}.`);
|
93
|
+
}
|
94
|
+
}
|
45
95
|
}
|
46
96
|
|
47
97
|
async function getCurrentBranch(cwd) {
|
package/src/run.js
CHANGED
@@ -13,6 +13,7 @@ async function run({
|
|
13
13
|
cwd = process.cwd(),
|
14
14
|
shouldOnlyIncludeReleasable = builder['only-include-releasable'].default,
|
15
15
|
shouldExcludeDevChanges = builder['exclude-dev-changes'].default,
|
16
|
+
shouldExcludeDeleted = builder['exclude-deleted'].default,
|
16
17
|
silent,
|
17
18
|
args,
|
18
19
|
cached,
|
@@ -25,6 +26,7 @@ async function run({
|
|
25
26
|
workspaceMeta,
|
26
27
|
shouldOnlyIncludeReleasable,
|
27
28
|
shouldExcludeDevChanges,
|
29
|
+
shouldExcludeDeleted,
|
28
30
|
cached,
|
29
31
|
});
|
30
32
|
|