Skip to content

Commit

Permalink
[Add] online version checking
Browse files Browse the repository at this point in the history
  • Loading branch information
samatstariongroup committed Oct 19, 2024
1 parent 2407d55 commit afbc658
Show file tree
Hide file tree
Showing 10 changed files with 328 additions and 4 deletions.
4 changes: 4 additions & 0 deletions ECoreNetto.Tools.Tests/ECoreNetto.Tools.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,8 @@
</None>
</ItemGroup>

<ItemGroup>
<Folder Include="Services\" />
</ItemGroup>

</Project>
74 changes: 74 additions & 0 deletions ECoreNetto.Tools.Tests/Services/VersionCheckerTestFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// -------------------------------------------------------------------------------------------------
// <copyright file="VersionCheckerTestFixture.cs" company="Starion Group S.A">
//
// Copyright 2017-2024 Starion Group S.A.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
// ------------------------------------------------------------------------------------------------

namespace ECoreNetto.Tools.Tests.Services
{
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using NUnit.Framework;
using Serilog;
using Tools.Services;

[TestFixture]
public class VersionCheckerTestFixture
{
private VersionChecker versionChecker;

private ILoggerFactory? loggerFactory;

[OneTimeSetUp]
public void OneTimeSetUp()
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Verbose()
.WriteTo.Console()
.CreateLogger();

this.loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddSerilog();
});
}

[SetUp]
public void SetUp()
{
var httpClient = new HttpClient();
httpClient.Timeout = TimeSpan.FromSeconds(5);

this.versionChecker = new VersionChecker(httpClient, this.loggerFactory);
}

[Test]
public async Task Verify_that_Query_version_returns_result()
{
var result = await this.versionChecker.QueryLatestRelease();

Assert.That(result, Is.Not.Null);

Log.Logger.Information(result.TagName);
Log.Logger.Information(result.Body);
Log.Logger.Information(result.HtmlUrl);

}
}
}
2 changes: 1 addition & 1 deletion ECoreNetto.Tools/Commands/MarkdownReportCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace ECoreNetto.Tools.Commands
using System.IO;

using ECoreNetto.Reporting.Generators;

/// <summary>
/// The <see cref="MarkdownReportCommand"/> that generates a Markdown report
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion ECoreNetto.Tools/Commands/ModelInspectionCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace ECoreNetto.Tools.Commands
using System.IO;

using ECoreNetto.Reporting.Generators;

/// <summary>
/// The <see cref="ModelInspectionCommand"/> that inspects an ECore model and generates
/// a text report
Expand Down
2 changes: 1 addition & 1 deletion ECoreNetto.Tools/Commands/ReportHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@

namespace ECoreNetto.Tools.Commands
{
using System.CommandLine.Invocation;
using System;
using System.CommandLine.Invocation;
using System.Diagnostics;
using System.IO;
using System.Threading;
Expand Down
1 change: 1 addition & 0 deletions ECoreNetto.Tools/ECoreNetto.Tools.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@

<ItemGroup>
<PackageReference Include="ClosedXML" Version="0.104.1" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.1" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
<PackageReference Include="System.CommandLine.Hosting" Version="0.4.0-alpha.22272.1" />
<PackageReference Include="Spectre.Console" Version="0.49.1" />
Expand Down
95 changes: 95 additions & 0 deletions ECoreNetto.Tools/Middlewares/VersionCheckerMiddleware.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// -------------------------------------------------------------------------------------------------
// <copyright file="VersionCheckerMiddleware.cs" company="Starion Group S.A">
//
// Copyright 2017-2024 Starion Group S.A.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
// ------------------------------------------------------------------------------------------------

namespace ECoreNetto.Tools.Middlewares
{
using System;
using System.CommandLine.Builder;
using System.CommandLine.Invocation;
using System.Net.Http;
using System.Reflection;
using System.Threading.Tasks;

using ECoreNetto.Tools.Services;

using Spectre.Console;

/// <summary>
/// A middleware that checks whether a newer version is available
/// </summary>
internal static class VersionCheckerMiddleware
{
/// <summary>
/// Configures the application to show check for a new version
/// </summary>
/// <param name="builder">
/// A command line builder.
/// </param>
/// <returns>
/// The same instance of <see cref="CommandLineBuilder"/>.
/// </returns>
public static CommandLineBuilder UseVersionChecker(this CommandLineBuilder builder)
{
return builder.AddMiddleware(async (context, next) =>
{
var httpClient = new HttpClient();
httpClient.Timeout = TimeSpan.FromSeconds(2);
var versionChecker = new VersionChecker(httpClient);

try
{
var payload = await versionChecker.QueryLatestRelease();

if (payload != null)
{
var currentVersion = Assembly.GetExecutingAssembly().GetName().Version;
var publishedVersion = new Version(payload.TagName);

if (currentVersion < publishedVersion)
{
AnsiConsole.WriteLine("");
AnsiConsole.MarkupLine($"[Green] a newer version is available at {payload.HtmlUrl} [/]");
AnsiConsole.MarkupLine($"[Green] {payload.Body} [/]");
AnsiConsole.WriteLine("");
}
else
{
AnsiConsole.WriteLine("");
AnsiConsole.MarkupLine($"[Green] you are using the most recent version. [/]");
AnsiConsole.WriteLine("");
}
}

await next(context);
}
catch (TaskCanceledException ex)
{
AnsiConsole.WriteLine("");
AnsiConsole.MarkupLine($"[Red] Checking version at GitHub API timed out. [/]");
AnsiConsole.WriteLine("");
}
catch (Exception ex)
{
throw;
}
}, MiddlewareOrder.ExceptionHandler);
}
}
}
6 changes: 5 additions & 1 deletion ECoreNetto.Tools/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ namespace ECoreNetto.Tools

using Spectre.Console;
using ECoreNetto.Reporting.Generators;
using ECoreNetto.Tools.Services;
using Middlewares;

/// <summary>
/// Main entry point for the command line application
Expand Down Expand Up @@ -65,6 +67,7 @@ public static int Main(string[] args)
services.AddSingleton<IModelInspector, ModelInspector>();
services.AddSingleton<IHtmlReportGenerator, HtmlReportGenerator>();
services.AddSingleton<IMarkdownReportGenerator, MarkdownReportGenerator>();

})
.UseCommandHandler<XlReportCommand, XlReportCommand.Handler>()
.UseCommandHandler<ModelInspectionCommand, ModelInspectionCommand.Handler>()
Expand Down Expand Up @@ -101,7 +104,8 @@ private static CommandLineBuilder BuildCommandLine()
AnsiConsole.Markup($"[blue]{ResourceLoader.QueryLogo()}[/]");
}
));
});
})
.UseVersionChecker();
}

