monorepo-next 7.2.4 → 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.4",
3
+ "version": "7.3.0",
4
4
  "description": "Detach monorepo packages from normal linking",
5
5
  "bin": {
6
6
  "next": "bin/next.js"
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
  }
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
 
@@ -54,7 +55,7 @@ async function init({
54
55
  isPackage,
55
56
  packageName: name,
56
57
  cwd,
57
- } = dag;
58
+ } = dag.node;
58
59
 
59
60
  let packageJsonPath = path.join(cwd, 'package.json');
60
61
 
@@ -116,12 +117,12 @@ async function secondPass({
116
117
  dag,
117
118
  parent,
118
119
  }) {
119
- let doesPackageHaveChanges = !!releaseTrees[dag.packageName];
120
+ let doesPackageHaveChanges = !!releaseTrees[dag.node.packageName];
120
121
  if (!doesPackageHaveChanges) {
121
122
  let isDevDep = dag.dependencyType === 'devDependencies';
122
123
  let shouldVersionBump = !shouldExcludeDevChanges || !isDevDep;
123
124
 
124
- if (dag.isPackage && shouldInheritGreaterReleaseType && !isDevDep && shouldBumpInRangeDependencies) {
125
+ if (dag.node.isPackage && shouldInheritGreaterReleaseType && !isDevDep && shouldBumpInRangeDependencies) {
125
126
  await init({ dag, releaseTrees, releaseType: parent.releaseType });
126
127
  } else if (!isReleaseTypeInRange(parent.oldVersion, parent.releaseType, dag.dependencyRange)) {
127
128
  await init({ dag, releaseTrees, releaseType: defaultReleaseType, shouldVersionBump });
@@ -136,14 +137,14 @@ async function secondPass({
136
137
  }
137
138
  }
138
139
 
139
- for (let node of dag.dependents) {
140
- if (node.isCycle) {
140
+ for (let group of dag.node.dependents) {
141
+ if (isCycle(group)) {
141
142
  continue;
142
143
  }
143
144
 
144
145
  await crawlDag({
145
- dag: node,
146
- parent: releaseTrees[dag.packageName],
146
+ dag: group,
147
+ parent: releaseTrees[dag.node.packageName],
147
148
  });
148
149
  }
149
150
  })({
@@ -166,7 +167,7 @@ function thirdPass({
166
167
  dag,
167
168
  parent,
168
169
  }) {
169
- let current = releaseTrees[dag.packageName];
170
+ let current = releaseTrees[dag.node.packageName];
170
171
 
171
172
  if (!current) {
172
173
  return;
@@ -182,13 +183,13 @@ function thirdPass({
182
183
 
183
184
  current.releaseType = currentReleaseType;
184
185
 
185
- for (let node of dag.dependents) {
186
- if (!node.isPackage || node.isCycle) {
186
+ for (let group of dag.node.dependents) {
187
+ if (!group.node.isPackage || isCycle(group)) {
187
188
  continue;
188
189
  }
189
190
 
190
191
  crawlDag({
191
- dag: node,
192
+ dag: group,
192
193
  parent: current,
193
194
  });
194
195
  }
@@ -212,7 +213,7 @@ function fourthPass({
212
213
  dag,
213
214
  parent,
214
215
  }) {
215
- let current = releaseTrees[dag.packageName];
216
+ let current = releaseTrees[dag.node.packageName];
216
217
 
217
218
  if (!current) {
218
219
  return;
@@ -247,13 +248,13 @@ function fourthPass({
247
248
  });
248
249
  }
249
250
 
250
- for (let node of dag.dependents) {
251
- if (node.isCycle) {
251
+ for (let group of dag.node.dependents) {
252
+ if (isCycle(group)) {
252
253
  continue;
253
254
  }
254
255
 
255
256
  crawlDag({
256
- dag: node,
257
+ dag: group,
257
258
  parent: current,
258
259
  });
259
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([{
@@ -72,18 +72,18 @@ async function detach({
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 dependents) {
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);