UNPKG

@itwin/appui-codemod

Version:

Codemod scripts for AppUI.

241 lines (240 loc) 11.9 kB
#!/usr/bin/env node "use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ var fs_1 = require("fs"); var glob_1 = require("glob"); var Runner_1 = require("jscodeshift/src/Runner"); var path_1 = require("path"); var postcss_1 = __importDefault(require("postcss")); var postcss_scss_1 = require("postcss-scss"); var ts_node_1 = require("ts-node"); var yargs_1 = __importDefault(require("yargs")); var defaultOptions = { trailingComma: true, }; function toPrintOptions(options) { var printOptions = options.printOptions; if (!printOptions) { return defaultOptions; } if (typeof printOptions === "string") { printOptions = JSON.parse(options.printOptions); } return __assign(__assign({}, defaultOptions), printOptions); } function run(args, optionOverrides) { return __awaiter(this, void 0, void 0, function () { var codemod, paths, debug, skipCss, transformFile, options, _a; return __generator(this, function (_b) { switch (_b.label) { case 0: codemod = args.codemod, paths = args.paths, debug = args.debug, skipCss = args.skipCss; transformFile = (0, path_1.resolve)(__dirname, "..", "src", "".concat(codemod, ".ts")); if (!(0, fs_1.existsSync)(transformFile)) { throw new Error("Codemod '".concat(transformFile, "' not found.")); } options = __assign(__assign({ extensions: "ts,tsx", parser: "tsx", babel: true, verbose: 1, ignorePattern: "**/node_modules/**" }, optionOverrides), { printOptions: toPrintOptions(optionOverrides) }); debug && console.log("Running 'jscodeshift' with following configuration:", { transformFile: transformFile, paths: paths, options: options }); return [4 /*yield*/, (0, Runner_1.run)(transformFile, paths, options)]; case 1: _b.sent(); _a = !skipCss; if (!_a) return [3 /*break*/, 3]; return [4 /*yield*/, runCssCodemod(args, transformFile)]; case 2: _a = (_b.sent()); _b.label = 3; case 3: _a; return [2 /*return*/]; } }); }); } yargs_1.default.parserConfiguration({ "camel-case-expansion": false, }) .command({ command: "$0 <codemod> <paths...>", describe: "Applies an `@itwin/appui-codemod` to the specified paths", builder: function (command) { return command .positional("codemod", { description: "The name of the codemod", type: "string", demandOption: true, }) .positional("paths", { description: "Paths forwarded to `jscodeshift`", type: "string", array: true, demandOption: true, }) .option("debug", { description: "Prints configuration used by `jscodeshift`.", type: "boolean", default: false, }) .option("printOptions", { description: "Options that are passed down to recast's printer. See: https://github.com/benjamn/recast/blob/master/lib/options.ts", }) .option("skipCss", { description: "Controls if the CSS files should be modified.", type: "boolean", default: false, }) .epilogue("Additional options are passed down to `jsdcodeshift`."); }, handler: function (argv) { var codemod = argv.codemod, debug = argv.debug, paths = argv.paths, skipCss = argv.skipCss, _ = argv._, $0 = argv.$0, options = __rest(argv, ["codemod", "debug", "paths", "skipCss", "_", "$0"]); return run({ codemod: codemod, paths: paths, debug: debug, skipCss: skipCss, }, options); }, }) .scriptName("npx @itwin/appui-codemod") .example("$0 v4.0.0/full src", "Apply all 4.0.0 transforms on `src` path.") .example("$0 v4.0.0/layout-react src", "Apply a specific transform on `src` path.") .example("$0 <codemod> <paths...> --printOptions.quote=\"single\"", "Pass additional options to recast's printer.") .example("$0 <codemod> <paths...> --printOptions='{\\\"lineTerminator\\\":\\\"\\r\\n\\\"}'", "Pass additional options to recast's printer as a string.") .help() .parse(); function runCssCodemod(args, transformFile) { return __awaiter(this, void 0, void 0, function () { var transformModule, processor, plugins, files, _i, _a, path, pattern, matches, filePromises; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: (0, ts_node_1.register)({ compilerOptions: { target: "ES6", esModuleInterop: true, }, skipIgnore: true, }); transformModule = require(transformFile); if (!("cssPlugin" in transformModule)) { return [2 /*return*/]; } processor = (0, postcss_1.default)([transformModule.cssPlugin]); plugins = processor.plugins.map(function (p) { return p["postcssPlugin"]; }).filter(function (p) { return !!p; }); files = []; _i = 0, _a = args.paths; _b.label = 1; case 1: if (!(_i < _a.length)) return [3 /*break*/, 4]; path = _a[_i]; pattern = (0, path_1.resolve)(path, "**/*.{css,sass,scss}").replace(/\\/g, '/'); return [4 /*yield*/, (0, glob_1.glob)(pattern, { ignore: ["**/node_modules/**"], })]; case 2: matches = _b.sent(); files.push.apply(files, matches); _b.label = 3; case 3: _i++; return [3 /*break*/, 1]; case 4: args.debug && console.log("Running 'PostCSS' with following configuration:", { plugins: plugins, files: files }); filePromises = files.map(function (file) { return __awaiter(_this, void 0, void 0, function () { var contents, result, e_1; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); contents = (0, fs_1.readFileSync)(file).toString(); return [4 /*yield*/, processor.process(contents, { from: undefined, parser: postcss_scss_1.parse, stringifier: postcss_scss_1.stringify, })]; case 1: result = _a.sent(); (0, fs_1.writeFileSync)(file, result.css); return [3 /*break*/, 3]; case 2: e_1 = _a.sent(); console.error(e_1); return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }); return [4 /*yield*/, Promise.all(filePromises)]; case 5: _b.sent(); return [2 /*return*/]; } }); }); }