Skip to content

Commit

Permalink
Backup configs automatically upon upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
Vankka committed Jan 25, 2025
1 parent abef18a commit 20d9326
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 9 deletions.
16 changes: 13 additions & 3 deletions common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,12 @@
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
Expand Down Expand Up @@ -747,12 +750,19 @@ protected List<ReloadResult> reload(Set<ReloadFlag> flags, boolean initial) thro
}

boolean configUpgrade = flags.contains(ReloadFlag.CONFIG_UPGRADE);
Path backupPath = null;
if (configUpgrade) {
String dateAndTime = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss").format(LocalDateTime.now());
backupPath = dataDirectory().resolve("config-migrated").resolve(dateAndTime);
Files.createDirectories(backupPath);
}

if (flags.contains(ReloadFlag.CONFIG) || configUpgrade) {
try {
AtomicBoolean anyMissingOptions = new AtomicBoolean(false);
connectionConfigManager().reload(configUpgrade, anyMissingOptions);
configManager().reload(configUpgrade, anyMissingOptions);
messagesConfigManager().reload(configUpgrade, anyMissingOptions);
connectionConfigManager().reload(configUpgrade, anyMissingOptions, backupPath);
configManager().reload(configUpgrade, anyMissingOptions, backupPath);
messagesConfigManager().reload(configUpgrade, anyMissingOptions, backupPath);

if (anyMissingOptions.get()) {
logger().info("Use \"/discordsrv reload config_upgrade\" to write the latest configuration");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.discordsrv.common.core.logging.Logger;
import com.discordsrv.common.core.logging.NamedLogger;
import com.discordsrv.common.exception.ConfigException;
import org.jetbrains.annotations.Nullable;

import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -63,7 +64,7 @@ public Path directory() {
return discordSRV.dataDirectory().resolve("messages");
}

public void reload(boolean forceSave, AtomicBoolean anyMissingOptions) throws ConfigException {
public void reload(boolean forceSave, AtomicBoolean anyMissingOptions, @Nullable Path backupPath) throws ConfigException {
synchronized (configs) {
configs.clear();

Expand Down Expand Up @@ -112,7 +113,7 @@ public void reload(boolean forceSave, AtomicBoolean anyMissingOptions) throws Co
}

for (Map.Entry<Locale, MessagesConfigSingleManager<C>> entry : configs.entrySet()) {
entry.getValue().reload(forceSave, anyMissingOptions);
entry.getValue().reload(forceSave, anyMissingOptions, backupPath);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,18 @@
package com.discordsrv.common.config.configurate.manager.abstraction;

import com.discordsrv.common.exception.ConfigException;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.configurate.CommentedConfigurationNode;
import org.spongepowered.configurate.loader.AbstractConfigurationLoader;

import java.nio.file.Path;
import java.util.concurrent.atomic.AtomicBoolean;

public interface ConfigManager<T> {

T createConfiguration();
T config();

void reload(boolean forceSave, AtomicBoolean anyMissingOptions) throws ConfigException;
void reload(boolean forceSave, AtomicBoolean anyMissingOptions, @Nullable Path backupPath) throws ConfigException;
void save(AbstractConfigurationLoader<CommentedConfigurationNode> loader) throws ConfigException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import org.spongepowered.configurate.yaml.ScalarStyle;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
Expand Down Expand Up @@ -391,7 +392,7 @@ protected void translate(CommentedConfigurationNode node) throws ConfigurateExce

@SuppressWarnings("unchecked") // Cast to generic
@Override
public void reload(boolean forceSave, AtomicBoolean anyMissingOptions) throws ConfigException {
public void reload(boolean forceSave, AtomicBoolean anyMissingOptions, @Nullable Path backupPath) throws ConfigException {
T defaultConfig = createConfiguration();
Class<T> defaultConfigClass = (Class<T>) defaultConfig.getClass();

Expand All @@ -410,6 +411,10 @@ public void reload(boolean forceSave, AtomicBoolean anyMissingOptions) throws Co
return;
}

if (backupPath != null) {
Files.copy(filePath(), backupPath.resolve(fileName()));
}

// Load existing file & translate
CommentedConfigurationNode node = loader().load();

Expand All @@ -427,9 +432,9 @@ public void reload(boolean forceSave, AtomicBoolean anyMissingOptions) throws Co
if (forceSave) {
save(loader);
}
} catch (ConfigurateException e) {
} catch (IOException e) {
Class<?> configClass = defaultConfig.getClass();
if (!configClass.isAnnotationPresent(ConfigSerializable.class)) {
if (e instanceof ConfigurateException && !configClass.isAnnotationPresent(ConfigSerializable.class)) {
// Not very obvious and can easily happen
throw new ConfigException(configClass.getName() + " is not annotated with @ConfigSerializable", e);
}
Expand Down

0 comments on commit 20d9326

Please sign in to comment.