diff --git a/lang/de.json b/lang/de.json index 7808f7d9..d447fb6b 100644 --- a/lang/de.json +++ b/lang/de.json @@ -289,9 +289,10 @@ "DS4.WarningItemIsNotRollable": "Für das Item '{name}' ({id}) vom Typ '{type}' kann nicht gewürfelt werden.", "DS4.WarningMacrosCanOnlyBeCreatedForOwnedItems": "Makros können nur für besessene Items angelegt werden.", "DS4.WarningInvalidCheckDropped": "Eine ungültige Probe wurde auf die Hotbar gezogen.", + "DS4.WarningSystemUpdateCompletedWithErrors": "Aktualisierung des DS4 Systems von Migrationsversion {currentVersion} auf {targetVersion} abgeschlossen, aber es sind Fehler aufgetreten. Bitte prüfen Sie in der Entwicklerkonsole, ob es sich um relevante Fehler handelt, oder ob sie ignoriert werden können. Insbesondere kann https://github.com/foundryvtt/foundryvtt/issues/9672 zu Fehlern führen, die ignoriert werden können.", "DS4.InfoManuallyEnterSpellModifier": "Der korrekte Wert für den Zauberbonus '{spellModifier}' des Zaubers '{name}' muss manuell angegeben werden.", "DS4.InfoSystemUpdateStart": "Aktualisiere DS4 System von Migrationsversion {currentVersion} auf {targetVersion}. Bitte haben Sie etwas Geduld, schließen Sie nicht das Spiel und fahren Sie nicht den Server herunter.", - "DS4.InfoSystemUpdateCompleted": "Aktualisierung des DS4 Systems von Migrationsversion {currentVersion} auf {targetVersion} erfolgreich!", + "DS4.InfoSystemUpdateCompletedSuccessfully": "Aktualisierung des DS4 Systems von Migrationsversion {currentVersion} auf {targetVersion} erfolgreich!", "DS4.InfoCompendiumMigrationStart": "Aktualisiere Kompendium '{pack}' für DS4 von Migrationsversion {currentVersion} auf {targetVersion}. Bitte haben Sie etwas Geduld, schließen Sie nicht das Spiel und fahren Sie nicht den Server herunter.", "DS4.InfoCompendiumMigrationCompleted": "Aktualisierung des Kompendiums '{pack}' für DS4 von Migrationsversion {currentVersion} auf {targetVersion} erfolgreich!", "DS4.UnitRounds": "Runden", diff --git a/lang/en.json b/lang/en.json index ae1a1705..fb7415b2 100644 --- a/lang/en.json +++ b/lang/en.json @@ -289,9 +289,10 @@ "DS4.WarningItemIsNotRollable": "Item '{name}' ({id}) of type '{type}' is not rollable.", "DS4.WarningMacrosCanOnlyBeCreatedForOwnedItems": "Macros can only be created for owned items.", "DS4.WarningInvalidCheckDropped": "An invalid check was dropped on the Hotbar.", + "DS4.WarningSystemUpdateCompletedWithErrors": "Migration of DS4 system from migration version {currentVersion} to {targetVersion} completed with errors. Please check the development console (F12) to see whether the errors have significant impact or can be ignored. In particular, https://github.com/foundryvtt/foundryvtt/issues/9672 may cause issues that simply can be ignored.", "DS4.InfoManuallyEnterSpellModifier": "The correct value of the spell modifier '{spellModifier}' of the spell '{name}' needs to be entered by manually.", "DS4.InfoSystemUpdateStart": "Migrating DS4 system from migration version {currentVersion} to {targetVersion}. Please be patient and do not close your game or shut down your server.", - "DS4.InfoSystemUpdateCompleted": "Migration of DS4 system from migration version {currentVersion} to {targetVersion} successful!", + "DS4.InfoSystemUpdateCompletedSuccessfully": "Migration of DS4 system from migration version {currentVersion} to {targetVersion} successful!", "DS4.InfoCompendiumMigrationStart": "Migrating compendium '{pack}' for DS4 from migration version {currentVersion} to {targetVersion}. Please be patient and do not close your game or shut down your server.", "DS4.InfoCompendiumMigrationCompleted": "Migration of compendium '{pack}' for DS4 from migration version {currentVersion} to {targetVersion} successful!", "DS4.UnitRounds": "Rounds", diff --git a/src/migration/001.js b/src/migration/001.js index b0b67cf8..1c152223 100644 --- a/src/migration/001.js +++ b/src/migration/001.js @@ -6,9 +6,10 @@ import { getSceneMigrator, migrateCollection, migrateCompendiums, getCompendiumM /** @type {import("./migration.js").Migration["migrate"]} */ async function migrate() { - await migrateCollection(game.actors, migrateActor); - await migrateCollection(game.scenes, migrateScene); - await migrateCompendiums(migrateCompendium); + const actorsResult = await migrateCollection(game.actors, migrateActor); + const scenesResult = await migrateCollection(game.scenes, migrateScene); + const compendiumsResult = await migrateCompendiums(migrateCompendium); + return actorsResult === "error" || scenesResult === "error" || compendiumsResult === "error" ? "error" : "success"; } /** @type {import('./migrationHelpers.js').Migrator} */ diff --git a/src/migration/002.js b/src/migration/002.js index f2848060..d73dddea 100644 --- a/src/migration/002.js +++ b/src/migration/002.js @@ -12,10 +12,16 @@ import { /** @type {import("./migration.js").Migration["migrate"]} */ async function migrate() { - await migrateCollection(game.items, migrateItem); - await migrateCollection(game.actors, migrateActor); - await migrateCollection(game.scenes, migrateScene); - await migrateCompendiums(migrateCompendium); + const itemsResult = await migrateCollection(game.items, migrateItem); + const actorsResult = await migrateCollection(game.actors, migrateActor); + const scenesResult = await migrateCollection(game.scenes, migrateScene); + const compendiumsResult = await migrateCompendiums(migrateCompendium); + return itemsResult === "error" || + actorsResult === "error" || + scenesResult === "error" || + compendiumsResult === "error" + ? "error" + : "success"; } /** @type {import('./migrationHelpers.js').Migrator} */ diff --git a/src/migration/003.js b/src/migration/003.js index 4d62321e..2d92a6ba 100644 --- a/src/migration/003.js +++ b/src/migration/003.js @@ -12,10 +12,16 @@ import { /** @type {import("./migration.js").Migration["migrate"]} */ async function migrate() { - await migrateCollection(game.items, migrateItem); - await migrateCollection(game.actors, migrateActor); - await migrateCollection(game.scenes, migrateScene); - await migrateCompendiums(migrateCompendium); + const itemsResult = await migrateCollection(game.items, migrateItem); + const actorsResult = await migrateCollection(game.actors, migrateActor); + const scenesResult = await migrateCollection(game.scenes, migrateScene); + const compendiumsResult = await migrateCompendiums(migrateCompendium); + return itemsResult === "error" || + actorsResult === "error" || + scenesResult === "error" || + compendiumsResult === "error" + ? "error" + : "success"; } /** @type {import("./migrationHelpers.js").Migrator} */ diff --git a/src/migration/004.js b/src/migration/004.js index d211ae6a..85306cba 100644 --- a/src/migration/004.js +++ b/src/migration/004.js @@ -12,10 +12,16 @@ import { /** @type {import("./migration.js").Migration["migrate"]} */ async function migrate() { - await migrateCollection(game.items, migrateItem); - await migrateCollection(game.actors, migrateActor); - await migrateCollection(game.scenes, migrateScene); - await migrateCompendiums(migrateCompendium); + const itemsResult = await migrateCollection(game.items, migrateItem); + const actorsResult = await migrateCollection(game.actors, migrateActor); + const scenesResult = await migrateCollection(game.scenes, migrateScene); + const compendiumsResult = await migrateCompendiums(migrateCompendium); + return itemsResult === "error" || + actorsResult === "error" || + scenesResult === "error" || + compendiumsResult === "error" + ? "error" + : "success"; } /** @type {import('./migrationHelpers.js').Migrator} */ diff --git a/src/migration/005.js b/src/migration/005.js index faeebd94..b8754fe4 100644 --- a/src/migration/005.js +++ b/src/migration/005.js @@ -21,10 +21,16 @@ const secondsPerDay = secondsPerMinute * minutesPerHour * hoursPerDay; /** @type {import("./migration.js").Migration["migrate"]} */ async function migrate() { - await migrateCollection(game.items, migrateItem); - await migrateCollection(game.actors, migrateActor); - await migrateCollection(game.scenes, migrateScene); - await migrateCompendiums(migrateCompendium); + const itemsResult = await migrateCollection(game.items, migrateItem); + const actorsResult = await migrateCollection(game.actors, migrateActor); + const scenesResult = await migrateCollection(game.scenes, migrateScene); + const compendiumsResult = await migrateCompendiums(migrateCompendium); + return itemsResult === "error" || + actorsResult === "error" || + scenesResult === "error" || + compendiumsResult === "error" + ? "error" + : "success"; } /** @type {import('./migrationHelpers.js').Migrator} */ diff --git a/src/migration/006.js b/src/migration/006.js index 3afceaa9..7acabc82 100644 --- a/src/migration/006.js +++ b/src/migration/006.js @@ -12,10 +12,16 @@ import { /** @type {import("./migration.js").Migration["migrate"]} */ async function migrate() { - await migrateCollection(game.items, migrateItem); - await migrateCollection(game.actors, migrateActor); - await migrateCollection(game.scenes, migrateScene); - await migrateCompendiums(migrateCompendium); + const itemsResult = await migrateCollection(game.items, migrateItem); + const actorsResult = await migrateCollection(game.actors, migrateActor); + const scenesResult = await migrateCollection(game.scenes, migrateScene); + const compendiumsResult = await migrateCompendiums(migrateCompendium); + return itemsResult === "error" || + actorsResult === "error" || + scenesResult === "error" || + compendiumsResult === "error" + ? "error" + : "success"; } /** @type {import('./migrationHelpers.js').Migrator} */ diff --git a/src/migration/007.js b/src/migration/007.js index 70a64437..6ca9585a 100644 --- a/src/migration/007.js +++ b/src/migration/007.js @@ -12,10 +12,16 @@ import { /** @type {import("./migration.js").Migration["migrate"]} */ async function migrate() { - await migrateCollection(game.items, migrateItem); - await migrateCollection(game.actors, migrateActor); - await migrateCollection(game.scenes, migrateScene); - await migrateCompendiums(migrateCompendium); + const itemsResult = await migrateCollection(game.items, migrateItem); + const actorsResult = await migrateCollection(game.actors, migrateActor); + const scenesResult = await migrateCollection(game.scenes, migrateScene); + const compendiumsResult = await migrateCompendiums(migrateCompendium); + return itemsResult === "error" || + actorsResult === "error" || + scenesResult === "error" || + compendiumsResult === "error" + ? "error" + : "success"; } /** @type {import('./migrationHelpers.js').Migrator} */ diff --git a/src/migration/008.js b/src/migration/008.js index e517c429..46a543a3 100644 --- a/src/migration/008.js +++ b/src/migration/008.js @@ -13,10 +13,16 @@ import { /** @type {import("./migration.js").Migration["migrate"]} */ async function migrate() { - await migrateCollection(game.items, migrateItem); - await migrateCollection(game.actors, migrateActor); - await migrateCollection(game.scenes, migrateScene); - await migrateCompendiums(migrateCompendium); + const itemsResult = await migrateCollection(game.items, migrateItem); + const actorsResult = await migrateCollection(game.actors, migrateActor); + const scenesResult = await migrateCollection(game.scenes, migrateScene); + const compendiumsResult = await migrateCompendiums(migrateCompendium); + return itemsResult === "error" || + actorsResult === "error" || + scenesResult === "error" || + compendiumsResult === "error" + ? "error" + : "success"; } /** @type {import('./migrationHelpers.js').Migrator} */ diff --git a/src/migration/009.js b/src/migration/009.js index ee3f6083..4a4b85f9 100644 --- a/src/migration/009.js +++ b/src/migration/009.js @@ -12,9 +12,10 @@ import { /** @type {import("./migration.js").Migration["migrate"]} */ async function migrate() { - await migrateCollection(game.actors, migrateActor); - await migrateCollection(game.scenes, migrateScene); - await migrateCompendiums(migrateCompendium); + const actorsResult = await migrateCollection(game.actors, migrateActor); + const scenesResult = await migrateCollection(game.scenes, migrateScene); + const compendiumsResult = await migrateCompendiums(migrateCompendium); + return actorsResult === "error" || scenesResult === "error" || compendiumsResult === "error" ? "error" : "success"; } const itemIdRegex = /Item\.([a-zA-Z0-9]+)/; diff --git a/src/migration/migration.js b/src/migration/migration.js index 4fadaaf6..026d4f26 100644 --- a/src/migration/migration.js +++ b/src/migration/migration.js @@ -58,12 +58,17 @@ async function migrateFromTo(oldMigrationVersion, targetMigrationVersion) { { permanent: true }, ); + /** @type {Result} */ + let result = "success"; for (const [i, { migrate }] of migrationsToExecute.entries()) { const currentMigrationVersion = oldMigrationVersion + i + 1; logger.info("executing migration script", currentMigrationVersion); try { - await migrate(); + const r = await migrate(); getGame().settings.set("ds4", "systemMigrationVersion", currentMigrationVersion); + if (r === "error") { + result = "error"; + } } catch (err) { notifications.error( getGame().i18n.format("DS4.ErrorDuringMigration", { @@ -78,13 +83,23 @@ async function migrateFromTo(oldMigrationVersion, targetMigrationVersion) { } } - notifications.info( - getGame().i18n.format("DS4.InfoSystemUpdateCompleted", { - currentVersion: oldMigrationVersion, - targetVersion: targetMigrationVersion, - }), - { permanent: true }, - ); + if (result === "success") { + notifications.info( + getGame().i18n.format("DS4.InfoSystemUpdateCompletedSuccessfully", { + currentVersion: oldMigrationVersion, + targetVersion: targetMigrationVersion, + }), + { permanent: true }, + ); + } else { + notifications.warn( + getGame().i18n.format("DS4.WarningSystemUpdateCompletedWithErrors", { + currentVersion: oldMigrationVersion, + targetVersion: targetMigrationVersion, + }), + { permanent: true }, + ); + } } } @@ -159,9 +174,11 @@ function getTargetMigrationVersion() { return migrations.length; } +/** @typedef {"success" | "error"} Result */ + /** * @typedef {object} Migration - * @property {() => Promise} migrate + * @property {() => Promise} migrate * @property {import("./migrationHelpers").CompendiumMigrator} migrateCompendium */ diff --git a/src/migration/migrationHelpers.js b/src/migration/migrationHelpers.js index 9b6b036a..0b169e77 100644 --- a/src/migration/migrationHelpers.js +++ b/src/migration/migrationHelpers.js @@ -17,9 +17,11 @@ import { getGame } from "../utils/utils.js"; * @template T * @param {WorldCollection} collection * @param {Migrator} migrateDocument - * @returns {Promise} A promise that resolves once the migration is complete + * @returns {Promise} A promise that resolves once the migration is complete */ export async function migrateCollection(collection, migrateDocument) { + /** @type {import("./migration.js").Result} */ + let result = "success"; const { documentName } = collection.constructor; for (const document of collection) { logger.info(`Migrating ${documentName} document ${document.name} (${document.id})`); @@ -30,8 +32,10 @@ export async function migrateCollection(collection, migrateDocument) { `Error during migration of ${documentName} document ${document.name} (${document.id}), continuing anyways.`, err, ); + result = "error"; } } + return result; } /** @@ -93,19 +97,25 @@ export function getSceneMigrator(migrateActor) { }; } -/** @typedef {(pack: CompendiumCollection) => Promise} CompendiumMigrator */ +/** @typedef {(pack: CompendiumCollection) => Promise} CompendiumMigrator */ /** * Migrate world compendium packs. * @param {CompendiumMigrator} migrateCompendium A function for migrating a single compendium pack - * @returns {Promise} A promise that resolves once the migration is complete + * @returns {Promise} A promise that resolves once the migration is complete */ export async function migrateCompendiums(migrateCompendium) { + /** @type {import("./migration.js").Result} */ + let result = "success"; for (const compendium of getGame().packs ?? []) { if (compendium.metadata.package !== "world") continue; if (!["Actor", "Item", "Scene"].includes(compendium.metadata.type)) continue; - await migrateCompendium(compendium); + const r = await migrateCompendium(compendium); + if (r === "error") { + result = "error"; + } } + return result; } /** @@ -126,6 +136,8 @@ export function getCompendiumMigrator( { migrateToTemplateEarly = true } = {}, ) { return async (pack) => { + /** @type {import("./migration.js").Result} */ + let result = "success"; const type = pack.metadata.type; if (!["Actor", "Item", "Scene"].includes(type)) return; const wasLocked = pack.locked; @@ -151,6 +163,7 @@ export function getCompendiumMigrator( `Error during migration of document ${doc.name} (${doc.id}) in compendium ${pack.collection}, continuing anyways.`, err, ); + result = "error"; } } @@ -158,5 +171,6 @@ export function getCompendiumMigrator( await pack.migrate(); } await pack.configure({ locked: wasLocked }); + return result; }; }