Skip to content

Commit

Permalink
new plugin compatibility check
Browse files Browse the repository at this point in the history
  • Loading branch information
HendrikMennen committed Nov 8, 2024
1 parent 60009b2 commit 46d82f8
Show file tree
Hide file tree
Showing 21 changed files with 254 additions and 145 deletions.
6 changes: 3 additions & 3 deletions build/props/Base.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<StudioVersion>0.20.6.0</StudioVersion>
<CoreVersion>0.30.5.0</CoreVersion>
<UniversalFpgaProjectSystemVersion>0.40.0.0</UniversalFpgaProjectSystemVersion>
<EssentialsVersion>0.10.1</EssentialsVersion>
<CoreVersion>0.31.0.0</CoreVersion>
<UniversalFpgaProjectSystemVersion>0.41.0.0</UniversalFpgaProjectSystemVersion>
<EssentialsVersion>0.11.0.0</EssentialsVersion>
<Version>$(CoreVersion)</Version>
<Authors>Hendrik Mennen</Authors>
<Company>One Ware</Company>
Expand Down
10 changes: 0 additions & 10 deletions src/OneWare.Core/ModuleLogic/PackageDependency.cs

This file was deleted.

6 changes: 0 additions & 6 deletions src/OneWare.Core/ModuleLogic/PackageManifest.cs

This file was deleted.

67 changes: 6 additions & 61 deletions src/OneWare.Core/Services/PluginService.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System.Text.Json;
using System.Text.Json.Nodes;
using OneWare.Core.Models;
using OneWare.Core.ModuleLogic;
using OneWare.Essentials.Helpers;
using OneWare.Essentials.Models;
using OneWare.Essentials.PackageManager.Compatibility;
using OneWare.Essentials.Services;
using Prism.Ioc;
using Prism.Modularity;
Expand Down Expand Up @@ -36,10 +38,11 @@ public IPlugin AddPlugin(string path)
{
var plugin = new Plugin(Path.GetFileName(path), path);
InstalledPlugins.Add(plugin);
if (CheckCompatibility(path) is { compatible: false } test)

if (PluginCompatibilityChecker.CheckCompatibilityPath(path) is { IsCompatible: false } test)
{
plugin.CompatibilityReport = test.report;
ContainerLocator.Container.Resolve<ILogger>().Error($"Plugin {path} failed loading: \n {test.report}");
plugin.CompatibilityReport = test.Report;
ContainerLocator.Container.Resolve<ILogger>().Error($"Plugin {path} failed loading: \n {test.Report}");
return plugin;
}

Expand Down Expand Up @@ -86,62 +89,4 @@ public void RemovePlugin(IPlugin plugin)
ContainerLocator.Container.Resolve<ILogger>().Error(e.Message, e);
}
}

private (bool compatible, string? report) CheckCompatibility(string path)
{
try
{
var pluginName = Path.GetFileName(path);

var compatibilityIssues = string.Empty;

//Dependency check
var depFilePath = Path.Combine(path, "oneware.json");

if (!File.Exists(depFilePath))
{
compatibilityIssues +=
$"Extension {pluginName} incompatible:\n\noneware.json not found in plugin folder\n";
return (false, compatibilityIssues);
}

var packageManifest =
JsonSerializer.Deserialize<PackageManifest>(File.ReadAllText(depFilePath), _jsonSerializerOptions);

if (packageManifest?.Dependencies is { } deps)
foreach (var dep in deps)
{
var minVersion = Version.Parse(dep.MinVersion ?? "0");
var maxVersion = Version.Parse(dep.MaxVersion ?? "10000");

var coreDep = AppDomain.CurrentDomain.GetAssemblies()
.SingleOrDefault(x => x.GetName().Name == dep.Name)?.GetName();

if (coreDep == null)
{
compatibilityIssues += $"Dependency {dep.Name} not found\n";
continue;
}

if (coreDep.Version < minVersion)
compatibilityIssues +=
$"Studio {dep.Name} v{coreDep.Version} is older than min Plugin v{minVersion}\n";
if (coreDep.Version > maxVersion)
compatibilityIssues +=
$"Studio {dep.Name} v{coreDep.Version} is newer than max Plugin v{maxVersion}\n";
}

if (compatibilityIssues.Length > 0)
{
compatibilityIssues = $"Extension {pluginName} incompatible:\n" + compatibilityIssues;
return (false, compatibilityIssues);
}
}
catch (Exception e)
{
return (false, e.Message);
}

return (true, null);
}
}
29 changes: 19 additions & 10 deletions src/OneWare.Essentials/Models/PackageModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
using OneWare.Essentials.Enums;
using OneWare.Essentials.Helpers;
using OneWare.Essentials.PackageManager;
using OneWare.Essentials.PackageManager.Compatibility;
using OneWare.Essentials.Services;

