11 Commits

8 changed files with 246 additions and 123 deletions

View File

@@ -75,8 +75,7 @@
"Clean", "Clean",
"Publish", "Publish",
"PublishLinux", "PublishLinux",
"PublishWin", "PublishWin"
"Restore"
] ]
} }
}, },
@@ -89,8 +88,7 @@
"Clean", "Clean",
"Publish", "Publish",
"PublishLinux", "PublishLinux",
"PublishWin", "PublishWin"
"Restore"
] ]
} }
}, },

View File

@@ -20,7 +20,7 @@
Accent="#677696" Accent="#677696"
RegionColor="#282c34" RegionColor="#282c34"
ErrorText="Red" ErrorText="Red"
AltHigh="#282c34" AltHigh="#343a45"
AltMediumLow="#2c313c" AltMediumLow="#2c313c"
ListLow="#21252b" ListLow="#21252b"
ListMedium="#2c313c" ListMedium="#2c313c"

View File

@@ -9,7 +9,7 @@
<Configurations>Debug;Release</Configurations> <Configurations>Debug;Release</Configurations>
<Platforms>AnyCPU</Platforms> <Platforms>AnyCPU</Platforms>
<ApplicationIcon>Assets/app.ico</ApplicationIcon> <ApplicationIcon>Assets/app.ico</ApplicationIcon>
<Version>0.0.9</Version> <Version>0.1.2</Version>
<RuntimeIdentifiers>win-x64;linux-x64</RuntimeIdentifiers> <RuntimeIdentifiers>win-x64;linux-x64</RuntimeIdentifiers>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

View File

