diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2019-12-04 15:23:43 +0200 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2019-12-04 15:23:43 +0200 |
| commit | e8c9c0b649f31bf5170be409cdf6925aa9fc11b6 (patch) | |
| tree | 14e9e27618a74ac7619e935c9e2dfbd2aaf1e649 /Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages | |
| parent | 4fb7e23ead019e9c2b573eb4ccc89444fb5a7a6f (diff) | |
| download | Tango-e8c9c0b649f31bf5170be409cdf6925aa9fc11b6.tar.gz Tango-e8c9c0b649f31bf5170be409cdf6925aa9fc11b6.zip | |
Working on PPC packages
Diffstat (limited to 'Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages')
10 files changed, 368 insertions, 0 deletions
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/DefaultPackageRunner.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/DefaultPackageRunner.cs new file mode 100644 index 000000000..882896f04 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/DefaultPackageRunner.cs @@ -0,0 +1,225 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Tango.Core; +using Tango.Core.Helpers; + +namespace Tango.PPC.Common.UpdatePackages +{ + public class DefaultPackageRunner : ExtendedObject, IPackageRunner + { + private JsonSerializerSettings _jsonSettings; + private String _configFile; + private PackagesFile _packagesFile; + + public event EventHandler<PackageStateChangedEventArgs> PackageStateChanged; + + public DefaultPackageRunner() + { + _jsonSettings = new JsonSerializerSettings + { + Formatting = Formatting.Indented, + Error = (sender, args) => + { + args.ErrorContext.Handled = true; + LogManager.Log(args.ErrorContext.Error.Message); + } + }; + + _jsonSettings.Converters.Add(new StringEnumConverter(false)); + + _configFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "Packages", "packages.json"); + } + + public Task<PackagesFile> GetPackagesFile() + { + return Task.Factory.StartNew<PackagesFile>(() => + { + if (_packagesFile != null) + { + return _packagesFile; + } + else + { + Directory.CreateDirectory(Path.GetDirectoryName(_configFile)); + + _packagesFile = new PackagesFile(); + + try + { + if (File.Exists(_configFile)) + { + LogManager.Log("Loading packages config from " + _configFile + "..."); + _packagesFile = JsonConvert.DeserializeObject<PackagesFile>(File.ReadAllText(_configFile), _jsonSettings); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading packages file."); + } + + return _packagesFile; + } + }); + } + + private void SavePackagesConfig() + { + Directory.CreateDirectory(Path.GetDirectoryName(_configFile)); + + String json = String.Empty; + + if (_packagesFile != null) + { + json = JsonConvert.SerializeObject(_packagesFile, _jsonSettings); + } + else + { + json = JsonConvert.SerializeObject(new PackagesFile(), _jsonSettings); + } + + File.WriteAllText(_configFile, json); + } + + public Task Run(PackageType type, String packagesFolder) + { + return Task.Factory.StartNew(() => + { + PackageContext context = new PackageContext(); + + LogManager.Log($"Running {type}-update packages..."); + + //Get installed packages. + _packagesFile = GetPackagesFile().Result; + + LogManager.Log($"Installed packages file:\n{_packagesFile}"); + + LogManager.Log($"Scanning for packages on '{packagesFolder}'..."); + + //Get all packages in folder. + foreach (var packageFile in Directory.GetFiles(packagesFolder, "*.dll")) + { + LogManager.Log($"Loading assembly '{Path.GetFileName(packageFile)}'..."); + + Assembly asm; + + //Load assembly and investigate for types based on package type. + try + { + asm = Assembly.LoadFile(packageFile); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading assembly!"); + continue; + } + + try + { + foreach (var packageType in asm.GetTypes().Where( + x => typeof(IPPCPackage).IsAssignableFrom(x) && + x.GetCustomAttribute<PPCPackageAttribute>() != null && + x.GetCustomAttribute<PPCPackageAttribute>().Type == type)) + { + LogManager.Log($"Checking package '{packageType.FullName}'..."); + + try + { + //Getting installed package from file. + var installedPackage = _packagesFile.PackageInstallations.SingleOrDefault(x => x.PackageName == packageType.FullName); + + //Check if requires installation. + if (installedPackage == null || installedPackage.State != PackageInstallationState.Installed) + { + if (installedPackage == null) + { + LogManager.Log("Package was never installed."); + + installedPackage = new PackageInstallation(); + installedPackage.State = PackageInstallationState.NotInstalled; + installedPackage.PackageName = packageType.FullName; + installedPackage.Type = type; + _packagesFile.PackageInstallations.Add(installedPackage); + } + else + { + LogManager.Log($"Package installation state is '{installedPackage.State}' due to {installedPackage.FailedReason}"); + } + + LogManager.Log("Installing package..."); + + //Install package... + var att = packageType.GetCustomAttribute<PPCPackageAttribute>(); + + var packageInstance = Activator.CreateInstance(packageType) as IPPCPackage; + + if (packageInstance != null) + { + try + { + OnPackageRuns(att.Name, installedPackage.State); + packageInstance.Run(context).GetAwaiter().GetResult(); + installedPackage.State = PackageInstallationState.Installed; + installedPackage.FailedReason = null; + OnPackageRuns(att.Name, installedPackage.State); + LogManager.Log("Package installed successfully."); + } + catch (Exception ex) + { + LogManager.Log(ex, "Package installation failed."); + installedPackage.State = PackageInstallationState.Failed; + installedPackage.FailedReason = ex.FlattenMessage(); + OnPackageRuns(att.Name, installedPackage.State); + continue; + } + } + } + else + { + LogManager.Log("Package is already installed."); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error in handling the package!"); + continue; + } + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error investigating assembly!"); + continue; + } + } + + //Save package file. + LogManager.Log("Running packages has completed. Saving packages config file."); + + try + { + SavePackagesConfig(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error saving packages file!"); + } + }); + } + + protected virtual void OnPackageRuns(String packageName, PackageInstallationState state) + { + PackageStateChanged?.Invoke(this, new PackageStateChangedEventArgs() + { + PackageName = packageName, + State = state, + }); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/IPPCPackage.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/IPPCPackage.cs new file mode 100644 index 000000000..d9dc70135 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/IPPCPackage.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Common.UpdatePackages +{ + public interface IPPCPackage + { + Task Run(PackageContext context); + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/IPackageRunner.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/IPackageRunner.cs new file mode 100644 index 000000000..03c583dca --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/IPackageRunner.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Common.UpdatePackages +{ + public interface IPackageRunner + { + event EventHandler<PackageStateChangedEventArgs> PackageStateChanged; + Task<PackagesFile> GetPackagesFile(); + Task Run(PackageType type, String packagesFolder); + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PPCPackageAttribute.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PPCPackageAttribute.cs new file mode 100644 index 000000000..7ae4ea52d --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PPCPackageAttribute.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Common.UpdatePackages +{ + [AttributeUsage(AttributeTargets.Class)] + public class PPCPackageAttribute : Attribute + { + public String Name { get; set; } + + public PackageType Type { get; set; } + + public PPCPackageAttribute(PackageType type, String name) + { + Type = type; + Name = name; + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackageContext.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackageContext.cs new file mode 100644 index 000000000..cf96ff026 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackageContext.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Common.UpdatePackages +{ + public class PackageContext + { + + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackageInstallation.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackageInstallation.cs new file mode 100644 index 000000000..bcffb1b6e --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackageInstallation.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Common.UpdatePackages +{ + public class PackageInstallation + { + public String PackageName { get; set; } + + public PackageType Type { get; set; } + + public PackageInstallationState State { get; set; } + + public String FailedReason { get; set; } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackageInstallationState.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackageInstallationState.cs new file mode 100644 index 000000000..1300352fb --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackageInstallationState.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Common.UpdatePackages +{ + public enum PackageInstallationState + { + NotInstalled, + Installed, + Failed, + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackageStateChangedEventArgs.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackageStateChangedEventArgs.cs new file mode 100644 index 000000000..62eb00e5e --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackageStateChangedEventArgs.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Common.UpdatePackages +{ + public class PackageStateChangedEventArgs : EventArgs + { + public PackageInstallationState State { get; set; } + public String PackageName { get; set; } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackageType.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackageType.cs new file mode 100644 index 000000000..48a2140b1 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackageType.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Common.UpdatePackages +{ + public enum PackageType + { + Pre, + Post + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackagesFile.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackagesFile.cs new file mode 100644 index 000000000..2fbd30d9f --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/UpdatePackages/PackagesFile.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Common.UpdatePackages +{ + public class PackagesFile + { + public List<PackageInstallation> PackageInstallations { get; set; } + + public PackagesFile() + { + PackageInstallations = new List<PackageInstallation>(); + } + } +} |