namespace OneWare.Essentials.Models;

public abstract class PackageModel : ObservableObject
{
private readonly IApplicationStateService _applicationStateService;
private readonly IHttpService _httpService;
private readonly ILogger _logger;
private PackageVersion? _installedVersion;
private Package _package;
Expand All @@ -19,7 +19,9 @@ public abstract class PackageModel : ObservableObject

private PackageStatus _status;

private string? _warningText;
private string? _installedVersionWarningText;

protected readonly IHttpService HttpService;

protected PackageModel(Package package,
string packageType,
Expand All @@ -29,7 +31,7 @@ protected PackageModel(Package package,
IApplicationStateService applicationStateService)
{
_package = package;
_httpService = httpService;
HttpService = httpService;
_logger = logger;
_applicationStateService = applicationStateService;
ExtractionFolder = extractionFolder;
Expand All @@ -48,10 +50,10 @@ public PackageVersion? InstalledVersion
}
}

public string? WarningText
public string? InstalledVersionWarningText
{
get => _warningText;
set => SetProperty(ref _warningText, value);
get => _installedVersionWarningText;
set => SetProperty(ref _installedVersionWarningText, value);
}

public PackageStatus Status
Expand Down Expand Up @@ -104,7 +106,7 @@ public async Task<bool> UpdateAsync(PackageVersion version)
var target = version.Targets?.FirstOrDefault(x => x.Target?.Replace("-", "") == currentTarget) ?? version.Targets?.FirstOrDefault(x => x.Target == "all");
return target;
}

public Task<bool> DownloadAsync(PackageVersion version)
{
var task = PerformDownloadAsync(version);
Expand All @@ -121,9 +123,11 @@ private async Task<bool> PerformDownloadAsync(PackageVersion version)
Status = PackageStatus.Installing;

var target = SelectTarget(version);

if (target is { Url: not null })
if (target is not null)
{
var zipUrl = target.Url ?? $"{Package.SourceUrl}/{version.Version}/{Package.Id}_{version.Version}_{target.Target}.zip";

var state = _applicationStateService.AddState($"Downloading {Package.Id}...", AppState.Loading);

var progress = new Progress<float>(x =>
Expand All @@ -138,7 +142,7 @@ private async Task<bool> PerformDownloadAsync(PackageVersion version)
});

//Download
var result = await _httpService.DownloadAndExtractArchiveAsync(target.Url, ExtractionFolder, progress);
var result = await HttpService.DownloadAndExtractArchiveAsync(zipUrl, ExtractionFolder, progress);

_applicationStateService.RemoveState(state);

Expand Down Expand Up @@ -242,4 +246,9 @@ private void UpdateStatus()
else
Status = PackageStatus.Unavailable;
}

