fix(launch): reject option-like and missing paths, resolve them absolute and drop the folder-missing page
This commit is contained in:
1 parent
157f597eed
commit
e3265e3c89
9 files changed
+91
-94
No files matched your search
@@ -265,12 +265,6 @@
|
||||
<data name="Error_Argument_Usage" xml:space="preserve">
|
||||
<value>Usage: ykanban <path></value>
|
||||
</data>
|
||||
<data name="Error_DirectoryMissing_Title" xml:space="preserve">
|
||||
<value>Folder not found</value>
|
||||
</data>
|
||||
<data name="Error_DirectoryMissing_Message" xml:space="preserve">
|
||||
<value>The folder does not exist: {0}</value>
|
||||
</data>
|
||||
<data name="Error_NotInitialized_Title" xml:space="preserve">
|
||||
<value>No workspace here</value>
|
||||
</data>
|
||||
|
||||
@@ -265,12 +265,6 @@
|
||||
<data name="Error_Argument_Usage" xml:space="preserve">
|
||||
<value>用法:ykanban <路径></value>
|
||||
</data>
|
||||
<data name="Error_DirectoryMissing_Title" xml:space="preserve">
|
||||
<value>目录不存在</value>
|
||||
</data>
|
||||
<data name="Error_DirectoryMissing_Message" xml:space="preserve">
|
||||
<value>目录不存在:{0}</value>
|
||||
</data>
|
||||
<data name="Error_NotInitialized_Title" xml:space="preserve">
|
||||
<value>尚未初始化</value>
|
||||
</data>
|
||||
|
||||
@@ -4,9 +4,11 @@ namespace YKanBan.Launching;
|
||||
|
||||
/// <summary>
|
||||
/// Parses raw command-line arguments. The only accepted form is a single,
|
||||
/// non-blank workspace path (<c>ykanban <path></c>); zero arguments,
|
||||
/// more than one argument, or a blank argument is rejected as an argument
|
||||
/// error. The path itself is not checked for existence here.
|
||||
/// non-blank, existing workspace folder (<c>ykanban <path></c>); zero
|
||||
/// arguments, more than one argument, a blank argument, an argument starting
|
||||
/// with <c>-</c> (any option form, <c>--help</c> included), a malformed path or
|
||||
/// a path that is not an existing folder is rejected as an argument error. A
|
||||
/// relative path is resolved against the process's current directory.
|
||||
/// </summary>
|
||||
public static class LaunchArguments {
|
||||
/// <summary>
|
||||
@@ -14,15 +16,28 @@ public static class LaunchArguments {
|
||||
/// <c>ykanban <path></c> contract.
|
||||
/// </summary>
|
||||
/// <param name="arguments">The raw arguments, excluding the executable name.</param>
|
||||
/// <param name="folderPath">The parsed workspace path on success, otherwise <see langword="null"/>.</param>
|
||||
/// <returns><see langword="true"/> when exactly one non-blank path was supplied.</returns>
|
||||
/// <param name="folderPath">The absolute, existing workspace folder on success, otherwise <see langword="null"/>.</param>
|
||||
/// <returns><see langword="true"/> when exactly one usable path was supplied.</returns>
|
||||
public static bool TryParse(IReadOnlyList<string> arguments, [NotNullWhen(true)] out string? folderPath) {
|
||||
if (arguments.Count == 1 && !string.IsNullOrWhiteSpace(arguments[0])) {
|
||||
folderPath = arguments[0];
|
||||
return true;
|
||||
folderPath = null;
|
||||
if (arguments.Count != 1 || string.IsNullOrWhiteSpace(arguments[0]) || arguments[0].StartsWith('-')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
folderPath = null;
|
||||
return false;
|
||||
string fullPath;
|
||||
try {
|
||||
fullPath = Path.GetFullPath(arguments[0]);
|
||||
} catch (Exception exception) when (exception is ArgumentException or NotSupportedException or PathTooLongException) {
|
||||
// A path the OS cannot even represent is a bad argument, not a missing folder.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Existence is checked here so every caller gets an already validated folder.
|
||||
if (!Directory.Exists(fullPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
folderPath = fullPath;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
using System.Globalization;
|
||||
|
||||
namespace YKanBan.ViewModels.ErrorPages;
|
||||
|
||||
/// <summary>
|
||||
/// The full-window page shown when the folder passed on the command line does
|
||||
/// not exist. It has no operations.
|
||||
/// </summary>
|
||||
public sealed class DirectoryMissingPageViewModel : ViewModelBase {
|
||||
/// <summary>
|
||||
/// Initializes the page for a missing folder.
|
||||
/// </summary>
|
||||
/// <param name="folderPath">The folder path that does not exist.</param>
|
||||
public DirectoryMissingPageViewModel(string folderPath) {
|
||||
FolderPath = folderPath;
|
||||
Message = string.Format(
|
||||
Resources.Culture ?? CultureInfo.CurrentCulture, Resources.Error_DirectoryMissing_Message, folderPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the folder path that does not exist.
|
||||
/// </summary>
|
||||
public string FolderPath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the localized explanatory message.
|
||||
/// </summary>
|
||||
public string Message { get; }
|
||||
}
|
||||
@@ -69,11 +69,6 @@ public sealed partial class MainWindowViewModel : ViewModelBase {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Directory.Exists(folderPath)) {
|
||||
Content = new DirectoryMissingPageViewModel(folderPath);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
OpenWorkspace(folderPath);
|
||||
} catch (WorkspaceNotInitializedException) {
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:YKanBan.ViewModels.ErrorPages"
|
||||
xmlns:lang="using:YKanBan"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="1000" d:DesignHeight="640"
|
||||
x:Class="YKanBan.Views.ErrorPages.DirectoryMissingPageView"
|
||||
x:DataType="vm:DirectoryMissingPageViewModel">
|
||||
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="12"
|
||||
MaxWidth="560" Margin="32">
|
||||
<TextBlock Text="{x:Static lang:Resources.Error_DirectoryMissing_Title}"
|
||||
FontSize="20" FontWeight="SemiBold" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding Message}"
|
||||
TextWrapping="Wrap" HorizontalAlignment="Center" TextAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@@ -1,9 +0,0 @@
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace YKanBan.Views.ErrorPages;
|
||||
|
||||
public partial class DirectoryMissingPageView : UserControl {
|
||||
public DirectoryMissingPageView() {
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user