@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
@@ -6,110 +6,40 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.getMeta = getMeta;
8
8
  exports.uploadMeta = uploadMeta;
9
- var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
10
- var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
11
9
  var _nodeFetch = _interopRequireDefault(require("node-fetch"));
12
- var STATLAS_BASE_URL = 'https://statlas.prod.atl-paas.net/af-product-analytics';
13
- function getMeta(_x) {
14
- return _getMeta.apply(this, arguments);
15
- }
16
- function _getMeta() {
17
- _getMeta = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(product) {
18
- var response;
19
- return _regenerator.default.wrap(function _callee$(_context) {
20
- while (1) {
21
- switch (_context.prev = _context.next) {
22
- case 0:
23
- _context.next = 2;
24
- return retrieveJSON(getProductMetaPath(product));
25
- case 2:
26
- response = _context.sent;
27
- return _context.abrupt("return", response.json);
28
- case 4:
29
- case "end":
30
- return _context.stop();
31
- }
32
- }
33
- }, _callee);
34
- }));
35
- return _getMeta.apply(this, arguments);
10
+ const STATLAS_BASE_URL = 'https://statlas.prod.atl-paas.net/af-product-analytics';
11
+ async function getMeta(product) {
12
+ const response = await retrieveJSON(getProductMetaPath(product));
13
+ return response.json;
36
14
  }
37
15
  function uploadMeta(product, lastRunHash) {
38
16
  return uploadJSON(getProductMetaPath(product), {
39
- lastRunHash: lastRunHash
17
+ lastRunHash
40
18
  });
41
19
  }
42
20
  function getProductMetaPath(product) {
43
- return "product/".concat(product, ".json");
44
- }
45
- function retrieveJSON(_x2) {
46
- return _retrieveJSON.apply(this, arguments);
21
+ return `product/${product}.json`;
47
22
  }
48
- function _retrieveJSON() {
49
- _retrieveJSON = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(filepath) {
50
- var response, json;
51
- return _regenerator.default.wrap(function _callee2$(_context2) {
52
- while (1) {
53
- switch (_context2.prev = _context2.next) {
54
- case 0:
55
- _context2.next = 2;
56
- return (0, _nodeFetch.default)("".concat(STATLAS_BASE_URL, "/").concat(filepath, "?statlasredirect"));
57
- case 2:
58
- response = _context2.sent;
59
- json = null;
60
- if (!response.ok) {
61
- _context2.next = 8;
62
- break;
63
- }
64
- _context2.next = 7;
65
- return response.json();
66
- case 7:
67
- json = _context2.sent;
68
- case 8:
69
- return _context2.abrupt("return", {
70
- json: json,
71
- rawResponse: response
72
- });
73
- case 9:
74
- case "end":
75
- return _context2.stop();
76
- }
77
- }
78
- }, _callee2);
79
- }));
80
- return _retrieveJSON.apply(this, arguments);
23
+ async function retrieveJSON(filepath) {
24
+ const response = await (0, _nodeFetch.default)(`${STATLAS_BASE_URL}/${filepath}?statlasredirect`);
25
+ let json = null;
26
+ if (response.ok) {
27
+ json = await response.json();
28
+ }
29
+ return {
30
+ json,
31
+ rawResponse: response
32
+ };
81
33
  }
82
- function uploadJSON(_x3, _x4) {
83
- return _uploadJSON.apply(this, arguments);
84
- }
85
- function _uploadJSON() {
86
- _uploadJSON = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(filepath, json) {
87
- var res;
88
- return _regenerator.default.wrap(function _callee3$(_context3) {
89
- while (1) {
90
- switch (_context3.prev = _context3.next) {
91
- case 0:
92
- _context3.next = 2;
93
- return (0, _nodeFetch.default)("".concat(STATLAS_BASE_URL, "/").concat(filepath), {
94
- method: 'PUT',
95
- body: JSON.stringify(json),
96
- headers: {
97
- Authorization: "Bearer ".concat(process.env.bamboo_JWT_TOKEN)
98
- }
99
- });
100
- case 2:
101
- res = _context3.sent;
102
- if (res.ok) {
103
- _context3.next = 5;
104
- break;
105
- }
106
- throw new Error("Statlas upload failed: ".concat(res.statusText));
107
- case 5:
108
- case "end":
109
- return _context3.stop();
110
- }
111
- }
112
- }, _callee3);
113
- }));
114
- return _uploadJSON.apply(this, arguments);
34
+ async function uploadJSON(filepath, json) {
35
+ const res = await (0, _nodeFetch.default)(`${STATLAS_BASE_URL}/${filepath}`, {
36
+ method: 'PUT',
37
+ body: JSON.stringify(json),
38
+ headers: {
39
+ Authorization: `Bearer ${process.env.bamboo_JWT_TOKEN}`
40
+ }
41
+ });
42
+ if (!res.ok) {
43
+ throw new Error(`Statlas upload failed: ${res.statusText}`);
44
+ }
115
45
  }
@@ -1,115 +1,54 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- var _typeof = require("@babel/runtime/helpers/typeof");
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
8
7
  exports.getWorkspaceGlobs = getWorkspaceGlobs;
9
8
  exports.getWorkspacePaths = getWorkspacePaths;
10
- var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
- var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
12
- var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
9
  var _path = _interopRequireDefault(require("path"));
14
10
  var _debug = _interopRequireDefault(require("debug"));
15
11
  var _micromatch = _interopRequireDefault(require("micromatch"));
16
12
  var git = _interopRequireWildcard(require("./git"));
17
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
18
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
19
- var rootPackageJsonPath = 'package.json';
20
- var debug = (0, _debug.default)('atlaskit:yarn');
21
- function getWorkspaceGlobs(_x, _x2) {
22
- return _getWorkspaceGlobs.apply(this, arguments);
13
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
14
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
15
+ const rootPackageJsonPath = 'package.json';
16
+ const debug = (0, _debug.default)('atlaskit:yarn');
17
+ async function getWorkspaceGlobs(ref, cwd) {
18
+ let file;
19
+ try {
20
+ file = await git.showFile(ref, rootPackageJsonPath, {
21
+ cwd
22
+ });
23
+ } catch (e) {
24
+ debug(`${rootPackageJsonPath} does not exist`);
25
+ return new Set([]);
26
+ }
27
+ let rootPackageJsonFile;
28
+ try {
29
+ rootPackageJsonFile = JSON.parse(file);
30
+ } catch (e) {
31
+ console.error(`Error parsing ${file}@${ref}: ${e}`);
32
+ return null;
33
+ }
34
+ const workspaces = rootPackageJsonFile.workspaces;
35
+ if (!workspaces) {
36
+ return new Set([rootPackageJsonPath]);
37
+ }
38
+ // There are actually two formats for workspaces and they are poorly documented
39
+ const workspacePackages = Array.isArray(workspaces) ? workspaces : workspaces.packages;
40
+ return new Set([rootPackageJsonPath, ...workspacePackages.map(glob => _path.default.join(glob, 'package.json'))]);
23
41
  }
24
- function _getWorkspaceGlobs() {
25
- _getWorkspaceGlobs = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(ref, cwd) {
26
- var file, rootPackageJsonFile, workspaces, workspacePackages;
27
- return _regenerator.default.wrap(function _callee$(_context) {
28
- while (1) {
29
- switch (_context.prev = _context.next) {
30
- case 0:
31
- _context.prev = 0;
32
- _context.next = 3;
33
- return git.showFile(ref, rootPackageJsonPath, {
34
- cwd: cwd
35
- });
36
- case 3:
37
- file = _context.sent;
38
- _context.next = 10;
39
- break;
40
- case 6:
41
- _context.prev = 6;
42
- _context.t0 = _context["catch"](0);
43
- debug("".concat(rootPackageJsonPath, " does not exist"));
44
- return _context.abrupt("return", new Set([]));
45
- case 10:
46
- _context.prev = 10;
47
- rootPackageJsonFile = JSON.parse(file);
48
- _context.next = 18;
49
- break;
50
- case 14:
51
- _context.prev = 14;
52
- _context.t1 = _context["catch"](10);
53
- console.error("Error parsing ".concat(file, "@").concat(ref, ": ").concat(_context.t1));
54
- return _context.abrupt("return", null);
55
- case 18:
56
- workspaces = rootPackageJsonFile.workspaces;
57
- if (workspaces) {
58
- _context.next = 21;
59
- break;
60
- }
61
- return _context.abrupt("return", new Set([rootPackageJsonPath]));
62
- case 21:
63
- // There are actually two formats for workspaces and they are poorly documented
64
- workspacePackages = Array.isArray(workspaces) ? workspaces : workspaces.packages;
65
- return _context.abrupt("return", new Set([rootPackageJsonPath].concat((0, _toConsumableArray2.default)(workspacePackages.map(function (glob) {
66
- return _path.default.join(glob, 'package.json');
67
- })))));
68
- case 23:
69
- case "end":
70
- return _context.stop();
71
- }
72
- }
73
- }, _callee, null, [[0, 6], [10, 14]]);
74
- }));
75
- return _getWorkspaceGlobs.apply(this, arguments);
76
- }
77
- function getWorkspacePaths(_x3, _x4, _x5) {
78
- return _getWorkspacePaths.apply(this, arguments);
79
- }
80
- function _getWorkspacePaths() {
81
- _getWorkspacePaths = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(ref, workspaceGlobs, cwd) {
82
- var workspacePackageJsons, matchedWorkspaces;
83
- return _regenerator.default.wrap(function _callee2$(_context2) {
84
- while (1) {
85
- switch (_context2.prev = _context2.next) {
86
- case 0:
87
- if (!(workspaceGlobs.size === 0)) {
88
- _context2.next = 2;
89
- break;
90
- }
91
- return _context2.abrupt("return", []);
92
- case 2:
93
- _context2.next = 4;
94
- return git.getFiles(ref, '**/package.json', {
95
- cwd: cwd
96
- });
97
- case 4:
98
- workspacePackageJsons = _context2.sent;
99
- matchedWorkspaces = (0, _micromatch.default)(workspacePackageJsons, (0, _toConsumableArray2.default)(workspaceGlobs));
100
- if (!(matchedWorkspaces.length === 0)) {
101
- _context2.next = 8;
102
- break;
103
- }
104
- throw new Error("Could not find any workspace or package.json under ".concat(cwd));
105
- case 8:
106
- return _context2.abrupt("return", matchedWorkspaces);
107
- case 9:
108
- case "end":
109
- return _context2.stop();
110
- }
111
- }
112
- }, _callee2);
113
- }));
114
- return _getWorkspacePaths.apply(this, arguments);
42
+ async function getWorkspacePaths(ref, workspaceGlobs, cwd) {
43
+ if (workspaceGlobs.size === 0) {
44
+ return [];
45
+ }
46
+ const workspacePackageJsons = await git.getFiles(ref, '**/package.json', {
47
+ cwd
48
+ });
49
+ const matchedWorkspaces = (0, _micromatch.default)(workspacePackageJsons, [...workspaceGlobs]);
50
+ if (matchedWorkspaces.length === 0) {
51
+ throw new Error(`Could not find any workspace or package.json under ${cwd}`);
52
+ }
53
+ return matchedWorkspaces;
115
54
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/dependency-version-analytics",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "sideEffects": false
5
5
  }
