Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-native.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ concurrency:

jobs:
native:
uses: SimonCropp/PlatformHeads/.github/workflows/build-native.yml@0.11.0
uses: SimonCropp/PlatformHeads/.github/workflows/build-native.yml@0.12.0
permissions:
contents: write
pull-requests: write
Expand Down
2 changes: 1 addition & 1 deletion native/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ include(FetchContent)
FetchContent_Declare(
platformheads
GIT_REPOSITORY https://github.com/SimonCropp/PlatformHeads.git
GIT_TAG 0.11.0
GIT_TAG 0.12.0
GIT_SHALLOW ON)
FetchContent_MakeAvailable(platformheads)
include(${platformheads_SOURCE_DIR}/cmake/PlatformHeads.cmake)
Expand Down
2 changes: 1 addition & 1 deletion native/swift/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ let package = Package(
dependencies: [
// What every AppKit head does underneath its drawing, shared with DiffEngine's viewer. The
// sixth pin of PlatformHeads, moved with the other five.
.package(url: "https://github.com/SimonCropp/PlatformHeads", exact: "0.11.0")
.package(url: "https://github.com/SimonCropp/PlatformHeads", exact: "0.12.0")
],
targets: [
// Exists only to import the ABI. Swift does not guarantee struct layout, so the structs
Expand Down
49 changes: 15 additions & 34 deletions src/BuildMonitor.Core/App/UpdateOutcome.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/// <summary>
/// How the last update went, for the tray it started again to report, worded from PlatformHeads'
/// <see cref="ToolUpdateOutcome"/>. The update runs in a shell nobody sees, after the tray has
/// exited, so without this there is nothing to see at either end of it: the icon goes away and one
/// comes back, and whether that is the new version or the old one after a failure looks exactly
/// the same.
/// How the last update went, for the tray it started again to report, through PlatformHeads'
/// <see cref="ToolUpdateOutcome.Report"/>. The update runs in a shell nobody sees, after the tray
/// has exited, so without this there is nothing to see at either end of it: the icon goes away and
/// one comes back, and whether that is the new version or the old one after a failure looks
/// exactly the same.
/// </summary>
static class UpdateOutcome
{
Expand All @@ -13,41 +13,22 @@ static class UpdateOutcome
/// outcome is reported once rather than at every start, and the whole output goes to the log,
/// since a notification has room for a line of it.
/// </summary>
public static Notification? Take(string path)
{
ToolUpdateOutcome? outcome;
try
{
outcome = ToolUpdateOutcome.Take(path);
}
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException)
{
Log.Warning(exception, "Could not read the update outcome at {Path}", path);
return null;
}

if (outcome is null)
{
return null;
}
public static Notification? Take(string path) =>
ToolUpdateOutcome.Report(
path,
"BuildMonitor",
VersionReader.VersionString,
Taken,
_ => Log.Warning(_, "Could not read the update outcome at {Path}", path));

static void Taken(ToolUpdateOutcome outcome)
{
if (outcome.Succeeded)
{
Log.Information("Update finished. dotnet tool update said:\n{Output}", outcome.Output);
return Describe();
return;
}

Log.Warning("Update failed, so {Version} is still the one installed. dotnet tool update said:\n{Output}", VersionReader.VersionString, outcome.Output);
return Describe(outcome.Output);
}

/// <summary>
/// The version rather than what the tool said, because this is the tray the update started: it
/// is the installed one, whether the update moved it or found it already current.
/// </summary>
public static Notification Describe() =>
new("BuildMonitor updated", $"Now running {VersionReader.VersionString}.", Kind: NotificationKind.Info);

public static Notification Describe(string output) =>
new("Update failed", new ToolUpdateOutcome(false, output).Reason);
}
2 changes: 0 additions & 2 deletions src/BuildMonitor.Native/Native/BmStructs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,5 @@ static class BmFlags
public const int RowMember = 1 << 3;
public const int FieldEnabled = 1 << 0;
public const int ButtonEnabled = 1 << 0;
public const int TrayEnabled = 1 << 0;
public const int TraySeparator = 1 << 1;
public const int MenuSeparatorAbove = 1 << 0;
}
4 changes: 3 additions & 1 deletion src/BuildMonitor.Native/Native/ScreenPayload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,9 @@ public void Build(Screen source)
Id = Add(item.Id),
Label = Add(item.Label),
Icon = Add(item.IconName ?? ""),
Flags = (item.Enabled ? BmFlags.TrayEnabled : 0) | (item.Separator ? BmFlags.TraySeparator : 0)
// PlatformHeads' TrayMenuFlags, whose first two are BM_TRAY_ENABLED and
// BM_TRAY_SEPARATOR. The ABI carries no checks, so the rest stay behind.
Flags = (int) (item.Flags & (TrayMenuFlags.Enabled | TrayMenuFlags.Separator))
});
}
}
Expand Down
Binary file not shown.
Binary file not shown.
22 changes: 16 additions & 6 deletions src/BuildMonitor.Tests/UpdateOutcomeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public async Task TheFailureIsReportedOnceAndThenRemoved()
await File.WriteAllTextAsync(path, locked, new UTF8Encoding(encoderShouldEmitUTF8Identifier: true));
var notification = UpdateOutcome.Take(path);

