From 6b9268d2d88c81c18f2cc21e343d321989dad99c Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Fri, 9 Jan 2026 21:30:49 +0800 Subject: Set up project structure and CLI integration --- .gitignore | 13 + Collect-Command-Line.ps1 | 61 ++ Collect-Command-Line.sh | 53 ++ CommandLineWrapper/Class1.cs | 6 + CommandLineWrapper/CommandLineWrapper.csproj | 9 + .../CommandLineWrapperExample.csproj | 21 + CommandLineWrapperExample/Program.cs | 0 DesktopClient.sln | 44 +- Directory.Build.props | 19 + JVDesktop/App.axaml | 17 +- JVDesktop/App.axaml.cs | 11 +- JVDesktop/JVDesktop.csproj | 37 +- JVDesktop/Program.cs | 6 +- JVDesktop/ViewLocator.cs | 2 +- JVDesktop/ViewModels/DashboardViewModel.cs | 15 + JVDesktop/ViewModels/MainWindowViewModel.cs | 15 - JVDesktop/ViewModels/ViewModel.cs | 7 + JVDesktop/ViewModels/ViewModelBase.cs | 7 - JVDesktop/Views/DashboardView.axaml | 63 ++ JVDesktop/Views/DashboardView.axaml.cs | 15 + JVDesktop/Views/MainWindow.axaml | 23 - JVDesktop/Views/MainWindow.axaml.cs | 11 - JVDesktop/app.manifest | 4 +- LICENSE | 674 --------------------- LICENSE-GPLv3 | 674 +++++++++++++++++++++ Run-Desktop.ps1 | 5 + Run-Desktop.sh | 6 + Run-WrapperExample.ps1 | 6 + Run-WrapperExample.sh | 7 + run.sh | 2 - 30 files changed, 1065 insertions(+), 768 deletions(-) create mode 100644 Collect-Command-Line.ps1 create mode 100644 Collect-Command-Line.sh create mode 100644 CommandLineWrapper/Class1.cs create mode 100644 CommandLineWrapper/CommandLineWrapper.csproj create mode 100644 CommandLineWrapperExample/CommandLineWrapperExample.csproj create mode 100644 CommandLineWrapperExample/Program.cs create mode 100644 Directory.Build.props create mode 100644 JVDesktop/ViewModels/DashboardViewModel.cs delete mode 100644 JVDesktop/ViewModels/MainWindowViewModel.cs create mode 100644 JVDesktop/ViewModels/ViewModel.cs delete mode 100644 JVDesktop/ViewModels/ViewModelBase.cs create mode 100644 JVDesktop/Views/DashboardView.axaml create mode 100644 JVDesktop/Views/DashboardView.axaml.cs delete mode 100644 JVDesktop/Views/MainWindow.axaml delete mode 100644 JVDesktop/Views/MainWindow.axaml.cs delete mode 100644 LICENSE create mode 100644 LICENSE-GPLv3 create mode 100644 Run-Desktop.ps1 create mode 100644 Run-Desktop.sh create mode 100644 Run-WrapperExample.ps1 create mode 100644 Run-WrapperExample.sh delete mode 100755 run.sh diff --git a/.gitignore b/.gitignore index 0bcaf7c..10d24db 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,18 @@ +######################## +### IntelliJ (Rider) ### +######################## .idea/ + +##################### +### Build Targets ### +##################### **/bin **/obj bin/** obj/** + +######################## +### Temporary Folder ### +######################## +**/.Temp/ +**/.temp/ diff --git a/Collect-Command-Line.ps1 b/Collect-Command-Line.ps1 new file mode 100644 index 0000000..d8705a2 --- /dev/null +++ b/Collect-Command-Line.ps1 @@ -0,0 +1,61 @@ +# Set current working directory to the script's directory +Set-Location -Path $PSScriptRoot + +# Define the path to the target CLI executable +$cliPath = ".\.Temp\Debug\JustEnoughVCS.exe" + +# Check if the target CLI file already exists +if (-not (Test-Path $cliPath)) { + # If the file does not exist, define the relative path to the command-line project directory + $commandLineDir = ".\..\CommandLine" + + # Check if the command-line project directory exists + if (-not (Test-Path $commandLineDir)) { + # If the directory does not exist, output an error and exit the script + Write-Error "Error: $commandLineDir Not Found!" + exit 1 + } + + # Define the path to the pre-built CLI executable + $jvExePath = "$commandLineDir\.temp\deploy\bin\jv.exe" + + # Check if the pre-built CLI file exists + if (Test-Path $jvExePath) { + # If the pre-built file exists, ensure the target directory exists + $null = New-Item -ItemType Directory -Path (Split-Path $cliPath) -Force + # Copy the pre-built file to the target location + Copy-Item -Path $jvExePath -Destination $cliPath -Force + # Output a completion notification + Write-Host "CLI copied to $cliPath" + } + else { + # If the pre-built file does not exist, define the path to the deployment script + $deployScriptPath = "$commandLineDir\deploy.ps1" + + # Check if the deployment script exists + if (-not (Test-Path $deployScriptPath)) { + # If the deployment script does not exist, output an error and exit + Write-Error "Error: $deployScriptPath Not Found!" + exit 1 + } + + # Output a notification that building is starting + Write-Host "Building CLI from deploy.ps1..." + # Execute the deployment script to build the CLI + & $deployScriptPath + + # Check if the CLI file is generated after building + if (-not (Test-Path $jvExePath)) { + # If the file still does not exist after building, output an error and exit + Write-Error "Error: $jvExePath Not Found after deployment!" + exit 1 + } + + # Ensure the target directory exists + $null = New-Item -ItemType Directory -Path (Split-Path $cliPath) -Force + # Copy the newly built file to the target location + Copy-Item -Path $jvExePath -Destination $cliPath -Force + # Output a notification that building and copying are complete + Write-Host "CLI built and copied to $cliPath" + } +} diff --git a/Collect-Command-Line.sh b/Collect-Command-Line.sh new file mode 100644 index 0000000..61545b7 --- /dev/null +++ b/Collect-Command-Line.sh @@ -0,0 +1,53 @@ +# Get the absolute path of the directory where the current script is located +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# Switch to the script's directory, exit if it fails +cd "$SCRIPT_DIR" || exit 1 + +# Define the target path for the CLI tool +cliPath=".Temp/Debug/JustEnoughVCS" + +# Check if the CLI already exists at the target path +if [ ! -f "$cliPath" ]; then + # Check if the CommandLine directory exists in the parent directory + if [ -d "./../CommandLine/" ]; then + # Check if a built CLI executable already exists + if [ -f "./../CommandLine/.temp/deploy/bin/jv" ]; then + # Create the target directory (if it doesn't exist) + mkdir -p "$(dirname "$cliPath")" + # Copy the CLI executable to the target path + cp "./../CommandLine/.temp/deploy/bin/jv" "$cliPath" + # Add execute permission + chmod +x "$cliPath" + echo "CLI copied to $cliPath" + else + # Check if a deployment script exists + if [ -f "./../CommandLine/deploy.sh" ]; then + echo "Building CLI from deploy.sh..." + # Enter the CommandLine directory and execute the deployment script + (cd "./../CommandLine" && ./deploy.sh) + # Check if the CLI executable was generated after deployment + if [ -f "./../CommandLine/.temp/deploy/bin/jv" ]; then + # Create the target directory (if it doesn't exist) + mkdir -p "$(dirname "$cliPath")" + # Copy the newly built CLI executable + cp "./../CommandLine/.temp/deploy/bin/jv" "$cliPath" + # Add execute permission + chmod +x "$cliPath" + echo "CLI built and copied to $cliPath" + else + # CLI executable still not found after deployment, error and exit + echo "Error: ./../CommandLine/.temp/deploy/bin/jv Not Found after deployment!" + exit 1 + fi + else + # Deployment script not found, error and exit + echo "Error: ./../CommandLine/deploy.sh Not Found!" + exit 1 + fi + fi + else + # CommandLine directory not found, error and exit + echo "Error: ./../CommandLine/ Not Found!" + exit 1 + fi +fi diff --git a/CommandLineWrapper/Class1.cs b/CommandLineWrapper/Class1.cs new file mode 100644 index 0000000..f8ed117 --- /dev/null +++ b/CommandLineWrapper/Class1.cs @@ -0,0 +1,6 @@ +namespace CommandLineWrapper; + +public class Class1 +{ + +} diff --git a/CommandLineWrapper/CommandLineWrapper.csproj b/CommandLineWrapper/CommandLineWrapper.csproj new file mode 100644 index 0000000..b92e51b --- /dev/null +++ b/CommandLineWrapper/CommandLineWrapper.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/CommandLineWrapperExample/CommandLineWrapperExample.csproj b/CommandLineWrapperExample/CommandLineWrapperExample.csproj new file mode 100644 index 0000000..3732733 --- /dev/null +++ b/CommandLineWrapperExample/CommandLineWrapperExample.csproj @@ -0,0 +1,21 @@ + + + + ..\.Temp\Debug\ + $(OutputPath) + + + + + + + + Exe + net8.0 + enable + enable + + + diff --git a/CommandLineWrapperExample/Program.cs b/CommandLineWrapperExample/Program.cs new file mode 100644 index 0000000..e69de29 diff --git a/DesktopClient.sln b/DesktopClient.sln index 97fd4d3..f240af4 100644 --- a/DesktopClient.sln +++ b/DesktopClient.sln @@ -1,16 +1,58 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JVDesktop", "JVDesktop\JVDesktop.csproj", "{2EF80E70-ACDD-431B-A773-9CA2EA00A233}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommandLineWrapper", "CommandLineWrapper\CommandLineWrapper.csproj", "{46D98A4E-DF14-4553-837D-CA20CAAF5E8F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommandLineWrapperExample", "CommandLineWrapperExample\CommandLineWrapperExample.csproj", "{9AF08E06-0378-412D-BCF0-99BA0B1C63E0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {2EF80E70-ACDD-431B-A773-9CA2EA00A233}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2EF80E70-ACDD-431B-A773-9CA2EA00A233}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2EF80E70-ACDD-431B-A773-9CA2EA00A233}.Debug|x64.ActiveCfg = Debug|Any CPU + {2EF80E70-ACDD-431B-A773-9CA2EA00A233}.Debug|x64.Build.0 = Debug|Any CPU + {2EF80E70-ACDD-431B-A773-9CA2EA00A233}.Debug|x86.ActiveCfg = Debug|Any CPU + {2EF80E70-ACDD-431B-A773-9CA2EA00A233}.Debug|x86.Build.0 = Debug|Any CPU {2EF80E70-ACDD-431B-A773-9CA2EA00A233}.Release|Any CPU.ActiveCfg = Release|Any CPU {2EF80E70-ACDD-431B-A773-9CA2EA00A233}.Release|Any CPU.Build.0 = Release|Any CPU + {2EF80E70-ACDD-431B-A773-9CA2EA00A233}.Release|x64.ActiveCfg = Release|Any CPU + {2EF80E70-ACDD-431B-A773-9CA2EA00A233}.Release|x64.Build.0 = Release|Any CPU + {2EF80E70-ACDD-431B-A773-9CA2EA00A233}.Release|x86.ActiveCfg = Release|Any CPU + {2EF80E70-ACDD-431B-A773-9CA2EA00A233}.Release|x86.Build.0 = Release|Any CPU + {46D98A4E-DF14-4553-837D-CA20CAAF5E8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {46D98A4E-DF14-4553-837D-CA20CAAF5E8F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {46D98A4E-DF14-4553-837D-CA20CAAF5E8F}.Debug|x64.ActiveCfg = Debug|Any CPU + {46D98A4E-DF14-4553-837D-CA20CAAF5E8F}.Debug|x64.Build.0 = Debug|Any CPU + {46D98A4E-DF14-4553-837D-CA20CAAF5E8F}.Debug|x86.ActiveCfg = Debug|Any CPU + {46D98A4E-DF14-4553-837D-CA20CAAF5E8F}.Debug|x86.Build.0 = Debug|Any CPU + {46D98A4E-DF14-4553-837D-CA20CAAF5E8F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {46D98A4E-DF14-4553-837D-CA20CAAF5E8F}.Release|Any CPU.Build.0 = Release|Any CPU + {46D98A4E-DF14-4553-837D-CA20CAAF5E8F}.Release|x64.ActiveCfg = Release|Any CPU + {46D98A4E-DF14-4553-837D-CA20CAAF5E8F}.Release|x64.Build.0 = Release|Any CPU + {46D98A4E-DF14-4553-837D-CA20CAAF5E8F}.Release|x86.ActiveCfg = Release|Any CPU + {46D98A4E-DF14-4553-837D-CA20CAAF5E8F}.Release|x86.Build.0 = Release|Any CPU + {9AF08E06-0378-412D-BCF0-99BA0B1C63E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9AF08E06-0378-412D-BCF0-99BA0B1C63E0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9AF08E06-0378-412D-BCF0-99BA0B1C63E0}.Debug|x64.ActiveCfg = Debug|Any CPU + {9AF08E06-0378-412D-BCF0-99BA0B1C63E0}.Debug|x64.Build.0 = Debug|Any CPU + {9AF08E06-0378-412D-BCF0-99BA0B1C63E0}.Debug|x86.ActiveCfg = Debug|Any CPU + {9AF08E06-0378-412D-BCF0-99BA0B1C63E0}.Debug|x86.Build.0 = Debug|Any CPU + {9AF08E06-0378-412D-BCF0-99BA0B1C63E0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9AF08E06-0378-412D-BCF0-99BA0B1C63E0}.Release|Any CPU.Build.0 = Release|Any CPU + {9AF08E06-0378-412D-BCF0-99BA0B1C63E0}.Release|x64.ActiveCfg = Release|Any CPU + {9AF08E06-0378-412D-BCF0-99BA0B1C63E0}.Release|x64.Build.0 = Release|Any CPU + {9AF08E06-0378-412D-BCF0-99BA0B1C63E0}.Release|x86.ActiveCfg = Release|Any CPU + {9AF08E06-0378-412D-BCF0-99BA0B1C63E0}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE EndGlobalSection EndGlobal diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..40fe69a --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,19 @@ + + + $(MSBuildThisFileDirectory).Temp\$(MSBuildProjectName)\ + $(BaseOutputPath)$(Configuration)\ + + $(MSBuildThisFileDirectory).Temp\obj\$(MSBuildProjectName)\ + $(BaseIntermediateOutputPath)$(Configuration)\ + + $(BaseOutputPath)\ + $(BaseIntermediateOutputPath)\ + + diff --git a/JVDesktop/App.axaml b/JVDesktop/App.axaml index 4d268d0..1bebd8d 100644 --- a/JVDesktop/App.axaml +++ b/JVDesktop/App.axaml @@ -1,15 +1,16 @@ - - + - + - + diff --git a/JVDesktop/App.axaml.cs b/JVDesktop/App.axaml.cs index 4c26724..a2ba079 100644 --- a/JVDesktop/App.axaml.cs +++ b/JVDesktop/App.axaml.cs @@ -1,11 +1,10 @@ using Avalonia; using Avalonia.Controls.ApplicationLifetimes; -using Avalonia.Data.Core; using Avalonia.Data.Core.Plugins; using System.Linq; using Avalonia.Markup.Xaml; -using JVDesktop.ViewModels; using JVDesktop.Views; +using JVDesktop.ViewModels; namespace JVDesktop; @@ -20,12 +19,10 @@ public partial class App : Application { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { - // Avoid duplicate validations from both Avalonia and the CommunityToolkit. - // More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins DisableAvaloniaDataAnnotationValidation(); - desktop.MainWindow = new MainWindow + desktop.MainWindow = new DashboardView { - DataContext = new MainWindowViewModel(), + DataContext = new DashboardViewModel(), }; } @@ -34,11 +31,9 @@ public partial class App : Application private void DisableAvaloniaDataAnnotationValidation() { - // Get an array of plugins to remove var dataValidationPluginsToRemove = BindingPlugins.DataValidators.OfType().ToArray(); - // remove each entry found foreach (var plugin in dataValidationPluginsToRemove) { BindingPlugins.DataValidators.Remove(plugin); diff --git a/JVDesktop/JVDesktop.csproj b/JVDesktop/JVDesktop.csproj index e103899..2940b03 100644 --- a/JVDesktop/JVDesktop.csproj +++ b/JVDesktop/JVDesktop.csproj @@ -5,24 +5,39 @@ enable true app.manifest - true + true + ..\.Temp\Debug\ + $(OutputPath) + false + false - - + + - - - - - + + + - None - All + None + All - + + + + + diff --git a/JVDesktop/Program.cs b/JVDesktop/Program.cs index 8d39a63..850598c 100644 --- a/JVDesktop/Program.cs +++ b/JVDesktop/Program.cs @@ -1,18 +1,14 @@ -using Avalonia; +using Avalonia; using System; namespace JVDesktop; sealed class Program { - // Initialization code. Don't use any Avalonia, third-party APIs or any - // SynchronizationContext-reliant code before AppMain is called: things aren't initialized - // yet and stuff might break. [STAThread] public static void Main(string[] args) => BuildAvaloniaApp() .StartWithClassicDesktopLifetime(args); - // Avalonia configuration, don't remove; also used by visual designer. public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure() .UsePlatformDetect() diff --git a/JVDesktop/ViewLocator.cs b/JVDesktop/ViewLocator.cs index 6015998..57507a5 100644 --- a/JVDesktop/ViewLocator.cs +++ b/JVDesktop/ViewLocator.cs @@ -25,6 +25,6 @@ public class ViewLocator : IDataTemplate public bool Match(object? data) { - return data is ViewModelBase; + return data is ViewModel; } } diff --git a/JVDesktop/ViewModels/DashboardViewModel.cs b/JVDesktop/ViewModels/DashboardViewModel.cs new file mode 100644 index 0000000..5ae7d95 --- /dev/null +++ b/JVDesktop/ViewModels/DashboardViewModel.cs @@ -0,0 +1,15 @@ +using System; +using CommunityToolkit.Mvvm.Input; + +namespace JVDesktop.ViewModels; + +public partial class DashboardViewModel : ViewModel +{ + public string Greeting => "Welcome to Avalonia!"; + + [RelayCommand] + private void ButtonClick() + { + Console.WriteLine("Button clicked"); + } +} diff --git a/JVDesktop/ViewModels/MainWindowViewModel.cs b/JVDesktop/ViewModels/MainWindowViewModel.cs deleted file mode 100644 index 4dd12b4..0000000 --- a/JVDesktop/ViewModels/MainWindowViewModel.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Windows.Input; -using CommunityToolkit.Mvvm.Input; - -namespace JVDesktop.ViewModels; - -public class MainWindowViewModel : ViewModelBase -{ - public string Greeting => "Welcome to Avalonia!"; - - public ICommand ButtonClickCommand { get; } = new RelayCommand(() => - { - Console.WriteLine("Button clicked"); - }); -} diff --git a/JVDesktop/ViewModels/ViewModel.cs b/JVDesktop/ViewModels/ViewModel.cs new file mode 100644 index 0000000..c1c5055 --- /dev/null +++ b/JVDesktop/ViewModels/ViewModel.cs @@ -0,0 +1,7 @@ +using CommunityToolkit.Mvvm.ComponentModel; + +namespace JVDesktop.ViewModels; + +public class ViewModel : ObservableObject +{ +} diff --git a/JVDesktop/ViewModels/ViewModelBase.cs b/JVDesktop/ViewModels/ViewModelBase.cs deleted file mode 100644 index bd3dbd8..0000000 --- a/JVDesktop/ViewModels/ViewModelBase.cs +++ /dev/null @@ -1,7 +0,0 @@ -using CommunityToolkit.Mvvm.ComponentModel; - -namespace JVDesktop.ViewModels; - -public class ViewModelBase : ObservableObject -{ -} diff --git a/JVDesktop/Views/DashboardView.axaml b/JVDesktop/Views/DashboardView.axaml new file mode 100644 index 0000000..553754f --- /dev/null +++ b/JVDesktop/Views/DashboardView.axaml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + +