Add headless flag for unattended execution

This commit is contained in:
Marie Ramlow 2023-05-26 17:26:14 +02:00 committed by Jesse Plamondon-Willard
parent 251d83472c
commit 654ad4b4b2
No known key found for this signature in database
GPG Key ID: CF8B1456B3E29F49
4 changed files with 34 additions and 11 deletions

View File

@ -1,5 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -ex
########## ##########
## Read config ## Read config
########## ##########

View File

@ -32,6 +32,7 @@ argument | purpose
`--install` | Preselects the install action, skipping the prompt asking what the user wants to do. `--install` | Preselects the install action, skipping the prompt asking what the user wants to do.
`--uninstall` | Preselects the uninstall action, skipping the prompt asking what the user wants to do. `--uninstall` | Preselects the uninstall action, skipping the prompt asking what the user wants to do.
`--game-path "path"` | Specifies the full path to the folder containing the Stardew Valley executable, skipping automatic detection and any prompt to choose a path. If the path is not valid, the installer displays an error. `--game-path "path"` | Specifies the full path to the folder containing the Stardew Valley executable, skipping automatic detection and any prompt to choose a path. If the path is not valid, the installer displays an error.
`--headless` | Installs or Uninstalls SMAPI without any user interaction. Should only be used in scripts, tools or if you know what you're doing.
SMAPI itself recognises five arguments, but these are meant for internal use or testing, and might SMAPI itself recognises five arguments, but these are meant for internal use or testing, and might
change without warning. **On Linux/macOS**, command-line arguments won't work; see _environment change without warning. **On Linux/macOS**, command-line arguments won't work; see _environment

View File