@@ -4,30 +4,39 @@ using System.Linq;
using System.Reactive; using System.Reactive;
using System.Reactive.Concurrency; using System.Reactive.Concurrency;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using K8sFileBrowser.Models; using K8sFileBrowser.Models;
using K8sFileBrowser.Services; using K8sFileBrowser.Services;
using Microsoft.IdentityModel.Tokens;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Serilog;
namespace K8sFileBrowser.ViewModels; namespace K8sFileBrowser.ViewModels;
public class MainWindowViewModel : ViewModelBase public class MainWindowViewModel : ViewModelBase
{ {
private ObservableAsPropertyHelper<IEnumerable<ClusterContext>> _clusterContexts = null!;
public IEnumerable<ClusterContext> ClusterContexts => _clusterContexts.Value; #region Properties
[Reactive]
public string? Version { get; set; }
[Reactive]
public IEnumerable<ClusterContext> ClusterContexts { get; set; } = null!;
[Reactive] [Reactive]
public ClusterContext? SelectedClusterContext { get; set; } public ClusterContext? SelectedClusterContext { get; set; }
[Reactive] [Reactive]
public IEnumerable<Namespace> Namespaces { get; set; } public IEnumerable<Namespace> Namespaces { get; set; } = null!;
[Reactive] [Reactive]
public Namespace? SelectedNamespace { get; set; } public Namespace? SelectedNamespace { get; set; }
private ObservableAsPropertyHelper<IEnumerable<Pod>> _pods = null!; [Reactive]
public IEnumerable<Pod> Pods => _pods.Value; public IEnumerable<Pod> Pods { get; set; } = null!;
[Reactive] [Reactive]
public Pod? SelectedPod { get; set; } public Pod? SelectedPod { get; set; }
@@ -38,8 +47,8 @@ public class MainWindowViewModel : ViewModelBase
[Reactive] [Reactive]
public Container? SelectedContainer { get; set; } public Container? SelectedContainer { get; set; }
private ObservableAsPropertyHelper<IEnumerable<FileInformation>> _fileInformation = null!; [Reactive]
public IEnumerable<FileInformation> FileInformation => _fileInformation.Value; public IEnumerable<FileInformation> FileInformation { get; set; } = null!;
[Reactive] [Reactive]
public FileInformation? SelectedFile { get; set; } public FileInformation? SelectedFile { get; set; }
@@ -48,24 +57,33 @@ public class MainWindowViewModel : ViewModelBase
public string? SelectedPath { get; set; } public string? SelectedPath { get; set; }
[Reactive] [Reactive]
public Message Message { get; set; } public Message Message { get; set; } = null!;
private string _lastDirectory = ".";
#endregion Properties
#region Commands
public ReactiveCommand<Unit, Unit> DownloadCommand { get; private set; } = null!; public ReactiveCommand<Unit, Unit> DownloadCommand { get; private set; } = null!;
public ReactiveCommand<Unit, Unit> DownloadLogCommand { get; private set; } = null!; public ReactiveCommand<Unit, Unit> DownloadLogCommand { get; private set; } = null!;
public ReactiveCommand<Unit, Unit> RefreshCommand { get; private set; } = null!;
public ReactiveCommand<Unit, Unit> ParentCommand { get; private set; } = null!; public ReactiveCommand<Unit, Unit> ParentCommand { get; private set; } = null!;
public ReactiveCommand<Unit, Unit> OpenCommand { get; private set; } = null!; public ReactiveCommand<Unit, Unit> OpenCommand { get; private set; } = null!;
private ReactiveCommand<Namespace, IEnumerable<Pod>> GetPodsForNamespace { get; set; } = null!; private ReactiveCommand<Namespace, IEnumerable<Pod>> GetPodsForNamespace { get; set; } = null!;
#endregion Commands
public MainWindowViewModel() public MainWindowViewModel()
{ {
//TODO: use dependency injection to get the kubernetes service
IKubernetesService kubernetesService = new KubernetesService(); IKubernetesService kubernetesService = new KubernetesService();
Version = Assembly.GetExecutingAssembly().GetName().Version?.ToString();
// commands // commands
ConfigureOpenDirectoryCommand(); ConfigureOpenDirectoryCommand();
ConfigureDownloadFileCommand(kubernetesService); ConfigureDownloadFileCommand(kubernetesService);
ConfigureRefreshCommand(kubernetesService);
ConfigureDownloadLogCommand(kubernetesService); ConfigureDownloadLogCommand(kubernetesService);
ConfigureParentDirectoryCommand(); ConfigureParentDirectoryCommand();
ConfigureGetPodsForNamespaceCommand(kubernetesService); ConfigureGetPodsForNamespaceCommand(kubernetesService);
@@ -81,68 +99,25 @@ public class MainWindowViewModel : ViewModelBase
InitiallyLoadContexts(kubernetesService); InitiallyLoadContexts(kubernetesService);
} }
#region Property Subscriptions
private void InitiallyLoadContexts(IKubernetesService kubernetesService) private void InitiallyLoadContexts(IKubernetesService kubernetesService)
{ {
// load the cluster contexts when the view model is created // load the cluster contexts when the view model is created
var loadContexts = ReactiveCommand var loadContexts = ReactiveCommand
.Create<Unit, IEnumerable<ClusterContext>>(_ => kubernetesService.GetClusterContexts()); .Create<Unit, IEnumerable<ClusterContext>>(_ => kubernetesService.GetClusterContexts());
_clusterContexts = loadContexts.Execute().ToProperty( loadContexts.Execute()
this, x => x.ClusterContexts, scheduler: RxApp.MainThreadScheduler);
// select the current cluster context
SelectedClusterContext = ClusterContexts
.FirstOrDefault(x => x.Name == kubernetesService.GetCurrentContext());
}
private void RegisterResetPath()
{
// reset the path when the pod or namespace changes
this.WhenAnyValue(c => c.SelectedPod, c => c.SelectedNamespace)
.Throttle(new TimeSpan(10))
.ObserveOn(RxApp.TaskpoolScheduler)
.Subscribe(_ => SelectedPath = "/");
}
private void RegisterReadContainers()
{
// read the file information when the path changes
this
.WhenAnyValue(c => c.SelectedPod, c => c.SelectedNamespace)
.Throttle(new TimeSpan(10))
.Select(x => x.Item2 == null || x.Item1 == null
? new List<Container>()
: x.Item1.Containers.Select(c => new Container {Name = c}))
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe( x => Containers = x);
this.WhenAnyValue(x => x.Containers)
.Throttle(new TimeSpan(10)) .Throttle(new TimeSpan(10))
.ObserveOn(RxApp.MainThreadScheduler) .ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(x => SelectedContainer = x?.FirstOrDefault()); .Subscribe(x =>
} {
ResetNamespaces();
ClusterContexts = x.OrderBy(c => c.Name);
private void RegisterReadFiles(IKubernetesService kubernetesService) // select the current cluster context
{ SelectedClusterContext = ClusterContexts
// read the file information when the path changes .FirstOrDefault(c => c.Name == kubernetesService.GetCurrentContext());
_fileInformation = this });
.WhenAnyValue(c => c.SelectedPath, c => c.SelectedPod, c => c.SelectedNamespace, c => c.SelectedContainer)
.Throttle(new TimeSpan(10))
.Select(x => x.Item3 == null || x.Item2 == null || x.Item1 == null || x.Item4 == null
? new List<FileInformation>()
: GetFileInformation(kubernetesService, x.Item1, x.Item2, x.Item3, x.Item4))
.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.FileInformation);
}
private void RegisterReadPods()
{
// read the pods when the namespace changes
_pods = this
.WhenAnyValue(c => c.SelectedNamespace)
.Throttle(new TimeSpan(10))
.SelectMany(ns => GetPodsForNamespace.Execute(ns!))
.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.Pods);
} }
private void RegisterReadNamespaces(IKubernetesService kubernetesService) private void RegisterReadNamespaces(IKubernetesService kubernetesService)
@@ -153,16 +128,82 @@ public class MainWindowViewModel : ViewModelBase
.Throttle(new TimeSpan(10)) .Throttle(new TimeSpan(10))
.SelectMany(context => GetClusterContextAsync(context, kubernetesService)) .SelectMany(context => GetClusterContextAsync(context, kubernetesService))
.ObserveOn(RxApp.MainThreadScheduler) .ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(ns => Namespaces = ns); .Subscribe(ns =>
{
ResetPods();
Namespaces = ns.OrderBy(n => n.Name);
});
} }
private void RegisterReadPods()
{
// read the pods when the namespace changes
this
.WhenAnyValue(c => c.SelectedNamespace)
.Throttle(new TimeSpan(10))
.Where(x => x != null)
.SelectMany(ns => GetPodsForNamespace.Execute(ns!))
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(x =>
{
ResetContainers();
Pods = x.OrderBy(p => p.Name);
});
}
private void RegisterReadContainers()
{
// read the file information when the path changes
this
.WhenAnyValue(c => c.SelectedPod)
.Throttle(new TimeSpan(10))
.Where(x => x != null)
.Select(x => x!.Containers.Select(c => new Container {Name = c}))
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe( x =>
{
ResetPath();
Containers = x;
});
this.WhenAnyValue(x => x.Containers)
.Throttle(new TimeSpan(10))
.Where(x => !x.IsNullOrEmpty())
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(x => SelectedContainer = x?.FirstOrDefault());
}
private void RegisterResetPath()
{
// reset the path when the pod or namespace changes
this.WhenAnyValue(c => c.SelectedContainer)
.Throttle(new TimeSpan(10))
.Where(x => x != null)
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(_ => SelectedPath = "/");
}
private void RegisterReadFiles(IKubernetesService kubernetesService)
{
// read the file information when the path changes
this
.WhenAnyValue(c => c.SelectedContainer, c => c.SelectedPath)
.Throttle(new TimeSpan(10))
.Where(x => x is { Item1: not null, Item2: not null })
.Select(x => GetFileInformation(kubernetesService, x.Item2!, SelectedPod!, SelectedNamespace!, x.Item1!))
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(x => FileInformation = x);
}
#endregion Property Subscriptions
#region Configure Commands
private void ConfigureGetPodsForNamespaceCommand(IKubernetesService kubernetesService) private void ConfigureGetPodsForNamespaceCommand(IKubernetesService kubernetesService)
{ {
GetPodsForNamespace = ReactiveCommand.CreateFromObservable<Namespace, IEnumerable<Pod>>(ns => GetPodsForNamespace = ReactiveCommand.CreateFromObservable<Namespace, IEnumerable<Pod>>(ns =>
Observable.StartAsync(_ => PodsAsync(ns, kubernetesService), RxApp.TaskpoolScheduler)); Observable.StartAsync(_ => PodsAsync(ns, kubernetesService), RxApp.TaskpoolScheduler));
GetPodsForNamespace.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler) GetPodsForNamespace.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(ex => ShowErrorMessage(ex.Message).ConfigureAwait(false).GetAwaiter().GetResult()); .Subscribe(ShowErrorMessage);
} }
private void ConfigureParentDirectoryCommand() private void ConfigureParentDirectoryCommand()
@@ -181,7 +222,7 @@ public class MainWindowViewModel : ViewModelBase
}, isNotRoot, RxApp.MainThreadScheduler); }, isNotRoot, RxApp.MainThreadScheduler);
ParentCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler) ParentCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(ex => ShowErrorMessage(ex.Message).ConfigureAwait(false).GetAwaiter().GetResult()); .Subscribe(ShowErrorMessage);
} }
private void ConfigureDownloadLogCommand(IKubernetesService kubernetesService) private void ConfigureDownloadLogCommand(IKubernetesService kubernetesService)
@@ -195,9 +236,10 @@ public class MainWindowViewModel : ViewModelBase
await Observable.StartAsync(async () => await Observable.StartAsync(async () =>
{ {
var fileName = SelectedPod?.Name + ".log"; var fileName = SelectedPod?.Name + ".log";
var saveFileName = await ApplicationHelper.SaveFile(".", fileName); var saveFileName = await ApplicationHelper.SaveFile(_lastDirectory, fileName);
if (saveFileName != null) if (saveFileName != null)
{ {
SetLastDirectory(saveFileName);
ShowWorkingMessage("Downloading Log..."); ShowWorkingMessage("Downloading Log...");
await kubernetesService.DownloadLog(SelectedNamespace, SelectedPod, SelectedContainer, saveFileName); await kubernetesService.DownloadLog(SelectedNamespace, SelectedPod, SelectedContainer, saveFileName);
HideWorkingMessage(); HideWorkingMessage();
@@ -206,7 +248,25 @@ public class MainWindowViewModel : ViewModelBase
}, isSelectedPod, RxApp.MainThreadScheduler); }, isSelectedPod, RxApp.MainThreadScheduler);
DownloadLogCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler) DownloadLogCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(ex => ShowErrorMessage(ex.Message).ConfigureAwait(false).GetAwaiter().GetResult()); .Subscribe(ShowErrorMessage);
}
private void ConfigureRefreshCommand(IKubernetesService kubernetesService)
{
var isSelectedContainer = this
.WhenAnyValue(x => x.SelectedContainer)
.Select(x => x != null);
RefreshCommand = ReactiveCommand.CreateFromTask(async () =>
{
await Observable.Start(() =>
{
FileInformation = GetFileInformation(kubernetesService, SelectedPath!, SelectedPod!, SelectedNamespace!, SelectedContainer!);
}, RxApp.TaskpoolScheduler);
}, isSelectedContainer, RxApp.MainThreadScheduler);
RefreshCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(ShowErrorMessage);
} }
private void ConfigureDownloadFileCommand(IKubernetesService kubernetesService) private void ConfigureDownloadFileCommand(IKubernetesService kubernetesService)
@@ -221,9 +281,10 @@ public class MainWindowViewModel : ViewModelBase
{ {
var fileName = SelectedFile!.Name.Substring(SelectedFile!.Name.LastIndexOf('/') + 1, var fileName = SelectedFile!.Name.Substring(SelectedFile!.Name.LastIndexOf('/') + 1,
SelectedFile!.Name.Length - SelectedFile!.Name.LastIndexOf('/') - 1); SelectedFile!.Name.Length - SelectedFile!.Name.LastIndexOf('/') - 1);
var saveFileName = await ApplicationHelper.SaveFile(".", fileName); var saveFileName = await ApplicationHelper.SaveFile(_lastDirectory, fileName);
if (saveFileName != null) if (saveFileName != null)
{ {
SetLastDirectory(saveFileName);
ShowWorkingMessage("Downloading File..."); ShowWorkingMessage("Downloading File...");
await kubernetesService.DownloadFile(SelectedNamespace, SelectedPod, SelectedContainer, SelectedFile, saveFileName); await kubernetesService.DownloadFile(SelectedNamespace, SelectedPod, SelectedContainer, SelectedFile, saveFileName);
HideWorkingMessage(); HideWorkingMessage();
@@ -232,7 +293,12 @@ public class MainWindowViewModel : ViewModelBase
}, isFile, RxApp.MainThreadScheduler); }, isFile, RxApp.MainThreadScheduler);
DownloadCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler) DownloadCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(ex => ShowErrorMessage(ex.Message).ConfigureAwait(false).GetAwaiter().GetResult()); .Subscribe(ShowErrorMessage);
}
private void SetLastDirectory(string saveFileName)
{
_lastDirectory = saveFileName.Substring(0, saveFileName.LastIndexOf('\\'));
} }
private void ConfigureOpenDirectoryCommand() private void ConfigureOpenDirectoryCommand()
@@ -251,9 +317,13 @@ public class MainWindowViewModel : ViewModelBase
isDirectory, RxApp.MainThreadScheduler); isDirectory, RxApp.MainThreadScheduler);
OpenCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler) OpenCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(ex => ShowErrorMessage(ex.Message).ConfigureAwait(false).GetAwaiter().GetResult()); .Subscribe(ShowErrorMessage);
} }
#endregion Configure Commands
#region Get Data
private static async Task<IEnumerable<Pod>> PodsAsync(Namespace? ns, IKubernetesService kubernetesService) private static async Task<IEnumerable<Pod>> PodsAsync(Namespace? ns, IKubernetesService kubernetesService)
{ {
if (ns == null) if (ns == null)
@@ -277,10 +347,8 @@ public class MainWindowViewModel : ViewModelBase
} }
catch (Exception e) catch (Exception e)
{ {
RxApp.MainThreadScheduler.Schedule(Action); ShowErrorMessage(e);
return new List<Namespace>(); return new List<Namespace>();
async void Action() => await ShowErrorMessage(e.Message);
} }
} }
@@ -308,35 +376,89 @@ public class MainWindowViewModel : ViewModelBase
}).ToList(); }).ToList();
} }
private void ShowWorkingMessage(string message) #endregion Get Data
#region Reset Data
private void ResetPath()
{ {
Message = new Message FileInformation = new List<FileInformation>();
{ SelectedPath = null;
IsVisible = true, SelectedContainer = null;
Text = message,
IsError = false
};
} }
private async Task ShowErrorMessage(string message) private void ResetContainers()
{ {
Message = new Message ResetPath();
Containers = new List<Container>();
SelectedPod = null;
}
private void ResetPods()
{
ResetContainers();
SelectedNamespace = null;
Pods = new List<Pod>();
}
private void ResetNamespaces()
{
ResetPods();
Namespaces = new List<Namespace>();
SelectedClusterContext = null;
}
#endregion Reset Data
#region show messages
private void ShowWorkingMessage(string message)
{
RxApp.MainThreadScheduler.Schedule(Action);
return;
void Action()
{ {
IsVisible = true, Message = new Message
Text = message, {
IsError = true IsVisible = true,
}; Text = message,
await Task.Delay(7000); IsError = false
HideWorkingMessage(); };
}
}
private void ShowErrorMessage(string message)
{
RxApp.MainThreadScheduler.Schedule(Action);
return;
async void Action()
{
Message = new Message { IsVisible = true, Text = message, IsError = true };
await Task.Delay(7000);
HideWorkingMessage();
}
}
private void ShowErrorMessage(Exception exception)
{
// ReSharper disable once TemplateIsNotCompileTimeConstantProblem
Log.Error(exception, exception.Message);
ShowErrorMessage(exception.Message);
} }
private void HideWorkingMessage() private void HideWorkingMessage()
{ {
Message = new Message RxApp.MainThreadScheduler.Schedule(() => Message = new Message
{ {
IsVisible = false, IsVisible = false,
Text = "", Text = "",
IsError = false IsError = false
}; });
} }
#endregion show messages
} }

