@atlaskit/codemod-cli 0.7.0 → 0.8.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @atlaskit/codemod-cli
2
2
 
3
+ ## 0.8.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [`f4d22b1c8af`](https://bitbucket.org/atlassian/atlassian-frontend/commits/f4d22b1c8af) - Ignore directory filtering logic if filtering returns no paths
8
+
9
+ ## 0.8.2
10
+
11
+ ### Patch Changes
12
+
13
+ - [`650aa20f6fe`](https://bitbucket.org/atlassian/atlassian-frontend/commits/650aa20f6fe) - Upgrade meow dependency
14
+
15
+ ## 0.8.1
16
+
17
+ ### Patch Changes
18
+
19
+ - [`982e2f3d3d2`](https://bitbucket.org/atlassian/atlassian-frontend/commits/982e2f3d3d2) - Directory filtering now defaults to true
20
+
21
+ ## 0.8.0
22
+
23
+ ### Minor Changes
24
+
25
+ - [`f3d46c395b4`](https://bitbucket.org/atlassian/atlassian-frontend/commits/f3d46c395b4) - Add path filtering to codemod-cli
26
+
3
27
  ## 0.7.0
4
28
 
5
29
  ### Minor Changes
package/README.md CHANGED
@@ -1,3 +1,3 @@
1
1
  # Codemods
2
2
 
3
- For usage and docs see [here](../../../build/repo-docs/content/cloud/framework/atlassian-frontend/guides/23-atlassian-codemods.md)
3
+ For usage and docs see [here](../../../repo-docs/content/cloud/framework/atlassian-frontend/codemods/01-atlassian-codemods.md)
package/dist/cjs/cli.js CHANGED
@@ -30,7 +30,7 @@ function _run() {
30
30
  while (1) {
31
31
  switch (_context.prev = _context.next) {
32
32
  case 0:
33
- cli = (0, _meow.default)("\nUsage\n $ npx @atlaskit/codemod-cli [options] <file-paths>...\n\nOptions\n --transform, -t the transform to run, will prompt for a transform if not provided and no module is passed\n --since-ref, runs transforms for all packages that have been upgraded since the specified git ref\n --packages, runs transforms for the specified comma separated list of packages, optionally include a version for each package to run all transforms since that version\n --parser, -p babel|babylon|flow|ts|tsx parser to use for parsing the source files (default: babel)\n --extensions, -e transform files with these file extensions (comma separated list) (default: js)\n --ignore-pattern, ignore files that match a provided glob expression\n --fail-on-error, return a 1 exit code when errors were found during execution of codemods\n --version, -v version number\n --help Help me \uD83D\uDE31\n\nExamples\n # Run a codemod over the /project/src directory, will be prompted for which codemod to run\n $ npx @atlaskit/codemod-cli /project/src\n\n # Run the \"4.0.0-remove-appearance-prop\" transform of the \"button\" package\n $ npx @atlaskit/codemod-cli -t button@4.0.0-remove-appearance-prop /project/src\n\n # Run all transforms for \"@atlaskit/button\" greater than version 3.0.0 and @atlaskit/range greater than 4.0.0\n $ npx @atlaskit/codemod-cli --packages @atlaskit/button@3.0.0,@atlaskit/range@4.0.0 /project/src\n", {
33
+ cli = (0, _meow.default)("\nUsage\n $ npx @atlaskit/codemod-cli [options] <file-paths>...\n\nOptions\n --transform, -t the transform to run, will prompt for a transform if not provided and no module is passed\n --since-ref, runs transforms for all packages that have been upgraded since the specified git ref\n --packages, runs transforms for the specified comma separated list of packages, optionally include a version for each package to run all transforms since that version\n --parser, -p babel|babylon|flow|ts|tsx parser to use for parsing the source files (default: babel)\n --extensions, -e transform files with these file extensions (comma separated list) (default: js)\n --ignore-pattern, ignore files that match a provided glob expression\n --fail-on-error, return a 1 exit code when errors were found during execution of codemods\n --version, -v version number\n --no-filter-paths disables dependant package file path filtering logic \n --help Help me \uD83D\uDE31\n\nExamples\n # Run a codemod over the /project/src directory, will be prompted for which codemod to run\n $ npx @atlaskit/codemod-cli /project/src\n\n # Run the \"4.0.0-remove-appearance-prop\" transform of the \"button\" package\n $ npx @atlaskit/codemod-cli -t button@4.0.0-remove-appearance-prop /project/src\n\n # Run all transforms for \"@atlaskit/button\" greater than version 3.0.0 and @atlaskit/range greater than 4.0.0\n $ npx @atlaskit/codemod-cli --packages @atlaskit/button@3.0.0,@atlaskit/range@4.0.0 /project/src\n", {
34
34
  flags: {
35
35
  transform: {
36
36
  type: 'string',
@@ -55,6 +55,10 @@ function _run() {
55
55
  },
56
56
  failOnError: {
57
57
  type: 'boolean'
58
+ },
59
+ filterPaths: {
60
+ type: 'boolean',
61
+ default: true
58
62
  }
59
63
  }
60
64
  });
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.findDependentPackagePaths = findDependentPackagePaths;
9
+
10
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
+
12
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
+
14
+ var _glob = require("glob");
15
+
16
+ var _fs = require("fs");
17
+
18
+ var readFile = _fs.promises.readFile;
19
+ /** Return products packages filePaths for running codemods from specified dependent package */
20
+
21
+ function findDependentPackagePaths(_x, _x2) {
22
+ return _findDependentPackagePaths.apply(this, arguments);
23
+ }
24
+
25
+ function _findDependentPackagePaths() {
26
+ _findDependentPackagePaths = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(crawlPaths, dependencyPackage) {
27
+ var searchStrings, globString, packageJsonPaths, productPackageJsonPathPromises, productPackageJsonPaths, productPackagePaths;
28
+ return _regenerator.default.wrap(function _callee2$(_context2) {
29
+ while (1) {
30
+ switch (_context2.prev = _context2.next) {
31
+ case 0:
32
+ // Get file paths leading to package.jsons
33
+ searchStrings = crawlPaths.map(function (crawlPath) {
34
+ //Replace leading './' due to bug with node-glob not properly ignoring files https://github.com/isaacs/node-glob/issues/309
35
+ return "".concat(crawlPath.replace(/^\.\//, ''), "/**/package.json");
36
+ }); // Convert array into glob string
37
+
38
+ globString = searchStrings.length > 1 ? "{".concat(searchStrings.join(','), "}") : searchStrings[0];
39
+ packageJsonPaths = _glob.glob.sync(globString, {
40
+ ignore: '**/node_modules/**',
41
+ nodir: true
42
+ });
43
+ productPackageJsonPathPromises = packageJsonPaths.map( /*#__PURE__*/function () {
44
+ var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(filePath) {
45
+ var fileContents, isMatch;
46
+ return _regenerator.default.wrap(function _callee$(_context) {
47
+ while (1) {
48
+ switch (_context.prev = _context.next) {
49
+ case 0:
50
+ fileContents = readFile(filePath, 'utf8'); // Grep for installedPackage
51
+
52
+ _context.next = 3;
53
+ return fileContents;
54
+
55
+ case 3:
56
+ isMatch = _context.sent.toString().split(/\n/).some(function (line) {
57
+ return line.match(dependencyPackage);
58
+ });
59
+ return _context.abrupt("return", isMatch && filePath);
60
+
61
+ case 5:
62
+ case "end":
63
+ return _context.stop();
64
+ }
65
+ }
66
+ }, _callee);
67
+ }));
68
+
69
+ return function (_x3) {
70
+ return _ref.apply(this, arguments);
71
+ };
72
+ }());
73
+ _context2.next = 6;
74
+ return Promise.all(productPackageJsonPathPromises);
75
+
76
+ case 6:
77
+ productPackageJsonPaths = _context2.sent.filter(function (path) {
78
+ return path !== false;
79
+ });
80
+ // Get directory
81
+ productPackagePaths = productPackageJsonPaths.map(function (line) {
82
+ return line.replace('/package.json', '');
83
+ });
84
+ return _context2.abrupt("return", productPackagePaths);
85
+
86
+ case 9:
87
+ case "end":
88
+ return _context2.stop();
89
+ }
90
+ }
91
+ }, _callee2);
92
+ }));
93
+ return _findDependentPackagePaths.apply(this, arguments);
94
+ }
package/dist/cjs/index.js CHANGED
@@ -5,10 +5,10 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- Object.defineProperty(exports, "default", {
8
+ Object.defineProperty(exports, "NoTransformsExistError", {
9
9
  enumerable: true,
10
10
  get: function get() {
11
- return _main.default;
11
+ return _types.NoTransformsExistError;
12
12
  }
13
13
  });
14
14
  Object.defineProperty(exports, "ValidationError", {
@@ -17,10 +17,10 @@ Object.defineProperty(exports, "ValidationError", {
17
17
  return _types.ValidationError;
18
18
  }
19
19
  });
20
- Object.defineProperty(exports, "NoTransformsExistError", {
20
+ Object.defineProperty(exports, "default", {
21
21
  enumerable: true,
22
22
  get: function get() {
23
- return _types.NoTransformsExistError;
23
+ return _main.default;
24
24
  }
25
25
  });
26
26
 
package/dist/cjs/main.js CHANGED
@@ -33,6 +33,8 @@ var _types = require("./types");
33
33
 
34
34
  var _sinceRef = require("./sinceRef");
35
35
 
36
+ var _filepath = require("./filepath");
37
+
36
38
  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; } } }; }
37
39
 
38
40
  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); }
@@ -154,18 +156,41 @@ var resolveTransform = /*#__PURE__*/function () {
154
156
  }();
155
157
 
156
158
  var runTransform = /*#__PURE__*/function () {
157
- var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(filePath, transform, flags) {
158
- var logger, transformPath, args, jscodeshiftContent, jscodeshiftContentNew;
159
+ var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(filePaths, transform, flags) {
160
+ var logger, codemodDirs, transformPath, args, jscodeshiftContent, jscodeshiftContentNew;
159
161
  return _regenerator.default.wrap(function _callee3$(_context3) {
160
162
  while (1) {
161
163
  switch (_context3.prev = _context3.next) {
162
164
  case 0:
163
165
  logger = flags.logger;
164
- logger.log(_chalk.default.green("Running transform '".concat(_chalk.default.bold(transform.name), "' over ").concat(_chalk.default.bold(filePath.join(', ')), "...")));
166
+ logger.log(_chalk.default.green("Running transform '".concat(_chalk.default.bold(transform.name), "' over ").concat(_chalk.default.bold(filePaths.join(', ')), "...")));
167
+ codemodDirs = filePaths;
168
+
169
+ if (!flags.filterPaths) {
170
+ _context3.next = 9;
171
+ break;
172
+ }
173
+
174
+ logger.log(_chalk.default.green("Running filtering logic for module ".concat(transform.module, "...")));
175
+ _context3.next = 7;
176
+ return (0, _filepath.findDependentPackagePaths)(filePaths, transform.module);
177
+
178
+ case 7:
179
+ codemodDirs = _context3.sent;
180
+
181
+ if (codemodDirs.length === 0) {
182
+ // Fallback to non-filter logic if filtering returns no directories
183
+ logger.log(_chalk.default.yellow("Could not filter source paths for ".concat(transform.module, ", falling back to running over all specified paths. (See --no-filter-paths flag)")));
184
+ codemodDirs = filePaths;
185
+ } else {
186
+ logger.log(_chalk.default.green("Running transform '".concat(_chalk.default.bold(transform.name), "' over filtered dirs ").concat(_chalk.default.bold(codemodDirs.join(', ')), "...")));
187
+ }
188
+
189
+ case 9:
165
190
  logger.log(_chalk.default.green("Transforming files matching these extensions '".concat(_chalk.default.bold(flags.extensions), "'...")));
166
191
  transformPath = (0, _transforms.getTransformPath)(transform); // Limit CPUs to 8 to prevent issues when running on CI with a large amount of cpus
167
192
 
168
- args = ["--transform=".concat(transformPath), "--ignore-pattern=".concat(flags.ignorePattern), "--parser=".concat(flags.parser), "--extensions=".concat(flags.extensions), '--cpus=8'].concat((0, _toConsumableArray2.default)(filePath));
193
+ args = ["--transform=".concat(transformPath), "--ignore-pattern=".concat(flags.ignorePattern), "--parser=".concat(flags.parser), "--extensions=".concat(flags.extensions), '--cpus=8'].concat((0, _toConsumableArray2.default)(codemodDirs));
169
194
 
170
195
  if (flags.failOnError) {
171
196
  args.unshift('--fail-on-error');
@@ -179,12 +204,12 @@ var runTransform = /*#__PURE__*/function () {
179
204
 
180
205
  _fs.default.writeFileSync(jscodeshift, jscodeshiftContentNew);
181
206
 
182
- _context3.next = 11;
207
+ _context3.next = 18;
183
208
  return (0, _projectorSpawn.default)(jscodeshift, args, {
184
209
  stdio: 'inherit'
185
210
  });
186
211
 
187
- case 11:
212
+ case 18:
188
213
  case "end":
189
214
  return _context3.stop();
190
215
  }
@@ -338,7 +363,7 @@ function _main() {
338
363
  case 4:
339
364
  _yield$parseArgs = _context5.sent;
340
365
  packages = _yield$parseArgs.packages;
341
- _process$env$_PACKAGE = "0.7.0", _PACKAGE_VERSION_ = _process$env$_PACKAGE === void 0 ? '0.0.0-dev' : _process$env$_PACKAGE;
366
+ _process$env$_PACKAGE = "0.8.3", _PACKAGE_VERSION_ = _process$env$_PACKAGE === void 0 ? '0.0.0-dev' : _process$env$_PACKAGE;
342
367
  logger.log(_chalk.default.bgBlue(_chalk.default.black("\uD83D\uDCDA Atlassian-Frontend codemod library @ ".concat(_PACKAGE_VERSION_, " \uD83D\uDCDA"))));
343
368
 
344
369
  if (packages && packages.length > 0) {
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.getTransformVersion = exports.getTransformModule = exports.getTransformPath = exports.parseTransformPath = exports.getTransforms = exports.hasTransform = void 0;
8
+ exports.parseTransformPath = exports.hasTransform = exports.getTransforms = exports.getTransformVersion = exports.getTransformPath = exports.getTransformModule = void 0;
9
9
 
10
10
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
11
11
 
package/dist/cjs/types.js CHANGED
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.NoTransformsExistError = exports.ValidationError = void 0;
8
+ exports.ValidationError = exports.NoTransformsExistError = void 0;
9
9
 
10
10
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
11
11
 
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "name": "@atlaskit/codemod-cli",
3
- "version": "0.7.0"
3
+ "version": "0.8.3"
4
4
  }
@@ -16,6 +16,7 @@ Options
16
16
  --ignore-pattern, ignore files that match a provided glob expression
17
17
  --fail-on-error, return a 1 exit code when errors were found during execution of codemods
18
18
  --version, -v version number
19
+ --no-filter-paths disables dependant package file path filtering logic
19
20
  --help Help me 😱
20
21
 
21
22
  Examples
@@ -52,6 +53,10 @@ Examples
52
53
  },
53
54
  failOnError: {
54
55
  type: 'boolean'
56
+ },
57
+ filterPaths: {
58
+ type: 'boolean',
59
+ default: true
55
60
  }
56
61
  }
57
62
  });
@@ -0,0 +1,32 @@
1
+ import { glob } from 'glob';
2
+ import { promises } from 'fs';
3
+ const {
4
+ readFile
5
+ } = promises;
6
+ /** Return products packages filePaths for running codemods from specified dependent package */
7
+
8
+ export async function findDependentPackagePaths(crawlPaths, dependencyPackage) {
9
+ // Get file paths leading to package.jsons
10
+ const searchStrings = crawlPaths.map(crawlPath => {
11
+ //Replace leading './' due to bug with node-glob not properly ignoring files https://github.com/isaacs/node-glob/issues/309
12
+ return `${crawlPath.replace(/^\.\//, '')}/**/package.json`;
13
+ }); // Convert array into glob string
14
+
15
+ const globString = searchStrings.length > 1 ? `{${searchStrings.join(',')}}` : searchStrings[0];
16
+ const packageJsonPaths = glob.sync(globString, {
17
+ ignore: '**/node_modules/**',
18
+ nodir: true
19
+ });
20
+ let productPackageJsonPathPromises = packageJsonPaths.map(async filePath => {
21
+ const fileContents = readFile(filePath, 'utf8'); // Grep for installedPackage
22
+
23
+ const isMatch = (await fileContents).toString().split(/\n/).some(function (line) {
24
+ return line.match(dependencyPackage);
25
+ });
26
+ return isMatch && filePath;
27
+ });
28
+ const productPackageJsonPaths = (await Promise.all(productPackageJsonPathPromises)).filter(path => path !== false); // Get directory
29
+
30
+ const productPackagePaths = productPackageJsonPaths.map(line => line.replace('/package.json', ''));
31
+ return productPackagePaths;
32
+ }
@@ -10,6 +10,7 @@ import { fixLineEnding } from './utils';
10
10
  import { getTransforms, getTransformPath, hasTransform, parseTransformPath, getTransformModule } from './transforms';
11
11
  import { ValidationError, NoTransformsExistError } from './types';
12
12
  import { getPackagesSinceRef } from './sinceRef';
13
+ import { findDependentPackagePaths } from './filepath';
13
14
 
14
15
  const applyTransformMeta = transforms => transforms.map(transform => {
15
16
  const moduleMatch = transform.dir.match(/\/@atlaskit\/[^\/]+\//);
@@ -65,15 +66,30 @@ const resolveTransform = async (flags, transforms) => {
65
66
  return await getTransformPrompt(transforms);
66
67
  };
67
68
 
68
- const runTransform = async (filePath, transform, flags) => {
69
+ const runTransform = async (filePaths, transform, flags) => {
69
70
  const {
70
71
  logger
71
72
  } = flags;
72
- logger.log(chalk.green(`Running transform '${chalk.bold(transform.name)}' over ${chalk.bold(filePath.join(', '))}...`));
73
+ logger.log(chalk.green(`Running transform '${chalk.bold(transform.name)}' over ${chalk.bold(filePaths.join(', '))}...`));
74
+ let codemodDirs = filePaths;
75
+
76
+ if (flags.filterPaths) {
77
+ logger.log(chalk.green(`Running filtering logic for module ${transform.module}...`));
78
+ codemodDirs = await findDependentPackagePaths(filePaths, transform.module);
79
+
80
+ if (codemodDirs.length === 0) {
81
+ // Fallback to non-filter logic if filtering returns no directories
82
+ logger.log(chalk.yellow(`Could not filter source paths for ${transform.module}, falling back to running over all specified paths. (See --no-filter-paths flag)`));
83
+ codemodDirs = filePaths;
84
+ } else {
85
+ logger.log(chalk.green(`Running transform '${chalk.bold(transform.name)}' over filtered dirs ${chalk.bold(codemodDirs.join(', '))}...`));
86
+ }
87
+ }
88
+
73
89
  logger.log(chalk.green(`Transforming files matching these extensions '${chalk.bold(flags.extensions)}'...`));
74
90
  const transformPath = getTransformPath(transform); // Limit CPUs to 8 to prevent issues when running on CI with a large amount of cpus
75
91
 
76
- const args = [`--transform=${transformPath}`, `--ignore-pattern=${flags.ignorePattern}`, `--parser=${flags.parser}`, `--extensions=${flags.extensions}`, '--cpus=8', ...filePath];
92
+ const args = [`--transform=${transformPath}`, `--ignore-pattern=${flags.ignorePattern}`, `--parser=${flags.parser}`, `--extensions=${flags.extensions}`, '--cpus=8', ...codemodDirs];
77
93
 
78
94
  if (flags.failOnError) {
79
95
  args.unshift('--fail-on-error');
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "name": "@atlaskit/codemod-cli",
3
- "version": "0.7.0"
3
+ "version": "0.8.3"
4
4
  }
package/dist/esm/cli.js CHANGED
@@ -15,7 +15,7 @@ function _run() {
15
15
  while (1) {
16
16
  switch (_context.prev = _context.next) {
17
17
  case 0:
18
- cli = meow("\nUsage\n $ npx @atlaskit/codemod-cli [options] <file-paths>...\n\nOptions\n --transform, -t the transform to run, will prompt for a transform if not provided and no module is passed\n --since-ref, runs transforms for all packages that have been upgraded since the specified git ref\n --packages, runs transforms for the specified comma separated list of packages, optionally include a version for each package to run all transforms since that version\n --parser, -p babel|babylon|flow|ts|tsx parser to use for parsing the source files (default: babel)\n --extensions, -e transform files with these file extensions (comma separated list) (default: js)\n --ignore-pattern, ignore files that match a provided glob expression\n --fail-on-error, return a 1 exit code when errors were found during execution of codemods\n --version, -v version number\n --help Help me \uD83D\uDE31\n\nExamples\n # Run a codemod over the /project/src directory, will be prompted for which codemod to run\n $ npx @atlaskit/codemod-cli /project/src\n\n # Run the \"4.0.0-remove-appearance-prop\" transform of the \"button\" package\n $ npx @atlaskit/codemod-cli -t button@4.0.0-remove-appearance-prop /project/src\n\n # Run all transforms for \"@atlaskit/button\" greater than version 3.0.0 and @atlaskit/range greater than 4.0.0\n $ npx @atlaskit/codemod-cli --packages @atlaskit/button@3.0.0,@atlaskit/range@4.0.0 /project/src\n", {
18
+ cli = meow("\nUsage\n $ npx @atlaskit/codemod-cli [options] <file-paths>...\n\nOptions\n --transform, -t the transform to run, will prompt for a transform if not provided and no module is passed\n --since-ref, runs transforms for all packages that have been upgraded since the specified git ref\n --packages, runs transforms for the specified comma separated list of packages, optionally include a version for each package to run all transforms since that version\n --parser, -p babel|babylon|flow|ts|tsx parser to use for parsing the source files (default: babel)\n --extensions, -e transform files with these file extensions (comma separated list) (default: js)\n --ignore-pattern, ignore files that match a provided glob expression\n --fail-on-error, return a 1 exit code when errors were found during execution of codemods\n --version, -v version number\n --no-filter-paths disables dependant package file path filtering logic \n --help Help me \uD83D\uDE31\n\nExamples\n # Run a codemod over the /project/src directory, will be prompted for which codemod to run\n $ npx @atlaskit/codemod-cli /project/src\n\n # Run the \"4.0.0-remove-appearance-prop\" transform of the \"button\" package\n $ npx @atlaskit/codemod-cli -t button@4.0.0-remove-appearance-prop /project/src\n\n # Run all transforms for \"@atlaskit/button\" greater than version 3.0.0 and @atlaskit/range greater than 4.0.0\n $ npx @atlaskit/codemod-cli --packages @atlaskit/button@3.0.0,@atlaskit/range@4.0.0 /project/src\n", {
19
19
  flags: {
20
20
  transform: {
21
21
  type: 'string',
@@ -40,6 +40,10 @@ function _run() {
40
40
  },
41
41
  failOnError: {
42
42
  type: 'boolean'
43
+ },
44
+ filterPaths: {
45
+ type: 'boolean',
46
+ default: true
43
47
  }
44
48
  }
45
49
  });
@@ -0,0 +1,81 @@
1
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
+ import { glob } from 'glob';
4
+ import { promises } from 'fs';
5
+ var readFile = promises.readFile;
6
+ /** Return products packages filePaths for running codemods from specified dependent package */
7
+
8
+ export function findDependentPackagePaths(_x, _x2) {
9
+ return _findDependentPackagePaths.apply(this, arguments);
10
+ }
11
+
12
+ function _findDependentPackagePaths() {
13
+ _findDependentPackagePaths = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(crawlPaths, dependencyPackage) {
14
+ var searchStrings, globString, packageJsonPaths, productPackageJsonPathPromises, productPackageJsonPaths, productPackagePaths;
15
+ return _regeneratorRuntime.wrap(function _callee2$(_context2) {
16
+ while (1) {
17
+ switch (_context2.prev = _context2.next) {
18
+ case 0:
19
+ // Get file paths leading to package.jsons
20
+ searchStrings = crawlPaths.map(function (crawlPath) {
21
+ //Replace leading './' due to bug with node-glob not properly ignoring files https://github.com/isaacs/node-glob/issues/309
22
+ return "".concat(crawlPath.replace(/^\.\//, ''), "/**/package.json");
23
+ }); // Convert array into glob string
24
+
25
+ globString = searchStrings.length > 1 ? "{".concat(searchStrings.join(','), "}") : searchStrings[0];
26
+ packageJsonPaths = glob.sync(globString, {
27
+ ignore: '**/node_modules/**',
28
+ nodir: true
29
+ });
30
+ productPackageJsonPathPromises = packageJsonPaths.map( /*#__PURE__*/function () {
31
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(filePath) {
32
+ var fileContents, isMatch;
33
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
34
+ while (1) {
35
+ switch (_context.prev = _context.next) {
36
+ case 0:
37
+ fileContents = readFile(filePath, 'utf8'); // Grep for installedPackage
38
+
39
+ _context.next = 3;
40
+ return fileContents;
41
+
42
+ case 3:
43
+ isMatch = _context.sent.toString().split(/\n/).some(function (line) {
44
+ return line.match(dependencyPackage);
45
+ });
46
+ return _context.abrupt("return", isMatch && filePath);
47
+
48
+ case 5:
49
+ case "end":
50
+ return _context.stop();
51
+ }
52
+ }
53
+ }, _callee);
54
+ }));
55
+
56
+ return function (_x3) {
57
+ return _ref.apply(this, arguments);
58
+ };
59
+ }());
60
+ _context2.next = 6;
61
+ return Promise.all(productPackageJsonPathPromises);
62
+
63
+ case 6:
64
+ productPackageJsonPaths = _context2.sent.filter(function (path) {
65
+ return path !== false;
66
+ });
67
+ // Get directory
68
+ productPackagePaths = productPackageJsonPaths.map(function (line) {
69
+ return line.replace('/package.json', '');
70
+ });
71
+ return _context2.abrupt("return", productPackagePaths);
72
+
73
+ case 9:
74
+ case "end":
75
+ return _context2.stop();
76
+ }
77
+ }
78
+ }, _callee2);
79
+ }));
80
+ return _findDependentPackagePaths.apply(this, arguments);
81
+ }
package/dist/esm/main.js CHANGED
@@ -25,6 +25,7 @@ import { fixLineEnding } from './utils';
25
25
  import { getTransforms, getTransformPath, hasTransform, parseTransformPath, getTransformModule } from './transforms';
26
26
  import { ValidationError, NoTransformsExistError } from './types';
27
27
  import { getPackagesSinceRef } from './sinceRef';
28
+ import { findDependentPackagePaths } from './filepath';
28
29
 
29
30
  var applyTransformMeta = function applyTransformMeta(transforms) {
30
31
  return transforms.map(function (transform) {
@@ -135,18 +136,41 @@ var resolveTransform = /*#__PURE__*/function () {
135
136
  }();
136
137
 
137
138
  var runTransform = /*#__PURE__*/function () {
138
- var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(filePath, transform, flags) {
139
- var logger, transformPath, args, jscodeshiftContent, jscodeshiftContentNew;
139
+ var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(filePaths, transform, flags) {
140
+ var logger, codemodDirs, transformPath, args, jscodeshiftContent, jscodeshiftContentNew;
140
141
  return _regeneratorRuntime.wrap(function _callee3$(_context3) {
141
142
  while (1) {
142
143
  switch (_context3.prev = _context3.next) {
143
144
  case 0:
144
145
  logger = flags.logger;
145
- logger.log(chalk.green("Running transform '".concat(chalk.bold(transform.name), "' over ").concat(chalk.bold(filePath.join(', ')), "...")));
146
+ logger.log(chalk.green("Running transform '".concat(chalk.bold(transform.name), "' over ").concat(chalk.bold(filePaths.join(', ')), "...")));
147
+ codemodDirs = filePaths;
148
+
149
+ if (!flags.filterPaths) {
150
+ _context3.next = 9;
151
+ break;
152
+ }
153
+
154
+ logger.log(chalk.green("Running filtering logic for module ".concat(transform.module, "...")));
155
+ _context3.next = 7;
156
+ return findDependentPackagePaths(filePaths, transform.module);
157
+
158
+ case 7:
159
+ codemodDirs = _context3.sent;
160
+
161
+ if (codemodDirs.length === 0) {
162
+ // Fallback to non-filter logic if filtering returns no directories
163
+ logger.log(chalk.yellow("Could not filter source paths for ".concat(transform.module, ", falling back to running over all specified paths. (See --no-filter-paths flag)")));
164
+ codemodDirs = filePaths;
165
+ } else {
166
+ logger.log(chalk.green("Running transform '".concat(chalk.bold(transform.name), "' over filtered dirs ").concat(chalk.bold(codemodDirs.join(', ')), "...")));
167
+ }
168
+
169
+ case 9:
146
170
  logger.log(chalk.green("Transforming files matching these extensions '".concat(chalk.bold(flags.extensions), "'...")));
147
171
  transformPath = getTransformPath(transform); // Limit CPUs to 8 to prevent issues when running on CI with a large amount of cpus
148
172
 
149
- args = ["--transform=".concat(transformPath), "--ignore-pattern=".concat(flags.ignorePattern), "--parser=".concat(flags.parser), "--extensions=".concat(flags.extensions), '--cpus=8'].concat(_toConsumableArray(filePath));
173
+ args = ["--transform=".concat(transformPath), "--ignore-pattern=".concat(flags.ignorePattern), "--parser=".concat(flags.parser), "--extensions=".concat(flags.extensions), '--cpus=8'].concat(_toConsumableArray(codemodDirs));
150
174
 
151
175
  if (flags.failOnError) {
152
176
  args.unshift('--fail-on-error');
@@ -158,12 +182,12 @@ var runTransform = /*#__PURE__*/function () {
158
182
  jscodeshiftContent = fs.readFileSync(jscodeshift, 'utf8');
159
183
  jscodeshiftContentNew = fixLineEnding(jscodeshiftContent, 'LF');
160
184
  fs.writeFileSync(jscodeshift, jscodeshiftContentNew);
161
- _context3.next = 11;
185
+ _context3.next = 18;
162
186
  return spawn(jscodeshift, args, {
163
187
  stdio: 'inherit'
164
188
  });
165
189
 
166
- case 11:
190
+ case 18:
167
191
  case "end":
168
192
  return _context3.stop();
169
193
  }
@@ -316,7 +340,7 @@ function _main() {
316
340
  case 4:
317
341
  _yield$parseArgs = _context5.sent;
318
342
  packages = _yield$parseArgs.packages;
319
- _process$env$_PACKAGE = "0.7.0", _PACKAGE_VERSION_ = _process$env$_PACKAGE === void 0 ? '0.0.0-dev' : _process$env$_PACKAGE;
343
+ _process$env$_PACKAGE = "0.8.3", _PACKAGE_VERSION_ = _process$env$_PACKAGE === void 0 ? '0.0.0-dev' : _process$env$_PACKAGE;
320
344
  logger.log(chalk.bgBlue(chalk.black("\uD83D\uDCDA Atlassian-Frontend codemod library @ ".concat(_PACKAGE_VERSION_, " \uD83D\uDCDA"))));
321
345
 
322
346
  if (packages && packages.length > 0) {
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "name": "@atlaskit/codemod-cli",
3
- "version": "0.7.0"
3
+ "version": "0.8.3"
4
4
  }
@@ -0,0 +1,2 @@
1
+ /** Return products packages filePaths for running codemods from specified dependent package */
2
+ export declare function findDependentPackagePaths(crawlPaths: string[], dependencyPackage: string): Promise<string[]>;
@@ -29,6 +29,10 @@ export declare type CliFlags = {
29
29
  * Return a 1 exit code when errors were found during execution of codemods
30
30
  */
31
31
  failOnError?: boolean;
32
+ /**
33
+ * Filters source paths to package directories that declare a dependency on the package being upgraded
34
+ */
35
+ filterPaths?: boolean;
32
36
  };
33
37
  export declare type Flags = CliFlags & {
34
38
  logger: {
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "@atlaskit/codemod-cli/filepath",
3
+ "main": "../dist/cjs/filepath.js",
4
+ "module": "../dist/esm/filepath.js",
5
+ "module:es2019": "../dist/es2019/filepath.js",
6
+ "types": "../dist/types/filepath.d.ts"
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/codemod-cli",
3
- "version": "0.7.0",
3
+ "version": "0.8.3",
4
4
  "description": "A cli for distributing codemods for atlassian-frontend components and services",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -31,7 +31,7 @@
31
31
  "enquirer": "^2.3.4",
32
32
  "glob": "^7.1.2",
33
33
  "jscodeshift": "^0.13.0",
34
- "meow": "^6.0.0",
34
+ "meow": "^8.1.1",
35
35
  "projector-spawn": "^1.0.1",
36
36
  "semver": "^7.3.0",
37
37
  "simple-git": "^1.130.0"