@atlaskit/dependency-version-analytics 1.0.0 → 1.2.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +7 -4
  3. package/dist/cjs/cli.js +52 -17
  4. package/dist/cjs/commands/populate-historic-data/index.js +2 -2
  5. package/dist/cjs/commands/populate-historic-data/lib/dependency-store.js +227 -451
  6. package/dist/cjs/commands/populate-historic-data/package.js +31 -71
  7. package/dist/cjs/commands/populate-historic-data/product.js +130 -253
  8. package/dist/cjs/commands/populate-historic-data/util/allowed-scopes.js +15 -0
  9. package/dist/cjs/commands/populate-historic-data/util/generate-csv.js +16 -21
  10. package/dist/cjs/constants.js +2 -2
  11. package/dist/cjs/index.js +3 -3
  12. package/dist/cjs/util/analytics.js +82 -94
  13. package/dist/cjs/util/get-file-history-from-git.js +4 -4
  14. package/dist/cjs/util/get-package-version-history.js +11 -7
  15. package/dist/cjs/util/git.js +75 -205
  16. package/dist/cjs/util/statlas.js +27 -97
  17. package/dist/cjs/util/yarn.js +40 -101
  18. package/dist/cjs/version.json +1 -1
  19. package/dist/es2019/cli.js +10 -4
  20. package/dist/es2019/commands/populate-historic-data/lib/dependency-store.js +6 -4
  21. package/dist/es2019/commands/populate-historic-data/package.js +11 -6
  22. package/dist/es2019/commands/populate-historic-data/product.js +25 -7
  23. package/dist/es2019/commands/populate-historic-data/util/allowed-scopes.js +7 -0
  24. package/dist/es2019/commands/populate-historic-data/util/generate-csv.js +1 -1
  25. package/dist/es2019/util/analytics.js +13 -0
  26. package/dist/es2019/util/get-package-version-history.js +7 -3
  27. package/dist/es2019/version.json +1 -1
  28. package/dist/esm/cli.js +8 -3
  29. package/dist/esm/commands/populate-historic-data/lib/dependency-store.js +20 -15
  30. package/dist/esm/commands/populate-historic-data/package.js +27 -21
  31. package/dist/esm/commands/populate-historic-data/product.js +121 -81
  32. package/dist/esm/commands/populate-historic-data/util/allowed-scopes.js +11 -0
  33. package/dist/esm/commands/populate-historic-data/util/generate-csv.js +1 -1
  34. package/dist/esm/util/analytics.js +19 -5
  35. package/dist/esm/util/get-package-version-history.js +7 -3
  36. package/dist/esm/util/git.js +14 -13
  37. package/dist/esm/util/statlas.js +8 -7
  38. package/dist/esm/util/yarn.js +6 -5
  39. package/dist/esm/version.json +1 -1
  40. package/dist/types/commands/populate-historic-data/lib/dependency-store.d.ts +3 -2
  41. package/dist/types/commands/populate-historic-data/types.d.ts +3 -2
  42. package/dist/types/commands/populate-historic-data/util/allowed-scopes.d.ts +2 -0
  43. package/dist/types/commands/populate-historic-data/util/generate-csv.d.ts +2 -2
  44. package/dist/types/types.d.ts +7 -0
  45. package/dist/types/util/analytics.d.ts +2 -1
  46. package/dist/types/util/get-package-version-history.d.ts +7 -3
  47. package/package.json +2 -2
  48. package/report.api.md +5 -0
  49. package/tmp/api-report-tmp.d.ts +5 -0
  50. package/tokenize-arg-string.ts +0 -0
@@ -5,13 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.DependencyStore = void 0;
8
- var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
- var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
11
- var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
12
- var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
13
- var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
14
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
15
8
  var _debug = _interopRequireDefault(require("debug"));
16
9
  var _semver = _interopRequireDefault(require("semver"));
17
10
  var _yarn = require("../../../util/yarn");
@@ -19,477 +12,260 @@ var _git = require("../../../util/git");
19
12
  var _constants = require("../../../constants");
20
13
  var _assert = require("../../../util/assert");
21
14
  var _micromatch = _interopRequireDefault(require("micromatch"));
22
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
23
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
24
- function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
25
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
26
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
27
- var debug = (0, _debug.default)('atlaskit:dependency');
15
+ var _allowedScopes = require("../util/allowed-scopes");
16
+ /** Workspace code */
17
+
18
+ const debug = (0, _debug.default)('atlaskit:dependency');
28
19
  /**
29
20
  * Stores the state of atlaskit dependencies in a repository
30
21
  */
