rename `--headless` to `--no-prompt`, and parse with the other args
This commit is contained in:
parent
05695be390
commit
5196c3bad9
|
@ -32,7 +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.
|
`--no-prompt` | Don't let the installer wait for user input (e.g. for cases where it's being run by a script). If the installer is unable to continue without user input, it'll fail instead.
|
||||||
|
|
||||||
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
|
||||||
|
@ -97,7 +97,7 @@ Windows](#on-windows)_ section below to create a build that retains the icon.**
|
||||||
2. Run `sudo apt update` in WSL to update the package list.
|
2. Run `sudo apt update` in WSL to update the package list.
|
||||||
3. The rest of the instructions below should be run in WSL.
|
3. The rest of the instructions below should be run in WSL.
|
||||||
2. Install the required software:
|
2. Install the required software:
|
||||||
1. Install the [.NET 5 SDK](https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu).
|
1. Install the [.NET 5 SDK](https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu).
|
||||||
_For Ubuntu-based systems, you can run `lsb_release -a` to get the Ubuntu version number._
|
_For Ubuntu-based systems, you can run `lsb_release -a` to get the Ubuntu version number._
|
||||||
2. [Install Steam](https://linuxconfig.org/how-to-install-steam-on-ubuntu-20-04-focal-fossa-linux).
|
2. [Install Steam](https://linuxconfig.org/how-to-install-steam-on-ubuntu-20-04-focal-fossa-linux).
|
||||||
3. Launch `steam` and install the game like usual.
|
3. Launch `steam` and install the game like usual.
|
||||||
|
|
|
@ -33,9 +33,6 @@ 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>
|
||||||
|
@ -100,11 +97,10 @@ 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, bool headless)
|
public InteractiveInstaller(string bundlePath)
|
||||||
{
|
{
|
||||||
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>
|
||||||
|
@ -139,40 +135,24 @@ namespace StardewModdingApi.Installer
|
||||||
Console.Title = $"SMAPI {context.GetInstallerVersion()} installer on {context.Platform} {context.PlatformName}";
|
Console.Title = $"SMAPI {context.GetInstallerVersion()} installer on {context.Platform} {context.PlatformName}";
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
|
|
||||||
/****
|
|
||||||
** Check if correct installer
|
|
||||||
****/
|
|
||||||
#if SMAPI_FOR_WINDOWS
|
|
||||||
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.AwaitConfirmation();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (context.IsWindows)
|
|
||||||
{
|
|
||||||
this.PrintError($"This is the installer for Linux/macOS. Run the 'install on Windows.exe' file instead.");
|
|
||||||
this.AwaitConfirmation();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****
|
/****
|
||||||
** read command-line arguments
|
** read command-line arguments
|
||||||
****/
|
****/
|
||||||
// get action from CLI
|
// get input mode
|
||||||
|
bool allowUserInput = !args.Contains("--no-prompt");
|
||||||
|
|
||||||
|
// get action
|
||||||
bool installArg = args.Contains("--install");
|
bool installArg = args.Contains("--install");
|
||||||
bool uninstallArg = args.Contains("--uninstall");
|
bool uninstallArg = args.Contains("--uninstall");
|
||||||
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.");
|
||||||
this.AwaitConfirmation();
|
this.AwaitConfirmation(allowUserInput);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!installArg && !uninstallArg && Headless)
|
if (!allowUserInput && !installArg && !uninstallArg)
|
||||||
{
|
{
|
||||||
this.PrintError("Either --install or --uninstall is required when running with --headless.");
|
this.PrintError("You must specify --install or --uninstall when running with --no-prompt.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,12 +164,31 @@ namespace StardewModdingApi.Installer
|
||||||
gamePathArg = args[pathIndex];
|
gamePathArg = args[pathIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****
|
||||||
|
** Check if correct installer
|
||||||
|
****/
|
||||||
|
#if SMAPI_FOR_WINDOWS
|
||||||
|
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.AwaitConfirmation(allowUserInput);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (context.IsWindows)
|
||||||
|
{
|
||||||
|
this.PrintError($"This is the installer for Linux/macOS. Run the 'install on Windows.exe' file instead.");
|
||||||
|
this.AwaitConfirmation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*********
|
/*********
|
||||||
** 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 && !Headless)
|
if (context.IsUnix && allowUserInput)
|
||||||
{
|
{
|
||||||
/****
|
/****
|
||||||
** print header
|
** print header
|
||||||
|
@ -254,7 +253,7 @@ namespace StardewModdingApi.Installer
|
||||||
if (installDir == null)
|
if (installDir == null)
|
||||||
{
|
{
|
||||||
this.PrintError("Failed finding your game path.");
|
this.PrintError("Failed finding your game path.");
|
||||||
this.AwaitConfirmation();
|
this.AwaitConfirmation(allowUserInput);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +270,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.");
|
||||||
this.AwaitConfirmation();
|
this.AwaitConfirmation(allowUserInput);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Console.Clear();
|
Console.Clear();
|
||||||
|
@ -349,7 +348,7 @@ namespace StardewModdingApi.Installer
|
||||||
if (context.IsUnix && File.Exists(paths.BackupLaunchScriptPath))
|
if (context.IsUnix && File.Exists(paths.BackupLaunchScriptPath))
|
||||||
{
|
{
|
||||||
this.PrintDebug("Removing SMAPI launcher...");
|
this.PrintDebug("Removing SMAPI launcher...");
|
||||||
this.InteractivelyDelete(paths.VanillaLaunchScriptPath);
|
this.InteractivelyDelete(paths.VanillaLaunchScriptPath, allowUserInput);
|
||||||
File.Move(paths.BackupLaunchScriptPath, paths.VanillaLaunchScriptPath);
|
File.Move(paths.BackupLaunchScriptPath, paths.VanillaLaunchScriptPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,7 +360,7 @@ namespace StardewModdingApi.Installer
|
||||||
{
|
{
|
||||||
this.PrintDebug(action == ScriptAction.Install ? "Removing previous SMAPI files..." : "Removing SMAPI files...");
|
this.PrintDebug(action == ScriptAction.Install ? "Removing previous SMAPI files..." : "Removing SMAPI files...");
|
||||||
foreach (string path in removePaths)
|
foreach (string path in removePaths)
|
||||||
this.InteractivelyDelete(path);
|
this.InteractivelyDelete(path, allowUserInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
// move global save data folder (changed in 3.2)
|
// move global save data folder (changed in 3.2)
|
||||||
|
@ -373,7 +372,7 @@ namespace StardewModdingApi.Installer
|
||||||
if (oldDir.Exists)
|
if (oldDir.Exists)
|
||||||
{
|
{
|
||||||
if (newDir.Exists)
|
if (newDir.Exists)
|
||||||
this.InteractivelyDelete(oldDir.FullName);
|
this.InteractivelyDelete(oldDir.FullName, allowUserInput);
|
||||||
else
|
else
|
||||||
oldDir.MoveTo(newDir.FullName);
|
oldDir.MoveTo(newDir.FullName);
|
||||||
}
|
}
|
||||||
|
@ -388,7 +387,7 @@ namespace StardewModdingApi.Installer
|
||||||
this.PrintDebug("Adding SMAPI files...");
|
this.PrintDebug("Adding SMAPI files...");
|
||||||
foreach (FileSystemInfo sourceEntry in paths.BundleDir.EnumerateFileSystemInfos().Where(this.ShouldCopy))
|
foreach (FileSystemInfo sourceEntry in paths.BundleDir.EnumerateFileSystemInfos().Where(this.ShouldCopy))
|
||||||
{
|
{
|
||||||
this.InteractivelyDelete(Path.Combine(paths.GameDir.FullName, sourceEntry.Name));
|
this.InteractivelyDelete(Path.Combine(paths.GameDir.FullName, sourceEntry.Name), allowUserInput);
|
||||||
this.RecursiveCopy(sourceEntry, paths.GameDir);
|
this.RecursiveCopy(sourceEntry, paths.GameDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,7 +402,7 @@ namespace StardewModdingApi.Installer
|
||||||
if (!File.Exists(paths.BackupLaunchScriptPath))
|
if (!File.Exists(paths.BackupLaunchScriptPath))
|
||||||
File.Move(paths.VanillaLaunchScriptPath, paths.BackupLaunchScriptPath);
|
File.Move(paths.VanillaLaunchScriptPath, paths.BackupLaunchScriptPath);
|
||||||
else
|
else
|
||||||
this.InteractivelyDelete(paths.VanillaLaunchScriptPath);
|
this.InteractivelyDelete(paths.VanillaLaunchScriptPath, allowUserInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add new launcher
|
// add new launcher
|
||||||
|
@ -473,7 +472,7 @@ namespace StardewModdingApi.Installer
|
||||||
|
|
||||||
// remove existing folder
|
// remove existing folder
|
||||||
if (targetFolder.Exists)
|
if (targetFolder.Exists)
|
||||||
this.InteractivelyDelete(targetFolder.FullName);
|
this.InteractivelyDelete(targetFolder.FullName, allowUserInput);
|
||||||
|
|
||||||
// copy files
|
// copy files
|
||||||
this.RecursiveCopy(sourceMod.Directory, paths.ModsDir, filter: this.ShouldCopy);
|
this.RecursiveCopy(sourceMod.Directory, paths.ModsDir, filter: this.ShouldCopy);
|
||||||
|
@ -491,7 +490,7 @@ namespace StardewModdingApi.Installer
|
||||||
|
|
||||||
#if SMAPI_DEPRECATED
|
#if SMAPI_DEPRECATED
|
||||||
// remove obsolete appdata mods
|
// remove obsolete appdata mods
|
||||||
this.InteractivelyRemoveAppDataMods(paths.ModsDir, bundledModsDir);
|
this.InteractivelyRemoveAppDataMods(paths.ModsDir, bundledModsDir, allowUserInput);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -522,7 +521,7 @@ namespace StardewModdingApi.Installer
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.AwaitConfirmation();
|
this.AwaitConfirmation(allowUserInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -590,7 +589,8 @@ namespace StardewModdingApi.Installer
|
||||||
|
|
||||||
/// <summary>Interactively delete a file or folder path, and block until deletion completes.</summary>
|
/// <summary>Interactively delete a file or folder path, and block until deletion completes.</summary>
|
||||||
/// <param name="path">The file or folder path.</param>
|
/// <param name="path">The file or folder path.</param>
|
||||||
private void InteractivelyDelete(string path)
|
/// <param name="allowUserInput">Whether the installer can ask for user input from the terminal.</param>
|
||||||
|
private void InteractivelyDelete(string path, bool allowUserInput)
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
@ -603,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.");
|
||||||
this.AwaitConfirmation();
|
this.AwaitConfirmation(allowUserInput);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -823,7 +823,8 @@ namespace StardewModdingApi.Installer
|
||||||
/// <summary>Interactively move mods out of the app data directory.</summary>
|
/// <summary>Interactively move mods out of the app data directory.</summary>
|
||||||
/// <param name="properModsDir">The directory which should contain all mods.</param>
|
/// <param name="properModsDir">The directory which should contain all mods.</param>
|
||||||
/// <param name="packagedModsDir">The installer directory containing packaged mods.</param>
|
/// <param name="packagedModsDir">The installer directory containing packaged mods.</param>
|
||||||
private void InteractivelyRemoveAppDataMods(DirectoryInfo properModsDir, DirectoryInfo packagedModsDir)
|
/// <param name="allowUserInput">Whether the installer can ask for user input from the terminal.</param>
|
||||||
|
private void InteractivelyRemoveAppDataMods(DirectoryInfo properModsDir, DirectoryInfo packagedModsDir, bool allowUserInput)
|
||||||
{
|
{
|
||||||
// get packaged mods to delete
|
// get packaged mods to delete
|
||||||
string[] packagedModNames = packagedModsDir.GetDirectories().Select(p => p.Name).ToArray();
|
string[] packagedModNames = packagedModsDir.GetDirectories().Select(p => p.Name).ToArray();
|
||||||
|
@ -850,7 +851,7 @@ namespace StardewModdingApi.Installer
|
||||||
if (isDir && packagedModNames.Contains(entry.Name, StringComparer.OrdinalIgnoreCase))
|
if (isDir && packagedModNames.Contains(entry.Name, StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
this.PrintDebug($" Deleting {entry.Name} because it's bundled into SMAPI...");
|
this.PrintDebug($" Deleting {entry.Name} because it's bundled into SMAPI...");
|
||||||
this.InteractivelyDelete(entry.FullName);
|
this.InteractivelyDelete(entry.FullName, allowUserInput);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -916,13 +917,12 @@ namespace StardewModdingApi.Installer
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Await confirmation (pressing enter) from the User.</summary>
|
/// <summary>Wait until the user presses enter to confirm, if user input is allowed.</summary>
|
||||||
private void AwaitConfirmation()
|
/// <param name="allowUserInput">Whether the installer can ask for user input from the terminal.</param>
|
||||||
|
private void AwaitConfirmation(bool allowUserInput)
|
||||||
{
|
{
|
||||||
if (!this.Headless)
|
if (allowUserInput)
|
||||||
{
|
|
||||||
Console.ReadLine();
|
Console.ReadLine();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ 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
|
||||||
{
|
{
|
||||||
|
@ -48,9 +47,8 @@ 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, headless);
|
var installer = new InteractiveInstaller(bundleDir.FullName);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue