1
0
mirror of https://github.com/Eyre-S/sekai-scores.git synced 2024-11-22 11:14:56 +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:
A.C.Sukazyo Eyre 2022-11-25 20:43:46 +08:00
parent e6cbab2d3c
commit af53ed7f18
Signed by: Eyre_S
GPG Key ID: C17CE40291207874
6 changed files with 245 additions and 29 deletions

View File

@ -1,18 +1,38 @@
package cc.sukazyo.sekai_cli;
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 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) {
if (args.length > 0) {
if (args[0].equals("add")) {
AddScore.main(Arrays.copyOfRange(args, 1, args.length));
final List<String> $args = new java.util.ArrayList<>(List.of(args));
if ($args.remove("--debug")) Log.enableDebugging();
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();
}
}

View File

@ -4,12 +4,14 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Properties;
import static cc.sukazyo.sekai_cli.Log._debug;
import static cc.sukazyo.sekai_cli.Log._user;
public class Config {
@ -46,29 +48,98 @@ public class Config {
return v;
}
static Config loadUserConfig() {
try {
final Properties props = new Properties();
final File propFile = Paths.get(getAppConfigPath(getSysUserConfigRoot()).toString(), CONFIG_FILE).toFile();
props.load(new FileInputStream(propFile));
_debug("loaded config file: " + propFile.getAbsolutePath());
return new Config(props);
} catch (IOException e) {
throw new RuntimeException("error while load user config", e);
}
public void echo() {
echo("user.sekai-id", String.valueOf(sekai_id));
echo("db.server", db_host);
echo("db.database", db_name);
echo("db.auth.user", db_auth_user);
echo("db.auth.password", db_auth_pwd);
echo("db.table-prefix", db_prefix);
}
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);
}
private static Path getSysUserConfigRoot () {
final Path userhome = Paths.get(System.getProperty("user.home"), ".config");
_debug("read config from user home : " + userhome.toAbsolutePath());
public static Path getSysUserConfigRoot () {
final Path userhome = Paths.get(System.getProperty("user.home"), SysType.get().userConfigPath);
_debug("read config from user home config : " + userhome.toAbsolutePath());
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;
}
}
}

View File

@ -1,13 +1,36 @@
package cc.sukazyo.sekai_cli;
import java.io.PrintWriter;
import java.io.StringWriter;
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) {
if (!isDebug()) return;
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);
}

View File

@ -2,8 +2,6 @@ package cc.sukazyo.sekai_cli.client;
import cc.sukazyo.sekai_scores.ScoreBase;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.InputMismatchException;
import java.util.Scanner;
@ -44,11 +42,10 @@ public class AddScore {
} catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
System.out.println("unsupported yet.");
final StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
_debug(sw.toString());
_debug(e);
} catch (InputMismatchException e) {
System.out.println("unavailable input: " + e.getMessage());
_debug(e);
}
}

View File

@ -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());
}
}

View 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);
}
}