View File

@@ -24,7 +24,7 @@
</Border> </Border>
<Grid RowDefinitions="Auto, *"> <Grid RowDefinitions="Auto, *">
<Border Padding="10 14" Background="#21252b"> <Border Padding="10 14" Background="#21252b">
<Grid ColumnDefinitions="Auto,Auto,Auto,*"> <Grid ColumnDefinitions="Auto,Auto,Auto,*,Auto">
<Label Grid.Column="0" <Label Grid.Column="0"
VerticalAlignment="Center" VerticalAlignment="Center"
Margin="0 0 10 0"> Margin="0 0 10 0">
@@ -49,6 +49,7 @@
MinWidth="200" MinWidth="200"
Margin="0 0 10 0"> Margin="0 0 10 0">
</ComboBox> </ComboBox>
<TextBlock Grid.Column="4" HorizontalAlignment="Right" VerticalAlignment="Center" Text="{Binding Version}"/>
</Grid> </Grid>
</Border> </Border>
@@ -93,6 +94,9 @@
<Button Command="{Binding DownloadLogCommand}" VerticalAlignment="Center" ToolTip.Tip="Download Container Log" Margin="0 0 48 0 "> <Button Command="{Binding DownloadLogCommand}" VerticalAlignment="Center" ToolTip.Tip="Download Container Log" Margin="0 0 48 0 ">
<PathIcon Data="{StaticResource document_one_page_regular}"></PathIcon> <PathIcon Data="{StaticResource document_one_page_regular}"></PathIcon>
</Button> </Button>
<Button Command="{Binding RefreshCommand}" VerticalAlignment="Center" ToolTip.Tip="Refresh Directory">
<PathIcon Data="{StaticResource arrow_sync_circle_regular}"></PathIcon>
</Button>
<Button Command="{Binding ParentCommand}" VerticalAlignment="Center" ToolTip.Tip="Go To Parent Directory"> <Button Command="{Binding ParentCommand}" VerticalAlignment="Center" ToolTip.Tip="Go To Parent Directory">
<PathIcon Data="{StaticResource arrow_curve_up_left_regular}"></PathIcon> <PathIcon Data="{StaticResource arrow_curve_up_left_regular}"></PathIcon>
</Button> </Button>

