monorepo-next 7.2.2 → 7.3.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "monorepo-next",
3
- "version": "7.2.2",
3
+ "version": "7.3.0",
4
4
  "description": "Detach monorepo packages from normal linking",
5
5
  "bin": {
6
6
  "next": "bin/next.js"
@@ -65,7 +65,7 @@
65
65
  "glob": "^7.1.4",
66
66
  "inquirer": "^8.0.0",
67
67
  "minimatch": "^5.0.0",
68
- "npm-packlist": "^3.0.0",
68
+ "npm-packlist": "^4.0.0",
69
69
  "rfc6902": "^5.0.0",
70
70
  "semver": "7.3.5",
71
71
  "standard-version": "9.3.2",
package/src/attach.js CHANGED
@@ -4,6 +4,7 @@ const path = require('path');
4
4
  const writeJson = require('./json').write;
5
5
  const buildDepGraph = require('./build-dep-graph');
6
6
  const buildDAG = require('./build-dag');
7
+ const { isCycle } = buildDAG;
7
8
  const dependencyTypes = require('./dependency-types');
8
9
  const {
9
10
  getWorkspaceCwd,
@@ -29,16 +30,16 @@ async function detachDependents(dag) {
29
30
  // prevent loops
30
31
  const detach = require('./detach');
31
32
 
32
- for (let node of dag.dependents) {
33
+ for (let group of dag.node.dependents) {
33
34
  await detach({
34
- package: path.basename(dag.cwd),
35
- cwd: node.cwd,
35
+ package: path.basename(dag.node.cwd),
36
+ cwd: group.node.cwd,
36
37
  });
37
38
 
38
- if (node.isPackage) {
39
+ if (group.node.isPackage) {
39
40
  await attach({
40
- cwd: node.cwd,
41
- dag: node,
41
+ cwd: group.node.cwd,
42
+ dag: group,
42
43
  });
43
44
  }
44
45
  }
@@ -83,7 +84,7 @@ async function attach({
83
84
  // don't mutate package.json until after DAG is built
84
85
  myPackageJson.version = matches[1];
85
86
 
86
- if (!dag.isCycle) {
87
+ if (!isCycle(dag)) {
87
88
  await detachDependents(dag);
88
89
  }
89
90
  }
@@ -41,19 +41,19 @@ async function getPackageChangedFiles({
41
41
  }
42
42
 
43
43
  function crawlDag(dag, packagesWithChanges) {
44
- for (let node of dag.dependents) {
45
- if (packagesWithChanges[node.packageName]) {
44
+ for (let group of dag.node.dependents) {
45
+ if (packagesWithChanges[group.node.packageName]) {
46
46
  continue;
47
47
  }
48
48
 
49
- packagesWithChanges[node.packageName] = {
49
+ packagesWithChanges[group.node.packageName] = {
50
50
  changedFiles: [],
51
51
  changedReleasableFiles: [],
52
- dag: node,
52
+ dag: group,
53
53
  };
54
54
 
55
- if (node.dependencyType !== 'devDependencies') {
56
- crawlDag(node, packagesWithChanges);
55
+ if (group.dependencyType !== 'devDependencies') {
56
+ crawlDag(group, packagesWithChanges);
57
57
  }
58
58
  }
59
59
  }
@@ -153,7 +153,7 @@ async function buildChangeGraph({
153
153
 
154
154
  let dag = buildDAG(workspaceMeta, _package.packageName);
155
155
 
156
- packagesWithChanges[dag.packageName] = {
156
+ packagesWithChanges[_package.packageName] = {
157
157
  changedFiles: newFiles,
158
158
  changedReleasableFiles,
159
159
  dag,
package/src/build-dag.js CHANGED
@@ -14,8 +14,15 @@ function doesDependOnPackage(_package, packageName) {
14
14
  }
15
15
  }
16
16
 
17
- function thirdPass(workspaceMeta, dag) {
18
- let currentPackageName = dag.packageName;
17
+ function thirdPass({
18
+ workspaceMeta,
19
+ group,
20
+ branch,
21
+ visitedNodes,
22
+ }) {
23
+ let currentPackageName = group.node.packageName;
24
+
25
+ visitedNodes[currentPackageName] = group.node;
19
26
 
20
27
  for (let _package of collectPackages(workspaceMeta)) {
21
28
  if (_package.packageName === currentPackageName) {
@@ -28,57 +35,122 @@ function thirdPass(workspaceMeta, dag) {
28
35
  } = doesDependOnPackage(_package, currentPackageName) || {};
29
36
 
30
37
  if (dependencyType) {
31
- let node = createPackageNode({
38
+ let parent = group;
39
+
40
+ let visitedNode = visitedNodes[_package.packageName];
41
+
42
+ if (visitedNode) {
43
+ group.node.dependents.push({
44
+ parent,
45
+ dependencyType,
46
+ dependencyRange,
47
+ node: visitedNode,
48
+ });
49
+
50
+ continue;
51
+ }
52
+
53
+ let {
54
+ newGroup,
55
+ newBranch,
56
+ } = createPackageNode({
32
57
  workspaceMeta,
33
58
  packageName: _package.packageName,
34
59
  dependencyType,
35
60
  dependencyRange,
36
- dag,
61
+ parent,
62
+ branch,
37
63
  });
38
- dag.dependents.push(node);
39
- if (node.isPackage && !node.isCycle) {
40
- thirdPass(workspaceMeta, node);
64
+
65
+ group.node.dependents.push(newGroup);
66
+
67
+ if (group.node.isPackage && !isCycle(newGroup)) {
68
+ thirdPass({
69
+ workspaceMeta,
70
+ group: newGroup,
71
+ branch: newBranch,
72
+ visitedNodes,
73
+ });
41
74
  }
42
75
  }
43
76
  }
44
77
  }
45
78
 
79
+ function isCycle(group) {
80
+ let current = group;
81
+
82
+ do {
83
+ current = current.parent;
84
+
85
+ if (!current) {
86
+ return false;
87
+ }
88
+
89
+ if (current.node === group.node) {
90
+ return true;
91
+ }
92
+ } while (true);
93
+ }
94
+
46
95
  function createPackageNode({
47
96
  workspaceMeta,
48
97
  packageName,
49
98
  dependencyType,
50
99
  dependencyRange,
51
- dag,
100
+ parent,
101
+ branch,
52
102
  }) {
53
103
  let _package = workspaceMeta.packages[packageName];
104
+
54
105
  let node = {
55
106
  isPackage: !!(_package && !_package.isPrivate),
56
107
  cwd: _package ? _package.cwd : workspaceMeta.cwd,
57
108
  packageName,
58
109
  version: _package ? _package.version : workspaceMeta.version,
59
- ...dependencyType ? { dependencyType } : {},
60
- ...typeof dependencyRange === 'string' ? { dependencyRange } : {},
61
- branch: [...dag.branch, dag.packageName].filter(Boolean),
62
- ..._package ? { isCycle: dag.branch.includes(packageName) } : {},
63
110
  };
64
- if (!node.isCycle) {
111
+
112
+ let group = {
113
+ parent,
114
+ dependencyType,
115
+ dependencyRange,
116
+ node,
117
+ };
118
+
119
+ if (!isCycle(group)) {
65
120
  node.dependents = [];
66
121
  }
67
- return node;
122
+
123
+ let newBranch = [...branch, packageName].filter(Boolean);
124
+
125
+ return {
126
+ newGroup: group,
127
+ newBranch,
128
+ };
68
129
  }
69
130
 
70
131
  function buildDAG(workspaceMeta, packageName) {
71
- let dag = createPackageNode({
132
+ let {
133
+ newGroup,
134
+ newBranch,
135
+ } = createPackageNode({
72
136
  workspaceMeta,
73
137
  packageName,
74
- dag: {
75
- branch: [],
76
- },
138
+ branch: [],
77
139
  });
78
140
 
79
- thirdPass(workspaceMeta, dag);
141
+ let visitedNodes = {};
142
+
143
+ thirdPass({
144
+ workspaceMeta,
145
+ group: newGroup,
146
+ branch: newBranch,
147
+ visitedNodes,
148
+ });
80
149
 
81
- return dag;
150
+ return newGroup;
82
151
  }
83
152
 
84
153
  module.exports = buildDAG;
154
+ Object.assign(module.exports, {
155
+ isCycle,
156
+ });
@@ -9,6 +9,7 @@ const {
9
9
  const { trackNewVersion } = require('./version');
10
10
  const semver = require('semver');
11
11
  const dependencyTypes = require('./dependency-types');
12
+ const { isCycle } = require('./build-dag');
12
13
 
13
14
  const defaultReleaseType = 'patch';
14
15
 
@@ -51,9 +52,10 @@ async function init({
51
52
  shouldVersionBump = true,
52
53
  }) {
53
54
  let {
55
+ isPackage,
54
56
  packageName: name,
55
57
  cwd,
56
- } = dag;
58
+ } = dag.node;
57
59
 
58
60
  let packageJsonPath = path.join(cwd, 'package.json');
59
61
 
@@ -72,7 +74,7 @@ async function init({
72
74
  }
73
75
 
74
76
  let canBumpVersion = !!(version && name);
75
- let canPublish = dag.isPackage;
77
+ let canPublish = isPackage;
76
78
  let shouldBumpVersion = canBumpVersion && shouldVersionBump;
77
79
  let shouldPublish = canPublish && shouldBumpVersion;
78
80
 
@@ -115,12 +117,12 @@ async function secondPass({
115
117
  dag,
116
118
  parent,
117
119
  }) {
118
- let doesPackageHaveChanges = !!releaseTrees[dag.packageName];
120
+ let doesPackageHaveChanges = !!releaseTrees[dag.node.packageName];
119
121
  if (!doesPackageHaveChanges) {
120
122
  let isDevDep = dag.dependencyType === 'devDependencies';
121
123
  let shouldVersionBump = !shouldExcludeDevChanges || !isDevDep;
122
124
 
123
- if (dag.isPackage && shouldInheritGreaterReleaseType && !isDevDep && shouldBumpInRangeDependencies) {
125
+ if (dag.node.isPackage && shouldInheritGreaterReleaseType && !isDevDep && shouldBumpInRangeDependencies) {
124
126
  await init({ dag, releaseTrees, releaseType: parent.releaseType });
125
127
  } else if (!isReleaseTypeInRange(parent.oldVersion, parent.releaseType, dag.dependencyRange)) {
126
128
  await init({ dag, releaseTrees, releaseType: defaultReleaseType, shouldVersionBump });
@@ -135,14 +137,14 @@ async function secondPass({
135
137
  }
136
138
  }
137
139
 
138
- for (let node of dag.dependents) {
139
- if (node.isCycle) {
140
+ for (let group of dag.node.dependents) {
141
+ if (isCycle(group)) {
140
142
  continue;
141
143
  }
142
144
 
143
145
  await crawlDag({
144
- dag: node,
145
- parent: releaseTrees[dag.packageName],
146
+ dag: group,
147
+ parent: releaseTrees[dag.node.packageName],
146
148
  });
147
149
  }
148
150
  })({
@@ -165,7 +167,7 @@ function thirdPass({
165
167
  dag,
166
168
  parent,
167
169
  }) {
168
- let current = releaseTrees[dag.packageName];
170
+ let current = releaseTrees[dag.node.packageName];
169
171
 
170
172
  if (!current) {
171
173
  return;
@@ -181,13 +183,13 @@ function thirdPass({
181
183
 
182
184
  current.releaseType = currentReleaseType;
183
185
 
184
- for (let node of dag.dependents) {
185
- if (!node.isPackage || node.isCycle) {
186
+ for (let group of dag.node.dependents) {
187
+ if (!group.node.isPackage || isCycle(group)) {
186
188
  continue;
187
189
  }
188
190
 
189
191
  crawlDag({
190
- dag: node,
192
+ dag: group,
191
193
  parent: current,
192
194
  });
193
195
  }
@@ -211,7 +213,7 @@ function fourthPass({
211
213
  dag,
212
214
  parent,
213
215
  }) {
214
- let current = releaseTrees[dag.packageName];
216
+ let current = releaseTrees[dag.node.packageName];
215
217
 
216
218
  if (!current) {
217
219
  return;
@@ -246,13 +248,13 @@ function fourthPass({
246
248
  });
247
249
  }
248
250
 
249
- for (let node of dag.dependents) {
250
- if (node.isCycle) {
251
+ for (let group of dag.node.dependents) {
252
+ if (isCycle(group)) {
251
253
  continue;
252
254
  }
253
255
 
254
256
  crawlDag({
255
- dag: node,
257
+ dag: group,
256
258
  parent: current,
257
259
  });
258
260
  }
@@ -52,11 +52,11 @@ async function changedFiles({
52
52
  changedFiles: _changedFiles,
53
53
  dag,
54
54
  } of packagesWithChanges) {
55
- if (packages.length && !packages.includes(path.basename(dag.cwd))) {
55
+ if (packages.length && !packages.includes(path.basename(dag.node.cwd))) {
56
56
  continue;
57
57
  }
58
58
 
59
- if (isPackageCwd && !await arePathsTheSame(dag.cwd, cwd)) {
59
+ if (isPackageCwd && !await arePathsTheSame(dag.node.cwd, cwd)) {
60
60
  continue;
61
61
  }
62
62
 
package/src/changed.js CHANGED
@@ -33,7 +33,7 @@ async function changed({
33
33
  cached,
34
34
  });
35
35
 
36
- let _changed = packagesWithChanges.map(({ dag }) => dag.packageName);
36
+ let _changed = packagesWithChanges.map(({ dag }) => dag.node.packageName);
37
37
 
38
38
  return _changed;
39
39
  }
package/src/detach.js CHANGED
@@ -53,12 +53,12 @@ async function detach({
53
53
  // don't mutate package.json until after DAG is built
54
54
  myPackageJson.version = `${major}.${minor}.${patch}-detached`;
55
55
 
56
- if (dag.dependents.length) {
56
+ if (dag.node.dependents.length) {
57
57
  // include space as to never match a similarly named package
58
58
  let workspaceKey = 'Workspace Root';
59
59
 
60
- let choices = dag.dependents.map(dependent => {
61
- return dependent.packageName || path.basename(dependent.cwd);
60
+ let choices = dag.node.dependents.map(dependent => {
61
+ return dependent.node.packageName || path.basename(dependent.node.cwd);
62
62
  });
63
63
 
64
64
  let { answers } = await inquirer.prompt([{
@@ -68,22 +68,22 @@ async function detach({
68
68
  choices,
69
69
  }]);
70
70
 
71
- let dependencts = answers.map(answer => {
71
+ let dependents = answers.map(answer => {
72
72
  // switch to key/value instead of array?
73
73
  let isPackage = answer !== workspaceKey;
74
74
 
75
- return dag.dependents.find(dependent => {
76
- return isPackage ? dependent.packageName === answer : !dependent.isPackage;
75
+ return dag.node.dependents.find(dependent => {
76
+ return isPackage ? dependent.node.packageName === answer : !dependent.node.isPackage;
77
77
  });
78
78
  });
79
79
 
80
80
  // prevent loops
81
81
  const attach = require('./attach');
82
82
 
83
- for (let node of dependencts) {
83
+ for (let group of dependents) {
84
84
  await attach({
85
85
  package: path.basename(cwd),
86
- cwd: node.cwd,
86
+ cwd: group.node.cwd,
87
87
  });
88
88
  }
89
89
  }
@@ -40,7 +40,7 @@ async function getChangelog({
40
40
  });
41
41
 
42
42
  packagesWithChanges = packagesWithChanges.filter(({ dag }) => {
43
- return dag.packageName && dag.version;
43
+ return dag.node.packageName && dag.node.version;
44
44
  });
45
45
 
46
46
  let releaseTrees = await buildReleaseGraph({
package/src/release.js CHANGED
@@ -53,7 +53,7 @@ async function release({
53
53
  });
54
54
 
55
55
  packagesWithChanges = packagesWithChanges.filter(({ dag }) => {
56
- return dag.packageName && dag.version;
56
+ return dag.node.packageName && dag.node.version;
57
57
  });
58
58
 
59
59
  if (!packagesWithChanges.some(({ changedReleasableFiles }) => changedReleasableFiles.length)) {
package/src/run.js CHANGED
@@ -30,7 +30,7 @@ async function run({
30
30
  let stderr = '';
31
31
 
32
32
  for (let { dag } of packagesWithChanges) {
33
- let cp = execa('yarn', args, { cwd: dag.cwd });
33
+ let cp = execa('yarn', args, { cwd: dag.node.cwd });
34
34
 
35
35
  if (!silent) {
36
36
  cp.stdout.pipe(process.stdout);