public virtual Task<CompatibilityReport> CheckCompatibilityAsync(PackageVersion version)
{
return Task.FromResult(new CompatibilityReport(true, null));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace OneWare.Essentials.PackageManager.Compatibility;

public class CompatibilityReport(bool isCompatible, string? report = null)
{
public bool IsCompatible { get; } = isCompatible;

public string? Report { get; } = report;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
namespace OneWare.Essentials.PackageManager.Compatibility;

public class PluginCompatibilityChecker
{
public static CompatibilityReport CheckCompatibilityPath(string path)
{
try
{
var pluginName = Path.GetFileName(path);

var depFilePath = Path.Combine(path, "minimal-dependencies.txt");

var compatibilityIssues = "";

if (!File.Exists(depFilePath))
{
compatibilityIssues +=
$"Extension {pluginName} incompatible:\n\nminimal-dependencies.txt not found in plugin folder\n";
return new CompatibilityReport(false, compatibilityIssues);
}

return CheckCompatibility(File.ReadAllText(depFilePath));
}
catch (Exception e)
{
return new CompatibilityReport(false, e.Message);
}
}

public static CompatibilityReport CheckCompatibility(string? deps)
{
try
{
var compatibilityIssues = "";

if (deps == null) return new CompatibilityReport(false, "Error checking compatibility");

var depsList = deps.Trim().Split('\n');

foreach (var dep in depsList)
{
var parts = dep.Split(':');
var dependencyName = parts[0].Trim();
var versionString = parts[1].Trim();
var dependencyVersion = Version.Parse(NormalizeVersion(versionString));

var coreDep = AppDomain.CurrentDomain.GetAssemblies()
.SingleOrDefault(x => x.GetName().Name == dependencyName)?.GetName();

if (coreDep == null)
{
compatibilityIssues += $"Dependency {dependencyName} not found\n";
continue;
}

if (coreDep.Version < dependencyVersion)
compatibilityIssues +=
$"Studio {dependencyName} v{coreDep.Version} is older than Plugin v{dependencyVersion}\n";
if (coreDep.Version > dependencyVersion)
compatibilityIssues +=
$"Studio {dependencyName} v{coreDep.Version} is newer than Plugin v{dependencyVersion}\n";
}

return new CompatibilityReport(compatibilityIssues.Length == 0, compatibilityIssues);
}
catch (Exception e)
{
return new CompatibilityReport(false, e.Message);
}
}

static string NormalizeVersion(string version)
{
string[] parts = version.Split('.');
while (parts.Length < 4)
{
Array.Resize(ref parts, parts.Length + 1);
parts[^1] = "0";
}
return string.Join('.', parts);
}
}
2 changes: 2 additions & 0 deletions src/OneWare.Essentials/PackageManager/Package.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public class Package
public string? License { get; init; }

public string? IconUrl { get; init; }

public string? SourceUrl { get; init; }

public PackageTab[]? Tabs { get; init; }

Expand Down
2 changes: 1 addition & 1 deletion src/OneWare.Essentials/PackageManager/PackageTarget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ public class PackageTarget
public string? Target { get; init; }

public string? Url { get; init; }

public PackageAutoSetting[]? AutoSetting { get; init; }
}
2 changes: 1 addition & 1 deletion src/OneWare.Essentials/PackageManager/PackageVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ public class PackageVersion

public PackageTarget[]? Targets { get; init; }

public bool TargetAll => Targets is [{ Target: "all" }];
public string? DepsUrl { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ public class OssCadSuiteIntegrationModule : IModule
new PackageTarget
{
Target = "win-x64",
Url =
"https://github.com/HendrikMennen/oss-cad-suite-build/releases/download/2024-07-27/oss-cad-suite-windows-x64-20240727.tgz",
Url = "https://github.com/HendrikMennen/oss-cad-suite-build/releases/download/2024-07-27/oss-cad-suite-windows-x64-20240727.tgz",
AutoSetting =
[
new PackageAutoSetting
Expand All @@ -84,8 +83,7 @@ public class OssCadSuiteIntegrationModule : IModule
new PackageTarget
{
Target = "linux-x64",
Url =
"https://github.com/YosysHQ/oss-cad-suite-build/releases/download/2024-07-27/oss-cad-suite-linux-x64-20240727.tgz",
Url = "https://github.com/YosysHQ/oss-cad-suite-build/releases/download/2024-07-27/oss-cad-suite-linux-x64-20240727.tgz",
AutoSetting =
[
new PackageAutoSetting
Expand All @@ -98,8 +96,7 @@ public class OssCadSuiteIntegrationModule : IModule
new PackageTarget
{
Target = "osx-x64",
Url =
"https://github.com/YosysHQ/oss-cad-suite-build/releases/download/2024-07-27/oss-cad-suite-darwin-x64-20240727.tgz",
Url = "https://github.com/YosysHQ/oss-cad-suite-build/releases/download/2024-07-27/oss-cad-suite-darwin-x64-20240727.tgz",
AutoSetting =
[
new PackageAutoSetting
Expand All @@ -112,8 +109,7 @@ public class OssCadSuiteIntegrationModule : IModule
new PackageTarget
{
Target = "osx-arm64",
Url =
"https://github.com/YosysHQ/oss-cad-suite-build/releases/download/2024-07-27/oss-cad-suite-darwin-arm64-20240727.tgz",
Url = "https://github.com/YosysHQ/oss-cad-suite-build/releases/download/2024-07-27/oss-cad-suite-darwin-arm64-20240727.tgz",
AutoSetting =
[
new PackageAutoSetting
Expand Down
20 changes: 20 additions & 0 deletions src/OneWare.PackageManager/Models/PackageVersionModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using CommunityToolkit.Mvvm.ComponentModel;
using OneWare.Essentials.PackageManager;
using OneWare.Essentials.PackageManager.Compatibility;

namespace OneWare.PackageManager.Models;

public class PackageVersionModel(PackageVersion version) : ObservableObject
{
private CompatibilityReport? _compatibilityReport;

public PackageVersion Version { get; } = version;

public bool TargetAll => Version.Targets is [{ Target: "all" }];

public CompatibilityReport? CompatibilityReport
{
get => _compatibilityReport;
set => SetProperty(ref _compatibilityReport, value);
}
}
Loading

0 comments on commit 46d82f8

Please sign in to comment.