@@ -11,6 +11,7 @@ ${chalk.green('Global options')}
11
11
  ${chalk.yellow('--dryRun')} Performs a dry run, prints analytics events to console in JSON format instead of sending them
12
12
  ${chalk.yellow('--limit')} Limit the number of events sent, used for validation purposes
13
13
  ${chalk.yellow('--no-interactive')} Disable any interactive prompts
14
+ ${chalk.yellow('--include-restricted-scopes')} Include analytics for @atlassian and @atlassiansox scoped packages as well
14
15
 
15
16
  ${chalk.yellow.bold('[populate-product] <product>')}
16
17
  Sends analytics events for atlaskit dependency versions changes in package.json.
@@ -20,7 +21,7 @@ ${chalk.yellow.bold('[populate-product] <product>')}
20
21
  If running the tool for the first time (last run does not exist), --reset must be used to detect changes since the beginning of the repo.
21
22
 
22
23
  ${chalk.green('Options')}
23
- ${chalk.yellow('--csv')} Prints AK dependency history in CSV format
24
+ ${chalk.yellow('--csv')} Prints dependency history in CSV format
24
25
  ${chalk.yellow('--reset')} Reset change detection to detect changes from the beginning of time
25
26
  ${chalk.yellow('--tag')} Specify a different tag to mark when the tool was last run
26
27
  ${chalk.yellow('--statlas')} Use statlas rather than git tags for storing and sourcing last run info
