From 1e0c4caeccc2ab104ffb0ccc0f20237a07721fa2 Mon Sep 17 00:00:00 2001 From: filoghost Date: Thu, 23 Jul 2020 16:57:51 +0200 Subject: [PATCH] Improve automatic configuration upgrades --- .../chestcommands/ChestCommands.java | 8 +- .../chestcommands/legacy/Backup.java | 36 +++++ .../chestcommands/legacy/Upgrade.java | 111 ++++++++++++++++ .../legacy/UpgradesDoneRegistry.java | 26 +--- .../legacy/UpgradesExecutor.java | 123 ++++++------------ ...{LangUpgrade.java => LangUpgradeTask.java} | 4 +- ...de.java => MenuNodeExpandUpgradeTask.java} | 16 +-- ...de.java => MenuNodeRenameUpgradeTask.java} | 4 +- ....java => PlaceholdersYamlUpgradeTask.java} | 10 +- ...egexUpgrade.java => RegexUpgradeTask.java} | 10 +- ...sUpgrade.java => SettingsUpgradeTask.java} | 10 +- .../{Upgrade.java => UpgradeTask.java} | 42 +++--- ...ception.java => UpgradeTaskException.java} | 4 +- .../chestcommands/logging/ErrorMessages.java | 17 +-- .../logging/PrintableErrorCollector.java | 4 +- 15 files changed, 250 insertions(+), 175 deletions(-) create mode 100644 Plugin/src/main/java/me/filoghost/chestcommands/legacy/Backup.java create mode 100644 Plugin/src/main/java/me/filoghost/chestcommands/legacy/Upgrade.java rename Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/{LangUpgrade.java => LangUpgradeTask.java} (89%) rename Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/{MenuNodeExpandUpgrade.java => MenuNodeExpandUpgradeTask.java} (92%) rename Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/{MenuNodeRenameUpgrade.java => MenuNodeRenameUpgradeTask.java} (93%) rename Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/{PlaceholdersYamlUpgrade.java => PlaceholdersYamlUpgradeTask.java} (92%) rename Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/{RegexUpgrade.java => RegexUpgradeTask.java} (91%) rename Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/{SettingsUpgrade.java => SettingsUpgradeTask.java} (88%) rename Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/{Upgrade.java => UpgradeTask.java} (58%) rename Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/{UpgradeException.java => UpgradeTaskException.java} (86%) diff --git a/Plugin/src/main/java/me/filoghost/chestcommands/ChestCommands.java b/Plugin/src/main/java/me/filoghost/chestcommands/ChestCommands.java index 810230a..8bb2209 100644 --- a/Plugin/src/main/java/me/filoghost/chestcommands/ChestCommands.java +++ b/Plugin/src/main/java/me/filoghost/chestcommands/ChestCommands.java @@ -166,10 +166,16 @@ public class ChestCommands extends BaseJavaPlugin { return errorCollector; } + UpgradesExecutor upgradeExecutor = new UpgradesExecutor(configManager); + try { - new UpgradesExecutor(configManager).run(isFreshInstall, errorCollector); + boolean allUpgradesSuccessful = upgradeExecutor.run(isFreshInstall, errorCollector); + if (!allUpgradesSuccessful) { + errorCollector.add(ErrorMessages.Upgrade.failedSomeUpgrades); + } } catch (UpgradeExecutorException e) { errorCollector.add(ErrorMessages.Upgrade.genericExecutorError, e); + errorCollector.add(ErrorMessages.Upgrade.failedSomeUpgrades); } settings = configManager.tryLoadSettings(errorCollector); diff --git a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/Backup.java b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/Backup.java new file mode 100644 index 0000000..ac953a2 --- /dev/null +++ b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/Backup.java @@ -0,0 +1,36 @@ +package me.filoghost.chestcommands.legacy; + +import me.filoghost.chestcommands.util.Preconditions; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class Backup { + + private final Path dataFolder; + private final Path backupFolder; + + public Backup(Path dataFolder, String backupName) { + this.dataFolder = dataFolder; + this.backupFolder = dataFolder.resolve("backups").resolve(backupName); + } + + public static Backup newTimestampedBackup(Path dataFolder) { + String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy.MM.dd-HH.mm")); + String backupName = "backup_" + date; + return new Backup(dataFolder, backupName); + } + + public void backupFile(Path fileToBackup) throws IOException { + Preconditions.checkArgument(fileToBackup.startsWith(dataFolder), "file is not inside data folder"); + Path destination = backupFolder.resolve(dataFolder.relativize(fileToBackup)); + Files.createDirectories(destination.getParent()); + if (!Files.isRegularFile(destination)) { + Files.copy(fileToBackup, destination); + } + } + +} diff --git a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/Upgrade.java b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/Upgrade.java new file mode 100644 index 0000000..b6ce2d4 --- /dev/null +++ b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/Upgrade.java @@ -0,0 +1,111 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package me.filoghost.chestcommands.legacy; + +import me.filoghost.chestcommands.config.ConfigManager; +import me.filoghost.chestcommands.config.framework.ConfigLoader; +import me.filoghost.chestcommands.legacy.upgrade.LangUpgradeTask; +import me.filoghost.chestcommands.legacy.upgrade.MenuNodeExpandUpgradeTask; +import me.filoghost.chestcommands.legacy.upgrade.MenuNodeRenameUpgradeTask; +import me.filoghost.chestcommands.legacy.upgrade.PlaceholdersYamlUpgradeTask; +import me.filoghost.chestcommands.legacy.upgrade.SettingsUpgradeTask; +import me.filoghost.chestcommands.legacy.upgrade.UpgradeTask; +import me.filoghost.chestcommands.legacy.upgrade.UpgradeTaskException; +import me.filoghost.chestcommands.logging.ErrorMessages; +import me.filoghost.chestcommands.util.collection.CollectionUtils; +import me.filoghost.chestcommands.util.logging.Log; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Collections; +import java.util.List; + +public enum Upgrade { + + V4_MENUS_RENAME("v4.0-menus-rename", (configManager) -> { + List menuFiles = getMenuFiles(configManager); + + return CollectionUtils.transform(menuFiles, + MenuNodeRenameUpgradeTask::new); + }), + + V4_MENUS_REFORMAT("v4.0-menus-reformat", (configManager) -> { + String legacyCommandSeparator = readLegacyCommandSeparator(configManager); + List menuFiles = getMenuFiles(configManager); + + return CollectionUtils.transform(menuFiles, + file -> new MenuNodeExpandUpgradeTask(configManager, file, legacyCommandSeparator)); + }), + + V4_CONFIG("v4.0-config", (configManager) -> { + return Collections.singletonList(new SettingsUpgradeTask(configManager)); + }), + + V4_PLACEHOLDERS("v4.0-placeholders", (configManager) -> { + return Collections.singletonList(new PlaceholdersYamlUpgradeTask(configManager)); + }), + + V4_LANG("v4.0-lang", (configManager) -> { + return Collections.singletonList(new LangUpgradeTask(configManager)); + }); + + + private final String id; + private final UpgradeTasksSupplier upgradeTasksSupplier; + + Upgrade(String id, UpgradeTasksSupplier upgradeTasksSupplier) { + this.id = id; + this.upgradeTasksSupplier = upgradeTasksSupplier; + } + + public String getID() { + return id; + } + + public List createUpgradeTasks(ConfigManager configManager) throws UpgradeTaskException { + return upgradeTasksSupplier.getTasks(configManager); + } + + private static List getMenuFiles(ConfigManager configManager) throws UpgradeTaskException { + try { + return configManager.getMenuPaths(); + } catch (IOException e) { + throw new UpgradeTaskException(ErrorMessages.Upgrade.menuListIOException, e); + } + } + + private static String readLegacyCommandSeparator(ConfigManager configManager) { + ConfigLoader settingsConfigLoader = configManager.getConfigLoader("config.yml"); + + if (!settingsConfigLoader.fileExists()) { + return null; + } + + try { + return settingsConfigLoader.load().getString("multiple-commands-separator"); + } catch (Throwable t) { + Log.warning("Failed to load \"" + settingsConfigLoader.getFile() + "\", assuming default command separator \";\"."); + return null; + } + } + + @FunctionalInterface + interface UpgradeTasksSupplier { + + List getTasks(ConfigManager configManager) throws UpgradeTaskException; + + } + +} diff --git a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/UpgradesDoneRegistry.java b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/UpgradesDoneRegistry.java index 3005969..7e76bde 100644 --- a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/UpgradesDoneRegistry.java +++ b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/UpgradesDoneRegistry.java @@ -42,19 +42,19 @@ public class UpgradesDoneRegistry { } public void setAllDone() { - for (UpgradeID upgrade : UpgradeID.values()) { + for (Upgrade upgrade : Upgrade.values()) { setDone(upgrade); } } - public void setDone(UpgradeID upgrade) { - if (upgradesDone.add(upgrade.stringID)) { + public void setDone(Upgrade upgrade) { + if (upgradesDone.add(upgrade.getID())) { needSave = true; } } - public boolean isDone(UpgradeID upgrade) { - return upgradesDone.contains(upgrade.stringID); + public boolean isDone(Upgrade upgrade) { + return upgradesDone.contains(upgrade.getID()); } public void save() throws IOException { @@ -70,20 +70,4 @@ public class UpgradesDoneRegistry { } } - - public enum UpgradeID { - - V4_MENU_REPLACE("v4.0-menus-rename"), - V4_MENUS_REFORMAT("v4.0-menus-reformat"), - V4_CONFIG("v4.0-config"), - V4_PLACEHOLDERS("v4.0-placeholders"), - V4_LANG("v4.0-lang"); - - private final String stringID; - - UpgradeID(String stringID) { - this.stringID = stringID; - } - } - } diff --git a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/UpgradesExecutor.java b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/UpgradesExecutor.java index 6d5a90f..b2f4207 100644 --- a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/UpgradesExecutor.java +++ b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/UpgradesExecutor.java @@ -15,40 +15,28 @@ package me.filoghost.chestcommands.legacy; import me.filoghost.chestcommands.config.ConfigManager; -import me.filoghost.chestcommands.config.framework.ConfigLoader; -import me.filoghost.chestcommands.legacy.UpgradesDoneRegistry.UpgradeID; -import me.filoghost.chestcommands.legacy.upgrade.LangUpgrade; -import me.filoghost.chestcommands.legacy.upgrade.MenuNodeExpandUpgrade; -import me.filoghost.chestcommands.legacy.upgrade.MenuNodeRenameUpgrade; -import me.filoghost.chestcommands.legacy.upgrade.PlaceholdersYamlUpgrade; -import me.filoghost.chestcommands.legacy.upgrade.SettingsUpgrade; -import me.filoghost.chestcommands.legacy.upgrade.Upgrade; -import me.filoghost.chestcommands.legacy.upgrade.UpgradeException; +import me.filoghost.chestcommands.legacy.upgrade.UpgradeTask; +import me.filoghost.chestcommands.legacy.upgrade.UpgradeTaskException; import me.filoghost.chestcommands.logging.ErrorMessages; -import me.filoghost.chestcommands.util.collection.CollectionUtils; import me.filoghost.chestcommands.util.logging.ErrorCollector; import me.filoghost.chestcommands.util.logging.Log; import java.io.IOException; import java.nio.file.Path; -import java.util.Collections; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import java.util.function.Supplier; public class UpgradesExecutor { private final ConfigManager configManager; - private Set failedUpgrades; + private boolean allUpgradesSuccessful; private UpgradesDoneRegistry upgradesDoneRegistry; public UpgradesExecutor(ConfigManager configManager) { this.configManager = configManager; } - public void run(boolean isFreshInstall, ErrorCollector errorCollector) throws UpgradeExecutorException { - this.failedUpgrades = new HashSet<>(); + public boolean run(boolean isFreshInstall, ErrorCollector errorCollector) throws UpgradeExecutorException { + this.allUpgradesSuccessful = true; Path upgradesDoneFile = configManager.getRootDataFolder().resolve(".upgrades-done"); try { @@ -61,99 +49,64 @@ public class UpgradesExecutor { if (isFreshInstall) { // Mark all currently existing upgrades as already done, assuming default configuration files are up to date upgradesDoneRegistry.setAllDone(); - } else { - String legacyCommandSeparator; - if (!upgradesDoneRegistry.isDone(UpgradeID.V4_MENUS_REFORMAT)) { - legacyCommandSeparator = readLegacyCommandSeparator(); - } else { - legacyCommandSeparator = null; - } - - runIfNecessary(UpgradeID.V4_CONFIG, () -> new SettingsUpgrade(configManager), errorCollector); - runIfNecessary(UpgradeID.V4_PLACEHOLDERS, () -> new PlaceholdersYamlUpgrade(configManager), errorCollector); - runIfNecessary(UpgradeID.V4_LANG, () -> new LangUpgrade(configManager), errorCollector); - - try { - List menuFiles = configManager.getMenuPaths(); - - runIfNecessaryMultiple(UpgradeID.V4_MENU_REPLACE, () -> { - return CollectionUtils.transform(menuFiles, - MenuNodeRenameUpgrade::new); - }, errorCollector); - - runIfNecessaryMultiple(UpgradeID.V4_MENUS_REFORMAT, () -> { - return CollectionUtils.transform(menuFiles, - file -> new MenuNodeExpandUpgrade(configManager, file, legacyCommandSeparator)); - }, errorCollector); - - } catch (IOException e) { - errorCollector.add(ErrorMessages.Upgrade.menuListIOException, e); - failedUpgrades.add(configManager.getMenusFolder()); - } + // Run missing upgrades + Backup backup = Backup.newTimestampedBackup(configManager.getRootDataFolder()); + runMissingUpgrades(backup, errorCollector); } try { upgradesDoneRegistry.save(); } catch (IOException e) { - // Upgrades can't proceed if metadata file is not read correctly + // Upgrades can't proceed if metadata file is not saved correctly throw new UpgradeExecutorException(ErrorMessages.Upgrade.metadataSaveError(upgradesDoneFile), e); } - // Success only if no upgrade failed - if (!failedUpgrades.isEmpty()) { - throw new UpgradeExecutorException(ErrorMessages.Upgrade.failedUpgradesList(failedUpgrades)); + return allUpgradesSuccessful; + } + + + private void runMissingUpgrades(Backup backup, ErrorCollector errorCollector) { + for (Upgrade upgrade : Upgrade.values()) { + if (!upgradesDoneRegistry.isDone(upgrade)) { + boolean allTasksSuccessful = tryRunUpgradeTasks(upgrade, backup, errorCollector); + + // Consider an upgrade "done" if all its tasks were completed successfully + if (allTasksSuccessful) { + upgradesDoneRegistry.setDone(upgrade); + } else { + allUpgradesSuccessful = false; + } + } } } - private String readLegacyCommandSeparator() { - ConfigLoader settingsConfigLoader = configManager.getConfigLoader("config.yml"); - if (!settingsConfigLoader.fileExists()) { - return null; - } + private boolean tryRunUpgradeTasks(Upgrade upgrade, Backup backup, ErrorCollector errorCollector) { + boolean allTasksSuccessful = true; + List upgradeTasks; try { - return settingsConfigLoader.load().getString("multiple-commands-separator"); - } catch (Throwable t) { - Log.warning("Failed to load \"" + settingsConfigLoader.getFile() + "\", assuming default command separator \";\"."); - return null; - } - } - - - private void runIfNecessary(UpgradeID upgradeID, Supplier upgradeTask, ErrorCollector errorCollector) { - runIfNecessaryMultiple(upgradeID, () -> Collections.singletonList(upgradeTask.get()), errorCollector); - } - - - private void runIfNecessaryMultiple(UpgradeID upgradeID, Supplier> upgradeTasks, ErrorCollector errorCollector) { - if (upgradesDoneRegistry.isDone(upgradeID)) { - return; + upgradeTasks = upgrade.createUpgradeTasks(configManager); + } catch (UpgradeTaskException e) { + errorCollector.add(ErrorMessages.Upgrade.failedToPrepareUpgradeTasks, e); + return false; } - boolean failedAnyUpgrade = false; - - for (Upgrade upgradeTask : upgradeTasks.get()) { + for (UpgradeTask upgradeTask : upgradeTasks) { try { - boolean modified = upgradeTask.backupAndUpgradeIfNecessary(); + boolean modified = upgradeTask.runAndBackupIfNecessary(backup); if (modified) { - Log.info( - "Automatically upgraded configuration file \"" - + upgradeTask.getUpgradedFile() + "\" with newer configuration nodes. " + Log.info("Automatically upgraded configuration file \"" + upgradeTask.getUpgradedFile() + "\". " + "A backup of the old file has been saved."); } - } catch (UpgradeException e) { - failedAnyUpgrade = true; - failedUpgrades.add(upgradeTask.getOriginalFile()); + } catch (UpgradeTaskException e) { + allTasksSuccessful = false; errorCollector.add(ErrorMessages.Upgrade.failedSingleUpgrade(upgradeTask.getOriginalFile()), e); } } - // Upgrade ID is considered complete only if all relative upgrades tasks are successful - if (!failedAnyUpgrade) { - upgradesDoneRegistry.setDone(upgradeID); - } + return allTasksSuccessful; } } diff --git a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/LangUpgrade.java b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/LangUpgradeTask.java similarity index 89% rename from Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/LangUpgrade.java rename to Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/LangUpgradeTask.java index 22c67f7..9df8f7a 100644 --- a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/LangUpgrade.java +++ b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/LangUpgradeTask.java @@ -18,9 +18,9 @@ import me.filoghost.chestcommands.config.ConfigManager; import java.util.regex.Pattern; -public class LangUpgrade extends RegexUpgrade { +public class LangUpgradeTask extends RegexUpgradeTask { - public LangUpgrade(ConfigManager configManager) { + public LangUpgradeTask(ConfigManager configManager) { super(configManager.getRootDataFolder().resolve("lang.yml")); addRegexReplacer(Pattern.compile(Pattern.quote("{datavalue}")), matcher -> "{durability}"); diff --git a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/MenuNodeExpandUpgrade.java b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/MenuNodeExpandUpgradeTask.java similarity index 92% rename from Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/MenuNodeExpandUpgrade.java rename to Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/MenuNodeExpandUpgradeTask.java index c2d5cec..e311f76 100644 --- a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/MenuNodeExpandUpgrade.java +++ b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/MenuNodeExpandUpgradeTask.java @@ -30,13 +30,13 @@ import java.util.Collections; import java.util.List; import java.util.regex.Pattern; -public class MenuNodeExpandUpgrade extends Upgrade { +public class MenuNodeExpandUpgradeTask extends UpgradeTask { private final ConfigLoader menuConfigLoader; private final String legacyCommandSeparator; private Config updatedConfig; - public MenuNodeExpandUpgrade(ConfigManager configManager, Path menuFile, String legacyCommandSeparator) { + public MenuNodeExpandUpgradeTask(ConfigManager configManager, Path menuFile, String legacyCommandSeparator) { this.menuConfigLoader = configManager.getConfigLoader(menuFile); this.legacyCommandSeparator = legacyCommandSeparator; } @@ -52,7 +52,7 @@ public class MenuNodeExpandUpgrade extends Upgrade { } @Override - protected void computeChanges() throws ConfigLoadException { + public void computeChanges() throws ConfigLoadException { Config menuConfig = menuConfigLoader.load(); menuConfig.setHeader(null); @@ -74,7 +74,7 @@ public class MenuNodeExpandUpgrade extends Upgrade { } @Override - protected void saveChanges() throws ConfigSaveException { + public void saveChanges() throws ConfigSaveException { menuConfigLoader.save(updatedConfig); } @@ -110,7 +110,7 @@ public class MenuNodeExpandUpgrade extends Upgrade { } material = parts[0]; section.set(IconSettingsNode.MATERIAL, material); - setModified(); + setSaveRequired(); } if (material.contains(":")) { @@ -124,7 +124,7 @@ public class MenuNodeExpandUpgrade extends Upgrade { } material = parts[0]; section.set(IconSettingsNode.MATERIAL, material); - setModified(); + setSaveRequired(); } } @@ -132,7 +132,7 @@ public class MenuNodeExpandUpgrade extends Upgrade { if (config.isSet(node)) { if (config.isString(node)) { config.set(node, getSeparatedValues(config.getString(node), separator)); - setModified(); + setSaveRequired(); } } } @@ -140,7 +140,7 @@ public class MenuNodeExpandUpgrade extends Upgrade { private void expandSingletonList(ConfigSection config, String node) { if (config.isSet(node)) { config.set(node, Collections.singletonList(config.get(node))); - setModified(); + setSaveRequired(); } } diff --git a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/MenuNodeRenameUpgrade.java b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/MenuNodeRenameUpgradeTask.java similarity index 93% rename from Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/MenuNodeRenameUpgrade.java rename to Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/MenuNodeRenameUpgradeTask.java index f1bb9cf..5cb85b6 100644 --- a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/MenuNodeRenameUpgrade.java +++ b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/MenuNodeRenameUpgradeTask.java @@ -19,9 +19,9 @@ import me.filoghost.chestcommands.parsing.icon.IconSettingsNode; import java.nio.file.Path; import java.util.regex.Pattern; -public class MenuNodeRenameUpgrade extends RegexUpgrade { +public class MenuNodeRenameUpgradeTask extends RegexUpgradeTask { - public MenuNodeRenameUpgrade(Path menuFile) { + public MenuNodeRenameUpgradeTask(Path menuFile) { super(menuFile); addSubNodeReplacer("command", "commands"); diff --git a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/PlaceholdersYamlUpgrade.java b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/PlaceholdersYamlUpgradeTask.java similarity index 92% rename from Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/PlaceholdersYamlUpgrade.java rename to Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/PlaceholdersYamlUpgradeTask.java index 4112d49..06dc4a0 100644 --- a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/PlaceholdersYamlUpgrade.java +++ b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/PlaceholdersYamlUpgradeTask.java @@ -28,13 +28,13 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.List; -public class PlaceholdersYamlUpgrade extends Upgrade { +public class PlaceholdersYamlUpgradeTask extends UpgradeTask { private final Path oldPlaceholdersFile; private final ConfigLoader newPlaceholdersConfigLoader; private Config updatedConfig; - public PlaceholdersYamlUpgrade(ConfigManager configManager) { + public PlaceholdersYamlUpgradeTask(ConfigManager configManager) { this.oldPlaceholdersFile = configManager.getRootDataFolder().resolve("placeholders.yml"); this.newPlaceholdersConfigLoader = configManager.getConfigLoader("custom-placeholders.yml"); } @@ -50,7 +50,7 @@ public class PlaceholdersYamlUpgrade extends Upgrade { } @Override - protected void computeChanges() throws ConfigLoadException { + public void computeChanges() throws ConfigLoadException { if (!Files.isRegularFile(oldPlaceholdersFile)) { return; } @@ -80,14 +80,14 @@ public class PlaceholdersYamlUpgrade extends Upgrade { String replacement = StringEscapeUtils.unescapeJava(unquote(parts[1])); newPlaceholdersConfig.set(placeholder, replacement); - setModified(); + setSaveRequired(); } this.updatedConfig = newPlaceholdersConfig; } @Override - protected void saveChanges() throws ConfigSaveException { + public void saveChanges() throws ConfigSaveException { try { Files.deleteIfExists(oldPlaceholdersFile); } catch (IOException ignored) {} diff --git a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/RegexUpgrade.java b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/RegexUpgradeTask.java similarity index 91% rename from Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/RegexUpgrade.java rename to Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/RegexUpgradeTask.java index 503d35b..2f4d8f9 100644 --- a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/RegexUpgrade.java +++ b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/RegexUpgradeTask.java @@ -30,13 +30,13 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -public class RegexUpgrade extends Upgrade { +public class RegexUpgradeTask extends UpgradeTask { private final Path file; private final List replacers; private List newContents; - public RegexUpgrade(Path file) { + public RegexUpgradeTask(Path file) { this.file = file; this.replacers = new ArrayList<>(); } @@ -56,7 +56,7 @@ public class RegexUpgrade extends Upgrade { } @Override - protected void computeChanges() throws ConfigLoadException { + public void computeChanges() throws ConfigLoadException { if (!Files.isRegularFile(file)) { return; } @@ -76,12 +76,12 @@ public class RegexUpgrade extends Upgrade { newContents = linesStream.collect(Collectors.toList()); if (!newContents.equals(lines)) { - setModified(); + setSaveRequired(); } } @Override - protected void saveChanges() throws ConfigSaveException { + public void saveChanges() throws ConfigSaveException { try { Files.write(file, newContents); } catch (IOException e) { diff --git a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/SettingsUpgrade.java b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/SettingsUpgradeTask.java similarity index 88% rename from Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/SettingsUpgrade.java rename to Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/SettingsUpgradeTask.java index dccbaf5..f26663d 100644 --- a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/SettingsUpgrade.java +++ b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/SettingsUpgradeTask.java @@ -22,12 +22,12 @@ import me.filoghost.chestcommands.config.framework.exception.ConfigSaveException import java.nio.file.Path; -public class SettingsUpgrade extends Upgrade { +public class SettingsUpgradeTask extends UpgradeTask { private final ConfigLoader settingsConfigLoader; private Config updatedConfig; - public SettingsUpgrade(ConfigManager configManager) { + public SettingsUpgradeTask(ConfigManager configManager) { this.settingsConfigLoader = configManager.getConfigLoader("config.yml"); } @@ -42,7 +42,7 @@ public class SettingsUpgrade extends Upgrade { } @Override - protected void computeChanges() throws ConfigLoadException { + public void computeChanges() throws ConfigLoadException { if (!settingsConfigLoader.fileExists()) { return; } @@ -58,13 +58,13 @@ public class SettingsUpgrade extends Upgrade { private void removeNode(Config config, String node) { if (config.isSet(node)) { config.set(node, null); - setModified(); + setSaveRequired(); } } @Override - protected void saveChanges() throws ConfigSaveException { + public void saveChanges() throws ConfigSaveException { settingsConfigLoader.save(updatedConfig); } } diff --git a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/Upgrade.java b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/UpgradeTask.java similarity index 58% rename from Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/Upgrade.java rename to Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/UpgradeTask.java index c9daefa..a6d9cbc 100644 --- a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/Upgrade.java +++ b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/UpgradeTask.java @@ -16,58 +16,50 @@ package me.filoghost.chestcommands.legacy.upgrade; import me.filoghost.chestcommands.config.framework.exception.ConfigLoadException; import me.filoghost.chestcommands.config.framework.exception.ConfigSaveException; +import me.filoghost.chestcommands.legacy.Backup; import me.filoghost.chestcommands.logging.ErrorMessages; import me.filoghost.chestcommands.util.Preconditions; import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -public abstract class Upgrade { +public abstract class UpgradeTask { - private boolean modified; + private boolean saveRequired; private boolean hasRun; - protected void setModified() { - this.modified = true; + protected void setSaveRequired() { + this.saveRequired = true; } - - public boolean backupAndUpgradeIfNecessary() throws UpgradeException { - Preconditions.checkState(!hasRun, "Upgrade can only be run once"); + public boolean runAndBackupIfNecessary(Backup backup) throws UpgradeTaskException { + Preconditions.checkState(!hasRun, "Upgrade task has already run"); hasRun = true; try { computeChanges(); } catch (ConfigLoadException e) { - throw new UpgradeException(ErrorMessages.Upgrade.loadError(getOriginalFile()), e); + throw new UpgradeTaskException(ErrorMessages.Upgrade.loadError(getOriginalFile()), e); } - if (modified) { + if (saveRequired) { try { - createBackupFile(getOriginalFile()); + backup.backupFile(getOriginalFile()); } catch (IOException e) { - throw new UpgradeException(ErrorMessages.Upgrade.backupError(getOriginalFile()), e); + throw new UpgradeTaskException(ErrorMessages.Upgrade.backupError(getOriginalFile()), e); } try { saveChanges(); } catch (ConfigSaveException e) { - throw new UpgradeException(ErrorMessages.Upgrade.saveError(getUpgradedFile()), e); + throw new UpgradeTaskException(ErrorMessages.Upgrade.saveError(getUpgradedFile()), e); } + + return true; + + } else { + return false; } - - return modified; - } - - private void createBackupFile(Path path) throws IOException { - String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy.MM.dd-HH.mm")); - String backupName = path.getFileName() + "_" + date + ".backup"; - - Files.copy(path, path.resolveSibling(backupName), StandardCopyOption.REPLACE_EXISTING); } public abstract Path getOriginalFile(); diff --git a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/UpgradeException.java b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/UpgradeTaskException.java similarity index 86% rename from Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/UpgradeException.java rename to Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/UpgradeTaskException.java index 3f1a77d..18db42a 100644 --- a/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/UpgradeException.java +++ b/Plugin/src/main/java/me/filoghost/chestcommands/legacy/upgrade/UpgradeTaskException.java @@ -14,9 +14,9 @@ */ package me.filoghost.chestcommands.legacy.upgrade; -public class UpgradeException extends Exception { +public class UpgradeTaskException extends Exception { - public UpgradeException(String message, Throwable cause) { + public UpgradeTaskException(String message, Throwable cause) { super(message, cause); } diff --git a/Plugin/src/main/java/me/filoghost/chestcommands/logging/ErrorMessages.java b/Plugin/src/main/java/me/filoghost/chestcommands/logging/ErrorMessages.java index 8ea48a9..c5c17ba 100644 --- a/Plugin/src/main/java/me/filoghost/chestcommands/logging/ErrorMessages.java +++ b/Plugin/src/main/java/me/filoghost/chestcommands/logging/ErrorMessages.java @@ -18,8 +18,6 @@ import me.filoghost.chestcommands.config.framework.mapped.MappedConfig; import me.filoghost.chestcommands.parsing.icon.IconSettings; import java.nio.file.Path; -import java.util.Set; -import java.util.stream.Collectors; public class ErrorMessages { @@ -72,9 +70,10 @@ public class ErrorMessages { public static class Upgrade { - public static final String genericExecutorError = "encountered errors while running run automatic configuration upgrades, " - + "some configuration files or menus may require manual updates."; - public static final String menuListIOException = "couldn't obtain a list of menu files, some automatic upgrades were skipped"; + public static final String genericExecutorError = "error while running automatic configuration upgrades"; + public static final String menuListIOException = "couldn't obtain a list of menu files"; + public static final String failedSomeUpgrades = "note: one or more automatic upgrades may have not been applied, configuration files or menus may require manual changes"; + public static final String failedToPrepareUpgradeTasks = "error while trying to prepare an automatic configuration upgrade"; public static String metadataReadError(Path metadataFile) { return "couldn't read upgrades metadata file \"" + formatPath(metadataFile) + "\""; @@ -88,13 +87,6 @@ public class ErrorMessages { return "error while trying to automatically upgrade \"" + formatPath(file) + "\""; } - public static String failedUpgradesList(Set failedUpgrades) { - String failedConversionFiles = failedUpgrades.stream() - .map(path -> "\"" + path + "\"") - .collect(Collectors.joining(", ")); - return "failed to automatically upgrade the following files: " + failedConversionFiles; - } - public static String loadError(Path file) { return "couldn't load file to upgrade \"" + formatPath(file) + "\""; } @@ -106,6 +98,7 @@ public class ErrorMessages { public static String saveError(Path file) { return "couldn't save upgraded file \"" + formatPath(file) + "\""; } + } diff --git a/Plugin/src/main/java/me/filoghost/chestcommands/logging/PrintableErrorCollector.java b/Plugin/src/main/java/me/filoghost/chestcommands/logging/PrintableErrorCollector.java index 443c5bf..f640d1c 100644 --- a/Plugin/src/main/java/me/filoghost/chestcommands/logging/PrintableErrorCollector.java +++ b/Plugin/src/main/java/me/filoghost/chestcommands/logging/PrintableErrorCollector.java @@ -18,7 +18,7 @@ import me.filoghost.chestcommands.ChestCommands; import me.filoghost.chestcommands.config.framework.exception.ConfigException; import me.filoghost.chestcommands.config.framework.exception.ConfigSyntaxException; import me.filoghost.chestcommands.legacy.UpgradeExecutorException; -import me.filoghost.chestcommands.legacy.upgrade.UpgradeException; +import me.filoghost.chestcommands.legacy.upgrade.UpgradeTaskException; import me.filoghost.chestcommands.parsing.ParseException; import me.filoghost.chestcommands.util.logging.ErrorCollector; import me.filoghost.chestcommands.util.logging.ErrorInfo; @@ -65,7 +65,7 @@ public class PrintableErrorCollector extends ErrorCollector { } else if (cause instanceof ConfigException || cause instanceof ParseException - || cause instanceof UpgradeException + || cause instanceof UpgradeTaskException || cause instanceof UpgradeExecutorException) { message.add(cause.getMessage()); cause = cause.getCause(); // Print the cause (or nothing if null), not our "known" exception