@ -33,6 +33,9 @@ namespace StardewModdingApi.Installer
"SMAPI.ErrorHandler" "SMAPI.ErrorHandler"
}; };
/// <summary>If the installer should run headless, does not ask the user for any input when true.</summary>
private readonly bool Headless;
/// <summary>Get the absolute file or folder paths to remove when uninstalling SMAPI.</summary> /// <summary>Get the absolute file or folder paths to remove when uninstalling SMAPI.</summary>
/// <param name="installDir">The folder for Stardew Valley and SMAPI.</param> /// <param name="installDir">The folder for Stardew Valley and SMAPI.</param>
/// <param name="modsDir">The folder for SMAPI mods.</param> /// <param name="modsDir">The folder for SMAPI mods.</param>
@ -97,10 +100,11 @@ namespace StardewModdingApi.Installer
*********/ *********/
/// <summary>Construct an instance.</summary> /// <summary>Construct an instance.</summary>
/// <param name="bundlePath">The absolute path to the directory containing the files to copy into the game folder.</param> /// <param name="bundlePath">The absolute path to the directory containing the files to copy into the game folder.</param>
public InteractiveInstaller(string bundlePath) public InteractiveInstaller(string bundlePath, bool headless)
{ {
this.BundlePath = bundlePath; this.BundlePath = bundlePath;
this.ConsoleWriter = new ColorfulConsoleWriter(EnvironmentUtility.DetectPlatform()); this.ConsoleWriter = new ColorfulConsoleWriter(EnvironmentUtility.DetectPlatform());
this.Headless = headless;
} }
/// <summary>Run the install or uninstall script.</summary> /// <summary>Run the install or uninstall script.</summary>
@ -142,14 +146,14 @@ namespace StardewModdingApi.Installer
if (context.IsUnix) if (context.IsUnix)
{ {
this.PrintError($"This is the installer for Windows. Run the 'install on {context.Platform}.{(context.Platform == Platform.Mac ? "command" : "sh")}' file instead."); this.PrintError($"This is the installer for Windows. Run the 'install on {context.Platform}.{(context.Platform == Platform.Mac ? "command" : "sh")}' file instead.");
Console.ReadLine(); this.AwaitConfirmation();
return; return;
} }
#else #else
if (context.IsWindows) if (context.IsWindows)
{ {
this.PrintError($"This is the installer for Linux/macOS. Run the 'install on Windows.exe' file instead."); this.PrintError($"This is the installer for Linux/macOS. Run the 'install on Windows.exe' file instead.");
Console.ReadLine(); this.AwaitConfirmation();
return; return;
} }
#endif #endif
@ -163,7 +167,12 @@ namespace StardewModdingApi.Installer
if (installArg && uninstallArg) if (installArg && uninstallArg)
{ {
this.PrintError("You can't specify both --install and --uninstall command-line flags."); this.PrintError("You can't specify both --install and --uninstall command-line flags.");
Console.ReadLine(); this.AwaitConfirmation();
return;
}
if (!installArg && !uninstallArg && Headless)
{
this.PrintError("Either --install or --uninstall is required when running with --headless.");
return; return;
} }
@ -180,7 +189,7 @@ namespace StardewModdingApi.Installer
** Step 2: choose a theme (can't auto-detect on Linux/macOS) ** Step 2: choose a theme (can't auto-detect on Linux/macOS)
*********/ *********/
MonitorColorScheme scheme = MonitorColorScheme.AutoDetect; MonitorColorScheme scheme = MonitorColorScheme.AutoDetect;
if (context.IsUnix) if (context.IsUnix && !Headless)
{ {
/**** /****
** print header ** print header
@ -245,7 +254,7 @@ namespace StardewModdingApi.Installer
if (installDir == null) if (installDir == null)
{ {
this.PrintError("Failed finding your game path."); this.PrintError("Failed finding your game path.");
Console.ReadLine(); this.AwaitConfirmation();
return; return;
} }
@ -262,7 +271,7 @@ namespace StardewModdingApi.Installer
if (!File.Exists(paths.GameDllPath)) if (!File.Exists(paths.GameDllPath))
{ {
this.PrintError("The detected game install path doesn't contain a Stardew Valley executable."); this.PrintError("The detected game install path doesn't contain a Stardew Valley executable.");
Console.ReadLine(); this.AwaitConfirmation();
return; return;
} }
Console.Clear(); Console.Clear();
@ -513,7 +522,7 @@ namespace StardewModdingApi.Installer
); );
} }
Console.ReadKey(); this.AwaitConfirmation();
} }
@ -594,7 +603,7 @@ namespace StardewModdingApi.Installer
{ {
this.PrintError($"Oops! The installer couldn't delete {path}: [{ex.GetType().Name}] {ex.Message}."); this.PrintError($"Oops! The installer couldn't delete {path}: [{ex.GetType().Name}] {ex.Message}.");
this.PrintError("Try rebooting your computer and then run the installer again. If that doesn't work, try deleting it yourself then press any key to retry."); this.PrintError("Try rebooting your computer and then run the installer again. If that doesn't work, try deleting it yourself then press any key to retry.");
Console.ReadKey(); this.AwaitConfirmation();
} }
} }
} }
@ -906,5 +915,14 @@ namespace StardewModdingApi.Installer
_ => true _ => true
}; };
} }
/// <summary>Await confirmation (pressing enter) from the User.</summary>
private void AwaitConfirmation()
{
if (!this.Headless)
{
Console.ReadLine();
}
}
} }
} }

View File

@ -4,6 +4,7 @@ using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
using System.Linq;
namespace StardewModdingApi.Installer namespace StardewModdingApi.Installer
{ {
@ -47,8 +48,9 @@ namespace StardewModdingApi.Installer
// set up assembly resolution // set up assembly resolution
AppDomain.CurrentDomain.AssemblyResolve += Program.CurrentDomain_AssemblyResolve; AppDomain.CurrentDomain.AssemblyResolve += Program.CurrentDomain_AssemblyResolve;
var headless = args.Contains("--headless");
// launch installer // launch installer
var installer = new InteractiveInstaller(bundleDir.FullName); var installer = new InteractiveInstaller(bundleDir.FullName, headless);
try try
{ {