diff --git a/CodeMonitor/CodeMonitor.csproj b/CodeMonitor/CodeMonitor.csproj index 1f230cd..50a25f1 100644 --- a/CodeMonitor/CodeMonitor.csproj +++ b/CodeMonitor/CodeMonitor.csproj @@ -1,8 +1,12 @@ - + WinExe netcoreapp3.0 + + none + false + %(Filename) diff --git a/CodeMonitor/Models/CleanupCodeFile.cs b/CodeMonitor/Models/CleanupCodeFile.cs index e6cbc0f..6b65dc9 100644 --- a/CodeMonitor/Models/CleanupCodeFile.cs +++ b/CodeMonitor/Models/CleanupCodeFile.cs @@ -1,4 +1,4 @@ -namespace CodeMonitor +namespace CodeMonitor.Models { public class CleanupCodeFile { @@ -7,6 +7,6 @@ public CleanupCodeFile(string path) Path = path; } - public string Path {get;} + public string Path { get; } } } diff --git a/CodeMonitor/Models/CleanupCodeWatcher.cs b/CodeMonitor/Models/CleanupCodeWatcher.cs index 65e5b01..1957dc5 100644 --- a/CodeMonitor/Models/CleanupCodeWatcher.cs +++ b/CodeMonitor/Models/CleanupCodeWatcher.cs @@ -1,16 +1,14 @@ using System; using System.Linq; -using System.Xml.Linq; using System.Collections.Generic; using System.IO; using System.Diagnostics; using System.Text; using System.Reactive.Subjects; using System.Reactive.Linq; -using System.Reactive.Concurrency; using DynamicData; - -namespace CodeMonitor + +namespace CodeMonitor.Models { public class CleanupCodeWatcher { @@ -57,8 +55,11 @@ private bool ShouldHandle(string s) s.EndsWith("~") || s.EndsWith(".csproj") || s.EndsWith(".TMP") - ) return false; - + ) + { + return false; + } + if (Directory.Exists(s)) { return false; @@ -76,9 +77,7 @@ private bool ShouldHandle(string s) var result = proc.StandardOutput.ReadToEnd(); proc.WaitForExit(); - if (result != "") return false; - - return true; + return result?.Length == 0; } public void ResetChanged() @@ -112,7 +111,7 @@ public void CleanupFiles() { var psi = new ProcessStartInfo { - FileName = @"c:\bin\cleanupcode.exe", + FileName = $@"{Settings.RsCltPath}\cleanupcode.exe", CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true, @@ -150,7 +149,7 @@ public void CleanupFiles() throw new Exception("CleanupCode was sad"); } - lock(_mutex) + lock (_mutex) { _changed.Clear(); results.Clear(); @@ -182,6 +181,5 @@ public void Start() ResetChanged(); } - } } diff --git a/CodeMonitor/Models/InspectCodeLoop.cs b/CodeMonitor/Models/InspectCodeLoop.cs index 4597474..65a2885 100644 --- a/CodeMonitor/Models/InspectCodeLoop.cs +++ b/CodeMonitor/Models/InspectCodeLoop.cs @@ -9,8 +9,8 @@ using System.Reactive.Linq; using System.Reactive.Concurrency; using DynamicData; - -namespace CodeMonitor + +namespace CodeMonitor.Models { public class InspectCodeLoop { @@ -54,8 +54,11 @@ private bool ShouldHandle(string s) s.EndsWith("~") || s.EndsWith(".csproj") || s.EndsWith(".TMP") - ) return false; - + ) + { + return false; + } + if (Directory.Exists(s)) { return false; @@ -73,9 +76,7 @@ private bool ShouldHandle(string s) var result = proc.StandardOutput.ReadToEnd(); proc.WaitForExit(); - if (result != "") return false; - - return true; + return result?.Length == 0; } private void ExamineFiles(ICollection filePaths) @@ -84,7 +85,7 @@ private void ExamineFiles(ICollection filePaths) var psi = new ProcessStartInfo { - FileName = @"c:\bin\inspectcode.exe", + FileName = $@"{Settings.RsCltPath}\inspectcode.exe", CreateNoWindow = true, RedirectStandardOutput = true }; @@ -104,7 +105,7 @@ private void ExamineFiles(ICollection filePaths) } //TODO: Use a config file - if(filePaths.Count < 100) + if (filePaths.Count < 100) { args.AddRange(filePaths.Select(x => $"--input={x}")); } @@ -114,7 +115,7 @@ private void ExamineFiles(ICollection filePaths) args.ForEach(psi.ArgumentList.Add); var proc = Process.Start(psi); - proc.OutputDataReceived += (o,e) => status.OnNext(e.Data); + proc.OutputDataReceived += (o, e) => status.OnNext(e.Data); proc.BeginOutputReadLine(); proc.WaitForExit(); var xml = File.ReadAllText(outFile); @@ -123,7 +124,7 @@ private void ExamineFiles(ICollection filePaths) var problems = doc.Root.Element("Issues") .Elements("Project") - .Elements((XName)"Issue") + .Elements("Issue") .Select(x => ( File: x.Attribute("File").Value, @@ -145,7 +146,7 @@ private void ExamineFiles(ICollection filePaths) } } - IDisposable subscription; + private IDisposable subscription; internal void Stop() { @@ -197,25 +198,24 @@ private void Loop(long _) .Select(x => x.key) .ToList(); - if (gone.Any() || _changed.Any()) + if (gone.Count > 0 || _changed.Count > 0) { var changeNote = new StringBuilder(); changeNote.AppendLine(); changeNote.AppendLine("Changes detected!"); - if (gone.Any()) + if (gone.Count > 0) { changeNote.AppendLine("Gone: "); changeNote.AppendLine(string.Join(Environment.NewLine, gone)); } - if (_changed.Any()) + if (_changed.Count > 0) { changeNote.AppendLine("Changed: "); changeNote.AppendLine(string.Join(Environment.NewLine, _changed)); } changeNote.AppendLine("Analyzing..."); - foreach (var g in gone) { results.Remove(g); @@ -230,7 +230,6 @@ private void Loop(long _) } finally { - status.OnNext("Idle"); active.OnNext(false); } diff --git a/CodeMonitor/Models/InspectCodeProblem.cs b/CodeMonitor/Models/InspectCodeProblem.cs index d2ddd25..fab5012 100644 --- a/CodeMonitor/Models/InspectCodeProblem.cs +++ b/CodeMonitor/Models/InspectCodeProblem.cs @@ -1,4 +1,4 @@ -namespace CodeMonitor +namespace CodeMonitor.Models { public class InspectCodeProblem { diff --git a/CodeMonitor/Models/InspectCodeResult.cs b/CodeMonitor/Models/InspectCodeResult.cs index 88684a1..42980bd 100644 --- a/CodeMonitor/Models/InspectCodeResult.cs +++ b/CodeMonitor/Models/InspectCodeResult.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace CodeMonitor +namespace CodeMonitor.Models { public class InspectCodeFileProblems { diff --git a/CodeMonitor/Program.cs b/CodeMonitor/Program.cs index f496777..de517bb 100644 --- a/CodeMonitor/Program.cs +++ b/CodeMonitor/Program.cs @@ -1,21 +1,30 @@ using Avalonia; using Avalonia.Logging.Serilog; using Avalonia.ReactiveUI; - +using System; +using System.IO; + namespace CodeMonitor { - class Program + public static 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. public static void Main(string[] args) { + AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; + BuildAvaloniaApp() .StartWithClassicDesktopLifetime(args); - } - - // Avalonia configuration, don't remove; also used by visual designer. + } + + private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + File.WriteAllText("Error-" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".trace", (e.ExceptionObject as Exception)?.ToString()); + } + + // Avalonia configuration, don't remove; also used by visual designer. public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure() .UsePlatformDetect() diff --git a/CodeMonitor/ViewModels/FileToCleanViewModel.cs b/CodeMonitor/ViewModels/FileToCleanViewModel.cs index da1e646..1b6ad28 100644 --- a/CodeMonitor/ViewModels/FileToCleanViewModel.cs +++ b/CodeMonitor/ViewModels/FileToCleanViewModel.cs @@ -1,16 +1,4 @@ -using System; -using System.Collections.ObjectModel; -using System.Dynamic; -using System.IO; -using System.Linq; -using System.Reactive; -using System.Reactive.Linq; -using DynamicData; -using ReactiveUI; -using SharpDX.Direct2D1; - -#warning subscriptions need disposing -namespace CodeMonitor.ViewModels +namespace CodeMonitor.ViewModels { public class FileToCleanViewModel { diff --git a/CodeMonitor/ViewModels/MainWindowViewModel.cs b/CodeMonitor/ViewModels/MainWindowViewModel.cs index ddee4c0..82bb46e 100644 --- a/CodeMonitor/ViewModels/MainWindowViewModel.cs +++ b/CodeMonitor/ViewModels/MainWindowViewModel.cs @@ -1,16 +1,15 @@ using System; using System.Collections.ObjectModel; -using System.Dynamic; using System.IO; using System.Linq; using System.Reactive; using System.Reactive.Linq; using Avalonia.Controls; +using CodeMonitor.Models; using DynamicData; using PropertyChanged; using ReactiveUI; -#warning subscriptions need disposing namespace CodeMonitor.ViewModels { [AddINotifyPropertyChangedInterface] @@ -19,9 +18,11 @@ public class MainWindowViewModel : ViewModelBase public ReactiveCommand Add { get; } public ReadOnlyObservableCollection Monitored => monitored; - private ReadOnlyObservableCollection monitored; + private readonly ReadOnlyObservableCollection monitored; - private SourceCache monitoredSourceCache; + private readonly SourceCache monitoredSourceCache; + + public ReactiveCommand SetResharperCliPath {get; } public MainWindowViewModel() { @@ -30,13 +31,14 @@ public MainWindowViewModel() monitoredSourceCache.Connect() .ObserveOn(RxApp.MainThreadScheduler) .Bind(out monitored) + .DisposeMany() .Subscribe(); - Add = ReactiveCommand.CreateFromTask(async w => + Add = ReactiveCommand.CreateFromTask(async w => { var d = new OpenFolderDialog(); - var result = await d.ShowAsync(w); + var result = await d.ShowAsync(w).ConfigureAwait(false); if (Directory.Exists(result)) { @@ -47,7 +49,13 @@ public MainWindowViewModel() monitoredSourceCache.AddOrUpdate(new MonitoredDirectoryViewModel(result)); } - return Unit.Default; + }); + + SetResharperCliPath = ReactiveCommand.Create(async w => + { + var d = new OpenFolderDialog (); + + Settings.RsCltPath = await d.ShowAsync(w).ConfigureAwait(false); }); } } diff --git a/CodeMonitor/ViewModels/MonitoredDirectoryViewModel.cs b/CodeMonitor/ViewModels/MonitoredDirectoryViewModel.cs index ffd5f44..da378eb 100644 --- a/CodeMonitor/ViewModels/MonitoredDirectoryViewModel.cs +++ b/CodeMonitor/ViewModels/MonitoredDirectoryViewModel.cs @@ -1,37 +1,34 @@ using System; using System.Collections.ObjectModel; -using System.Dynamic; using System.IO; using System.Linq; using System.Reactive; using System.Reactive.Linq; using System.Threading.Tasks; +using CodeMonitor.Models; using DynamicData; using ReactiveUI; -using SharpDX.Direct2D1; -#warning subscriptions need disposing namespace CodeMonitor.ViewModels { public class MonitoredDirectoryViewModel : ViewModelBase { public string Name { get; } - private ObservableAsPropertyHelper updating; + private readonly ObservableAsPropertyHelper updating; public bool Updating => updating.Value; - private ObservableAsPropertyHelper status; + private readonly ObservableAsPropertyHelper status; public string Status => status?.Value; public ReadOnlyObservableCollection ProblemGroups => problemGroups; - private ReadOnlyObservableCollection problemGroups; + private readonly ReadOnlyObservableCollection problemGroups; public ReadOnlyObservableCollection FilesToClean => filesToClean; - private ReadOnlyObservableCollection filesToClean; + private readonly ReadOnlyObservableCollection filesToClean; - private InspectCodeLoop _inspectLoop; - private CleanupCodeWatcher _cleanupWatcher; - + private readonly InspectCodeLoop _inspectLoop; + private readonly CleanupCodeWatcher _cleanupWatcher; public ReactiveCommand CleanFiles { get; } public ReactiveCommand ResetCleanFiles { get; } @@ -66,8 +63,8 @@ public MonitoredDirectoryViewModel(string directory) .DisposeMany() .Subscribe(); - status = _inspectLoop.Status.Concat(_cleanupWatcher.Status).ToProperty(this, x => x.Status); - updating = _inspectLoop.Active.Concat(_cleanupWatcher.Active).ToProperty(this, x => x.Updating); + status = _inspectLoop.Status.Merge(_cleanupWatcher.Status).ToProperty(this, x => x.Status); + updating = _inspectLoop.Active.Merge(_cleanupWatcher.Active).ToProperty(this, x => x.Updating); CleanFiles = ReactiveCommand.CreateFromTask(() => Task.Run(() => _cleanupWatcher.CleanupFiles())); diff --git a/CodeMonitor/ViewModels/ProblemGroupViewModel.cs b/CodeMonitor/ViewModels/ProblemGroupViewModel.cs index ea18aef..a0636e1 100644 --- a/CodeMonitor/ViewModels/ProblemGroupViewModel.cs +++ b/CodeMonitor/ViewModels/ProblemGroupViewModel.cs @@ -1,24 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Dynamic; -using System.IO; -using System.Linq; -using System.Reactive; -using System.Reactive.Linq; -using DynamicData; -using ReactiveUI; +using System.Collections.Generic; +using CodeMonitor.Models; namespace CodeMonitor.ViewModels { -#warning subscriptions need disposing - public class ProblemGroupViewModel : ViewModelBase { public ProblemGroupViewModel(InspectCodeFileProblems model) { Group = model.File; - Problems = model.Problems.Select(y => new ProblemViewModel(model.File, y.Message, y.Line, y.Type)).ToList(); + Problems = model.Problems.ConvertAll(y => new ProblemViewModel(model.File, y.Message, y.Line, y.Type)); } public string Group { get; } diff --git a/CodeMonitor/ViewModels/ProblemViewModel.cs b/CodeMonitor/ViewModels/ProblemViewModel.cs index 2ea666d..d8f50e2 100644 --- a/CodeMonitor/ViewModels/ProblemViewModel.cs +++ b/CodeMonitor/ViewModels/ProblemViewModel.cs @@ -2,7 +2,6 @@ namespace CodeMonitor.ViewModels { - public class ProblemViewModel : ViewModelBase { public ProblemViewModel(string file, string message, int line, string type) diff --git a/CodeMonitor/Views/MainWindow.xaml b/CodeMonitor/Views/MainWindow.xaml index 02c85c6..be33def 100644 --- a/CodeMonitor/Views/MainWindow.xaml +++ b/CodeMonitor/Views/MainWindow.xaml @@ -4,8 +4,9 @@ xmlns:l="clr-namespace:CodeMonitor.Views;assembly=CodeMonitor" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - Width="700" Height="300" - mc:Ignorable="d" d:DesignWidth="700" d:DesignHeight="300" + xmlns:s="clr-namespace:System;assembly=mscorlib" + Width="900" Height="300" + mc:Ignorable="d" d:DesignWidth="900" d:DesignHeight="300" HasSystemDecorations="False" x:Name="mw" Topmost="True" @@ -47,14 +48,14 @@ - + @@ -133,14 +134,14 @@ - - + @@ -173,7 +174,7 @@ - + @@ -194,7 +195,7 @@ - + @@ -203,9 +204,33 @@ - - + + - + + + + - \ No newline at end of file + diff --git a/CodeMonitor/Views/MainWindow.xaml.cs b/CodeMonitor/Views/MainWindow.xaml.cs index b4dcff6..7093a2e 100644 --- a/CodeMonitor/Views/MainWindow.xaml.cs +++ b/CodeMonitor/Views/MainWindow.xaml.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Reactive; using System.Windows.Input; using Avalonia; @@ -10,7 +9,7 @@ namespace CodeMonitor.Views { - public class dmd + public class TestData { public string Name => "Test dir"; public string Status => "Testing"; @@ -31,11 +30,11 @@ public class dmd public ReactiveCommand ResetCleanFiles => ReactiveCommand.Create(delegate{ }); } - public class dvm + public class TestMainVM { - public object Monitored => new dmd[] + public object Monitored => new TestData[] { - new dmd() + new TestData() }; }