Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(upgrade): run migrations from upgrade cli #10494

Merged
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6419b27
wip: augment updates to include migrations, add prompts, run migrate …
tay1orjones Jan 20, 2022
5d8b914
wip(cli): add separate migrate command, run all migrations during upg…
tay1orjones Jan 21, 2022
4b02857
wip: add migrate command file
tay1orjones Jan 21, 2022
ae09122
fix(cli): await migrate calls, use flatMap for gathering migrations
tay1orjones Jan 21, 2022
b72859f
chore(project): move transforms from codemods package to upgrade package
tay1orjones Jan 24, 2022
8869983
chore(project): remove codemods directory, update transforms arch doc
tay1orjones Jan 24, 2022
45da9f0
chore: update yarn.lock removing codemods package
tay1orjones Jan 24, 2022
ab58703
feat(upgrade): add imports-to-unified-package migration, associated r…
tay1orjones Jan 24, 2022
a6c7716
feat(upgrade): add imports-to-unified-package migration, associated r…
tay1orjones Jan 24, 2022
51a8241
chore(upgrade): ignore future updates to test file in sample project
tay1orjones Jan 24, 2022
acee025
fix(upgrade): add transformDir argument to migrate() call
tay1orjones Jan 24, 2022
daf4700
chore(upgrade): don't hoist dependencies all the way up to the monorepo
tay1orjones Jan 24, 2022
66451a7
chore(upgrade): minor code cleanup
tay1orjones Jan 24, 2022
a799612
chore(project): run yarn dedupe
tay1orjones Jan 25, 2022
bbe8f03
fix(upgrade): remove prompt for migrations, clean up, review feedback
tay1orjones Jan 25, 2022
0878a1b
fix(upgrade): use execa to invoke jscodeshift, gather jscodeshift bin…
tay1orjones Jan 25, 2022
55b38b2
chore(project): run yarn dedupe
tay1orjones Jan 25, 2022
6edbd2f
chore(upgrade): remove codemod - move it to it's own PR
tay1orjones Jan 25, 2022
aff92b9
Merge branch 'main' into 10466-upgrade-cli-run-codemods
tay1orjones Jan 25, 2022
6d234da
chore(upgrade): revert execa to devDependency and intended version
tay1orjones Jan 25, 2022
176c780
Merge branch '10466-upgrade-cli-run-codemods' of github.com:tay1orjon…
tay1orjones Jan 25, 2022
487f9fc
Merge branch 'main' into 10466-upgrade-cli-run-codemods
tay1orjones Jan 26, 2022
0750a05
Update packages/upgrade/src/commands/migrate.js
tay1orjones Jan 26, 2022
5659c29
fix(upgrade): use execa default export
tay1orjones Jan 26, 2022
d9c829d
fix(upgrade): remove TRANSFORM_DIR as an option, include directly in …
tay1orjones Jan 26, 2022
189b2d9
Merge branch 'main' into 10466-upgrade-cli-run-codemods
tay1orjones Jan 26, 2022
904f70e
Merge branch 'main' into 10466-upgrade-cli-run-codemods
kodiakhq[bot] Jan 27, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
4 changes: 0 additions & 4 deletions codemods/.npmignore

This file was deleted.

24 changes: 0 additions & 24 deletions codemods/package.json

This file was deleted.

1 change: 0 additions & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"useWorkspaces": true,
"ignoreChanges": [
"actions/**",
"codemods/**",
"**/__fixtures__/**",
"**/__tests__/**",
"**/docs/**",
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
},
"workspaces": [
"actions/*",
"codemods",
"config/*",
"packages/*",
"www"
Expand All @@ -21,7 +20,7 @@
"doctoc": "doctoc --title '## Table of Contents'",
"format": "prettier --write '**/*.{js,md,scss,ts}' '!**/{build,es,lib,storybook,ts,umd}/**'",
"format:diff": "prettier --list-different '**/*.{js,md,scss,ts}' '!**/{build,es,lib,storybook,ts,umd}/**' '!packages/components/**'",
"lint": "eslint actions config codemods packages www",
"lint": "eslint actions config packages www",
"lint:styles": "stylelint '**/*.{css,scss}' --report-needless-disables --report-invalid-scope-disables",
"sync": "carbon-cli sync",
"test": "cross-env BABEL_ENV=test jest",
Expand Down
2 changes: 1 addition & 1 deletion packages/upgrade/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Generated by `esbuild` using `yarn build`
/cli.js
/cli.js
10 changes: 6 additions & 4 deletions packages/upgrade/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"bugs": "https://github.com/carbon-design-system/carbon/issues",
"files": [
"bin",
"cli.js"
"cli.js",
"transforms"
],
"keywords": [
"carbon",
Expand All @@ -30,22 +31,20 @@
"access": "public"
},
"scripts": {
"build": "esbuild src/cli.js --bundle --platform=node --outfile=cli.js --target=node14",
"build": "esbuild src/cli.js --bundle --platform=node --outfile=cli.js --target=node14 --external:jscodeshift",
"clean": "rimraf cli.js",
"watch": "yarn build --watch"
},
"devDependencies": {
"chalk": "^4.1.1",
"change-case": "^4.1.2",
"cross-spawn": "^7.0.3",
"esbuild": "^0.14.10",
"execa": "^5.1.1",
tay1orjones marked this conversation as resolved.
Show resolved Hide resolved
"fast-glob": "^3.2.7",
"fs-extra": "^10.0.0",
"inquirer": "^8.1.0",
"is-git-clean": "^1.1.0",
"jest-diff": "^27.4.6",
"jscodeshift": "^0.13.0",
"lodash.clonedeep": "^4.5.0",
"lodash.merge": "^4.6.2",
"memfs": "^3.4.0",
Expand All @@ -54,5 +53,8 @@
"rimraf": "^3.0.2",
"semver": "^7.3.5",
"yargs": "^17.0.1"
},
"dependencies": {
"jscodeshift": "^0.13.1"
}
}
37 changes: 33 additions & 4 deletions packages/upgrade/src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import chalk from 'chalk';
import isGitClean from 'is-git-clean';
import { upgrade } from './commands/upgrade';
import { migrate } from './commands/migrate';
import { UpgradeError } from './error';
import { logger } from './logger';
import { upgrades } from './upgrades';
Expand Down Expand Up @@ -42,8 +43,9 @@ export async function main({ argv, cwd }) {
type: 'boolean',
});

// $0: the default command
cli.usage('Usage: $0 [options]').command(
'$0',
['upgrade', '$0'],
'upgrade your project',
{},
run(async (args) => {
tay1orjones marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -57,14 +59,41 @@ export async function main({ argv, cwd }) {
})
);

cli.command(
'migrate <migration>',
'run a Carbon migration on your source files',
async (cli) => {
cli.command(
'list',
'list all migrations',
{},
run(async (args) => {
const { verbose } = args;
const options = { cwd: cwd(), verbose, list: true };
await migrate(options, upgrades);
}, true)
);
},
run(async (args) => {
const { verbose, migration, write } = args;
const options = {
cwd: cwd(),
verbose,
write,
migration,
};
await migrate(options, upgrades);
})
);

cli.strict().parse(argv.slice(2));
}

