feat: add support for applying migrations automatically
All checks were successful
Update changelog / changelog (push) Successful in 25s

This commit is contained in:
2025-12-17 01:07:05 +01:00
parent f5df949a4c
commit ac2b6aba6e
4 changed files with 102 additions and 12 deletions

View File

@@ -17,7 +17,7 @@ public class Cli
args = _args;
}
public async Task<bool> Parse()
public bool Parse()
{
// Returns true if the program can finish execution.
bool exit = true;
@@ -30,16 +30,19 @@ public class Cli
case "adduser":
case "--adduser":
case "--add-user":
if (!Seeder.EnsureMigrations(db)) return true;
AddUser();
break;
case "resetpassword":
case "--resetpassword":
case "--reset-password":
if (!Seeder.EnsureMigrations(db)) return true;
ResetPassword();
break;
case "removeuser":
case "--removeuser":
case "--remove-user":
if (!Seeder.EnsureMigrations(db)) return true;
RemoveUser();
break;
case "help":
@@ -49,6 +52,7 @@ public class Cli
case "/h":
case "/?":
case "?":
// Help should be shown without forcing migrations.
ShowHelp();
break;
case "setupwizard":
@@ -58,6 +62,7 @@ public class Cli
case "--setup":
case "configure":
case "--configure":
if (!Seeder.EnsureMigrations(db)) return true;
SetupWizard();
break;
default:
@@ -73,13 +78,21 @@ public class Cli
// Shown when "Shadow --help"/"Shadow help"/... is ran.
Console.WriteLine(
$"--- Shadow commandline utility ---\n" +
$"Shadow version: #{ThisAssembly.Git.Commit} {ThisAssembly.Git.Branch} ({ThisAssembly.Git.CommitDate})\n\n" +
$"Shadow version: #{ThisAssembly.Git.Commit} {ThisAssembly.Git.Branch} ({ThisAssembly.Git.CommitDate})\n" +
$"\n" +
$"Available commands:\n" +
$"\n" +
$"=== User management ===\n" +
$"- addUser [username] - create a new user,\n" +
$"- resetPassword [username] - reset a user's password,\n" +
$"- removeUser [username] - remove the user COMPLETELY.\n\n" +
$"- removeUser [username] - remove the user COMPLETELY.\n" +
$"\n" +
$"=== Server maintenance ===\n" +
$"- setupWizard - configure library and thumbnail location on disk.\n" +
$"\n" +
$"Username is optional. If not provided, user will be prompted to enter it.\n" +
$"Running without specifying a command launches a Kestrel web server.\n\n" +
$"Running without specifying a command launches a Kestrel web server.\n" +
$"\n" +
$"License: AGPLv3+, Source code: https://gitea.7o7.cx/sherl/Shadow"
);
}
@@ -271,7 +284,8 @@ public class Cli
Global? musicLibraryPath = db.Globals.FirstOrDefault(g => g.Key == "musicLibraryPath");
Global? musicThumbnailPath = db.Globals.FirstOrDefault(g => g.Key == "musicThumbnailPath");
if (musicLibraryPath is not null || musicThumbnailPath is not null)
bool configurationExists = musicLibraryPath is not null || musicThumbnailPath is not null;
if (configurationExists)
{
Console.WriteLine(" Found existing configuration:");
if (musicLibraryPath is not null)
@@ -314,12 +328,17 @@ public class Cli
Console.WriteLine("success!");
success = true;
Console.WriteLine("\n" +
"Tip: On your next run of Shadow, a web server will start.\n" +
"If you ever need to enter setup wizard again, use `Shadow setupWizard`.\n" +
"For a complete list of available commands use `Shadow help`.\n");
}
return success;
}
public string ReadPassword(string prompt = " Enter password (will not be echoed back): ")
public static string ReadPassword(string prompt = " Enter password (will not be echoed back): ")
{
// https://www.silicloud.com/blog/how-to-hide-content-in-the-console-using-c/
string password = String.Empty;
@@ -344,14 +363,14 @@ public class Cli
return password;
}
public string? ReadName(string prompt = " Enter username: ")
public static string? ReadName(string prompt = " Enter username: ")
{
Console.Write(prompt);
string? input = Console.ReadLine();
return input;
}
public bool YesNoPrompt(string prompt, bool? default_value = null)
public static bool YesNoPrompt(string prompt, bool? default_value = null)
{
// Checks if user input starts with "y", and if it does, returns true.
// Otherwise checks for "n". If both checks fail, and default_value is null,
@@ -388,7 +407,7 @@ public class Cli
return response;
}
public string DefaultPrompt(string prompt, string? default_value = null)
public static string DefaultPrompt(string prompt, string? default_value = null)
{
// Prompt the user repeatedly for answer. If default value
// is specified, an enter will be treated as if the user