mirror of
https://github.com/frosch95/K8sFileBrowser.git
synced 2026-04-11 12:58:22 +02:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d405677420 | |||
| 0e979fad5f | |||
| 6754210e9b | |||
| 0d11fdd000 | |||
| b33552531a | |||
| 7f7471d47b | |||
| 6d03c88261 | |||
| a696152667 | |||
| 491127d460 |
@@ -75,8 +75,7 @@
|
||||
"Clean",
|
||||
"Publish",
|
||||
"PublishLinux",
|
||||
"PublishWin",
|
||||
"Restore"
|
||||
"PublishWin"
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -89,8 +88,7 @@
|
||||
"Clean",
|
||||
"Publish",
|
||||
"PublishLinux",
|
||||
"PublishWin",
|
||||
"Restore"
|
||||
"PublishWin"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
Accent="#677696"
|
||||
RegionColor="#282c34"
|
||||
ErrorText="Red"
|
||||
AltHigh="#282c34"
|
||||
AltHigh="#343a45"
|
||||
AltMediumLow="#2c313c"
|
||||
ListLow="#21252b"
|
||||
ListMedium="#2c313c"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Platforms>AnyCPU</Platforms>
|
||||
<ApplicationIcon>Assets/app.ico</ApplicationIcon>
|
||||
<Version>0.0.9</Version>
|
||||
<Version>0.1.2</Version>
|
||||
<RuntimeIdentifiers>win-x64;linux-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
|
||||
@@ -4,16 +4,25 @@ using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Concurrency;
|
||||
using System.Reactive.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using K8sFileBrowser.Models;
|
||||
using K8sFileBrowser.Services;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using Serilog;
|
||||
|
||||
namespace K8sFileBrowser.ViewModels;
|
||||
|
||||
public class MainWindowViewModel : ViewModelBase
|
||||
{
|
||||
|
||||
#region Properties
|
||||
|
||||
[Reactive]
|
||||
public string? Version { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public IEnumerable<ClusterContext> ClusterContexts { get; set; } = null!;
|
||||
|
||||
@@ -50,22 +59,31 @@ public class MainWindowViewModel : ViewModelBase
|
||||
[Reactive]
|
||||
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> 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> OpenCommand { get; private set; } = null!;
|
||||
|
||||
private ReactiveCommand<Namespace, IEnumerable<Pod>> GetPodsForNamespace { get; set; } = null!;
|
||||
|
||||
#endregion Commands
|
||||
|
||||
public MainWindowViewModel()
|
||||
{
|
||||
//TODO: use dependency injection to get the kubernetes service
|
||||
IKubernetesService kubernetesService = new KubernetesService();
|
||||
|
||||
Version = Assembly.GetExecutingAssembly().GetName().Version?.ToString();
|
||||
|
||||
// commands
|
||||
ConfigureOpenDirectoryCommand();
|
||||
ConfigureDownloadFileCommand(kubernetesService);
|
||||
ConfigureRefreshCommand(kubernetesService);
|
||||
ConfigureDownloadLogCommand(kubernetesService);
|
||||
ConfigureParentDirectoryCommand();
|
||||
ConfigureGetPodsForNamespaceCommand(kubernetesService);
|
||||
@@ -81,6 +99,8 @@ public class MainWindowViewModel : ViewModelBase
|
||||
InitiallyLoadContexts(kubernetesService);
|
||||
}
|
||||
|
||||
#region Property Subscriptions
|
||||
|
||||
private void InitiallyLoadContexts(IKubernetesService kubernetesService)
|
||||
{
|
||||
// load the cluster contexts when the view model is created
|
||||
@@ -91,70 +111,12 @@ public class MainWindowViewModel : ViewModelBase
|
||||
.ObserveOn(RxApp.MainThreadScheduler)
|
||||
.Subscribe(x =>
|
||||
{
|
||||
ClusterContexts = x;
|
||||
ResetNamespaces();
|
||||
ClusterContexts = x.OrderBy(c => c.Name);
|
||||
|
||||
// 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.SelectedContainer)
|
||||
.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)
|
||||
.Throttle(new TimeSpan(10))
|
||||
.Select(x => x == null
|
||||
? new List<Container>()
|
||||
: x.Containers.Select(c => new Container {Name = c}))
|
||||
.ObserveOn(RxApp.MainThreadScheduler)
|
||||
.Subscribe( x =>
|
||||
{
|
||||
Containers = x;
|
||||
FileInformation = new List<FileInformation>();
|
||||
});
|
||||
|
||||
this.WhenAnyValue(x => x.Containers)
|
||||
.Throttle(new TimeSpan(10))
|
||||
.ObserveOn(RxApp.MainThreadScheduler)
|
||||
.Subscribe(x => SelectedContainer = x?.FirstOrDefault());
|
||||
}
|
||||
|
||||
private void RegisterReadFiles(IKubernetesService kubernetesService)
|
||||
{
|
||||
// read the file information when the path changes
|
||||
this
|
||||
.WhenAnyValue(c => c.SelectedContainer)
|
||||
.Throttle(new TimeSpan(10))
|
||||
.Select(x => x == null
|
||||
? new List<FileInformation>()
|
||||
: GetFileInformation(kubernetesService, SelectedPath!, SelectedPod!, SelectedNamespace!, x))
|
||||
.ObserveOn(RxApp.MainThreadScheduler)
|
||||
.Subscribe(x => FileInformation = x);
|
||||
}
|
||||
|
||||
private void RegisterReadPods()
|
||||
{
|
||||
// read the pods when the namespace changes
|
||||
this
|
||||
.WhenAnyValue(c => c.SelectedNamespace)
|
||||
.Throttle(new TimeSpan(10))
|
||||
.SelectMany(ns => GetPodsForNamespace.Execute(ns!))
|
||||
.ObserveOn(RxApp.MainThreadScheduler)
|
||||
.Subscribe(x =>
|
||||
{
|
||||
Pods = x;
|
||||
Containers = null;
|
||||
FileInformation = new List<FileInformation>();
|
||||
.FirstOrDefault(c => c.Name == kubernetesService.GetCurrentContext());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -168,20 +130,80 @@ public class MainWindowViewModel : ViewModelBase
|
||||
.ObserveOn(RxApp.MainThreadScheduler)
|
||||
.Subscribe(ns =>
|
||||
{
|
||||
Namespaces = ns;
|
||||
Pods = new List<Pod>();
|
||||
Containers = null;
|
||||
FileInformation = new List<FileInformation>();
|
||||
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)
|
||||
{
|
||||
GetPodsForNamespace = ReactiveCommand.CreateFromObservable<Namespace, IEnumerable<Pod>>(ns =>
|
||||
Observable.StartAsync(_ => PodsAsync(ns, kubernetesService), RxApp.TaskpoolScheduler));
|
||||
|
||||
GetPodsForNamespace.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
|
||||
.Subscribe(ex => ShowErrorMessage(ex.Message).ConfigureAwait(false).GetAwaiter().GetResult());
|
||||
.Subscribe(ShowErrorMessage);
|
||||
}
|
||||
|
||||
private void ConfigureParentDirectoryCommand()
|
||||
@@ -200,7 +222,7 @@ public class MainWindowViewModel : ViewModelBase
|
||||
}, isNotRoot, RxApp.MainThreadScheduler);
|
||||
|
||||
ParentCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
|
||||
.Subscribe(ex => ShowErrorMessage(ex.Message).ConfigureAwait(false).GetAwaiter().GetResult());
|
||||
.Subscribe(ShowErrorMessage);
|
||||
}
|
||||
|
||||
private void ConfigureDownloadLogCommand(IKubernetesService kubernetesService)
|
||||
@@ -214,9 +236,10 @@ public class MainWindowViewModel : ViewModelBase
|
||||
await Observable.StartAsync(async () =>
|
||||
{
|
||||
var fileName = SelectedPod?.Name + ".log";
|
||||
var saveFileName = await ApplicationHelper.SaveFile(".", fileName);
|
||||
var saveFileName = await ApplicationHelper.SaveFile(_lastDirectory, fileName);
|
||||
if (saveFileName != null)
|
||||
{
|
||||
SetLastDirectory(saveFileName);
|
||||
ShowWorkingMessage("Downloading Log...");
|
||||
await kubernetesService.DownloadLog(SelectedNamespace, SelectedPod, SelectedContainer, saveFileName);
|
||||
HideWorkingMessage();
|
||||
@@ -225,7 +248,25 @@ public class MainWindowViewModel : ViewModelBase
|
||||
}, isSelectedPod, 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)
|
||||
@@ -240,9 +281,10 @@ public class MainWindowViewModel : ViewModelBase
|
||||
{
|
||||
var fileName = SelectedFile!.Name.Substring(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)
|
||||
{
|
||||
SetLastDirectory(saveFileName);
|
||||
ShowWorkingMessage("Downloading File...");
|
||||
await kubernetesService.DownloadFile(SelectedNamespace, SelectedPod, SelectedContainer, SelectedFile, saveFileName);
|
||||
HideWorkingMessage();
|
||||
@@ -251,7 +293,12 @@ public class MainWindowViewModel : ViewModelBase
|
||||
}, isFile, 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()
|
||||
@@ -270,9 +317,13 @@ public class MainWindowViewModel : ViewModelBase
|
||||
isDirectory, 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)
|
||||
{
|
||||
if (ns == null)
|
||||
@@ -296,10 +347,8 @@ public class MainWindowViewModel : ViewModelBase
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
RxApp.MainThreadScheduler.Schedule(Action);
|
||||
ShowErrorMessage(e);
|
||||
return new List<Namespace>();
|
||||
|
||||
async void Action() => await ShowErrorMessage(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,35 +376,89 @@ public class MainWindowViewModel : ViewModelBase
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
private void ShowWorkingMessage(string message)
|
||||
#endregion Get Data
|
||||
|
||||
#region Reset Data
|
||||
|
||||
private void ResetPath()
|
||||
{
|
||||
Message = new Message
|
||||
{
|
||||
IsVisible = true,
|
||||
Text = message,
|
||||
IsError = false
|
||||
};
|
||||
FileInformation = new List<FileInformation>();
|
||||
SelectedPath = null;
|
||||
SelectedContainer = null;
|
||||
}
|
||||
|
||||
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,
|
||||
Text = message,
|
||||
IsError = true
|
||||
};
|
||||
await Task.Delay(7000);
|
||||
HideWorkingMessage();
|
||||
Message = new Message
|
||||
{
|
||||
IsVisible = true,
|
||||
Text = message,
|
||||
IsError = false
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
Message = new Message
|
||||
RxApp.MainThreadScheduler.Schedule(() => Message = new Message
|
||||
{
|
||||
IsVisible = false,
|
||||
Text = "",
|
||||
IsError = false
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#endregion show messages
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
</Border>
|
||||
<Grid RowDefinitions="Auto, *">
|
||||
<Border Padding="10 14" Background="#21252b">
|
||||
<Grid ColumnDefinitions="Auto,Auto,Auto,*">
|
||||
<Grid ColumnDefinitions="Auto,Auto,Auto,*,Auto">
|
||||
<Label Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0 0 10 0">
|
||||
@@ -49,6 +49,7 @@
|
||||
MinWidth="200"
|
||||
Margin="0 0 10 0">
|
||||
</ComboBox>
|
||||
<TextBlock Grid.Column="4" HorizontalAlignment="Right" VerticalAlignment="Center" Text="{Binding Version}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
@@ -93,6 +94,9 @@
|
||||
<Button Command="{Binding DownloadLogCommand}" VerticalAlignment="Center" ToolTip.Tip="Download Container Log" Margin="0 0 48 0 ">
|
||||
<PathIcon Data="{StaticResource document_one_page_regular}"></PathIcon>
|
||||
</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">
|
||||
<PathIcon Data="{StaticResource arrow_curve_up_left_regular}"></PathIcon>
|
||||
</Button>
|
||||
|
||||
@@ -31,20 +31,11 @@ class Build : NukeBuild
|
||||
|
||||
|
||||
Target Clean => _ => _
|
||||
.Before(Restore)
|
||||
.Executes(() =>
|
||||
{
|
||||
OutputDirectory.DeleteDirectory();
|
||||
});
|
||||
|
||||
Target Restore => _ => _
|
||||
.Executes(() =>
|
||||
{
|
||||
DotNet($"restore {ProjectFile}");
|
||||
//DotNetTasks.DotNetRestore(new DotNetRestoreSettings());
|
||||
});
|
||||
|
||||
|
||||
Target PublishWin => _ => _
|
||||
.DependsOn(Clean)
|
||||
.Executes(() =>
|
||||
@@ -62,8 +53,7 @@ class Build : NukeBuild
|
||||
.SetCopyright("Copyright (c) 2023")
|
||||
.SetVersion(Version)
|
||||
.SetProcessArgumentConfigurator(_ => _
|
||||
.Add("-p:IncludeNativeLibrariesForSelfExtract=true"))
|
||||
.EnableNoRestore());
|
||||
.Add("-p:IncludeNativeLibrariesForSelfExtract=true")));
|
||||
|
||||
WinOutputDirectory.ZipTo(
|
||||
WinZip,
|
||||
@@ -73,7 +63,7 @@ class Build : NukeBuild
|
||||
});
|
||||
|
||||
Target PublishLinux => _ => _
|
||||
.DependsOn(Clean)
|
||||
.DependsOn(Clean)
|
||||
.Executes(() =>
|
||||
{
|
||||
DotNetPublish(s => s
|
||||
@@ -89,8 +79,7 @@ class Build : NukeBuild
|
||||
.SetCopyright("Copyright (c) 2023")
|
||||
.SetVersion(Version)
|
||||
.SetProcessArgumentConfigurator(_ => _
|
||||
.Add("-p:IncludeNativeLibrariesForSelfExtract=true"))
|
||||
.EnableNoRestore());
|
||||
.Add("-p:IncludeNativeLibrariesForSelfExtract=true")));
|
||||
|
||||
LinuxOutputDirectory.TarGZipTo(
|
||||
LinuxGz,
|
||||
|
||||
Reference in New Issue
Block a user