await Assert.That(notification).IsEqualTo(new("Update failed", """Failed to uninstall tool package 'buildmonitor': Access to the path 'C:\Users\me\.dotnet\tools\.store\buildmonitor\0.1.0-beta.6' is denied."""));
await Assert.That(notification).IsEqualTo(new("BuildMonitor did not update", """Failed to uninstall tool package 'buildmonitor': Access to the path 'C:\Users\me\.dotnet\tools\.store\buildmonitor\0.1.0-beta.6' is denied."""));
await Assert.That(File.Exists(path)).IsFalse();
await Assert.That(UpdateOutcome.Take(path)).IsNull();
}
Expand Down Expand Up @@ -54,7 +54,7 @@ public async Task OutputWithNoStatusLineIsAFailure()
{
using var path = new TempFile();
await File.WriteAllTextAsync(path, "Tool 'buildmonitor' failed to update due to the following:\nIt did not work.\n");
await Assert.That(UpdateOutcome.Take(path)).IsEqualTo(new("Update failed", "It did not work."));
await Assert.That(UpdateOutcome.Take(path)).IsEqualTo(new("BuildMonitor did not update", "It did not work."));
}

[Test]
Expand All @@ -66,11 +66,21 @@ public async Task NoFileMeansNothingToReport() =>
/// at the end are what the shells leave.
/// </summary>
[Test]
public async Task TheReasonIsTheLastLineWritten() =>
await Assert.That(UpdateOutcome.Describe("Tool 'buildmonitor' failed to update due to the following:\r\nUnable to load the service index for source https://api.nuget.org/v3/index.json.\r\n\r\n").Message)
public async Task TheReasonIsTheLastLineWritten()
{
using var path = new TempFile();
await File.WriteAllTextAsync(path, "failed\r\nTool 'buildmonitor' failed to update due to the following:\r\nUnable to load the service index for source https://api.nuget.org/v3/index.json.\r\n\r\n");

await Assert.That(UpdateOutcome.Take(path)?.Message)
.IsEqualTo("Unable to load the service index for source https://api.nuget.org/v3/index.json.");
}

[Test]
public async Task NoOutputStillSaysTheUpdateFailed() =>
await Assert.That(UpdateOutcome.Describe(" \n")).IsEqualTo(new("Update failed", "dotnet tool update failed without saying why."));
public async Task NoOutputStillSaysTheUpdateFailed()
{
using var path = new TempFile();
await File.WriteAllTextAsync(path, "failed\n \n");

await Assert.That(UpdateOutcome.Take(path)).IsEqualTo(new("BuildMonitor did not update", "dotnet tool update failed without saying why."));
}
}
20 changes: 0 additions & 20 deletions src/BuildMonitor.Windows/MenuColours.cs

This file was deleted.

14 changes: 0 additions & 14 deletions src/BuildMonitor.Windows/MenuRenderer.cs

This file was deleted.

18 changes: 17 additions & 1 deletion src/BuildMonitor.Windows/MenuTheme.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
/// <summary>
/// Dark or light menus, drawn by PlatformHeads' <see cref="PaletteMenuRenderer" />. Applied each
/// time a menu opens, so the renderer is made from the palette as it is then, and a menu follows a
/// change of theme as it did when the renderer read the palette itself.
/// </summary>
static class MenuTheme
{
public static void Apply(ToolStrip strip)
{
strip.Renderer = new MenuRenderer();
strip.Renderer = new PaletteMenuRenderer(Colours());
strip.BackColor = Palette.Surface;
strip.ForeColor = Palette.Text;
}

static MenuPalette Colours() =>
new(
Background: Palette.Surface,
Border: Palette.Border,
ItemBorder: Palette.Border,
Selected: Palette.SelectedRow,
Pressed: Palette.SelectedRow,
Separator: Palette.Border,
Text: Palette.Text,
Dim: Palette.Dim);
}
8 changes: 4 additions & 4 deletions src/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.14" />
<PackageVersion Include="Microsoft.Testing.Extensions.CodeCoverage" Version="18.12.0" />
<PackageVersion Include="ModelContextProtocol" Version="2.3.1" />
<PackageVersion Include="PlatformHeads" Version="0.11.0" />
<PackageVersion Include="PlatformHeads.Core" Version="0.11.0" />
<PackageVersion Include="PlatformHeads.Linux" Version="0.11.0" />
<PackageVersion Include="PlatformHeads.WindowsForms" Version="0.11.0" />
<PackageVersion Include="PlatformHeads" Version="0.12.0" />
<PackageVersion Include="PlatformHeads.Core" Version="0.12.0" />
<PackageVersion Include="PlatformHeads.Linux" Version="0.12.0" />
<PackageVersion Include="PlatformHeads.WindowsForms" Version="0.12.0" />
<PackageVersion Include="Polyfill" Version="11.4.5" />
<PackageVersion Include="ProjectDefaults" Version="1.0.187" />
<PackageVersion Include="Serilog" Version="4.4.0" />
Expand Down
Loading