/// <summary>
Expand Down
48 changes: 48 additions & 0 deletions ECoreNetto.Tools/Services/GitHubRelease.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// -------------------------------------------------------------------------------------------------
// <copyright file="GitHubRelease.cs" company="Starion Group S.A">
//
// Copyright 2017-2024 Starion Group S.A.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
// ------------------------------------------------------------------------------------------------

namespace ECoreNetto.Tools.Services
{
using System.Text.Json.Serialization;

/// <summary>
/// The <see cref="GitHubRelease"/> class represents a response from the GitHb API
/// </summary>
public class GitHubRelease
{
/// <summary>
/// Gets or sets the url of the release page
/// </summary>
[JsonPropertyName("html_url")]
public string HtmlUrl { get; set; }

/// <summary>
/// Gets or sets the name of the tag
/// </summary>
[JsonPropertyName("tag_name")]
public string TagName{ get; set; }

/// <summary>
/// Gets or sets the description of the release
/// </summary>
[JsonPropertyName("body")]
public string Body { get; set; }
}
}
98 changes: 98 additions & 0 deletions ECoreNetto.Tools/Services/VersionChecker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// -------------------------------------------------------------------------------------------------
// <copyright file="VersionChecker.cs" company="Starion Group S.A">
//
// Copyright 2017-2024 Starion Group S.A.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
// ------------------------------------------------------------------------------------------------

namespace ECoreNetto.Tools.Services
{
using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;

/// <summary>
/// The purpose of the <see cref="VersionChecker"/> is to check whether a newer version is available
/// </summary>
public class VersionChecker
{
/// <summary>
/// The (injected) <see cref="HttpClient"/> used to check the latest version that is available
/// </summary>
private readonly HttpClient httpClient;

/// <summary>
/// The <see cref="ILogger"/> used to log
/// </summary>
private readonly ILogger<VersionChecker> logger;

/// <summary>
/// Initializes a new instance of the <see cref="VersionChecker"/>
/// </summary>
/// <param name="httpClient">
/// The (injected) <see cref="HttpClient"/> used to check the latest version that is available
/// </param>
/// <param name="loggerFactory">
/// The (injected) <see cref="ILoggerFactory"/> used to set up logging
/// </param>
public VersionChecker(HttpClient httpClient, ILoggerFactory loggerFactory = null)
{
this.httpClient = httpClient;
this.logger = loggerFactory == null ? NullLogger<VersionChecker>.Instance : loggerFactory.CreateLogger<VersionChecker>();
}

/// <summary>
/// Queries the latest version from the GitHub API
/// </summary>
/// <returns>
/// an instance of <see cref="GitHubRelease"/> or null if not found or a connection
/// error occured
/// </returns>
public async Task<GitHubRelease> QueryLatestRelease()
{
var requestUrl = "https://api.github.com/repos/STARIONGROUP/EcoreNetto/releases/latest";

try
{
this.httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("ECoreNetto.Tools");

var response = await this.httpClient.GetAsync(requestUrl);

if (response.IsSuccessStatusCode)
{
var jsonResponse = await response.Content.ReadAsStringAsync();
var release = JsonSerializer.Deserialize<GitHubRelease>(jsonResponse);

return release;
}
}
catch (TaskCanceledException ex)
{
this.logger.LogWarning("Contacting the GitGub API at {url} timed out", requestUrl);
}
catch (Exception ex)
{
this.logger.LogError(ex, "");
}

return null;
}
}
}

0 comments on commit afbc658

Please sign in to comment.