31
- var DependencyStore = /*#__PURE__*/function () {
22
+ class DependencyStore {
32
23
  /** Mapping of dependency names to arrays of unique dependency type + versions */
33
-
24
+ dependencies = {};
34
25
  /** Mapping of workspaces to their dependency map. Each dependency in their map links to an entry in `dependencies` */
35
-
26
+ workspaces = {};
36
27
  /** Set of workspace globs. Used to verify that a package.json is a valid workspace */
37
-
38
- function DependencyStore() {
39
- var cwd = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : process.cwd();
40
- (0, _classCallCheck2.default)(this, DependencyStore);
41
- (0, _defineProperty2.default)(this, "dependencies", {});
42
- (0, _defineProperty2.default)(this, "workspaces", {});
43
- (0, _defineProperty2.default)(this, "workspaceGlobs", new Set());
44
- (0, _defineProperty2.default)(this, "initialised", false);
28
+ workspaceGlobs = new Set();
29
+ initialised = false;
30
+ constructor(cwd = process.cwd(), supportedScopes) {
45
31
  this.cwd = cwd;
32
+ this.supportedScopes = supportedScopes;
46
33
  }
47
34
 
48
35
  /** Scans the repo for dependencies at the specified git ref and return the flattened dependency map */
49
- (0, _createClass2.default)(DependencyStore, [{
50
- key: "initialise",
51
- value: function () {
52
- var _initialise = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(gitRef) {
53
- return _regenerator.default.wrap(function _callee$(_context) {
54
- while (1) {
55
- switch (_context.prev = _context.next) {
56
- case 0:
57
- if (!gitRef) {
58
- _context.next = 3;
59
- break;
60
- }
61
- _context.next = 3;
62
- return this.resetStore(gitRef);
63
- case 3:
64
- this.initialised = true;
65
- return _context.abrupt("return", this.getFlattenedDeps());
66
- case 5:
67
- case "end":
68
- return _context.stop();
69
- }
70
- }
71
- }, _callee, this);
72
- }));
73
- function initialise(_x) {
74
- return _initialise.apply(this, arguments);
75
- }
76
- return initialise;
77
- }()
78
- /** Updates the repo dependency store based on the changes in `logItem`.
79
- * Returns the updated flattened dependencies
80
- */
81
- }, {
82
- key: "update",
83
- value: function () {
84
- var _update = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(logItem) {
85
- var hash, changedPackageJsons, didRootPackageJsonChange, workspaceGlobs, globsChanged, changedWorkspaces, _iterator, _step, workspacePath, workspaceDeps, validWorkspace, noLongerWorkspace;
86
- return _regenerator.default.wrap(function _callee2$(_context2) {
87
- while (1) {
88
- switch (_context2.prev = _context2.next) {
89
- case 0:
90
- this.assertInitialised();
91
- hash = logItem.hash;
92
- (0, _assert.assert)(!!logItem.diff, "Diff must exist in log ".concat(logItem, " ").concat(hash));
93
- changedPackageJsons = logItem.diff.files.filter(function (f) {
94
- return f.file === 'package.json' || f.file.endsWith('/package.json');
95
- }).map(function (f) {
96
- return f.file;
97
- });
98
- didRootPackageJsonChange = !!changedPackageJsons.find(function (file) {
99
- return file === 'package.json';
100
- });
101
- if (!didRootPackageJsonChange) {
102
- _context2.next = 15;
103
- break;
104
- }
105
- _context2.next = 8;
106
- return (0, _yarn.getWorkspaceGlobs)(hash, this.cwd);
107
- case 8:
108
- workspaceGlobs = _context2.sent;
109
- globsChanged = workspaceGlobs !== null && (this.workspaceGlobs.size !== workspaceGlobs.size || (0, _toConsumableArray2.default)(this.workspaceGlobs).some(function (glob) {
110
- return !workspaceGlobs.has(glob);
111
- }));
112
- if (!globsChanged) {
113
- _context2.next = 15;
114
- break;
115
- }
116
- debug("Workspace globs changed: ".concat((0, _toConsumableArray2.default)(workspaceGlobs), ". Resetting store."));
117
- _context2.next = 14;
118
- return this.resetStore(hash);
119
- case 14:
120
- return _context2.abrupt("return", this.getFlattenedDeps());
121
- case 15:
122
- changedWorkspaces = (0, _micromatch.default)(changedPackageJsons, (0, _toConsumableArray2.default)(this.workspaceGlobs));
123
- debug("Updating changed workspaces@".concat(hash, ": ").concat(changedWorkspaces));
124
-
125
- // Iterate over all changed package.jsons rather than only valid workspaces so that we can
126
- // remove older workspaces that are no longer valid
127
- _iterator = _createForOfIteratorHelper(changedPackageJsons);
128
- _context2.prev = 18;
129
- _iterator.s();
130
- case 20:
131
- if ((_step = _iterator.n()).done) {
132
- _context2.next = 33;
133
- break;
134
- }
135
- workspacePath = _step.value;
136
- _context2.next = 24;
137
- return this.getWorkspaceDependencies(hash, workspacePath);
138
- case 24:
139
- workspaceDeps = _context2.sent;
140
- validWorkspace = changedWorkspaces.includes(workspacePath);
141
- if (!(!validWorkspace && !this.workspaces[workspacePath])) {
142
- _context2.next = 28;
143
- break;
144
- }
145
- return _context2.abrupt("continue", 31);
146
- case 28:
147
- // For workspaces that are no longer a valid workspace but were previously, explicitly remove them
148
- noLongerWorkspace = !validWorkspace && this.workspaces[workspacePath];
149
- if (workspaceDeps == null || noLongerWorkspace) {
150
- // If workspaceDeps is undefined, package.json existed but JSON was invalid
151
- // Else if workspaceDeps is null, package.json doesn't exist and has hence been deleted
152
- if (workspaceDeps === undefined) {
153
- console.error("Error parsing metadata for workspace ".concat(workspacePath, "@").concat(hash));
154
- }
155
- // set the workspaceDeps to empty here explicitly to remove any deleted workspaces
156
- workspaceDeps = {};
157
- }
158
- this.updateWorkspaces(workspacePath, workspaceDeps);
159
- case 31:
160
- _context2.next = 20;
161
- break;
162
- case 33:
163
- _context2.next = 38;
164
- break;
165
- case 35:
166
- _context2.prev = 35;
167
- _context2.t0 = _context2["catch"](18);
168
- _iterator.e(_context2.t0);
169
- case 38:
170
- _context2.prev = 38;
171
- _iterator.f();
172
- return _context2.finish(38);
173
- case 41:
174
- return _context2.abrupt("return", this.getFlattenedDeps());
175
- case 42:
176
- case "end":
177
- return _context2.stop();
178
- }
179
- }
180
- }, _callee2, this, [[18, 35, 38, 41]]);
181
- }));
182
- function update(_x2) {
183
- return _update.apply(this, arguments);
184
- }
185
- return update;
186
- }()
187
- /** Retrieve a flattened list of p repo dependencies.
188
- * If multiple versions of a dependency exist, the lowest version is returned.
189
- * If the dependency is listed under multiple dependency types, 'dependencies' is prioritised over 'devDependencies'
190
- */
191
- }, {
192
- key: "getFlattenedDeps",
193
- value: function getFlattenedDeps() {
194
- var deps = Object.entries(this.dependencies).filter(function (_ref) {
195
- var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
196
- versions = _ref2[1];
197
- return versions.length > 0;
198
- }).map(function (_ref3) {
199
- var _ref4 = (0, _slicedToArray2.default)(_ref3, 2),
200
- depName = _ref4[0],
201
- versions = _ref4[1];
202
- return [depName, DependencyStore.getMinimumVersion(versions, depName)];
203
- });
204
- return fromEntries(deps);
36
+ async initialise(gitRef) {
37
+ if (gitRef) {
38
+ await this.resetStore(gitRef);
205
39
  }
206
- }, {
207
- key: "assertInitialised",
208
- value: function assertInitialised() {
209
- if (!this.initialised) {
210
- throw new Error('Class must be initialised first with `.initialise()`');
40
+ this.initialised = true;
41
+ return this.getFlattenedDeps();
42
+ }
43
+
44
+ /** Updates the repo dependency store based on the changes in `logItem`.
45
+ * Returns the updated flattened dependencies
46
+ */
47
+ async update(logItem) {
48
+ this.assertInitialised();
49
+ const hash = logItem.hash;
50
+ (0, _assert.assert)(!!logItem.diff, `Diff must exist in log ${logItem} ${hash}`);
51
+ const changedPackageJsons = logItem.diff.files.filter(f => f.file === 'package.json' || f.file.endsWith('/package.json')).map(f => f.file);
52
+ const didRootPackageJsonChange = !!changedPackageJsons.find(file => file === 'package.json');
53
+ if (didRootPackageJsonChange) {
54
+ const workspaceGlobs = await (0, _yarn.getWorkspaceGlobs)(hash, this.cwd);
55
+ const globsChanged = workspaceGlobs !== null && (this.workspaceGlobs.size !== workspaceGlobs.size || [...this.workspaceGlobs].some(glob => !workspaceGlobs.has(glob)));
56
+ if (globsChanged) {
57
+ debug(`Workspace globs changed: ${[...workspaceGlobs]}. Resetting store.`);
58
+ await this.resetStore(hash);
59
+ return this.getFlattenedDeps();
211
60
  }
212
61
  }
62
+ const changedWorkspaces = (0, _micromatch.default)(changedPackageJsons, [...this.workspaceGlobs]);
63
+ debug(`Updating changed workspaces@${hash}: ${changedWorkspaces}`);
213
64
 
214
- /** Scans all workspaces in repo and rebuilds dependency store */
215
- }, {
216
- key: "resetStore",
217
- value: function () {
218
- var _resetStore = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(gitRef) {
219
- var workspaceGlobs, workspacePaths, _iterator2, _step2, wsPath, workspaceDeps;
220
- return _regenerator.default.wrap(function _callee3$(_context3) {
221
- while (1) {
222
- switch (_context3.prev = _context3.next) {
223
- case 0:
224
- this.dependencies = {};
225
- this.workspaces = {};
226
- _context3.next = 4;
227
- return (0, _yarn.getWorkspaceGlobs)(gitRef, this.cwd);
228
- case 4:
229
- workspaceGlobs = _context3.sent;
230
- if (workspaceGlobs !== null) {
231
- this.workspaceGlobs = workspaceGlobs;
232
- }
233
- _context3.next = 8;
234
- return (0, _yarn.getWorkspacePaths)(gitRef, this.workspaceGlobs, this.cwd);
235
- case 8:
236
- workspacePaths = _context3.sent;
237
- debug("Workspace paths: ".concat(workspacePaths));
238
- _iterator2 = _createForOfIteratorHelper(workspacePaths);
239
- _context3.prev = 11;
240
- _iterator2.s();
241
- case 13:
242
- if ((_step2 = _iterator2.n()).done) {
243
- _context3.next = 25;
244
- break;
245
- }
246
- wsPath = _step2.value;
247
- if (!this.workspaces[wsPath]) {
248
- _context3.next = 17;
249
- break;
250
- }
251
- throw new Error("Duplicate workspace path found: ".concat(wsPath));
252
- case 17:
253
- _context3.next = 19;
254
- return this.getWorkspaceDependencies(gitRef, wsPath);
255
- case 19:
256
- workspaceDeps = _context3.sent;
257
- if (!(workspaceDeps == null)) {
258
- _context3.next = 22;
259
- break;
260
- }
261
- return _context3.abrupt("continue", 23);
262
- case 22:
263
- this.updateWorkspaces(wsPath, workspaceDeps);
264
- case 23:
265
- _context3.next = 13;
266
- break;
267
- case 25:
268
- _context3.next = 30;
269
- break;
270
- case 27:
271
- _context3.prev = 27;
272
- _context3.t0 = _context3["catch"](11);
273
- _iterator2.e(_context3.t0);
274
- case 30:
275
- _context3.prev = 30;
276
- _iterator2.f();
277
- return _context3.finish(30);
278
- case 33:
279
- case "end":
280
- return _context3.stop();
281
- }
282
- }
283
- }, _callee3, this, [[11, 27, 30, 33]]);
284
- }));
285
- function resetStore(_x3) {
286
- return _resetStore.apply(this, arguments);
65
+ // Iterate over all changed package.jsons rather than only valid workspaces so that we can
66
+ // remove older workspaces that are no longer valid
67
+ for (const workspacePath of changedPackageJsons) {
68
+ let workspaceDeps = await this.getWorkspaceDependencies(hash, workspacePath);
69
+ const validWorkspace = changedWorkspaces.includes(workspacePath);
70
+ if (!validWorkspace && !this.workspaces[workspacePath]) {
71
+ // Ignore package.jsons that aren't a valid workspace and weren't valid previously
72
+ continue;
287
73
  }
288
- return resetStore;
289
- }()
290
- }, {
291
- key: "getWorkspaceDependencies",
292
- value: function () {
293
- var _getWorkspaceDependencies = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(hash, workspacePath) {
294
- var file, json, workspaceDeps, _iterator3, _step3, _step3$value, packageJsonKey, depTypeName, wsDeps;
295
- return _regenerator.default.wrap(function _callee4$(_context4) {
296
- while (1) {
297
- switch (_context4.prev = _context4.next) {
298
- case 0:
299
- _context4.prev = 0;
300
- _context4.next = 3;
301
- return (0, _git.showFile)(hash, workspacePath, {
302
- cwd: this.cwd
303
- });
304
- case 3:
305
- file = _context4.sent;
306
- _context4.next = 10;
307
- break;
308
- case 6:
309
- _context4.prev = 6;
310
- _context4.t0 = _context4["catch"](0);
311
- debug("Could not show file ".concat(workspacePath, "@").concat(hash));
312
- return _context4.abrupt("return", null);
313
- case 10:
314
- _context4.prev = 10;
315
- json = JSON.parse(file);
316
- _context4.next = 18;
317
- break;
318
- case 14:
319
- _context4.prev = 14;
320
- _context4.t1 = _context4["catch"](10);
321
- console.error("Error parsing JSON - \"".concat(file, "\"@").concat(hash));
322
- return _context4.abrupt("return", undefined);
323
- case 18:
324
- workspaceDeps = {};
325
- _iterator3 = _createForOfIteratorHelper(_constants.DEP_TYPES);
326
- try {
327
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
328
- _step3$value = _step3.value, packageJsonKey = _step3$value.packageJsonKey, depTypeName = _step3$value.depTypeName;
329
- wsDeps = DependencyStore.getAkDependencies(json[packageJsonKey] || {}, depTypeName);
330
- workspaceDeps = _objectSpread(_objectSpread({}, workspaceDeps), wsDeps);
331
- }
332
- } catch (err) {
333
- _iterator3.e(err);
334
- } finally {
335
- _iterator3.f();
336
- }
337
- return _context4.abrupt("return", workspaceDeps);
338
- case 22:
339
- case "end":
340
- return _context4.stop();
341
- }
342
- }
343
- }, _callee4, this, [[0, 6], [10, 14]]);
344
- }));
345
- function getWorkspaceDependencies(_x4, _x5) {
346
- return _getWorkspaceDependencies.apply(this, arguments);
347
- }
348
- return getWorkspaceDependencies;
349
- }()
350
- }, {
351
- key: "updateWorkspaces",
352
- value: function updateWorkspaces(workspacePath, workspaceDeps) {
353
- debug("Updating workspace ".concat(workspacePath));
354
- if (!this.workspaces[workspacePath]) {
355
- this.workspaces[workspacePath] = {};
356
- }
357
- var prevWorkspaceDeps = this.workspaces[workspacePath];
358
- for (var _i = 0, _Object$keys = Object.keys(prevWorkspaceDeps); _i < _Object$keys.length; _i++) {
359
- var depName = _Object$keys[_i];
360
- if (!workspaceDeps[depName]) {
361
- this.removeDependency(workspacePath, depName, prevWorkspaceDeps[depName]);
74
+
75
+ // For workspaces that are no longer a valid workspace but were previously, explicitly remove them
76
+ const noLongerWorkspace = !validWorkspace && this.workspaces[workspacePath];
77
+ if (workspaceDeps == null || noLongerWorkspace) {
78
+ // If workspaceDeps is undefined, package.json existed but JSON was invalid
79
+ // Else if workspaceDeps is null, package.json doesn't exist and has hence been deleted
80
+ if (workspaceDeps === undefined) {
81
+ console.error(`Error parsing metadata for workspace ${workspacePath}@${hash}`);
362
82
  }
83
+ // set the workspaceDeps to empty here explicitly to remove any deleted workspaces
84
+ workspaceDeps = {};
363
85
  }
364
- for (var _i2 = 0, _Object$entries = Object.entries(workspaceDeps); _i2 < _Object$entries.length; _i2++) {
365
- var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i2], 2),
366
- _depName = _Object$entries$_i[0],
367
- _Object$entries$_i$ = _Object$entries$_i[1],
368
- version = _Object$entries$_i$.version,
369
- type = _Object$entries$_i$.type;
370
- this.addDependency(workspacePath, _depName, version, type);
371
- }
86
+ this.updateWorkspaces(workspacePath, workspaceDeps);
372
87
  }
373
- }, {
374
- key: "addDependency",
375
- value: function addDependency(workspacePath, depName, version, type) {
376
- if (!this.dependencies[depName]) {
377
- debug("Adding new dep ".concat(depName));
378
- this.dependencies[depName] = [];
379
- }
380
- var prevEntry = this.workspaces[workspacePath][depName];
381
- var existingEntry = this.dependencies[depName].find(function (entry) {
382
- return entry.version === version && entry.type === type;
383
- });
384
- if (existingEntry && existingEntry === prevEntry) {
385
- // We haven't added or updated the dep, exit early
386
- return;
387
- }
388
- if (prevEntry) {
389
- this.removeDependency(workspacePath, depName, prevEntry);
88
+ return this.getFlattenedDeps();
89
+ }
90
+
91
+ /** Retrieve a flattened list of p repo dependencies.
92
+ * If multiple versions of a dependency exist, the lowest version is returned.
93
+ * If the dependency is listed under multiple dependency types, 'dependencies' is prioritised over 'devDependencies'
94
+ */
95
+ getFlattenedDeps() {
96
+ const deps = Object.entries(this.dependencies).filter(([, versions]) => versions.length > 0).map(([depName, versions]) => [depName, DependencyStore.getMinimumVersion(versions, depName)]);
97
+ return fromEntries(deps);
98
+ }
99
+ assertInitialised() {
100
+ if (!this.initialised) {
101
+ throw new Error('Class must be initialised first with `.initialise()`');
102
+ }
103
+ }
104
+
105
+ /** Scans all workspaces in repo and rebuilds dependency store */
106
+ async resetStore(gitRef) {
107
+ this.dependencies = {};
108
+ this.workspaces = {};
109
+ const workspaceGlobs = await (0, _yarn.getWorkspaceGlobs)(gitRef, this.cwd);
110
+ if (workspaceGlobs !== null) {
111
+ this.workspaceGlobs = workspaceGlobs;
112
+ }
113
+ const workspacePaths = await (0, _yarn.getWorkspacePaths)(gitRef, this.workspaceGlobs, this.cwd);
114
+ debug(`Workspace paths: ${workspacePaths}`);
115
+ for (const wsPath of workspacePaths) {
116
+ if (this.workspaces[wsPath]) {
117
+ throw new Error(`Duplicate workspace path found: ${wsPath}`);
390
118
  }
391
- if (existingEntry) {
392
- existingEntry.workspaces.add(workspacePath);
393
- this.workspaces[workspacePath][depName] = existingEntry;
394
- } else {
395
- debug("Adding new dependency version ".concat(depName, "@").concat(version, " (").concat(type, ")"));
396
- var newEntry = {
397
- version: version,
398
- type: type,
399
- workspaces: new Set([workspacePath])
400
- };
401
- this.dependencies[depName].push(newEntry);
402
- this.workspaces[workspacePath][depName] = newEntry;
119
+ const workspaceDeps = await this.getWorkspaceDependencies(gitRef, wsPath);
120
+ if (workspaceDeps == null) {
121
+ continue;
403
122
  }
123
+ this.updateWorkspaces(wsPath, workspaceDeps);
404
124
  }
405
- }, {
406
- key: "removeDependency",
407
- value: function removeDependency(workspacePath, depName, depEntry) {
408
- debug("".concat(depName, " removed from ").concat(workspacePath));
409
- (0, _assert.assert)(depEntry && depEntry.workspaces, "Dep entry should exist for ".concat(depName));
410
- depEntry.workspaces.delete(workspacePath);
411
- if (depEntry.workspaces.size === 0) {
412
- debug("No more workspaces depend on ".concat(depName, "@").concat(depEntry.version, " as a ").concat(depEntry.type, ", deleting"));
413
- this.dependencies[depName] = this.dependencies[depName].filter(function (entry) {
414
- return entry !== depEntry;
415
- });
416
- }
125
+ }
126
+ async getWorkspaceDependencies(hash, workspacePath) {
127
+ let file;
128
+ try {
129
+ file = await (0, _git.showFile)(hash, workspacePath, {
130
+ cwd: this.cwd
131
+ });
132
+ } catch (e) {
133
+ debug(`Could not show file ${workspacePath}@${hash}`);
134
+ return null;
417
135
  }
418
- }], [{
419
- key: "getAkDependencies",
420
- value: function getAkDependencies(depMap, type) {
421
- return fromEntries(Object.entries(depMap).filter(
422
- // Ignore suffixed `--next` deps in jira used for independent upgrades
423
- function (_ref5) {
424
- var _ref6 = (0, _slicedToArray2.default)(_ref5, 1),
425
- name = _ref6[0];
426
- return name.includes('@atlaskit') && !name.endsWith('--next');
427
- }).map(function (_ref7) {
428
- var _ref8 = (0, _slicedToArray2.default)(_ref7, 2),
429
- name = _ref8[0],
430
- version = _ref8[1];
431
- return [DependencyStore.transformDepName(name), {
432
- version: DependencyStore.transformDepVersion(version),
433
- type: type
434
- }];
435
- }));
136
+ let json;
137
+ try {
138
+ json = JSON.parse(file);
139
+ } catch (e) {
140
+ console.error(`Error parsing JSON - "${file}"@${hash}`);
141
+ return undefined;
436
142
  }
437
- }, {
438
- key: "getMinimumVersion",
439
- value: function getMinimumVersion(versions, depName) {
440
- var depOrder = ['dependency', 'peerDependency', 'devDependency', 'optionalDependency'];
441
- // Sort deps before devDeps and then take the lowest version
442
- var sorted = versions.sort(function (a, b) {
443
- var depSort = depOrder.indexOf(a.type) - depOrder.indexOf(b.type);
444
- if (depSort !== 0) {
445
- return depSort;
446
- }
447
- var aVersion = _semver.default.coerce(a.version);
448
- var bVersion = _semver.default.coerce(b.version);
449
- if (!aVersion) {
450
- console.error("Invalid version ".concat(depName, "@").concat(a.version));
451
- return 1;
452
- } else if (!bVersion) {
453
- console.error("Invalid version ".concat(depName, "@").concat(b.version));
454
- return -1;
455
- }
456
- return _semver.default.compare(aVersion, bVersion);
457
- });
458
- if (sorted.length > 1) {
459
- debug("Multiple versions found for ".concat(depName, ": ").concat(JSON.stringify(sorted.map(function (depInfo) {
460
- return _objectSpread(_objectSpread({}, depInfo), {}, {
461
- workspaces: (0, _toConsumableArray2.default)(depInfo.workspaces)
462
- });
463
- }))));
143
+ let workspaceDeps = {};
144
+ for (const {
145
+ packageJsonKey,
146
+ depTypeName
147
+ } of _constants.DEP_TYPES) {
148
+ const wsDeps = this.getSupportedDependencies(json[packageJsonKey] || {}, depTypeName);
149
+ workspaceDeps = {
150
+ ...workspaceDeps,
151
+ ...wsDeps
152
+ };
153
+ }
154
+ return workspaceDeps;
155
+ }
156
+ updateWorkspaces(workspacePath, workspaceDeps) {
157
+ debug(`Updating workspace ${workspacePath}`);
158
+ if (!this.workspaces[workspacePath]) {
159
+ this.workspaces[workspacePath] = {};
160
+ }
161
+ const prevWorkspaceDeps = this.workspaces[workspacePath];
162
+ for (const depName of Object.keys(prevWorkspaceDeps)) {
163
+ if (!workspaceDeps[depName]) {
164
+ this.removeDependency(workspacePath, depName, prevWorkspaceDeps[depName]);
464
165
  }
465
- return sorted[0];
466
166
  }
467
- }, {
468
- key: "transformDepName",
469
- value: function transformDepName(name) {
470
- // Treat `--current` as the standard dependency
471
- return name.replace(/--current$/, '');
167
+ for (const [depName, {
168
+ version,
169
+ type
170
+ }] of Object.entries(workspaceDeps)) {
171
+ this.addDependency(workspacePath, depName, version, type);
472
172
  }
473
-
474
- /* Coerce non-standard versions to a semver version.
475
- * This essentially ignores everything up until the first number and then tries to parse a version
476
- * out of that.
477
- * Used to yarn alias versions used by jira's independent upgrades, e.g. npm:@atlaskit/button@^15.0.8
478
- */
479
- }, {
480
- key: "transformDepVersion",
481
- value: function transformDepVersion(version) {
482
- var parts = version.split('@');
483
- return parts[parts.length - 1];
173
+ }
174
+ addDependency(workspacePath, depName, version, type) {
175
+ if (!this.dependencies[depName]) {
176
+ debug(`Adding new dep ${depName}`);
177
+ this.dependencies[depName] = [];
178
+ }
179
+ const prevEntry = this.workspaces[workspacePath][depName];
180
+ const existingEntry = this.dependencies[depName].find(entry => entry.version === version && entry.type === type);
181
+ if (existingEntry && existingEntry === prevEntry) {
182
+ // We haven't added or updated the dep, exit early
183
+ return;
184
+ }
185
+ if (prevEntry) {
186
+ this.removeDependency(workspacePath, depName, prevEntry);
187
+ }
188
+ if (existingEntry) {
189
+ existingEntry.workspaces.add(workspacePath);
190
+ this.workspaces[workspacePath][depName] = existingEntry;
191
+ } else {
192
+ debug(`Adding new dependency version ${depName}@${version} (${type})`);
193
+ const newEntry = {
194
+ version,
195
+ type,
196
+ workspaces: new Set([workspacePath])
197
+ };
198
+ this.dependencies[depName].push(newEntry);
199
+ this.workspaces[workspacePath][depName] = newEntry;
484
200
  }
485
- }]);
486
- return DependencyStore;
487
- }(); // Object.fromEntries polyfill, remove when upgraded to node 10
201
+ }
202
+ removeDependency(workspacePath, depName, depEntry) {
203
+ debug(`${depName} removed from ${workspacePath}`);
204
+ (0, _assert.assert)(depEntry && depEntry.workspaces, `Dep entry should exist for ${depName}`);
205
+ depEntry.workspaces.delete(workspacePath);
206
+ if (depEntry.workspaces.size === 0) {
207
+ debug(`No more workspaces depend on ${depName}@${depEntry.version} as a ${depEntry.type}, deleting`);
208
+ this.dependencies[depName] = this.dependencies[depName].filter(entry => entry !== depEntry);
209
+ }
210
+ }
211
+ getSupportedDependencies(depMap, type) {
212
+ return fromEntries(Object.entries(depMap).filter(
213
+ // Ignore suffixed `--next` deps in jira used for independent upgrades
214
+ ([name]) => (0, _allowedScopes.isPackageFromSupportedScopes)(name, this.supportedScopes) && !name.endsWith('--next')).map(([name, version]) => [DependencyStore.transformDepName(name), {
215
+ version: DependencyStore.transformDepVersion(version),
216
+ type
217
+ }]));
218
+ }
219
+ static getMinimumVersion(versions, depName) {
220
+ const depOrder = ['dependency', 'peerDependency', 'devDependency', 'optionalDependency'];
221
+ // Sort deps before devDeps and then take the lowest version
222
+ const sorted = versions.sort((a, b) => {
223
+ const depSort = depOrder.indexOf(a.type) - depOrder.indexOf(b.type);
224
+ if (depSort !== 0) {
225
+ return depSort;
226
+ }
227
+ const aVersion = _semver.default.coerce(a.version);
228
+ const bVersion = _semver.default.coerce(b.version);
229
+ if (!aVersion) {
230
+ console.error(`Invalid version ${depName}@${a.version}`);
231
+ return 1;
232
+ } else if (!bVersion) {
233
+ console.error(`Invalid version ${depName}@${b.version}`);
234
+ return -1;
235
+ }
236
+ return _semver.default.compare(aVersion, bVersion);
237
+ });
238
+ if (sorted.length > 1) {
239
+ debug(`Multiple versions found for ${depName}: ${JSON.stringify(sorted.map(depInfo => ({
240
+ ...depInfo,
241
+ workspaces: [...depInfo.workspaces]
242
+ })))}`);
243
+ }
244
+ return sorted[0];
245
+ }
246
+ static transformDepName(name) {
247
+ // Treat `--current` as the standard dependency
248
+ return name.replace(/--current$/, '');
249
+ }
250
+
251
+ /* Coerce non-standard versions to a semver version.
252
+ * This essentially ignores everything up until the first number and then tries to parse a version
253
+ * out of that.
254
+ * Used to yarn alias versions used by jira's independent upgrades, e.g. npm:@atlaskit/button@^15.0.8
255
+ */
256
+ static transformDepVersion(version) {
257
+ const parts = version.split('@');
258
+ return parts[parts.length - 1];
259
+ }
260
+ }
261
+
262
+ // Object.fromEntries polyfill, remove when upgraded to node 10
488
263
  exports.DependencyStore = DependencyStore;
489
264
  function fromEntries(iterable) {
490
- return (0, _toConsumableArray2.default)(iterable).reduce(function (obj, _ref9) {
491
- var key = _ref9[0],
492
- val = _ref9[1];
493
- return Object.assign(obj, (0, _defineProperty2.default)({}, key, val));
494
- }, {});
265
+ return [...iterable].reduce((obj, {
266
+ 0: key,
267
+ 1: val
268
+ }) => Object.assign(obj, {
269
+ [key]: val
270
+ }), {});
495
271
  }