View File

@@ -3,4 +3,14 @@
A UI tool for downloading files from a Pod. A UI tool for downloading files from a Pod.
The application is also the first Avalonia UI and C# UI app I have written. The application is also the first Avalonia UI and C# UI app I have written.
## Usage
Just start the executable and select the cluster, namespace and pod you want to download files from.
Then select the files you want to download and click the download button.
The available clusters are read from the `~/.kube/config` file.
## Limitations
It only works on linux containers and the container must support `find` and `tar`.
![screenshot of K8sFileBrowser](https://github.com/frosch95/K8sFileBrowser/blob/master/screenshot.png?raw=true) ![screenshot of K8sFileBrowser](https://github.com/frosch95/K8sFileBrowser/blob/master/screenshot.png?raw=true)

View File

@@ -11,40 +11,31 @@ class Build : NukeBuild
{ {
[Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")] [Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")]
readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release; readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release;
[Parameter] readonly string Version = "1.0.0"; [Parameter] readonly string Version = "1.0.0";
AbsolutePath SourceDirectory => RootDirectory / "K8sFileBrowser"; AbsolutePath SourceDirectory => RootDirectory / "K8sFileBrowser";
AbsolutePath OutputDirectory => RootDirectory / "output"; AbsolutePath OutputDirectory => RootDirectory / "output";
AbsolutePath WinOutputDirectory => OutputDirectory / "win"; AbsolutePath WinOutputDirectory => OutputDirectory / "win";
AbsolutePath LinuxOutputDirectory => OutputDirectory / "linux"; AbsolutePath LinuxOutputDirectory => OutputDirectory / "linux";
AbsolutePath WinZip => OutputDirectory / $"K8sFileBrowser_{Version}.zip"; AbsolutePath WinZip => OutputDirectory / $"K8sFileBrowser_{Version}.zip";
AbsolutePath LinuxGz => OutputDirectory / $"K8sFileBrowser_{Version}.tgz"; AbsolutePath LinuxGz => OutputDirectory / $"K8sFileBrowser_{Version}.tgz";
AbsolutePath ProjectFile => SourceDirectory / "K8sFileBrowser.csproj"; AbsolutePath ProjectFile => SourceDirectory / "K8sFileBrowser.csproj";
readonly string ExcludedExtensions = "pdb"; readonly string ExcludedExtensions = "pdb";
public static int Main () => Execute<Build>(x => x.Publish); public static int Main () => Execute<Build>(x => x.Publish);
Target Clean => _ => _ Target Clean => _ => _
.Before(Restore)
.Executes(() => .Executes(() =>
{ {
OutputDirectory.DeleteDirectory(); OutputDirectory.DeleteDirectory();
}); });
Target Restore => _ => _
.Executes(() =>
{
DotNet($"restore {ProjectFile}");
//DotNetTasks.DotNetRestore(new DotNetRestoreSettings());
});
Target PublishWin => _ => _ Target PublishWin => _ => _
.DependsOn(Clean) .DependsOn(Clean)
.Executes(() => .Executes(() =>
@@ -62,18 +53,17 @@ class Build : NukeBuild
.SetCopyright("Copyright (c) 2023") .SetCopyright("Copyright (c) 2023")
.SetVersion(Version) .SetVersion(Version)
.SetProcessArgumentConfigurator(_ => _ .SetProcessArgumentConfigurator(_ => _
.Add("-p:IncludeNativeLibrariesForSelfExtract=true")) .Add("-p:IncludeNativeLibrariesForSelfExtract=true")));
.EnableNoRestore());
WinOutputDirectory.ZipTo( WinOutputDirectory.ZipTo(
WinZip, WinZip,
filter: x => !x.HasExtension(ExcludedExtensions), filter: x => !x.HasExtension(ExcludedExtensions),
compressionLevel: CompressionLevel.SmallestSize, compressionLevel: CompressionLevel.SmallestSize,
fileMode: FileMode.CreateNew); fileMode: FileMode.CreateNew);
}); });
Target PublishLinux => _ => _ Target PublishLinux => _ => _
.DependsOn(Clean) .DependsOn(Clean)
.Executes(() => .Executes(() =>
{ {
DotNetPublish(s => s DotNetPublish(s => s
@@ -89,19 +79,18 @@ class Build : NukeBuild
.SetCopyright("Copyright (c) 2023") .SetCopyright("Copyright (c) 2023")
.SetVersion(Version) .SetVersion(Version)
.SetProcessArgumentConfigurator(_ => _ .SetProcessArgumentConfigurator(_ => _
.Add("-p:IncludeNativeLibrariesForSelfExtract=true")) .Add("-p:IncludeNativeLibrariesForSelfExtract=true")));
.EnableNoRestore());
LinuxOutputDirectory.TarGZipTo( LinuxOutputDirectory.TarGZipTo(
LinuxGz, LinuxGz,
filter: x => !x.HasExtension(ExcludedExtensions), filter: x => !x.HasExtension(ExcludedExtensions),
fileMode: FileMode.CreateNew); fileMode: FileMode.CreateNew);
}); });
Target Publish => _ => _ Target Publish => _ => _
.DependsOn(PublishWin, PublishLinux) .DependsOn(PublishWin, PublishLinux)
.Executes(() => .Executes(() =>
{ {
}); });
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 150 KiB