@@ -29,7 +30,7 @@ ${chalk.yellow.bold('[populate-product] <product>')}
29
30
  ${chalk.dim('$ atlaskit-version-analytics populate-product jira')}
30
31
 
31
32
  ${chalk.yellow.bold('[populate-package] <package>')}
32
- Sends analytics events for published versions of the specified atlaskit package.
33
+ Sends analytics events for published versions of the specified package.
33
34
 
34
35
  ${chalk.green('Options')}
35
36
  ${chalk.yellow('--since')} Only publish versions since the following JS date string (exclusive)
@@ -70,6 +71,9 @@ export function run({
70
71
  },
71
72
  statlas: {
72
73
  type: 'boolean'
74
+ },
75
+ includeRestrictedScopes: {
76
+ type: 'boolean'
73
77
  }
74
78
  }
75
79
  });
@@ -90,7 +94,8 @@ export function run({
90
94
  product,
91
95
  reset: cli.flags.reset || false,
92
96
  statlas: cli.flags.statlas,
93
- tag: cli.flags.tag
97
+ tag: cli.flags.tag,
98
+ includeRestrictedScopes: cli.flags.includeRestrictedScopes || false
94
99
  });
95
100
  } else if (command === 'populate-package') {
96
101
  const pkg = inputs[0];
@@ -104,7 +109,8 @@ export function run({
104
109
  interactive: cli.flags.interactive,
105
110
  limit,
106
111
  pkg,
107
- since: cli.flags.since
112
+ since: cli.flags.since,
113
+ includeRestrictedScopes: cli.flags.includeRestrictedScopes || false
108
114
  });
109
115
  }
110
116
 
@@ -8,6 +8,7 @@ import { showFile } from '../../../util/git';
8
8
  import { DEP_TYPES } from '../../../constants';
9
9
  import { assert } from '../../../util/assert';
10
10
  import micromatch from 'micromatch';
11
+ import { isPackageFromSupportedScopes } from '../util/allowed-scopes';
11
12
  const debug = debugModule('atlaskit:dependency');
12
13
  /**
13
14
  * Stores the state of atlaskit dependencies in a repository
@@ -19,12 +20,13 @@ export class DependencyStore {
19
20
 
20
21
  /** Set of workspace globs. Used to verify that a package.json is a valid workspace */
21
22
 
22
- constructor(cwd = process.cwd()) {
23
+ constructor(cwd = process.cwd(), supportedScopes) {
23
24
  _defineProperty(this, "dependencies", {});
24
25
  _defineProperty(this, "workspaces", {});
25
26
  _defineProperty(this, "workspaceGlobs", new Set());
26
27
  _defineProperty(this, "initialised", false);
27
28
  this.cwd = cwd;
29
+ this.supportedScopes = supportedScopes;
28
30
  }
29
31
 
30
32
  /** Scans the repo for dependencies at the specified git ref and return the flattened dependency map */
@@ -140,7 +142,7 @@ export class DependencyStore {
140
142
  packageJsonKey,
141
143
  depTypeName
142
144
  } of DEP_TYPES) {
143
- const wsDeps = DependencyStore.getAkDependencies(json[packageJsonKey] || {}, depTypeName);
145
+ const wsDeps = this.getSupportedDependencies(json[packageJsonKey] || {}, depTypeName);
144
146
  workspaceDeps = {
145
147
  ...workspaceDeps,
146
148
  ...wsDeps
@@ -203,10 +205,10 @@ export class DependencyStore {
203
205
  this.dependencies[depName] = this.dependencies[depName].filter(entry => entry !== depEntry);
204
206
  }
205
207
  }
206
- static getAkDependencies(depMap, type) {
208
+ getSupportedDependencies(depMap, type) {
207
209
  return fromEntries(Object.entries(depMap).filter(
208
210
  // Ignore suffixed `--next` deps in jira used for independent upgrades
209
- ([name]) => name.includes('@atlaskit') && !name.endsWith('--next')).map(([name, version]) => [DependencyStore.transformDepName(name), {
211
+ ([name]) => isPackageFromSupportedScopes(name, this.supportedScopes) && !name.endsWith('--next')).map(([name, version]) => [DependencyStore.transformDepName(name), {
210
212
  version: DependencyStore.transformDepVersion(version),
211
213
  type
212
214
  }]));
@@ -1,7 +1,10 @@
1
1
  import semver from 'semver';
2
- import getPackageVersionHistory from '../../util/get-package-version-history';
2
+ import getPackageVersionHistoryAndTags from '../../util/get-package-version-history';
3
3
  import { createUpgradeEvent, sendAnalytics } from '../../util/analytics';
4
- const createAnalyticsEvents = (packageName, packageVersionHistory, since) => {
4
+ import { getSupportedScopes, isPackageFromSupportedScopes } from './util/allowed-scopes';
5
+ const createAnalyticsEvents = (packageName, packageVersionHistoryAndTags, since) => {
6
+ const packageVersionHistory = packageVersionHistoryAndTags['time'];
7
+ const tags = packageVersionHistoryAndTags['dist-tags'];
5
8
  const sortedPackageVersionHistory = Object.entries(packageVersionHistory).filter(([version]) => semver.valid(version)).sort((a, b) => Number(new Date(a[1])) - Number(new Date(b[1])));
6
9
  const upgradeEvents = sortedPackageVersionHistory.map(([version, time], i) => {
7
10
  if (since && Number(new Date(time)) <= Number(new Date(since))) {
@@ -9,16 +12,18 @@ const createAnalyticsEvents = (packageName, packageVersionHistory, since) => {
9
12
  }
10
13
  const previousVersion = sortedPackageVersionHistory[i - 1] && sortedPackageVersionHistory[i - 1][0];
11
14
  return createUpgradeEvent(packageName, version, previousVersion, time, {
12
- historical: true
15
+ historical: true,
16
+ tags
13
17
  });
14
18
  }).filter(e => e != null);
15
19
  return upgradeEvents;
16
20
  };
17
21
  export default async function populatePackage(flags) {
18
- if (!flags.pkg.startsWith('@atlaskit/')) {
19
- throw new Error(`Package must start with '@atlaskit/'`);
22
+ const supportedScopes = getSupportedScopes(flags.includeRestrictedScopes);
23
+ if (!isPackageFromSupportedScopes(flags.pkg, supportedScopes)) {
24
+ throw new Error(`Package must start with ${supportedScopes.join(', ')}`);
20
25
  }
21
- const packageVersionHistory = await getPackageVersionHistory(flags.pkg);
26
+ const packageVersionHistory = await getPackageVersionHistoryAndTags(flags.pkg);
22
27
  if (flags.since && Number.isNaN(Number(new Date(flags.since)))) {
23
28
  throw new Error(`'since' flag is an invalid date`);
24
29
  }
@@ -6,6 +6,8 @@ import * as statlas from '../../util/statlas';
6
6
  import { generateCSV } from './util/generate-csv';
7
7
  import { assert } from '../../util/assert';
8
8
  import { DependencyStore } from './lib/dependency-store';
9
+ import getPackageVersionHistoryAndTags from '../../util/get-package-version-history';
10
+ import { getSupportedScopes } from './util/allowed-scopes';
9
11
  const getUpgradeEventsFromPkgChange = (oldDeps, newDeps, {
10
12
  date,
11
13
  commitHash
@@ -42,21 +44,21 @@ const getUpgradeEventsFromPkgChange = (oldDeps, newDeps, {
42
44
  };
43
45
  const getEventsFromHistory = async (packageChangesLog, prevRunHash, {
44
46
  cwd
45
- }) => {
47
+ }, supportedScopes) => {
46
48
  const allPackageChanges = [];
47
- const allUpgradeEvents = [];
49
+ let allUpgradeEvents = [];
48
50
  assert(packageChangesLog.all.length > 0, '');
49
- let dependencyStore = new DependencyStore(cwd);
51
+ let dependencyStore = new DependencyStore(cwd, supportedScopes);
50
52
  let dependencies = await dependencyStore.initialise(prevRunHash);
51
53
  for (let i = 0; i < packageChangesLog.all.length; i++) {
52
54
  let item = packageChangesLog.all[i];
53
55
  if (allPackageChanges.length > 0) {
54
- dependencies = allPackageChanges[allPackageChanges.length - 1].akDeps;
56
+ dependencies = allPackageChanges[allPackageChanges.length - 1].deps;
55
57
  }
56
58
  const newDependencies = await dependencyStore.update(item);
57
59
  const packageChange = {
58
60
  date: new Date(item.date).toISOString(),
59
- akDeps: newDependencies
61
+ deps: newDependencies
60
62
  };
61
63
  const upgradeEvents = getUpgradeEventsFromPkgChange(dependencies, newDependencies, {
62
64
  date: packageChange.date,
@@ -67,6 +69,21 @@ const getEventsFromHistory = async (packageChangesLog, prevRunHash, {
67
69
  allPackageChanges.push(packageChange);
68
70
  }
69
71
  }
72
+ // add dist-tags to upgrade event
73
+ allUpgradeEvents = await Promise.all(allUpgradeEvents.map(async upgradeEvent => {
74
+ var _distTags$hotfix, _distTags$latest, _distTags$next;
75
+ const getPackageTags = await getPackageVersionHistoryAndTags(upgradeEvent.dependencyName);
76
+ const distTags = getPackageTags['dist-tags'];
77
+ Object.keys(distTags).forEach(key => {
78
+ if (key.startsWith('rc')) {
79
+ upgradeEvent.rcTag = distTags[key];
80
+ }
81
+ });
82
+ upgradeEvent.hotfixTag = (_distTags$hotfix = distTags['hotfix']) !== null && _distTags$hotfix !== void 0 ? _distTags$hotfix : null;
83
+ upgradeEvent.latestTag = (_distTags$latest = distTags['latest']) !== null && _distTags$latest !== void 0 ? _distTags$latest : null;
84
+ upgradeEvent.nextTag = (_distTags$next = distTags['next']) !== null && _distTags$next !== void 0 ? _distTags$next : null;
85
+ return upgradeEvent;
86
+ }));
70
87
  return {
71
88
  allPackageChanges,
72
89
  allUpgradeEvents
@@ -93,6 +110,7 @@ export default async function populateProduct(flags) {
93
110
  const cwd = flags.cwd || process.cwd();
94
111
  const sinceRef = flags.reset ? undefined : await getSinceRef(flags);
95
112
  const log = await getChangesSince(sinceRef);
113
+ const supportedScopes = getSupportedScopes(flags.includeRestrictedScopes);
96
114
  if (log.all.length === 0) {
97
115
  console.log(`No package.json changes found since '${sinceRef}'.`);
98
116
  return;
@@ -102,7 +120,7 @@ export default async function populateProduct(flags) {
102
120
  allUpgradeEvents
103
121
  } = await getEventsFromHistory(log, sinceRef, {
104
122
  cwd
105
- });
123
+ }, supportedScopes);
106
124
  if (flags.csv) {
107
125
  const csv = generateCSV(allPackageChanges);
108
126
  console.log(csv);
@@ -120,7 +138,7 @@ export default async function populateProduct(flags) {
120
138
  skipPrompt: !flags.interactive
121
139
  });
122
140
  } else {
123
- console.log(`Found no AK dependency changes since last run from ref "${sinceRef}"'`);
141
+ console.log(`Found no dependency changes from supported scopes ${supportedScopes.join(', ')} since last run from ref "${sinceRef}"'`);
124
142
  }
125
143
  if (flags.statlas) {
126
144
  // Upload latest commit to statlas
@@ -0,0 +1,7 @@
1
+ const defaultScopes = ['@atlaskit', '@atlassian', '@atlassiansox'];
2
+ export const getSupportedScopes = (enableNonAtlaskitPackages = false) => {
3
+ return enableNonAtlaskitPackages ? defaultScopes : ['@atlaskit'];
4
+ };
5
+ export const isPackageFromSupportedScopes = (packageName, supportedScopes = defaultScopes) => {
6
+ return supportedScopes.some(scope => packageName.startsWith(scope));
7
+ };
@@ -4,7 +4,7 @@ export const generateCSV = packageChanges => {
4
4
  packageChanges.forEach(packageChange => {
5
5
  const firstColumn = csvData[0];
6
6
  const currentRow = firstColumn.push(packageChange.date) - 1;
7
- Object.entries(packageChange.akDeps).forEach(([name, {
7
+ Object.entries(packageChange.deps).forEach(([name, {
8
8
  version
9
9
  }]) => {
10
10
  let depColumnIndex = csvData.findIndex(item => item[0] === name);
@@ -39,6 +39,7 @@ function getUpgradeSubType(version, previousVersion) {
39
39
  return upgradeSubType;
40
40
  }
41
41
  export function createUpgradeEvent(name, version, previousVersion, date, optionalArgs = {}) {
42
+ var _optionalArgs$tags, _ref, _tags$next, _tags$hotfix, _ref2;
42
43
  if (Number.isNaN(Date.parse(date))) {
43
44
  throw new Error(`Invalid date: '${date}'`);
44
45
  }
@@ -50,6 +51,14 @@ export function createUpgradeEvent(name, version, previousVersion, date, optiona
50
51
  const upgradeSubType = getUpgradeSubType(version, previousVersion);
51
52
  const eventVersion = upgradeType !== 'remove' ? version : previousVersion;
52
53
  const parsedVersion = semver.coerce(eventVersion);
54
+ let rcKey = null;
55
+ const tags = (_optionalArgs$tags = optionalArgs === null || optionalArgs === void 0 ? void 0 : optionalArgs.tags) !== null && _optionalArgs$tags !== void 0 ? _optionalArgs$tags : {};
56
+ Object.keys(tags).forEach(key => {
57
+ if (key.startsWith('rc')) {
58
+ rcKey = key;
59
+ return;
60
+ }
61
+ });
53
62
  return {
54
63
  cliVersion: packageVersion,
55
64
  dependencyName: name,
@@ -60,6 +69,10 @@ export function createUpgradeEvent(name, version, previousVersion, date, optiona
60
69
  date: new Date(date).toISOString(),
61
70
  upgradeType,
62
71
  upgradeSubType,
72
+ latestTag: (_ref = tags && tags['latest']) !== null && _ref !== void 0 ? _ref : null,
73
+ nextTag: (_tags$next = tags['next']) !== null && _tags$next !== void 0 ? _tags$next : null,
74
+ hotfixTag: (_tags$hotfix = tags['hotfix']) !== null && _tags$hotfix !== void 0 ? _tags$hotfix : null,
75
+ rcTag: (_ref2 = rcKey && tags[rcKey]) !== null && _ref2 !== void 0 ? _ref2 : null,
63
76
  ...optionalArgs
64
77
  };
65
78
  }
@@ -1,7 +1,7 @@
1
1
  import { exec } from 'child_process';
2
- export default function getPackageVersionHistory(packageName) {
2
+ export default function getPackageVersionHistoryAndTags(packageName) {
3
3
  return new Promise((resolve, reject) => {
4
- exec(`yarn info ${packageName} --json time`, (error, stdout, stderr) => {
4
+ exec(`yarn info ${packageName} --json`, (error, stdout, stderr) => {
5
5
  if (error) {
6
6
  reject(error);
7
7
  }
@@ -10,7 +10,11 @@ export default function getPackageVersionHistory(packageName) {
10
10
  }
11
11
  let json;
12
12
  try {
13
- json = JSON.parse(stdout).data;
13
+ const parseData = JSON.parse(stdout).data;
14
+ json = {
15
+ time: parseData['time'],
16
+ 'dist-tags': parseData['dist-tags']
17
+ };
14
18
  } catch (e) {
15
19
  reject(`Error parsing json output: ${e}`);
16
20
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/dependency-version-analytics",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "sideEffects": false
5
5
  }
package/dist/esm/cli.js CHANGED
@@ -6,7 +6,7 @@ import meow from 'meow';
6
6
  import { populateProduct, populatePackage } from './commands/populate-historic-data';
7
7
 
8
8
  // prettier-ignore
9
- var HELP_MSG = "\n".concat(chalk.green('Global options'), "\n ").concat(chalk.yellow('--dev'), " Send analytics to dev analytics pipeline instead of prod\n ").concat(chalk.yellow('--dryRun'), " Performs a dry run, prints analytics events to console in JSON format instead of sending them\n ").concat(chalk.yellow('--limit'), " Limit the number of events sent, used for validation purposes\n ").concat(chalk.yellow('--no-interactive'), " Disable any interactive prompts\n\n").concat(chalk.yellow.bold('[populate-product] <product>'), "\n Sends analytics events for atlaskit dependency versions changes in package.json.\n\n Detects changes since the last time the tool was run by storing the last run in either statlas (--statlas flag) or using the\n 'atlaskit-dependency-version-analytics-last-run' git tag.\n If running the tool for the first time (last run does not exist), --reset must be used to detect changes since the beginning of the repo.\n\n ").concat(chalk.green('Options'), "\n ").concat(chalk.yellow('--csv'), " Prints AK dependency history in CSV format\n ").concat(chalk.yellow('--reset'), " Reset change detection to detect changes from the beginning of time\n ").concat(chalk.yellow('--tag'), " Specify a different tag to mark when the tool was last run\n ").concat(chalk.yellow('--statlas'), " Use statlas rather than git tags for storing and sourcing last run info\n\n ").concat(chalk.green('Examples'), "\n ").concat(chalk.dim('$ atlaskit-version-analytics populate-product jira'), "\n\n").concat(chalk.yellow.bold('[populate-package] <package>'), "\n Sends analytics events for published versions of the specified atlaskit package.\n\n ").concat(chalk.green('Options'), "\n ").concat(chalk.yellow('--since'), " Only publish versions since the following JS date string (exclusive)\n\n ").concat(chalk.green('Examples'), "\n ").concat(chalk.dim('$ atlaskit-version-analytics populate-package @atlaskit/button'), "\n");
9
+ var HELP_MSG = "\n".concat(chalk.green('Global options'), "\n ").concat(chalk.yellow('--dev'), " Send analytics to dev analytics pipeline instead of prod\n ").concat(chalk.yellow('--dryRun'), " Performs a dry run, prints analytics events to console in JSON format instead of sending them\n ").concat(chalk.yellow('--limit'), " Limit the number of events sent, used for validation purposes\n ").concat(chalk.yellow('--no-interactive'), " Disable any interactive prompts\n ").concat(chalk.yellow('--include-restricted-scopes'), " Include analytics for @atlassian and @atlassiansox scoped packages as well\n\n").concat(chalk.yellow.bold('[populate-product] <product>'), "\n Sends analytics events for atlaskit dependency versions changes in package.json.\n\n Detects changes since the last time the tool was run by storing the last run in either statlas (--statlas flag) or using the\n 'atlaskit-dependency-version-analytics-last-run' git tag.\n If running the tool for the first time (last run does not exist), --reset must be used to detect changes since the beginning of the repo.\n\n ").concat(chalk.green('Options'), "\n ").concat(chalk.yellow('--csv'), " Prints dependency history in CSV format\n ").concat(chalk.yellow('--reset'), " Reset change detection to detect changes from the beginning of time\n ").concat(chalk.yellow('--tag'), " Specify a different tag to mark when the tool was last run\n ").concat(chalk.yellow('--statlas'), " Use statlas rather than git tags for storing and sourcing last run info\n\n ").concat(chalk.green('Examples'), "\n ").concat(chalk.dim('$ atlaskit-version-analytics populate-product jira'), "\n\n").concat(chalk.yellow.bold('[populate-package] <package>'), "\n Sends analytics events for published versions of the specified package.\n\n ").concat(chalk.green('Options'), "\n ").concat(chalk.yellow('--since'), " Only publish versions since the following JS date string (exclusive)\n\n ").concat(chalk.green('Examples'), "\n ").concat(chalk.dim('$ atlaskit-version-analytics populate-package @atlaskit/button'), "\n");
10
10
  export function run(_ref) {
11
11
  var dev = _ref.dev;
12
12
  var cli = meow(HELP_MSG, {
@@ -39,6 +39,9 @@ export function run(_ref) {
39
39
  },
40
40
  statlas: {
41
41
  type: 'boolean'
42
+ },
43
+ includeRestrictedScopes: {
44
+ type: 'boolean'
42
45
  }
43
46
  }
44
47
  });
@@ -61,7 +64,8 @@ export function run(_ref) {
61
64
  product: product,
62
65
  reset: cli.flags.reset || false,
63
66
  statlas: cli.flags.statlas,
64
- tag: cli.flags.tag
67
+ tag: cli.flags.tag,
68
+ includeRestrictedScopes: cli.flags.includeRestrictedScopes || false
65
69
  });
66
70
  } else if (command === 'populate-package') {
67
71
  var pkg = inputs[0];
@@ -75,7 +79,8 @@ export function run(_ref) {
75
79
  interactive: cli.flags.interactive,
76
80
  limit: limit,
77
81
  pkg: pkg,
78
- since: cli.flags.since
82
+ since: cli.flags.since,
83
+ includeRestrictedScopes: cli.flags.includeRestrictedScopes || false
79
84
  });
80
85
  }
81
86