From 6377b1bc78696e126320740a9a6896256c99f4ca Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 29 Jan 2020 15:58:43 -0700 Subject: [PATCH] Adds Global methods to check version dependencies of plugins --- PepperDashEssentials/ControlSystem.cs | 26 ++++- .../PepperDashEssentialsBase/Global/Global.cs | 107 +++++++++++++++++- .../PepperDash_Essentials_Core.csproj | 1 + 3 files changed, 129 insertions(+), 5 deletions(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 4cb58a24..17004617 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -95,9 +95,7 @@ namespace PepperDash.Essentials var dirSeparator = Global.DirectorySeparator; - var version = Crestron.SimplSharp.Reflection.Assembly.GetExecutingAssembly().GetName().Version; - - var versionString = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Build); + var versionString = Global.GetAssemblyVersion(); string directoryPrefix; @@ -254,6 +252,27 @@ namespace PepperDash.Essentials var loadPlugin = methods.FirstOrDefault(m => m.Name.Equals("LoadPlugin")); if (loadPlugin != null) { + var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Static); + var minimumVersion = properties.FirstOrDefault(p => p.Name.Equals("MinimumEssentialsFrameworkVersion")); + if (minimumVersion != null) + { + var minimumVersionString = minimumVersion.GetValue(null, null) as string; + + if (!string.IsNullOrEmpty(minimumVersionString)) + { + var passed = Global.IsRunningMinimumVersionOrHigher(minimumVersionString); + + if (!passed) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", minimumVersionString); + } + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Warning, "MinimumEssentialsFrameworkVersion not defined. Loading plugin, but your mileage may vary."); + } + } + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding type {0}", assy.Key, type.FullName); loadPlugin.Invoke(null, null); } @@ -263,7 +282,6 @@ namespace PepperDash.Essentials Debug.Console(2, "Load Plugin not found. {0} is not a plugin assembly", assy.Value.FullName); continue; } - } } catch diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs index 6ce3446e..174042de 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs @@ -1,4 +1,6 @@ -using Crestron.SimplSharp; +using System; +using System.Text.RegularExpressions; +using Crestron.SimplSharp; using Crestron.SimplSharp.CrestronDataStore; using Crestron.SimplSharpPro; @@ -45,6 +47,109 @@ namespace PepperDash.Essentials.Core FilePathPrefix = prefix; } + /// + /// Gets the Assembly Version of Essentials + /// + /// The Assembly Version at Runtime + public static string GetAssemblyVersion() + { + var version = Crestron.SimplSharp.Reflection.Assembly.GetExecutingAssembly().GetName().Version; + + return string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Build); + } + + /// + /// Checks to see if the running version meets or exceed the minimum specified version. For beta versions (0.xx.yy), will always return true. + /// + /// Minimum specified version in format of xx.yy.zz + /// Returns true if the running version meets or exceeds the minimum specified version + public static bool IsRunningMinimumVersionOrHigher(string minimumVersion) + { + var runtimeVersion = Crestron.SimplSharp.Reflection.Assembly.GetExecutingAssembly().GetName().Version; + + Debug.Console(2, "Comparing running version '{0}' to minimum version '{1}'", GetAssemblyVersion(), minimumVersion); + + if (runtimeVersion.Major == 0) + { + Debug.Console(2, "Running Beta Build. Bypassing Dependency Check."); + return true; + } + + var minVersion = Regex.Match(minimumVersion, @"^(\d*).(\d*).(\d*)$"); + + if(!minVersion.Success) + { + Debug.Console(2, "minimumVersion String does not match format xx.yy.zz"); + return false; + + } + + var minVersionMajor = Int16.Parse(minVersion.Groups[1].Value); + var minVersionMinor = Int16.Parse(minVersion.Groups[2].Value); + var minVersionBuild = Int16.Parse(minVersion.Groups[3].Value); + + if (minVersionMajor < runtimeVersion.Major) + return false; + + if (minVersionMinor < runtimeVersion.Minor) + return false; + + if (minVersionBuild < runtimeVersion.Build) + return false; + + return true; + } + + /// + /// Attempts to validate the JSON against the specified schema + /// + /// JSON to be validated + /// File name of schema to validate against + public static void ValidateSchema(string json, string schemaFileName) + { + try + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Validating Config against Schema..."); + JObject config = JObject.Parse(json); + + Debug.Console(2, "Config: \n{0}", json); + + using (StreamReader fileStream = new StreamReader(schemaFileName)) + { + JsonSchemaResolver resolver = new JsonSchemaResolver(); + + JsonSchema schema = JsonSchema.Parse(fileStream.ReadToEnd(), resolver); + + + Debug.Console(2, "Schema: \n{0}", schema.ToString()); + + if (config.IsValid(schema)) + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Configuration successfully Validated Against Schema"); + else + { + Debug.Console(0, Debug.ErrorLogLevel.Warning, "Validation Errors Found in Configuration:"); + config.Validate(schema, Json_ValidationEventHandler); + } + } + } + catch (Exception e) + { + Debug.Console(1, "Error in ValidateSchema: {0}", e); + } + } + + + + /// + /// Event Handler callback for JSON validation + /// + /// + /// + public static void Json_ValidationEventHandler(object sender, ValidationEventArgs args) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "JSON Validation error at line {0} position {1}: {2}", args.Exception.LineNumber, args.Exception.LinePosition, args.Message); + } + static Global() { // Fire up CrestronDataStoreStatic diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index c6915164..caffdc5b 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -152,6 +152,7 @@ +