Cosmos/source/Cosmos.Build.Builder/ViewModels/MainWindowViewModel.cs
José Pedro f969601a53
Builder improvements.
- Added check for dependencies, which can be installed from the builder.
- Replaced CosmosTask with CosmosBuildDefinition, which is much simpler.
- The builder can be opened without any command line arguments.
- If the VS path is not specified as a command line argument, it can be selected in a dialog.
2018-03-30 19:44:19 +01:00

153 lines
4.6 KiB
C#

using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Cosmos.Build.Builder.Collections;
using Cosmos.Build.Builder.Models;
using Cosmos.Build.Builder.Services;
namespace Cosmos.Build.Builder.ViewModels
{
internal class MainWindowViewModel : ViewModelBase
{
private const int TailItemCount = 10;
public ObservableFixedSizeStack<string> TailItems { get; }
public ObservableCollection<Section> Sections { get; }
public Section CurrentSection => Sections.LastOrDefault();
public ICommand CopyCommand { get; }
public bool CloseWhenCompleted
{
get => _closeWhenCompleted;
set => SetAndRaiseIfChanged(ref _closeWhenCompleted, value);
}
public WindowState WindowState
{
get => _windowState;
set => SetAndRaiseIfChanged(ref _windowState, value);
}
private ILogger _logger;
private IDialogService<DependencyInstallationDialogViewModel> _dependencyInstallationDialogService;
private IBuildDefinition _buildDefinition;
private Task _buildTask;
private bool _closeWhenCompleted;
private WindowState _windowState;
public MainWindowViewModel(
IDialogService<DependencyInstallationDialogViewModel> dependencyInstallationDialogService,
IBuildDefinition buildDefinition)
{
_dependencyInstallationDialogService = dependencyInstallationDialogService;
_buildDefinition = buildDefinition;
TailItems = new ObservableFixedSizeStack<string>(TailItemCount);
Sections = new ObservableCollection<Section>();
Sections.CollectionChanged += (sender, e) => OnPropertyChanged(nameof(CurrentSection));
CopyCommand = new RelayCommand(CopyLogToClipboard);
CloseWhenCompleted = true;
_logger = new MainWindowLogger(this);
_buildTask = BuildAsync();
}
private void CopyLogToClipboard(object parameter) => Clipboard.SetText(BuildLog());
private string BuildLog()
{
var log = @"
========================================
Builder Log
========================================
";
foreach (var section in Sections)
{
log += $@"
========================================
{section.Name}
========================================
";
log += section.Log + Environment.NewLine;
}
return log;
}
private async Task BuildAsync()
{
try
{
_logger.NewSection("Checking Dependencies");
foreach (var dependency in _buildDefinition.GetDependencies())
{
if (await dependency.IsInstalledAsync(CancellationToken.None).ConfigureAwait(false))
{
_logger.LogMessage($"{dependency.Name} is installed.");
}
else
{
_logger.LogMessage($"{dependency.Name} not found.");
var viewModel = new DependencyInstallationDialogViewModel(dependency);
_dependencyInstallationDialogService.ShowDialog(viewModel);
if (!viewModel.InstallationSucceeded)
{
throw new Exception($"Dependency installation failed! Dependency name: {dependency.Name}");
}
}
}
foreach (var buildTask in _buildDefinition.GetBuildTasks())
{
_logger.NewSection(buildTask.Name);
await buildTask.RunAsync(_logger).ConfigureAwait(false);
}
}
catch (Exception e)
{
_logger.SetError();
_logger.NewSection("Error");
_logger.LogMessage(e.ToString());
_logger.SetError();
}
await Task.Delay(5000).ConfigureAwait(false);
if (CloseWhenCompleted)
{
Application.Current.Dispatcher.Invoke(() => Application.Current?.MainWindow?.Close());
}
else
{
if (WindowState == WindowState.Maximized)
{
WindowState = WindowState.Normal;
}
}
}
}
}