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
5 changes: 3 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,9 @@ The type is `TrayAppBuilder` rather than `TrayApp` because a type whose name mat
its own namespace makes every `TrayApp.Something` reference ambiguous - which is the reason CA1724 is
suppressed across ktsu.Sdk, and not a reason to spend the name here.

A run goes: parse, then `--help`/`--version`, then restore preferences (tray only), then apply the
tool's own flags, then `--status`, then the run. The order of the middle two is the point: a remembered
A run goes: parse, then `--help`/`--version`, then restore preferences (tray only, and not for
`--status`, which reports the live state and must not run a setter), then apply the tool's own flags,
then `--status`, then the run. The order of the middle two is the point: a remembered
setting is restored first so that what was typed this time beats what the tray was left set to. The
parser records matches rather than invoking handlers, which is what makes that order possible.

Expand Down
37 changes: 37 additions & 0 deletions TrayApp.Test/TrayAppBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,43 @@
Assert.IsFalse(started);
}

[TestMethod]
public async Task RunAsync_WithStatusAndARememberedToggle_RunsNoSetterAndReportsTheLiveState()
{
InMemoryPersistenceProvider<string> provider = new();

using (DebouncedPreferenceStore seed = new(provider, "tray", Debounce))
{
await seed.LoadAsync().ConfigureAwait(false);

Check warning on line 261 in TrayApp.Test/TrayAppBuilderTests.cs

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Consider using the overload that accepts a CancellationToken and pass 'TestContext.CancellationToken'

See more on https://sonarcloud.io/project/issues?id=ktsu-dev_TrayApp&issues=AaEU28N5w78LEcInJMvk&open=AaEU28N5w78LEcInJMvk&pullRequest=35
seed.Set("awake", true);
await seed.FlushAsync().ConfigureAwait(false);

Check warning on line 263 in TrayApp.Test/TrayAppBuilderTests.cs

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Consider using the overload that accepts a CancellationToken and pass 'TestContext.CancellationToken'

See more on https://sonarcloud.io/project/issues?id=ktsu-dev_TrayApp&issues=AaEU28N5w78LEcInJMvl&open=AaEU28N5w78LEcInJMvl&pullRequest=35
}

bool awake = false;
int setterCalls = 0;
bool? awakeWhenReported = null;

int exitCode = await TrayAppBuilder.Create("demo")
.Toggle("Keep awake", () => awake, value =>
{
setterCalls++;
awake = value;
}, persistAs: "awake")
.Status(() =>
{
awakeWhenReported = awake;
return awake ? "Keeping awake" : "Idle";
})
.Preferences(provider)
.RunAsync(["--tray", "--status"])
.ConfigureAwait(false);

// A status query must not take what the toggle guards: it exits without OnStop to give it back.
Assert.AreEqual(0, exitCode);
Assert.AreEqual(0, setterCalls);
Assert.IsFalse(awakeWhenReported);
}

[TestMethod]
public void Menu_BuiltFromADefinition_CarriesTheToolsItems()
{
Expand Down
4 changes: 3 additions & 1 deletion TrayApp/TrayAppBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,9 @@ public Task<int> RunAsync(string[] args)
{
// Preferences are the tray's: a command line run says what it wants, so letting a remembered
// setting override an argument would be surprising, and the console path never reads them.
if (useTray && app.Persistence is not null)
// --status is a read-only report, so it restores nothing: a restore runs toggle setters that can
// take a resource, and the report returns without the OnStop that would release it.
if (useTray && !options.ShowStatus && app.Persistence is not null)
{
store = new DebouncedPreferenceStore(app.Persistence, app.PreferenceKey, app.PreferenceDebounce);
restoreError = LoadPreferences(app, store);
Expand Down
Loading