Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UpdaterPlugin YAML config #1031

Merged
merged 5 commits into from
Sep 18, 2024
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
12 changes: 12 additions & 0 deletions docs/docs/customize/yaml.md
Original file line number Diff line number Diff line change
Expand Up @@ -457,3 +457,15 @@ plugins:
layout_preview:
is_enabled: true
```

### Updater Plugin

The `UpdaterPlugin` adds the ability to notify the user when a new version of Whim is available.

```yaml
plugins:
updater:
is_enabled: true
release_channel: alpha
update_frequency: weekly
```
4 changes: 2 additions & 2 deletions src/Whim.Updater/UpdaterConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ public static class UpdateFrequencyExtensions
public class UpdaterConfig
{
/// <summary>
/// The release channel to install. Defaults to <see cref="ReleaseChannel.Stable"/>.
/// The release channel to install. Defaults to <see cref="ReleaseChannel.Alpha"/>.
/// </summary>
public ReleaseChannel ReleaseChannel { get; set; } = ReleaseChannel.Stable;
public ReleaseChannel ReleaseChannel { get; set; } = ReleaseChannel.Alpha;

/// <summary>
/// The frequency at which the updater should check for updates. Defaults to <see cref="UpdateFrequency.Weekly"/>.
Expand Down
16 changes: 16 additions & 0 deletions src/Whim.Yaml.Tests/YamlLoaderUtilsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,4 +217,20 @@ public void ParseBrush_String(string brush, Color expected)
// Then the string is converted to a brush
Assert.Equal(expected, result);
}

[Theory]
[InlineData(" ", " ")]
[InlineData("", "")]
[InlineData("a", "A")]
[InlineData("ab", "Ab")]
[InlineData("abc", "Abc")]
public void Capitalize(string str, string expected)
{
// Given a string
// When capitalizing it
string result = str.Capitalize();

// Then the first letter is capitalized
Assert.Equal(expected, result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Whim.Yaml.Tests;

public class YamlLoader_LoadFocusIndicatorTests
public class YamlLoader_LoadFocusIndicatorPluginTests
{
private const int _defaultBorderSize = 4;
private const bool _defaultIsFadeEnabled = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Whim.Yaml.Tests;

public class YamlLoader_LoadLayoutPreviewTests
public class YamlLoader_LoadLayoutPreviewPluginTests
{
public static TheoryData<string, bool, bool> LayoutPreviewConfig =>
new()
Expand Down
177 changes: 177 additions & 0 deletions src/Whim.Yaml.Tests/YamlLoader_LoadUpdaterPluginTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
using NSubstitute;
using Whim.TestUtils;
using Whim.Updater;
using Xunit;

namespace Whim.Yaml.Tests;

public class YamlLoader_LoadUpdaterPluginTests
{
public static TheoryData<string, bool, UpdateFrequency, ReleaseChannel> UpdaterPluginConfig =>
new()
{
// YAML, all values set
{
"""
plugins:
updater:
is_enabled: true
update_frequency: daily
release_channel: alpha
""",
true,
UpdateFrequency.Daily,
ReleaseChannel.Alpha
},
// JSON, all values set
{
"""
{
"plugins": {
"updater": {
"is_enabled": true,
"update_frequency": "daily",
"release_channel": "alpha"
}
}
}
""",
false,
UpdateFrequency.Daily,
ReleaseChannel.Alpha
},
// YAML, no values set
{
"""
plugins:
updater: {}
""",
true,
UpdateFrequency.Weekly,
ReleaseChannel.Alpha
},
// JSON, no values set
{
"""
{
"plugins": {
"updater": {}
}
}
""",
false,
UpdateFrequency.Weekly,
ReleaseChannel.Alpha
},
};

[Theory, MemberAutoSubstituteData<YamlLoaderCustomization>(nameof(UpdaterPluginConfig))]
public void LoadUpdaterPlugin_ConfigIsSet_PluginIsLoaded(
string schema,
bool isYaml,
UpdateFrequency updateFrequency,
ReleaseChannel releaseChannel,
IContext ctx
)
{
// Given a valid config with the updater plugin
YamlLoaderTestUtils.SetupFileConfig(ctx, schema, isYaml);

// When loading the config
bool result = YamlLoader.Load(ctx);

// Then the updater plugin is loaded
Assert.True(result);
ctx.PluginManager.Received()
.AddPlugin(
Arg.Is<UpdaterPlugin>(p =>
p.Config.UpdateFrequency == updateFrequency && p.Config.ReleaseChannel == releaseChannel
)
);
}

public static TheoryData<string, bool> UpdaterPluginNotEnabledConfig =>
new()
{
// YAML, disabled
{
"""
plugins:
updater:
is_enabled: false
""",
true
},
// JSON, disabled
{
"""
{
"plugins": {
"updater": {
"is_enabled": false
}
}
}
""",
false
},
// YAML, invalid release channel
{
"""
plugins:
updater:
release_channel: invalid
""",
true
},
// JSON, invalid release channel
{
"""
{
"plugins": {
"updater": {
"release_channel": "invalid"
}
}
}
""",
false
},
// YAML, invalid update frequency
{
"""
plugins:
updater:
update_frequency: invalid
""",
true
},
// JSON, invalid update frequency
{
"""
{
"plugins": {
"updater": {
"update_frequency": "invalid"
}
}
}
""",
false
},
};

[Theory, MemberAutoSubstituteData<YamlLoaderCustomization>(nameof(UpdaterPluginNotEnabledConfig))]
public void LoadUpdaterPlugin_ConfigNotEnabled_PluginIsNotLoaded(string schema, bool isYaml, IContext ctx)
{
// Given a valid config with the updater plugin not enabled
YamlLoaderTestUtils.SetupFileConfig(ctx, schema, isYaml);

// When loading the config
bool result = YamlLoader.Load(ctx);

// Then the updater plugin is not loaded
Assert.True(result);
ctx.PluginManager.DidNotReceive().AddPlugin(Arg.Any<UpdaterPlugin>());
}
}
1 change: 1 addition & 0 deletions src/Whim.Yaml/Whim.Yaml.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<ProjectReference Include="..\Whim.FocusIndicator\Whim.FocusIndicator.csproj" />
<ProjectReference Include="..\Whim.Gaps\Whim.Gaps.csproj" />
<ProjectReference Include="..\Whim.LayoutPreview\Whim.LayoutPreview.csproj" />
<ProjectReference Include="..\Whim.Updater\Whim.Updater.csproj" />
<ProjectReference Include="..\Whim\Whim.csproj" />
</ItemGroup>

Expand Down
13 changes: 13 additions & 0 deletions src/Whim.Yaml/YamlLoaderUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,17 @@ private static byte ParseHex(this ReadOnlySpan<char> hex)
return 0;
}
}

/// <summary>
/// Capitalizes the first letter of the string.
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string Capitalize(this string str) =>
str.Length switch
{
0 => str,
1 => char.ToUpperInvariant(str[0]).ToString(),
_ => char.ToUpperInvariant(str[0]) + str[1..],
};
}
39 changes: 39 additions & 0 deletions src/Whim.Yaml/YamlPluginLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Whim.FocusIndicator;
using Whim.Gaps;
using Whim.LayoutPreview;
using Whim.Updater;

namespace Whim.Yaml;

Expand All @@ -24,6 +25,7 @@ public static void LoadPlugins(IContext ctx, Schema schema)
LoadCommandPalettePlugin(ctx, schema);
LoadFocusIndicatorPlugin(ctx, schema);
LoadLayoutPreviewPlugin(ctx, schema);
LoadUpdaterPlugin(ctx, schema);
}

private static void LoadGapsPlugin(IContext ctx, Schema schema)
Expand Down Expand Up @@ -171,4 +173,41 @@ private static void LoadLayoutPreviewPlugin(IContext ctx, Schema schema)

ctx.PluginManager.AddPlugin(new LayoutPreviewPlugin(ctx));
}

private static void LoadUpdaterPlugin(IContext ctx, Schema schema)
{
var updater = schema.Plugins.Updater;

if (!updater.IsValid())
{
Logger.Debug("Updater plugin is not valid.");
return;
}

if (updater.IsEnabled.AsOptional() is { } isEnabled && !isEnabled)
{
Logger.Debug("Updater plugin is not enabled.");
return;
}

UpdaterConfig config = new();

if (updater.UpdateFrequency.AsOptional() is { } updateFrequency)
{
string updateFrequencyStr = ((string)updateFrequency).Capitalize();
config.UpdateFrequency = Enum.TryParse<UpdateFrequency>(updateFrequencyStr, out var frequency)
? frequency
: UpdateFrequency.Never;
}

if (updater.ReleaseChannel.AsOptional() is { } releaseChannel)
{
string releaseChannelStr = ((string)releaseChannel).Capitalize();
config.ReleaseChannel = Enum.TryParse<ReleaseChannel>(releaseChannelStr, out var channel)
? channel
: ReleaseChannel.Stable;
}

ctx.PluginManager.AddPlugin(new UpdaterPlugin(ctx, config));
}
}
56 changes: 56 additions & 0 deletions src/Whim.Yaml/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@
"layout_preview": {
"$ref": "#/$defs/LayoutPreviewPlugin",
"description": "Plugin to add a layout preview"
},

"updater": {
"$ref": "#/$defs/UpdaterPlugin",
"description": "Plugin to add an updater"
}
}
}
Expand Down Expand Up @@ -324,6 +329,57 @@
}
},

"UpdaterPlugin": {
"type": "object",
"description": "Plugin to add an updater. For more, see https://dalyisaac.github.io/Whim/docs/plugins/updater.html",
"additionalProperties": false,
"properties": {
"is_enabled": {
"type": "boolean",
"description": "Whether the plugin is enabled",
"default": true
},
"release_channel": {
"anyOf": [
{
"const": "alpha",
"description": "Alpha releases are the most unstable, but have the latest features"
},
{
"const": "beta",
"description": "NOT YET AVAILABLE. Beta releases are more stable than alpha releases, but less stable than stable releases"
},
{
"const": "stable",
"description": "NOT YET AVAILABLE. Stable releases are the most stable, but have the least features"
}
],
"default": "alpha"
},
"update_frequency": {
"anyOf": [
{
"const": "never",
"description": "Never check for updates"
},
{
"const": "daily",
"description": "Check for updates daily"
},
{
"const": "weekly",
"description": "Check for updates weekly"
},
{
"const": "monthly",
"description": "Check for updates monthly"
}
],
"default": "weekly"
}
}
},

"Color": {
"anyOf": [
{
Expand Down