mirror of
https://github.com/Eyre-S/sekai-scores.git
synced 2024-11-25 12:37:40 +08:00
add config command with create/list/show with --user/--sys, add global param --debug/--verbose
- set default _debug output to false - add global param --debug/--verbose to enable _debug output - changed user config store path - on windows, it will be "~/AppData/Roaming" - on linux, it still is "~/.config" - added supported to system global config - which means "C:/ProgramData" on Windows and "/etc" on linux - the system global config can be override by user config - add config command - with param --user/--sys, which can control config command do on which config field. the default is user. - with subcommand create, it can create sekai-scores config dir and config file. it follows config field. - with subcommand list/show, it can show the config loaded. it shows all of the config will be load. so, it do not follow config field setting. - without subcommand, it will output the config file path.
This commit is contained in:
parent
e6cbab2d3c
commit
af53ed7f18
@ -1,18 +1,38 @@
|
|||||||
package cc.sukazyo.sekai_cli;
|
package cc.sukazyo.sekai_cli;
|
||||||
|
|
||||||
import cc.sukazyo.sekai_cli.client.AddScore;
|
import cc.sukazyo.sekai_cli.client.AddScore;
|
||||||
|
import cc.sukazyo.sekai_cli.client.Configs;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cc.sukazyo.sekai_cli.Log._user;
|
||||||
|
|
||||||
public class ClientMain {
|
public class ClientMain {
|
||||||
|
|
||||||
public static final Config config = Config.loadUserConfig();
|
private static Config config = null;
|
||||||
|
|
||||||
|
public static Config config() {
|
||||||
|
if (config == null) config = Config.load();
|
||||||
|
if (config == null) {
|
||||||
|
_user("read config failed.");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
public static void main (String[] args) {
|
public static void main (String[] args) {
|
||||||
|
|
||||||
if (args.length > 0) {
|
final List<String> $args = new java.util.ArrayList<>(List.of(args));
|
||||||
if (args[0].equals("add")) {
|
if ($args.remove("--debug")) Log.enableDebugging();
|
||||||
AddScore.main(Arrays.copyOfRange(args, 1, args.length));
|
if ($args.remove("--verbose")) Log.enableDebugging();
|
||||||
|
|
||||||
|
if ($args.size() > 0) {
|
||||||
|
final String i0 = $args.remove(0);
|
||||||
|
if (i0.equals("add")) {
|
||||||
|
AddScore.main($args.toArray(String[]::new));
|
||||||
|
$done();
|
||||||
|
} else if (i0.equals("config")) {
|
||||||
|
Configs.main($args.toArray(String[]::new));
|
||||||
$done();
|
$done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,14 @@ import javax.annotation.Nonnull;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import static cc.sukazyo.sekai_cli.Log._debug;
|
import static cc.sukazyo.sekai_cli.Log._debug;
|
||||||
|
import static cc.sukazyo.sekai_cli.Log._user;
|
||||||
|
|
||||||
public class Config {
|
public class Config {
|
||||||
|
|
||||||
@ -46,29 +48,98 @@ public class Config {
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Config loadUserConfig() {
|
public void echo() {
|
||||||
try {
|
echo("user.sekai-id", String.valueOf(sekai_id));
|
||||||
|
echo("db.server", db_host);
|
||||||
final Properties props = new Properties();
|
echo("db.database", db_name);
|
||||||
final File propFile = Paths.get(getAppConfigPath(getSysUserConfigRoot()).toString(), CONFIG_FILE).toFile();
|
echo("db.auth.user", db_auth_user);
|
||||||
props.load(new FileInputStream(propFile));
|
echo("db.auth.password", db_auth_pwd);
|
||||||
_debug("loaded config file: " + propFile.getAbsolutePath());
|
echo("db.table-prefix", db_prefix);
|
||||||
|
|
||||||
return new Config(props);
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("error while load user config", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Path getAppConfigPath(Path configRoot) {
|
private void echo (String k, String v) {
|
||||||
|
if (v == null) System.out.println(k + " [unset]");
|
||||||
|
System.out.println(k + " = " + v);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Config load() {
|
||||||
|
|
||||||
|
final Properties props = new Properties();
|
||||||
|
final File propFileSys = getAppConfigFile(getAppConfigPath(getSysGlobalConfigRoot()));
|
||||||
|
final File propFileUser = getAppConfigFile(getAppConfigPath(getSysUserConfigRoot()));
|
||||||
|
|
||||||
|
final boolean propSysLoaded = load(props, propFileSys);
|
||||||
|
final boolean propUserLoaded = load(props, propFileUser);
|
||||||
|
if (!propUserLoaded && !propSysLoaded) {
|
||||||
|
_user("no config available.\n use `$ sekai-cli config create | edit` to create a config file and edit it.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Config(props);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean load (Properties target, File file) {
|
||||||
|
try {
|
||||||
|
target.load(new FileInputStream(file));
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
_debug("config not created yet: " + file.getAbsolutePath());
|
||||||
|
_debug(e);
|
||||||
|
return false;
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
_debug("reading config: " + file.getAbsolutePath() + ": permission denied");
|
||||||
|
_debug(e);
|
||||||
|
return false;
|
||||||
|
} catch (IOException e) {
|
||||||
|
_debug("failed read config: " + file.getAbsolutePath());
|
||||||
|
_debug(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_debug("loaded config file: " + file.getAbsolutePath());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File getAppConfigFile (Path appConfigPath) {
|
||||||
|
return Paths.get(appConfigPath.toString(), CONFIG_FILE).toFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Path getAppConfigPath(Path configRoot) {
|
||||||
return Paths.get(configRoot.toString(), CONFIG_ROOT_NAME);
|
return Paths.get(configRoot.toString(), CONFIG_ROOT_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Path getSysUserConfigRoot () {
|
public static Path getSysUserConfigRoot () {
|
||||||
final Path userhome = Paths.get(System.getProperty("user.home"), ".config");
|
final Path userhome = Paths.get(System.getProperty("user.home"), SysType.get().userConfigPath);
|
||||||
_debug("read config from user home : " + userhome.toAbsolutePath());
|
_debug("read config from user home config : " + userhome.toAbsolutePath());
|
||||||
return userhome;
|
return userhome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Path getSysGlobalConfigRoot () {
|
||||||
|
final Path syshome = Paths.get(File.listRoots()[0].getPath(), SysType.get().sysConfigPath);
|
||||||
|
_debug("read config from system global config : " + syshome.toAbsolutePath());
|
||||||
|
return syshome;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SysType {
|
||||||
|
|
||||||
|
WINDOWS(new String[]{"AppData", "Roaming"}, new String[]{"ProgramData"}),
|
||||||
|
// LINUX(userConfigPath, sysConfigPath),
|
||||||
|
// MACOS(userConfigPath, sysConfigPath),
|
||||||
|
UNKNOWN(new String[]{".config"}, new String[]{"etc"});
|
||||||
|
|
||||||
|
public final String[] userConfigPath;
|
||||||
|
public final String[] sysConfigPath;
|
||||||
|
|
||||||
|
SysType (String[] userConfigPath, String[] sysConfigPath) {
|
||||||
|
this.userConfigPath = userConfigPath;
|
||||||
|
this.sysConfigPath = sysConfigPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SysType get () {
|
||||||
|
final String sysName = System.getProperty("os.name");
|
||||||
|
if (sysName.contains("Windows")) return SysType.WINDOWS;
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,36 @@
|
|||||||
package cc.sukazyo.sekai_cli;
|
package cc.sukazyo.sekai_cli;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
public class Log {
|
public class Log {
|
||||||
|
|
||||||
private static final boolean IS_DEBUG = true;
|
private static boolean IS_DEBUG = false;
|
||||||
|
|
||||||
|
public static void enableDebugging () {
|
||||||
|
if (IS_DEBUG) _debug("trying to enable debug: already in debug mode.");
|
||||||
|
else {
|
||||||
|
IS_DEBUG = true;
|
||||||
|
_debug("enabled debug\n cli will output the debug log now.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void _debug (String m) {
|
public static void _debug (String m) {
|
||||||
if (!isDebug()) return;
|
if (!isDebug()) return;
|
||||||
m = "[DEBUG]" + m;
|
m = "[DEBUG]" + m;
|
||||||
m = m.replaceAll("\\n", "'''''''");
|
m = m.replaceAll("\\n", "\n'''''''");
|
||||||
|
System.out.println(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void _debug (Exception e) {
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
e.printStackTrace(new PrintWriter(sw));
|
||||||
|
_debug(sw.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void _user (String m) {
|
||||||
|
m = "sekai-cli: " + m;
|
||||||
|
m = m.replaceAll("\\n", "\nsekai-cli: ");
|
||||||
System.out.println(m);
|
System.out.println(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,6 @@ package cc.sukazyo.sekai_cli.client;
|
|||||||
|
|
||||||
import cc.sukazyo.sekai_scores.ScoreBase;
|
import cc.sukazyo.sekai_scores.ScoreBase;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.util.InputMismatchException;
|
import java.util.InputMismatchException;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
@ -44,11 +42,10 @@ public class AddScore {
|
|||||||
|
|
||||||
} catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
|
} catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
|
||||||
System.out.println("unsupported yet.");
|
System.out.println("unsupported yet.");
|
||||||
final StringWriter sw = new StringWriter();
|
_debug(e);
|
||||||
e.printStackTrace(new PrintWriter(sw));
|
|
||||||
_debug(sw.toString());
|
|
||||||
} catch (InputMismatchException e) {
|
} catch (InputMismatchException e) {
|
||||||
System.out.println("unavailable input: " + e.getMessage());
|
System.out.println("unavailable input: " + e.getMessage());
|
||||||
|
_debug(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,89 @@
|
|||||||
|
package cc.sukazyo.sekai_cli.client;
|
||||||
|
|
||||||
|
import cc.sukazyo.sekai_cli.ClientMain;
|
||||||
|
import cc.sukazyo.sekai_cli.Config;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cc.sukazyo.sekai_cli.Log._debug;
|
||||||
|
import static cc.sukazyo.sekai_cli.Log._user;
|
||||||
|
|
||||||
|
public class Configs {
|
||||||
|
|
||||||
|
public static void main (String[] args) {
|
||||||
|
|
||||||
|
final List<String> $args = new java.util.ArrayList<>(List.of(args));
|
||||||
|
Path configRoot = Config.getSysUserConfigRoot();
|
||||||
|
if ($args.remove("--user"))
|
||||||
|
configRoot = Config.getSysUserConfigRoot();
|
||||||
|
if ($args.remove("--sys"))
|
||||||
|
configRoot = Config.getSysGlobalConfigRoot();
|
||||||
|
|
||||||
|
if ($args.isEmpty()) {
|
||||||
|
showConfigPath(configRoot);
|
||||||
|
} else if ($args.get(0).equals("create")) {
|
||||||
|
createConfigFile(configRoot);
|
||||||
|
} else if ($args.get(0).equals("list") || $args.get(0).equals("show")) {
|
||||||
|
listConfig();
|
||||||
|
} else {
|
||||||
|
System.out.println("unknown command in config manager.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void listConfig () {
|
||||||
|
ClientMain.config().echo();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void createConfigFile (Path configRoot) {
|
||||||
|
// check system/user config root
|
||||||
|
if (!configRoot.toFile().isDirectory()) {
|
||||||
|
_user(String.format("the config root `%s` is not a directory!", configRoot.toAbsolutePath()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// check and create sekai config dir
|
||||||
|
final Path configPath = Config.getAppConfigPath(configRoot);
|
||||||
|
final File configPathDir = configPath.toFile();
|
||||||
|
if (configPathDir.exists()) {
|
||||||
|
if (!configPathDir.isDirectory()) {
|
||||||
|
_user(String.format("the config path `%s` is not a directory!", configPath.toAbsolutePath()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
_debug("try create config path " + configPath.toAbsolutePath());
|
||||||
|
if (!configPathDir.mkdir()) {
|
||||||
|
_user(String.format("failed to create config path `%s`", configPath.toAbsolutePath()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
_user(String.format("%s: permission denied", configPath.toAbsolutePath()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// create config file
|
||||||
|
final File configFile = Config.getAppConfigFile(configPath);
|
||||||
|
try {
|
||||||
|
_debug("try create config " + configFile.getAbsolutePath());
|
||||||
|
if (!configFile.createNewFile()) {
|
||||||
|
_user(String.format("%s: already exists.", configFile.getAbsolutePath()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
_user(String.format("%s: create file failed: %s", configFile.getAbsolutePath(), e.getMessage()));
|
||||||
|
return;
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
_user(String.format("%s: permission denied", configFile.getAbsolutePath()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
System.out.println(configFile.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void showConfigPath (Path configRoot) {
|
||||||
|
System.out.println(Config.getAppConfigFile(Config.getAppConfigPath(configRoot)).getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
16
sekai-cli/src/test/java/cc/sukazyo/sekai_cli/CLI.java
Normal file
16
sekai-cli/src/test/java/cc/sukazyo/sekai_cli/CLI.java
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package cc.sukazyo.sekai_cli;
|
||||||
|
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
public class CLI {
|
||||||
|
|
||||||
|
public static void main (String[] args) {
|
||||||
|
|
||||||
|
final Scanner in = new Scanner(System.in);
|
||||||
|
System.out.print("$ java -jar sekai-cli.jar ");
|
||||||
|
String[] $args = in.nextLine().split(" ");
|
||||||
|
ClientMain.main($args);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user