mirror of
https://github.com/filoghost/ChestCommands.git
synced 2025-02-21 14:01:21 +01:00
Improve automatic configuration upgrades
This commit is contained in:
parent
d13f3ec68f
commit
1e0c4caecc
@ -166,10 +166,16 @@ public class ChestCommands extends BaseJavaPlugin {
|
|||||||
return errorCollector;
|
return errorCollector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpgradesExecutor upgradeExecutor = new UpgradesExecutor(configManager);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new UpgradesExecutor(configManager).run(isFreshInstall, errorCollector);
|
boolean allUpgradesSuccessful = upgradeExecutor.run(isFreshInstall, errorCollector);
|
||||||
|
if (!allUpgradesSuccessful) {
|
||||||
|
errorCollector.add(ErrorMessages.Upgrade.failedSomeUpgrades);
|
||||||
|
}
|
||||||
} catch (UpgradeExecutorException e) {
|
} catch (UpgradeExecutorException e) {
|
||||||
errorCollector.add(ErrorMessages.Upgrade.genericExecutorError, e);
|
errorCollector.add(ErrorMessages.Upgrade.genericExecutorError, e);
|
||||||
|
errorCollector.add(ErrorMessages.Upgrade.failedSomeUpgrades);
|
||||||
}
|
}
|
||||||
|
|
||||||
settings = configManager.tryLoadSettings(errorCollector);
|
settings = configManager.tryLoadSettings(errorCollector);
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
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<Path> menuFiles = getMenuFiles(configManager);
|
||||||
|
|
||||||
|
return CollectionUtils.transform(menuFiles,
|
||||||
|
MenuNodeRenameUpgradeTask::new);
|
||||||
|
}),
|
||||||
|
|
||||||
|
V4_MENUS_REFORMAT("v4.0-menus-reformat", (configManager) -> {
|
||||||
|
String legacyCommandSeparator = readLegacyCommandSeparator(configManager);
|
||||||
|
List<Path> 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<UpgradeTask> createUpgradeTasks(ConfigManager configManager) throws UpgradeTaskException {
|
||||||
|
return upgradeTasksSupplier.getTasks(configManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Path> 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<UpgradeTask> getTasks(ConfigManager configManager) throws UpgradeTaskException;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -42,19 +42,19 @@ public class UpgradesDoneRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setAllDone() {
|
public void setAllDone() {
|
||||||
for (UpgradeID upgrade : UpgradeID.values()) {
|
for (Upgrade upgrade : Upgrade.values()) {
|
||||||
setDone(upgrade);
|
setDone(upgrade);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDone(UpgradeID upgrade) {
|
public void setDone(Upgrade upgrade) {
|
||||||
if (upgradesDone.add(upgrade.stringID)) {
|
if (upgradesDone.add(upgrade.getID())) {
|
||||||
needSave = true;
|
needSave = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDone(UpgradeID upgrade) {
|
public boolean isDone(Upgrade upgrade) {
|
||||||
return upgradesDone.contains(upgrade.stringID);
|
return upgradesDone.contains(upgrade.getID());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() throws IOException {
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,40 +15,28 @@
|
|||||||
package me.filoghost.chestcommands.legacy;
|
package me.filoghost.chestcommands.legacy;
|
||||||
|
|
||||||
import me.filoghost.chestcommands.config.ConfigManager;
|
import me.filoghost.chestcommands.config.ConfigManager;
|
||||||
import me.filoghost.chestcommands.config.framework.ConfigLoader;
|
import me.filoghost.chestcommands.legacy.upgrade.UpgradeTask;
|
||||||
import me.filoghost.chestcommands.legacy.UpgradesDoneRegistry.UpgradeID;
|
import me.filoghost.chestcommands.legacy.upgrade.UpgradeTaskException;
|
||||||
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.logging.ErrorMessages;
|
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.ErrorCollector;
|
||||||
import me.filoghost.chestcommands.util.logging.Log;
|
import me.filoghost.chestcommands.util.logging.Log;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public class UpgradesExecutor {
|
public class UpgradesExecutor {
|
||||||
|
|
||||||
private final ConfigManager configManager;
|
private final ConfigManager configManager;
|
||||||
private Set<Path> failedUpgrades;
|
private boolean allUpgradesSuccessful;
|
||||||
private UpgradesDoneRegistry upgradesDoneRegistry;
|
private UpgradesDoneRegistry upgradesDoneRegistry;
|
||||||
|
|
||||||
public UpgradesExecutor(ConfigManager configManager) {
|
public UpgradesExecutor(ConfigManager configManager) {
|
||||||
this.configManager = configManager;
|
this.configManager = configManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run(boolean isFreshInstall, ErrorCollector errorCollector) throws UpgradeExecutorException {
|
public boolean run(boolean isFreshInstall, ErrorCollector errorCollector) throws UpgradeExecutorException {
|
||||||
this.failedUpgrades = new HashSet<>();
|
this.allUpgradesSuccessful = true;
|
||||||
Path upgradesDoneFile = configManager.getRootDataFolder().resolve(".upgrades-done");
|
Path upgradesDoneFile = configManager.getRootDataFolder().resolve(".upgrades-done");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -61,99 +49,64 @@ public class UpgradesExecutor {
|
|||||||
if (isFreshInstall) {
|
if (isFreshInstall) {
|
||||||
// Mark all currently existing upgrades as already done, assuming default configuration files are up to date
|
// Mark all currently existing upgrades as already done, assuming default configuration files are up to date
|
||||||
upgradesDoneRegistry.setAllDone();
|
upgradesDoneRegistry.setAllDone();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
String legacyCommandSeparator;
|
// Run missing upgrades
|
||||||
if (!upgradesDoneRegistry.isDone(UpgradeID.V4_MENUS_REFORMAT)) {
|
Backup backup = Backup.newTimestampedBackup(configManager.getRootDataFolder());
|
||||||
legacyCommandSeparator = readLegacyCommandSeparator();
|
runMissingUpgrades(backup, errorCollector);
|
||||||
} 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<Path> 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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
upgradesDoneRegistry.save();
|
upgradesDoneRegistry.save();
|
||||||
} catch (IOException e) {
|
} 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);
|
throw new UpgradeExecutorException(ErrorMessages.Upgrade.metadataSaveError(upgradesDoneFile), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Success only if no upgrade failed
|
return allUpgradesSuccessful;
|
||||||
if (!failedUpgrades.isEmpty()) {
|
}
|
||||||
throw new UpgradeExecutorException(ErrorMessages.Upgrade.failedUpgradesList(failedUpgrades));
|
|
||||||
|
|
||||||
|
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()) {
|
private boolean tryRunUpgradeTasks(Upgrade upgrade, Backup backup, ErrorCollector errorCollector) {
|
||||||
return null;
|
boolean allTasksSuccessful = true;
|
||||||
}
|
|
||||||
|
|
||||||
|
List<UpgradeTask> upgradeTasks;
|
||||||
try {
|
try {
|
||||||
return settingsConfigLoader.load().getString("multiple-commands-separator");
|
upgradeTasks = upgrade.createUpgradeTasks(configManager);
|
||||||
} catch (Throwable t) {
|
} catch (UpgradeTaskException e) {
|
||||||
Log.warning("Failed to load \"" + settingsConfigLoader.getFile() + "\", assuming default command separator \";\".");
|
errorCollector.add(ErrorMessages.Upgrade.failedToPrepareUpgradeTasks, e);
|
||||||
return null;
|
return false;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void runIfNecessary(UpgradeID upgradeID, Supplier<Upgrade> upgradeTask, ErrorCollector errorCollector) {
|
|
||||||
runIfNecessaryMultiple(upgradeID, () -> Collections.singletonList(upgradeTask.get()), errorCollector);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void runIfNecessaryMultiple(UpgradeID upgradeID, Supplier<List<? extends Upgrade>> upgradeTasks, ErrorCollector errorCollector) {
|
|
||||||
if (upgradesDoneRegistry.isDone(upgradeID)) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean failedAnyUpgrade = false;
|
for (UpgradeTask upgradeTask : upgradeTasks) {
|
||||||
|
|
||||||
for (Upgrade upgradeTask : upgradeTasks.get()) {
|
|
||||||
try {
|
try {
|
||||||
boolean modified = upgradeTask.backupAndUpgradeIfNecessary();
|
boolean modified = upgradeTask.runAndBackupIfNecessary(backup);
|
||||||
if (modified) {
|
if (modified) {
|
||||||
Log.info(
|
Log.info("Automatically upgraded configuration file \"" + upgradeTask.getUpgradedFile() + "\". "
|
||||||
"Automatically upgraded configuration file \""
|
|
||||||
+ upgradeTask.getUpgradedFile() + "\" with newer configuration nodes. "
|
|
||||||
+ "A backup of the old file has been saved.");
|
+ "A backup of the old file has been saved.");
|
||||||
}
|
}
|
||||||
} catch (UpgradeException e) {
|
} catch (UpgradeTaskException e) {
|
||||||
failedAnyUpgrade = true;
|
allTasksSuccessful = false;
|
||||||
failedUpgrades.add(upgradeTask.getOriginalFile());
|
|
||||||
errorCollector.add(ErrorMessages.Upgrade.failedSingleUpgrade(upgradeTask.getOriginalFile()), e);
|
errorCollector.add(ErrorMessages.Upgrade.failedSingleUpgrade(upgradeTask.getOriginalFile()), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upgrade ID is considered complete only if all relative upgrades tasks are successful
|
return allTasksSuccessful;
|
||||||
if (!failedAnyUpgrade) {
|
|
||||||
upgradesDoneRegistry.setDone(upgradeID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,9 @@ import me.filoghost.chestcommands.config.ConfigManager;
|
|||||||
|
|
||||||
import java.util.regex.Pattern;
|
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"));
|
super(configManager.getRootDataFolder().resolve("lang.yml"));
|
||||||
|
|
||||||
addRegexReplacer(Pattern.compile(Pattern.quote("{datavalue}")), matcher -> "{durability}");
|
addRegexReplacer(Pattern.compile(Pattern.quote("{datavalue}")), matcher -> "{durability}");
|
@ -30,13 +30,13 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class MenuNodeExpandUpgrade extends Upgrade {
|
public class MenuNodeExpandUpgradeTask extends UpgradeTask {
|
||||||
|
|
||||||
private final ConfigLoader menuConfigLoader;
|
private final ConfigLoader menuConfigLoader;
|
||||||
private final String legacyCommandSeparator;
|
private final String legacyCommandSeparator;
|
||||||
private Config updatedConfig;
|
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.menuConfigLoader = configManager.getConfigLoader(menuFile);
|
||||||
this.legacyCommandSeparator = legacyCommandSeparator;
|
this.legacyCommandSeparator = legacyCommandSeparator;
|
||||||
}
|
}
|
||||||
@ -52,7 +52,7 @@ public class MenuNodeExpandUpgrade extends Upgrade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void computeChanges() throws ConfigLoadException {
|
public void computeChanges() throws ConfigLoadException {
|
||||||
Config menuConfig = menuConfigLoader.load();
|
Config menuConfig = menuConfigLoader.load();
|
||||||
menuConfig.setHeader(null);
|
menuConfig.setHeader(null);
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ public class MenuNodeExpandUpgrade extends Upgrade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void saveChanges() throws ConfigSaveException {
|
public void saveChanges() throws ConfigSaveException {
|
||||||
menuConfigLoader.save(updatedConfig);
|
menuConfigLoader.save(updatedConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ public class MenuNodeExpandUpgrade extends Upgrade {
|
|||||||
}
|
}
|
||||||
material = parts[0];
|
material = parts[0];
|
||||||
section.set(IconSettingsNode.MATERIAL, material);
|
section.set(IconSettingsNode.MATERIAL, material);
|
||||||
setModified();
|
setSaveRequired();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (material.contains(":")) {
|
if (material.contains(":")) {
|
||||||
@ -124,7 +124,7 @@ public class MenuNodeExpandUpgrade extends Upgrade {
|
|||||||
}
|
}
|
||||||
material = parts[0];
|
material = parts[0];
|
||||||
section.set(IconSettingsNode.MATERIAL, material);
|
section.set(IconSettingsNode.MATERIAL, material);
|
||||||
setModified();
|
setSaveRequired();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ public class MenuNodeExpandUpgrade extends Upgrade {
|
|||||||
if (config.isSet(node)) {
|
if (config.isSet(node)) {
|
||||||
if (config.isString(node)) {
|
if (config.isString(node)) {
|
||||||
config.set(node, getSeparatedValues(config.getString(node), separator));
|
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) {
|
private void expandSingletonList(ConfigSection config, String node) {
|
||||||
if (config.isSet(node)) {
|
if (config.isSet(node)) {
|
||||||
config.set(node, Collections.singletonList(config.get(node)));
|
config.set(node, Collections.singletonList(config.get(node)));
|
||||||
setModified();
|
setSaveRequired();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -19,9 +19,9 @@ import me.filoghost.chestcommands.parsing.icon.IconSettingsNode;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.regex.Pattern;
|
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);
|
super(menuFile);
|
||||||
|
|
||||||
addSubNodeReplacer("command", "commands");
|
addSubNodeReplacer("command", "commands");
|
@ -28,13 +28,13 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class PlaceholdersYamlUpgrade extends Upgrade {
|
public class PlaceholdersYamlUpgradeTask extends UpgradeTask {
|
||||||
|
|
||||||
private final Path oldPlaceholdersFile;
|
private final Path oldPlaceholdersFile;
|
||||||
private final ConfigLoader newPlaceholdersConfigLoader;
|
private final ConfigLoader newPlaceholdersConfigLoader;
|
||||||
private Config updatedConfig;
|
private Config updatedConfig;
|
||||||
|
|
||||||
public PlaceholdersYamlUpgrade(ConfigManager configManager) {
|
public PlaceholdersYamlUpgradeTask(ConfigManager configManager) {
|
||||||
this.oldPlaceholdersFile = configManager.getRootDataFolder().resolve("placeholders.yml");
|
this.oldPlaceholdersFile = configManager.getRootDataFolder().resolve("placeholders.yml");
|
||||||
this.newPlaceholdersConfigLoader = configManager.getConfigLoader("custom-placeholders.yml");
|
this.newPlaceholdersConfigLoader = configManager.getConfigLoader("custom-placeholders.yml");
|
||||||
}
|
}
|
||||||
@ -50,7 +50,7 @@ public class PlaceholdersYamlUpgrade extends Upgrade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void computeChanges() throws ConfigLoadException {
|
public void computeChanges() throws ConfigLoadException {
|
||||||
if (!Files.isRegularFile(oldPlaceholdersFile)) {
|
if (!Files.isRegularFile(oldPlaceholdersFile)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -80,14 +80,14 @@ public class PlaceholdersYamlUpgrade extends Upgrade {
|
|||||||
String replacement = StringEscapeUtils.unescapeJava(unquote(parts[1]));
|
String replacement = StringEscapeUtils.unescapeJava(unquote(parts[1]));
|
||||||
|
|
||||||
newPlaceholdersConfig.set(placeholder, replacement);
|
newPlaceholdersConfig.set(placeholder, replacement);
|
||||||
setModified();
|
setSaveRequired();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updatedConfig = newPlaceholdersConfig;
|
this.updatedConfig = newPlaceholdersConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void saveChanges() throws ConfigSaveException {
|
public void saveChanges() throws ConfigSaveException {
|
||||||
try {
|
try {
|
||||||
Files.deleteIfExists(oldPlaceholdersFile);
|
Files.deleteIfExists(oldPlaceholdersFile);
|
||||||
} catch (IOException ignored) {}
|
} catch (IOException ignored) {}
|
@ -30,13 +30,13 @@ import java.util.regex.Pattern;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class RegexUpgrade extends Upgrade {
|
public class RegexUpgradeTask extends UpgradeTask {
|
||||||
|
|
||||||
private final Path file;
|
private final Path file;
|
||||||
private final List<RegexReplacer> replacers;
|
private final List<RegexReplacer> replacers;
|
||||||
private List<String> newContents;
|
private List<String> newContents;
|
||||||
|
|
||||||
public RegexUpgrade(Path file) {
|
public RegexUpgradeTask(Path file) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.replacers = new ArrayList<>();
|
this.replacers = new ArrayList<>();
|
||||||
}
|
}
|
||||||
@ -56,7 +56,7 @@ public class RegexUpgrade extends Upgrade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void computeChanges() throws ConfigLoadException {
|
public void computeChanges() throws ConfigLoadException {
|
||||||
if (!Files.isRegularFile(file)) {
|
if (!Files.isRegularFile(file)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -76,12 +76,12 @@ public class RegexUpgrade extends Upgrade {
|
|||||||
newContents = linesStream.collect(Collectors.toList());
|
newContents = linesStream.collect(Collectors.toList());
|
||||||
|
|
||||||
if (!newContents.equals(lines)) {
|
if (!newContents.equals(lines)) {
|
||||||
setModified();
|
setSaveRequired();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void saveChanges() throws ConfigSaveException {
|
public void saveChanges() throws ConfigSaveException {
|
||||||
try {
|
try {
|
||||||
Files.write(file, newContents);
|
Files.write(file, newContents);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
@ -22,12 +22,12 @@ import me.filoghost.chestcommands.config.framework.exception.ConfigSaveException
|
|||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
public class SettingsUpgrade extends Upgrade {
|
public class SettingsUpgradeTask extends UpgradeTask {
|
||||||
|
|
||||||
private final ConfigLoader settingsConfigLoader;
|
private final ConfigLoader settingsConfigLoader;
|
||||||
private Config updatedConfig;
|
private Config updatedConfig;
|
||||||
|
|
||||||
public SettingsUpgrade(ConfigManager configManager) {
|
public SettingsUpgradeTask(ConfigManager configManager) {
|
||||||
this.settingsConfigLoader = configManager.getConfigLoader("config.yml");
|
this.settingsConfigLoader = configManager.getConfigLoader("config.yml");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ public class SettingsUpgrade extends Upgrade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void computeChanges() throws ConfigLoadException {
|
public void computeChanges() throws ConfigLoadException {
|
||||||
if (!settingsConfigLoader.fileExists()) {
|
if (!settingsConfigLoader.fileExists()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -58,13 +58,13 @@ public class SettingsUpgrade extends Upgrade {
|
|||||||
private void removeNode(Config config, String node) {
|
private void removeNode(Config config, String node) {
|
||||||
if (config.isSet(node)) {
|
if (config.isSet(node)) {
|
||||||
config.set(node, null);
|
config.set(node, null);
|
||||||
setModified();
|
setSaveRequired();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void saveChanges() throws ConfigSaveException {
|
public void saveChanges() throws ConfigSaveException {
|
||||||
settingsConfigLoader.save(updatedConfig);
|
settingsConfigLoader.save(updatedConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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.ConfigLoadException;
|
||||||
import me.filoghost.chestcommands.config.framework.exception.ConfigSaveException;
|
import me.filoghost.chestcommands.config.framework.exception.ConfigSaveException;
|
||||||
|
import me.filoghost.chestcommands.legacy.Backup;
|
||||||
import me.filoghost.chestcommands.logging.ErrorMessages;
|
import me.filoghost.chestcommands.logging.ErrorMessages;
|
||||||
import me.filoghost.chestcommands.util.Preconditions;
|
import me.filoghost.chestcommands.util.Preconditions;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
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;
|
private boolean hasRun;
|
||||||
|
|
||||||
protected void setModified() {
|
protected void setSaveRequired() {
|
||||||
this.modified = true;
|
this.saveRequired = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean runAndBackupIfNecessary(Backup backup) throws UpgradeTaskException {
|
||||||
public boolean backupAndUpgradeIfNecessary() throws UpgradeException {
|
Preconditions.checkState(!hasRun, "Upgrade task has already run");
|
||||||
Preconditions.checkState(!hasRun, "Upgrade can only be run once");
|
|
||||||
hasRun = true;
|
hasRun = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
computeChanges();
|
computeChanges();
|
||||||
} catch (ConfigLoadException e) {
|
} catch (ConfigLoadException e) {
|
||||||
throw new UpgradeException(ErrorMessages.Upgrade.loadError(getOriginalFile()), e);
|
throw new UpgradeTaskException(ErrorMessages.Upgrade.loadError(getOriginalFile()), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modified) {
|
if (saveRequired) {
|
||||||
try {
|
try {
|
||||||
createBackupFile(getOriginalFile());
|
backup.backupFile(getOriginalFile());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new UpgradeException(ErrorMessages.Upgrade.backupError(getOriginalFile()), e);
|
throw new UpgradeTaskException(ErrorMessages.Upgrade.backupError(getOriginalFile()), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
saveChanges();
|
saveChanges();
|
||||||
} catch (ConfigSaveException e) {
|
} 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();
|
public abstract Path getOriginalFile();
|
@ -14,9 +14,9 @@
|
|||||||
*/
|
*/
|
||||||
package me.filoghost.chestcommands.legacy.upgrade;
|
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);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
|
@ -18,8 +18,6 @@ import me.filoghost.chestcommands.config.framework.mapped.MappedConfig;
|
|||||||
import me.filoghost.chestcommands.parsing.icon.IconSettings;
|
import me.filoghost.chestcommands.parsing.icon.IconSettings;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class ErrorMessages {
|
public class ErrorMessages {
|
||||||
|
|
||||||
@ -72,9 +70,10 @@ public class ErrorMessages {
|
|||||||
|
|
||||||
public static class Upgrade {
|
public static class Upgrade {
|
||||||
|
|
||||||
public static final String genericExecutorError = "encountered errors while running run automatic configuration upgrades, "
|
public static final String genericExecutorError = "error while running 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";
|
||||||
public static final String menuListIOException = "couldn't obtain a list of menu files, some automatic upgrades were skipped";
|
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) {
|
public static String metadataReadError(Path metadataFile) {
|
||||||
return "couldn't read upgrades metadata file \"" + formatPath(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) + "\"";
|
return "error while trying to automatically upgrade \"" + formatPath(file) + "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String failedUpgradesList(Set<Path> 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) {
|
public static String loadError(Path file) {
|
||||||
return "couldn't load file to upgrade \"" + formatPath(file) + "\"";
|
return "couldn't load file to upgrade \"" + formatPath(file) + "\"";
|
||||||
}
|
}
|
||||||
@ -106,6 +98,7 @@ public class ErrorMessages {
|
|||||||
public static String saveError(Path file) {
|
public static String saveError(Path file) {
|
||||||
return "couldn't save upgraded file \"" + formatPath(file) + "\"";
|
return "couldn't save upgraded file \"" + formatPath(file) + "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ import me.filoghost.chestcommands.ChestCommands;
|
|||||||
import me.filoghost.chestcommands.config.framework.exception.ConfigException;
|
import me.filoghost.chestcommands.config.framework.exception.ConfigException;
|
||||||
import me.filoghost.chestcommands.config.framework.exception.ConfigSyntaxException;
|
import me.filoghost.chestcommands.config.framework.exception.ConfigSyntaxException;
|
||||||
import me.filoghost.chestcommands.legacy.UpgradeExecutorException;
|
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.parsing.ParseException;
|
||||||
import me.filoghost.chestcommands.util.logging.ErrorCollector;
|
import me.filoghost.chestcommands.util.logging.ErrorCollector;
|
||||||
import me.filoghost.chestcommands.util.logging.ErrorInfo;
|
import me.filoghost.chestcommands.util.logging.ErrorInfo;
|
||||||
@ -65,7 +65,7 @@ public class PrintableErrorCollector extends ErrorCollector {
|
|||||||
|
|
||||||
} else if (cause instanceof ConfigException
|
} else if (cause instanceof ConfigException
|
||||||
|| cause instanceof ParseException
|
|| cause instanceof ParseException
|
||||||
|| cause instanceof UpgradeException
|
|| cause instanceof UpgradeTaskException
|
||||||
|| cause instanceof UpgradeExecutorException) {
|
|| cause instanceof UpgradeExecutorException) {
|
||||||
message.add(cause.getMessage());
|
message.add(cause.getMessage());
|
||||||
cause = cause.getCause(); // Print the cause (or nothing if null), not our "known" exception
|
cause = cause.getCause(); // Print the cause (or nothing if null), not our "known" exception
|
||||||
|
Loading…
Reference in New Issue
Block a user