diff --git a/bin.js b/bin.js index fe392e2..6e17a45 100755 --- a/bin.js +++ b/bin.js @@ -1,2 +1,2 @@ #!/usr/bin/env node -require("./dist/cli/bin.js"); +require("./dist/bin.js"); diff --git a/src/cli/bin.ts b/src/bin.ts similarity index 76% rename from src/cli/bin.ts rename to src/bin.ts index 6f5d061..a3d0b2f 100644 --- a/src/cli/bin.ts +++ b/src/bin.ts @@ -1,15 +1,19 @@ import yargs from "yargs"; -import { BehaviorOnError } from "../migration.types"; -import { migrateContentServerJson } from "./scripts/migrateContentServerJson"; -import { migrateNotebook } from "./scripts/migrateNotebook"; +import fs from "fs-extra"; +import path from "path"; +import { BehaviorOnError } from "./migration.types"; +import { migrateNotebook } from "./migrateNotebook"; import { convertFromVersion, convertToVersion, convertVersions, validFromVersions, validToVersions, -} from "../convertAtotiToAUIVersions"; -import { getTreeColumnWidthFromArgs } from "../getTreeColumnWidthFromArgs"; +} from "./convertAtotiToAUIVersions"; +import { getTreeColumnWidthFromArgs } from "./getTreeColumnWidthFromArgs"; +import { migrateContentServer } from "./migrateContentServer"; +import { DataModel, ContentRecord } from "@activeviam/activeui-sdk-5.1"; +import { logMigrationReport } from "./logMigrationReport"; const supportedFileExtension = ["JSON", "IPYNB"]; @@ -127,7 +131,7 @@ yargs }); args.implies("stack", "debug"); }, - ({ + async ({ inputPath, outputPath, serversPath, @@ -141,6 +145,7 @@ yargs onError, }) => { const doesReportIncludeStacks = stack; + const behaviorOnError = onError; const fileExtension = getFileExtension(inputPath); const { fromVersion: validFromVersion, toVersion: validToVersion } = @@ -149,32 +154,59 @@ yargs toVersion, }); + const fileToMigrate: ContentRecord = await fs.readJSON(inputPath); + + const servers: { + [serverKey: string]: { + dataModel: DataModel<"raw">; + url: string; + }; + } & { contentServerVersion?: string } = await fs.readJSON(serversPath); + if (fileExtension === "JSON") { - // Ensure that Atoti versions are not used as versions to migrate content server - migrateContentServerJson({ - inputPath, - outputPath, - serversPath, + const { counters, errorReport } = await migrateContentServer({ + contentServer: fileToMigrate, + servers, fromVersion: validFromVersion, toVersion: validToVersion, - removeWidgets, - debug, + keysOfWidgetPluginsToRemove: removeWidgets, doesReportIncludeStacks, - onError, + behaviorOnError: onError, treeTableColumnWidth: treeColumnWidth ? getTreeColumnWidthFromArgs(treeColumnWidth) : undefined, shouldUpdateFiltersMdx: updateFiltersMdx === undefined ? true : updateFiltersMdx, }); + + const { dir } = path.parse(outputPath); + await Promise.all([ + fs.writeJSON(outputPath, fileToMigrate, { spaces: 2 }), + logMigrationReport({ + counters, + errorReport, + debug, + doesReportIncludeStacks, + migrationOutputDirectory: dir, + behaviorOnError, + }), + ]); } else { - migrateNotebook({ - inputPath, - outputPath, - serversPath, - fromVersion: validFromVersion, - toVersion: validToVersion, - }); + const { numberOfMigratedWidgets, numberOfFailures } = + await migrateNotebook({ + notebook: fileToMigrate, + servers, + fromVersion: validFromVersion, + toVersion: validToVersion, + }); + + await fs.writeJSON(outputPath, fileToMigrate, { spaces: 2 }); + console.log( + `- Succesfully migrated ${numberOfMigratedWidgets} widget(s).`, + ); + if (numberOfFailures > 0) { + console.log(`- Failed to migrate ${numberOfFailures} widget(s)`); + } } }, ) diff --git a/src/cli/scripts/migrateContentServerJson.ts b/src/logMigrationReport.ts similarity index 75% rename from src/cli/scripts/migrateContentServerJson.ts rename to src/logMigrationReport.ts index ec88c0e..6b815d0 100644 --- a/src/cli/scripts/migrateContentServerJson.ts +++ b/src/logMigrationReport.ts @@ -1,13 +1,12 @@ import fs from "fs-extra"; import path from "path"; import _capitalize from "lodash/capitalize"; -import { ContentRecord, DataModel } from "@activeviam/activeui-sdk-5.1"; -import { BehaviorOnError } from "../../migration.types"; + import { - AtotiUIFromVersion, - AtotiUIToVersion, -} from "../../convertAtotiToAUIVersions"; -import { migrateContentServer } from "../../migrateContentServer"; + BehaviorOnError, + ErrorReport, + OutcomeCounters, +} from "./migration.types"; const summaryMessages: { [folderName: string]: { @@ -70,58 +69,24 @@ const summaryMessages: { }; /** - * Same as {@link migrateContentServer}, but reading its inputs from JSON files. + * Logs the outcome of the migration in the console, which includes the number of successful/failed individual resource migrations. + * If `debug` is set to `true`, also logs the detailed `errorReport` in a `report.json` file under `migrationOutputDirectory`. */ -export async function migrateContentServerJson({ - inputPath, - outputPath, - serversPath, - fromVersion, - toVersion, - removeWidgets: keysOfWidgetPluginsToRemove, +export async function logMigrationReport({ + counters, + errorReport, debug, doesReportIncludeStacks, - onError: behaviorOnError, - treeTableColumnWidth, - shouldUpdateFiltersMdx, + behaviorOnError, + migrationOutputDirectory, }: { - inputPath: string; - outputPath: string; - serversPath: string; - fromVersion: AtotiUIFromVersion; - toVersion: AtotiUIToVersion; - removeWidgets: string[]; + counters: OutcomeCounters; + errorReport: ErrorReport; debug: boolean; doesReportIncludeStacks: boolean; - onError: BehaviorOnError; - treeTableColumnWidth?: [number, number]; - shouldUpdateFiltersMdx: boolean; + behaviorOnError: BehaviorOnError; + migrationOutputDirectory: string; }): Promise { - const contentServer: ContentRecord = await fs.readJSON(inputPath); - - const servers: { - [serverKey: string]: { - dataModel: DataModel<"raw">; - url: string; - }; - } & { contentServerVersion?: string } = await fs.readJSON(serversPath); - - const { counters, errorReport } = await migrateContentServer({ - contentServer, - servers, - fromVersion, - toVersion, - keysOfWidgetPluginsToRemove, - doesReportIncludeStacks, - behaviorOnError, - treeTableColumnWidth, - shouldUpdateFiltersMdx, - }); - - const { dir } = path.parse(outputPath); - - await fs.writeJSON(outputPath, contentServer, { spaces: 2 }); - console.log("--------- END OF CONTENT MIGRATION ---------"); Object.entries(counters) @@ -159,7 +124,7 @@ export async function migrateContentServerJson({ ) { if (!debug) { console.log(`For more information about the errors that occurred, rerun the command with the \`--debug\` option. -This will output a file named \`report.json\` containing the error messages.`); + This will output a file named \`report.json\` containing the error messages.`); } else { console.log( `See report.json for more information about the errors that occurred.`, @@ -175,8 +140,12 @@ This will output a file named \`report.json\` containing the error messages.`); console.log("--------------------------------------------"); if (errorReport && debug) { - await fs.writeJSON(path.join(...dir, "report.json"), errorReport, { - spaces: 2, - }); + await fs.writeJSON( + path.join(...migrationOutputDirectory, "report.json"), + errorReport, + { + spaces: 2, + }, + ); } } diff --git a/src/cli/scripts/migrateNotebook.ts b/src/migrateNotebook.ts similarity index 75% rename from src/cli/scripts/migrateNotebook.ts rename to src/migrateNotebook.ts index 88120cd..2de1d52 100644 --- a/src/cli/scripts/migrateNotebook.ts +++ b/src/migrateNotebook.ts @@ -1,14 +1,13 @@ -import { migrateWidget } from "../../5.0_to_5.1/migrateWidget"; -import fs from "fs-extra"; +import { migrateWidget } from "./5.0_to_5.1/migrateWidget"; import { DataModel, getIndexedDataModel } from "@activeviam/data-model-5.1"; import _mapValues from "lodash/mapValues"; import { serializeWidgetState } from "@activeviam/activeui-sdk-5.1"; import { deserializeWidgetState } from "@activeviam/activeui-sdk-5.0"; -import { MigrateWidgetCallback } from "../../migration.types"; +import { MigrateWidgetCallback } from "./migration.types"; import { AtotiUIFromVersion, AtotiUIToVersion, -} from "../../convertAtotiToAUIVersions"; +} from "./convertAtotiToAUIVersions"; import { produce } from "immer"; const migrationSteps: { @@ -21,24 +20,18 @@ const migrationSteps: { * Migrates the Atoti UI widgets from 5.0 to 5.1 of an Atoti Jupter Notebook. */ export const migrateNotebook = async ({ - inputPath, - outputPath, - serversPath, + notebook, + servers, fromVersion, toVersion, }: { - inputPath: string; - outputPath: string; - serversPath: string; + notebook: any; + servers: { + [serverKey: string]: { dataModel: DataModel<"raw">; url: string }; + }; fromVersion: AtotiUIFromVersion; toVersion: AtotiUIToVersion; -}): Promise => { - const notebook = await fs.readJSON(inputPath); - - const servers: { - [serverKey: string]: { dataModel: DataModel<"raw">; url: string }; - } = await fs.readJSON(serversPath); - +}): Promise<{ numberOfMigratedWidgets: number; numberOfFailures: number }> => { const dataModels = _mapValues(servers, ({ dataModel }) => getIndexedDataModel(dataModel), ); @@ -77,10 +70,5 @@ export const migrateNotebook = async ({ } } - await fs.writeJSON(outputPath, notebook, { spaces: 2 }); - - console.log(`- Succesfully migrated ${numberOfMigratedWidgets} widget(s).`); - if (numberOfFailures > 0) { - console.log(`- Failed to migrate ${numberOfFailures} widget(s)`); - } + return { numberOfMigratedWidgets, numberOfFailures }; }; diff --git a/webpack.config.js b/webpack.config.js index c037339..443cd44 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -7,7 +7,7 @@ const webpack = require("webpack"); // This allows the functions exported by this package to be run smoothly in a Node.js environment (see https://support.activeviam.com/jira/browse/UI-6165). module.exports = { entry: { - bin: "./src/cli/bin.ts", + bin: "./src/bin.ts", }, module: { rules: [ @@ -39,8 +39,8 @@ module.exports = { output: { hashFunction: "xxhash64", globalObject: "window", - filename: (pathData) => { - return pathData.chunk.name === "bin" ? "cli/[name].js" : "[name].js"; + filename: () => { + return "[name].js"; }, path: path.resolve(__dirname, "dist"), },