/**
* @param {Function} command
* @returns {Function}
*/
function run(command) {
function run(command, ignoreSafetyChecks = false) {
return async (args) => {
if (args.verbose === true) {
logger.setLevel('verbose');
Expand All @@ -88,7 +117,7 @@ function run(command) {
}
}

if (!clean && args.force !== true) {
if (!ignoreSafetyChecks && !clean && args.force !== true) {
logger.log(
chalk.yellow('[warning]'),
'It appears that you have untracked changes in your project. Before we continue, please stash or commit your changes to git.'
Expand All @@ -101,7 +130,7 @@ function run(command) {

try {
await command(args);
logger.log('Done! ✨');
logger.verbose('Done! ✨');
} catch (error) {
if (error instanceof UpgradeError) {
logger.error(error.message);
Expand Down
112 changes: 112 additions & 0 deletions packages/upgrade/src/commands/migrate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/**
* Copyright IBM Corp. 2019, 2019
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import inquirer from 'inquirer';
import { UpgradeError } from '../error';
import { logger } from '../logger';
import { Workspace, getAvailableWorkspaces } from '../workspace';

export async function migrate(options, upgrades = []) {
logger.verbose('running migrate command with options: %o', options);

const migrations = upgrades
.filter((upgrade) => {
return upgrade.migrations && upgrade.migrations.length > 0;
})
.flatMap((upgrade) => {
return upgrade.migrations;
});

if (!migrations || migrations.length === 0) {
logger.info('No migrations available');
return;
}

// List available migrations
if (options.list) {
listMigrations(migrations);
return;
}

const workspaces = getAvailableWorkspaces(options.cwd);
if (workspaces.length === 0) {
throw new UpgradeError('Unable to find a workspace to migrate');
}

// Only run the migration specified in the options
if (options.migration) {
const migration = migrations.find((migration) => {
return migration.name === options.migration;
});

if (!migration) {
logger.error(
'Sorry, there is no migration with the name "%s"',
options.migration
);
listMigrations(migrations);
} else {
await runMigration(migration, workspaces, options);
}

return;
} else {
logger.error('A migration must be specified');
}
}

/**
* @param {Array<Migrations>} migrations
* @returns {<void>}
*/
function listMigrations(migrations) {
logger.log('Available migrations:');
for (const migration of migrations) {
logger.log(' - %s (%s)', migration.name, migration.description);
}
}

/**
* @param {object<Migration>} migration
* @param {Array<string>} workspaces
* @returns {<void>}
*/
async function runMigration(migration, workspaces, options) {
const workspace = await getSelectedWorkspace(workspaces);

logger.verbose(
'running migration: %s for workspace: %s',
migration.name,
workspace.directory
);

await migration.migrate({ ...options, workspaceDir: workspace.directory });
}

/**
* @param {Array<string>} workspaces
* @returns {Promise<Workspace>}
*/
async function getSelectedWorkspace(workspaces) {
// If only one workspace is available, we'll load that one by default
if (workspaces.length === 1) {
return await Workspace.load(workspaces[0]);
}

// If multiple workspaces are found, we'll prompt to see which one the user
// would like us to operate off of.
const answers = await inquirer.prompt([
{
type: 'list',
name: 'workspace',
message: 'What workspace would you like to use?',
choices: workspaces,
},
]);

return await Workspace.load(answers.workspace);
}
12 changes: 12 additions & 0 deletions packages/upgrade/src/commands/upgrade.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,18 @@ export async function upgrade(options, availableUpgrades = []) {
logger.log(packageJson.diff());
}
}

const migrations = upgrade.migrations;
if (migrations && migrations.length > 0) {
for (const migration of migrations) {
logger.verbose('running migration: %s', migration.name);

await migration.migrate({
...options,
workspaceDir: workspace.directory,
});
}
}
}

/**
Expand Down
60 changes: 60 additions & 0 deletions packages/upgrade/src/jscodeshift.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Copyright IBM Corp. 2019, 2019
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import path from 'path';
import execa from 'execa';

let _jscodeshift;

function getBinPath() {
if (!_jscodeshift) {
const directory = path.dirname(require.resolve('jscodeshift'));
_jscodeshift = path.join(directory, 'bin', 'jscodeshift.js');
}
return _jscodeshift;
}

export async function run(options) {
const {
cwd,
stdio = 'inherit',
parser = 'babel',
paths,
transform,
} = options;
const args = [
paths,
`-t=${transform}`,
`--parser=${parser}`,
`--ignore-pattern=**/build/**`,
`--ignore-pattern=**/dist/**`,
`--ignore-pattern=**/es/**`,
`--ignore-pattern=**/lib/**`,
`--ignore-pattern=**/node_modules/**`,
`--ignore-pattern=**/storybook-static/**`,
`--ignore-pattern=**/umd/**`,
];

if (options.print) {
args.push('--print');
}

if (options.verbose) {
args.push('-v');
}

if (options.dry) {
args.push('--dry');
}

console.log(args);

return await execa(getBinPath(), args, {
cwd,
stdio,
});
}
Loading