/// <summary> /// 创建插件对象。 /// </summary> /// <param name="pluginTree">依附的插件树对象。</param> /// <param name="name">插件名称,该名称必须在同级插件中唯一。</param> /// <param name="filePath">插件文件路径(完整路径)。</param> /// <param name="parent">所属的父插件。</param> /// <remarks>创建的插件对象,并没有被加入到<paramref name="parent"/>参数指定的父插件的子集中(<seealso cref="Zongsoft.Plugins.Plugin.Children"/>)。</remarks> internal Plugin(PluginTree pluginTree, string name, string filePath, Plugin parent) { if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentNullException("name"); } if (string.IsNullOrWhiteSpace(filePath)) { throw new ArgumentNullException("filePath"); } _pluginTree = pluginTree ?? throw new ArgumentNullException(nameof(pluginTree)); _name = name.Trim(); _filePath = filePath; _parent = parent; _isHidden = string.Equals(Path.GetFileName(filePath), ".plugin", StringComparison.OrdinalIgnoreCase); _status = PluginStatus.None; _manifest = new PluginManifest(this); _children = new PluginCollection(this); _builtins = new List <Builtin>(); _parsers = new FixedElementCollection <IParser>(); _builders = new BuilderElementCollection(); }
public void RulesPluginBuilder_CreateSimplePlugin_Succeeds() { string inputDir = TestUtils.CreateTestDirectory(this.TestContext, "input"); string outputDir = TestUtils.CreateTestDirectory(this.TestContext, "output"); string fullJarFilePath = Path.Combine(outputDir, "myPlugin.jar"); string language = "xx"; string rulesXmlFilePath = TestUtils.CreateTextFile("rules.xml", inputDir, "<xml Rules />"); string sqaleXmlFilePath = TestUtils.CreateTextFile("sqale.xml", inputDir, "<xml sqale />"); PluginManifest defn = new PluginManifest() { Key = "MyPlugin", Name = "My Plugin", Description = "Generated plugin", Version = "0.1-SNAPSHOT", Organization = "ACME Software Ltd", License = "Commercial", Developers = typeof(RulesPluginBuilder).FullName }; MockJdkWrapper mockJdkWrapper = new MockJdkWrapper(); RulesPluginBuilder builder = new RulesPluginBuilder(mockJdkWrapper, new MockMavenArtifactHandler(), new TestLogger()); builder.SetLanguage(language) .SetRulesFilePath(rulesXmlFilePath) .SetSqaleFilePath(sqaleXmlFilePath) .SetJarFilePath(fullJarFilePath) .SetProperties(defn); builder.Build(); // should not fail mockJdkWrapper.AssertJarBuilt(); }
public void Invalid_Manifest_Returns_Negative_Result_And_List_Of_Errors() { var manifest = new PluginManifest() { CdsConnection = new CdsConnection() { CdsUrl = "https://testurl.crm.dynamics.com", CdsAppId = "ID", CdsAppSecret = "SECRET!" }, PluginAssemblies = new[] { new CdsPluginAssembly() { Name = "Test Assembly", Plugins = new[] { new CdsPlugin() { Name = "Test Plugin" } } } } }; var wrapper = new PluginWrapper(); var result = wrapper.Validate(manifest); result.IsValid.Should().BeFalse("assembly and child plugin have missing mandatory data"); result.Errors.Should().HaveCount(3, "assembly has two errors and child plugin has one"); }
private PluginManifest GetManifestFromZip(string path) { try { using (var zipFile = ZipFile.OpenRead(path)) { foreach (var entry in zipFile.Entries) { if (!entry.Name.Equals(MANIFEST_NAME, StringComparison.CurrentCultureIgnoreCase)) { continue; } using (var stream = new StreamReader(entry.Open())) { return(PluginManifest.Load(stream)); } } } } catch (Exception ex) { _log.Error(ex, $"Error opening zip! File is likely corrupt. File at {path} will be deleted and re-acquired on the next restart!"); File.Delete(path); } return(null); }
public RoslynPluginJarBuilder SetPluginManifestProperties(PluginManifest definition) { if (definition == null) { throw new ArgumentNullException(nameof(definition)); } SetNonNullManifestProperty(WellKnownPluginProperties.License, definition.License); SetNonNullManifestProperty(WellKnownPluginProperties.OrganizationUrl, definition.OrganizationUrl); SetNonNullManifestProperty(WellKnownPluginProperties.Version, definition.Version); SetNonNullManifestProperty(WellKnownPluginProperties.Homepage, definition.Homepage); SetNonNullManifestProperty(WellKnownPluginProperties.SourcesUrl, definition.SourcesUrl); SetNonNullManifestProperty(WellKnownPluginProperties.Developers, definition.Developers); SetNonNullManifestProperty(WellKnownPluginProperties.IssueTrackerUrl, definition.IssueTrackerUrl); SetNonNullManifestProperty(WellKnownPluginProperties.TermsAndConditionsUrl, definition.TermsConditionsUrl); SetNonNullManifestProperty(WellKnownPluginProperties.OrganizationName, definition.Organization); SetNonNullManifestProperty(WellKnownPluginProperties.PluginName, definition.Name); SetNonNullManifestProperty(WellKnownPluginProperties.Description, definition.Description); string key = definition.Key; PluginKeyUtilities.ThrowIfInvalid(key); this.SetManifestProperty(WellKnownPluginProperties.Key, key); return(this); }
/// <summary> /// See interface docs. /// </summary> /// <param name="fileName"></param> /// <returns></returns> public PluginManifest LoadForPlugin(string fileName) { if (fileName == null) { throw new ArgumentNullException("fileName"); } if (fileName == "") { throw new InvalidOperationException("Plugin filename must be supplied"); } var extension = Path.GetExtension(fileName); if (extension.ToUpper() != ".DLL") { throw new InvalidOperationException(String.Format("{0} is not a DLL", fileName)); } var manifestFileName = Path.ChangeExtension(fileName, ".xml"); PluginManifest result = null; if (Provider.FileExists(manifestFileName)) { var fileContent = Provider.ReadAllText(manifestFileName); using (var textReader = new StringReader(fileContent)) { var serialiser = new XmlSerializer(typeof(PluginManifest)); result = (PluginManifest)serialiser.Deserialize(textReader); } } return(result); }
public override async Task SavePluginManifestAsync(PluginManifest manifest) { await Task.Delay(0); // load existing registry var registry = GetRegistry(); var registryItem = registry.FirstOrDefault( r => r.PluginId.Equals(manifest.PluginId, StringComparison.OrdinalIgnoreCase)); var updatedRegistryItem = MapToFsRegistryItem(manifest, registryItem); if (registryItem == null) { registry.Add(updatedRegistryItem); } // save registry SaveRegistry(registry); // save settings if (manifest.RegistrationInfo.PluginSettings == null || manifest.RegistrationInfo.PluginSettings.Count == 0) { manifest.RegistrationInfo.PluginSettings = manifest.PluginDefaultSettings; } SaveRegistryItemSettings(manifest.PluginId, manifest.RegistrationInfo.PluginSettings); }
/// <summary> /// See interface docs. /// </summary> /// <param name="fileName"></param> /// <returns></returns> public PluginManifest LoadForPlugin(string fileName) { if (fileName == null) { throw new ArgumentNullException("fileName"); } if (fileName == "") { throw new InvalidOperationException("Plugin filename must be supplied"); } var extension = Path.GetExtension(fileName); if (extension.ToUpper() != ".DLL") { throw new InvalidOperationException($"{fileName} is not a DLL"); } var manifestFileName = Path.ChangeExtension(fileName, ".xml"); PluginManifest result = null; if (Provider.FileExists(manifestFileName)) { var fileContent = Provider.ReadAllText(manifestFileName); using (var textReader = new StringReader(fileContent)) { var serialiser = Factory.Singleton.Resolve <IXmlSerialiser>(); result = serialiser.Deserialise <PluginManifest>(textReader); } } return(result); }
/// <summary> /// Loads the manifest and returns true if it permits the loading of the plugin. If it prohibits /// the load then <see cref="IgnoredPlugins"/> is updated. /// </summary> /// <param name="manifestStorage"></param> /// <param name="applicationVersion"></param> /// <param name="dllFileName"></param> /// <returns></returns> private bool ManifestAllowsLoad(IPluginManifestStorage manifestStorage, Version applicationVersion, string dllFileName) { PluginManifest manifest = null; try { manifest = manifestStorage.LoadForPlugin(dllFileName); if (manifest == null) { IgnoredPlugins.Add(dllFileName, Strings.CouldNotFindManifest); } } catch (Exception ex) { IgnoredPlugins.Add(dllFileName, String.Format(Strings.CouldNotParseManifest, ex.Message)); } var result = manifest != null; if (result && !String.IsNullOrEmpty(manifest.MinimumVersion)) { result = CompareManifestVersions(manifest.MinimumVersion, applicationVersion, dllFileName, true); } if (result && !String.IsNullOrEmpty(manifest.MaximumVersion)) { result = CompareManifestVersions(manifest.MaximumVersion, applicationVersion, dllFileName, false); } return(result); }
private void DownloadPlugins() { var folders = Directory.GetDirectories(PluginDir); var taskList = new List <Task>(); //Copy list because we don't want to modify the config. var toDownload = Torch.Config.Plugins.ToList(); foreach (var folder in folders) { var manifestPath = Path.Combine(folder, "manifest.xml"); if (!File.Exists(manifestPath)) { _log.Debug($"No manifest in {folder}, skipping"); continue; } var manifest = PluginManifest.Load(manifestPath); toDownload.RemoveAll(x => string.Compare(manifest.Repository, x, StringComparison.InvariantCultureIgnoreCase) == 0); taskList.Add(_updateManager.CheckAndUpdatePlugin(manifest)); } foreach (var repository in toDownload) { var manifest = new PluginManifest { Repository = repository, Version = "0.0" }; taskList.Add(_updateManager.CheckAndUpdatePlugin(manifest)); } Task.WaitAll(taskList.ToArray()); }
public async Task CheckAndUpdatePlugin(PluginManifest manifest) { if (!Torch.Config.GetPluginUpdates) { return; } var name = manifest.Repository.Split('/'); if (name.Length != 2) { _log.Error($"'{manifest.Repository}' is not a valid GitHub repository."); return; } var currentVersion = new Version(manifest.Version); var releaseInfo = await GetLatestRelease(name[0], name[1]).ConfigureAwait(false); if (releaseInfo.Item1 > currentVersion) { _log.Warn($"Updating {manifest.Repository} from version {currentVersion} to version {releaseInfo.Item1}"); var updateName = Path.Combine(_fsManager.TempDirectory, $"{name[0]}_{name[1]}.zip"); var updatePath = Path.Combine(_torchDir, "Plugins"); await new WebClient().DownloadFileTaskAsync(new Uri(releaseInfo.Item2), updateName).ConfigureAwait(false); UpdateFromZip(updateName, updatePath); File.Delete(updateName); } else { _log.Info($"{manifest.Repository} is up to date. ({currentVersion})"); } }
public void RulePluginGen_Simple() { string inputDir = TestUtils.CreateTestDirectory(this.TestContext, "input"); string outputDir = TestUtils.CreateTestDirectory(this.TestContext, "output"); string fullJarFilePath = Path.Combine(outputDir, "myPlugin.jar"); string language = "xx"; string rulesXmlFilePath = TestUtils.CreateTextFile("rules.xml", inputDir, "<xml Rules />"); IJdkWrapper jdkWrapper = new JdkWrapper(); RulesPluginBuilder generator = new RulesPluginBuilder(jdkWrapper, new TestLogger()); PluginManifest defn = new PluginManifest() { Key = "MyPlugin", Name = "My Plugin", Description = "Generated plugin", Version = "0.1-SNAPSHOT", Organization = "ACME Software Ltd", License = "Commercial", Developers = typeof(RulesPluginBuilder).FullName }; generator.GeneratePlugin(defn, language, rulesXmlFilePath, fullJarFilePath); if (File.Exists(fullJarFilePath)) { this.TestContext.AddResultFile(fullJarFilePath); } new JarChecker(this.TestContext, fullJarFilePath) .JarContainsFiles( "resources\\rules.xml", "org\\sonarqube\\plugin\\sdk\\MyPlugin\\Plugin.class", "org\\sonarqube\\plugin\\sdk\\MyPlugin\\PluginRulesDefinition.class"); }
public async Task RunPluginTests(string pluginDir, string filters, bool needsDepsDownload) { IPluginManifest manifest = new PluginManifest(pluginDir); var testFile = manifest.Test ?? throw new ArgumentException($"Plug-in does not contain tests: {manifest.AbsolutePath}"); var testsAsm = Assembly.LoadFrom(testFile.AbsolutePath); var downloadedDependenciesDirs = new List <string>(); try { if (manifest.Dependencies.Count > 0 && needsDepsDownload) { await DownloadPluginDependencies(manifest, downloadedDependenciesDirs); } await RunTests( testsAsm, string.Join(';', downloadedDependenciesDirs.Union(new[] { manifest.PluginDirectory })), filters, app => { var autoAccept = app.AutoAcceptPreprocessingUserInteraction(); return(() => { autoAccept.Dispose(); }); } ); } finally { downloadedDependenciesDirs.ForEach(d => Directory.Delete(d, true)); } }
/// <summary> /// Send feedback to Discord. /// </summary> /// <param name="plugin">The plugin to send feedback about.</param> /// <param name="isTesting">Whether or not the plugin is a testing plugin.</param> /// <param name="content">The content of the feedback.</param> /// <param name="reporter">The reporter name.</param> /// <param name="includeException">Whether or not the most recent exception to occur should be included in the report.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public static async Task SendFeedback(PluginManifest plugin, bool isTesting, string content, string reporter, bool includeException) { if (content.IsNullOrWhitespace()) { return; } var model = new FeedbackModel { Content = content, Reporter = reporter, Name = plugin.InternalName, Version = isTesting ? plugin.TestingAssemblyVersion?.ToString() : plugin.AssemblyVersion.ToString(), DalamudHash = Util.GetGitHash(), }; if (includeException) { model.Exception = Troubleshooting.LastException == null ? "Was included, but none happened" : Troubleshooting.LastException?.ToString(); } var postContent = new StringContent(JsonConvert.SerializeObject(model), Encoding.UTF8, "application/json"); var response = await Util.HttpClient.PostAsync(BugBaitUrl, postContent); response.EnsureSuccessStatusCode(); }
private void DownloadPlugins() { _log.Info("Downloading plugins"); var updater = new PluginUpdater(this); var folders = Directory.GetDirectories(PluginDir); var taskList = new List <Task>(); if (_torch.Config.RedownloadPlugins) { _log.Warn("Force downloading all plugins because the RedownloadPlugins flag is set in the config"); } foreach (var folder in folders) { var manifestPath = Path.Combine(folder, "manifest.xml"); if (!File.Exists(manifestPath)) { _log.Info($"No manifest in {folder}, skipping"); continue; } _log.Info($"Checking for updates for {folder}"); var manifest = PluginManifest.Load(manifestPath); taskList.Add(updater.CheckAndUpdate(manifest, _torch.Config.RedownloadPlugins)); } Task.WaitAll(taskList.ToArray()); _torch.Config.RedownloadPlugins = false; }
public void SaveManifest_RoundTrip_Success() { var pluginManager = new PluginManager(new NullLogger <PluginManager>(), null !, null !, null !, new Version(1, 0)); var manifest = new PluginManifest() { Version = "1.0" }; var tempPath = Path.Combine(_testPathRoot, "manifest-" + Path.GetRandomFileName()); Directory.CreateDirectory(tempPath); Assert.True(pluginManager.SaveManifest(manifest, tempPath)); var res = pluginManager.LoadManifest(tempPath); Assert.Equal(manifest.Category, res.Manifest.Category); Assert.Equal(manifest.Changelog, res.Manifest.Changelog); Assert.Equal(manifest.Description, res.Manifest.Description); Assert.Equal(manifest.Id, res.Manifest.Id); Assert.Equal(manifest.Name, res.Manifest.Name); Assert.Equal(manifest.Overview, res.Manifest.Overview); Assert.Equal(manifest.Owner, res.Manifest.Owner); Assert.Equal(manifest.TargetAbi, res.Manifest.TargetAbi); Assert.Equal(manifest.Timestamp, res.Manifest.Timestamp); Assert.Equal(manifest.Version, res.Manifest.Version); Assert.Equal(manifest.Status, res.Manifest.Status); Assert.Equal(manifest.AutoUpdate, res.Manifest.AutoUpdate); Assert.Equal(manifest.ImagePath, res.Manifest.ImagePath); }
public void PluginManifest_Constructor_Initialises_To_Known_State_And_Properties_Work() { var manifest = new PluginManifest(); TestUtilities.TestProperty(manifest, "MaximumVersion", null, "1.2.3"); TestUtilities.TestProperty(manifest, "MinimumVersion", null, "1.2.3"); }
public void Manifest_Should_Call_GrandChild_Validators_If_Populated_And_Bubble_Up_Errors() { var manifest = new PluginManifest() { CdsConnection = new CdsConnection() { CdsUrl = "https://testurl.crm.dynamics.com", CdsAppId = "ID", CdsAppSecret = "SECRET!" }, PluginAssemblies = new CdsPluginAssembly[] { new CdsPluginAssembly() { Name = "Test", FriendlyName = "Friend Test", Assembly = "c:/fake/test.dll", Plugins = new CdsPlugin[] { new CdsPlugin() { Name = "Test Plugin" } } } } }; var validator = new PluginManifestValidator(); var result = validator.Validate(manifest); result.IsValid.Should().BeFalse("grandchild plugin has missing mandatory data"); }
protected virtual PluginManifest LoadPluginManifest(DirectoryInfo pluginDirectory) { var pluginManifestFile = PluginManifestDiscoverer != null? PluginManifestDiscoverer(pluginDirectory) : pluginDirectory.GetFiles(FsConstants.DefaultPluginManifestFileName, SearchOption.TopDirectoryOnly).FirstOrDefault(); PluginManifest manifest = null; if (pluginManifestFile != null && pluginManifestFile.Exists) { manifest = LoadPluginManifest(pluginManifestFile); } if (manifest == null) { manifest = new PluginManifest { PluginId = pluginDirectory.Name }; } manifest.RuntimeInfo = new FsPluginRuntime { ManifestFile = pluginManifestFile, PluginDirectory = pluginDirectory }; return(manifest); }
public void TestInitialise() { _ClassFactorySnapshot = Factory.TakeSnapshot(); _PluginManager = Factory.ResolveNewInstance <IPluginManager>(); _Provider = new Mock <IPluginManagerProvider>() { DefaultValue = DefaultValue.Mock }.SetupAllProperties(); _Provider.Setup(p => p.ApplicationStartupPath).Returns("x"); _Provider.Setup(p => p.DirectoryExists(It.IsAny <string>())).Returns(true); _Provider.Setup(p => p.DirectoryGetDirectories(It.IsAny <string>())).Returns(new string[] { "subFolder" }); _PluginManager.Provider = _Provider.Object; _Manifest = new PluginManifest(); _ManifestStorage = TestUtilities.CreateMockImplementation <IPluginManifestStorage>(); _ManifestStorage.Setup(m => m.LoadForPlugin(It.IsAny <string>())).Returns(_Manifest); _ApplicationInformation = TestUtilities.CreateMockImplementation <IApplicationInformation>(); _Log = TestUtilities.CreateMockSingleton <ILog>(); Plugin._Reset(); PluginA._Reset(); PluginB._Reset(); PluginC._Reset(); NotPlugin._Reset(); Plugin_V2._Reset(); }
public void RulePluginGen_Simple() { string inputDir = TestUtils.CreateTestDirectory(this.TestContext, "input"); string outputDir = TestUtils.CreateTestDirectory(this.TestContext, "output"); string fullJarFilePath = Path.Combine(outputDir, "myPlugin.jar"); string language = "xx"; string rulesXmlFilePath = TestUtils.CreateTextFile("rules.xml", inputDir, "<xml Rules />"); IJdkWrapper jdkWrapper = new JdkWrapper(); RulesPluginBuilder generator = new RulesPluginBuilder(jdkWrapper, new TestLogger()); PluginManifest defn = new PluginManifest() { Key = "MyPlugin", Name = "My Plugin", Description = "Generated plugin", Version = "0.1-SNAPSHOT", Organization = "ACME Software Ltd", License = "Commercial", Developers = typeof(RulesPluginBuilder).FullName }; generator.GeneratePlugin(defn, language, rulesXmlFilePath, fullJarFilePath); if (File.Exists(fullJarFilePath)) { this.TestContext.AddResultFile(fullJarFilePath); } new JarChecker(this.TestContext, fullJarFilePath) .JarContainsFiles( "resources\\*rules.xml", "org\\sonarqube\\plugin\\sdk\\MyPlugin\\Plugin.class", "org\\sonarqube\\plugin\\sdk\\MyPlugin\\PluginRulesDefinition.class"); }
private void List(PluginManifest manifest) { _allPlugins = new List <Plugin>(); foreach (object asm_def_ in manifest.Children) { StructuredText asm_def = asm_def_ as StructuredText; if (asm_def == null) { continue; //エラーハンドリングやや甘 } string asm_name = asm_def.Name; PluginManifest.AssemblyNode asmnode = null; try { asmnode = manifest.LoadAssemblyNode(asm_def); } catch (Exception) { _tracer.Trace("PluginManager.Messages.AssemblyLoadError", asm_name); continue; } asmnode.TryToBind(_tracer); foreach (Type t in asmnode.PluginTypes) { _allPlugins.Add(new Plugin(this, asmnode.Assembly, t)); } } }
/// <summary> /// 创建插件对象。 /// </summary> /// <param name="pluginTree">依附的插件树对象。</param> /// <param name="name">插件名称,该名称必须在同级插件中唯一。</param> /// <param name="filePath">插件文件路径(完整路径)。</param> /// <param name="parent">所属的父插件。</param> /// <remarks>创建的插件对象,并没有被加入到<paramref name="parent"/>参数指定的父插件的子集中(<seealso cref="Zongsoft.Plugins.Plugin.Children"/>)。</remarks> internal Plugin(PluginTree pluginTree, string name, string filePath, Plugin parent) { if (pluginTree == null) { throw new ArgumentNullException("pluginTree"); } if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentNullException("name"); } if (string.IsNullOrWhiteSpace(filePath)) { throw new ArgumentNullException("filePath"); } _pluginTree = pluginTree; _name = name.Trim(); _filePath = filePath; _parent = parent; _status = PluginStatus.None; _manifest = new PluginManifest(this); _children = new PluginCollection(this); _builtins = new List <Builtin>(); _modules = new FixedElementCollection <IApplicationModule>(); _parsers = new FixedElementCollection <IParser>(); _builders = new BuilderElementCollection(); }
/* for test */ public static PluginManifest CreatePluginManifest(IPackage package) { // The manifest properties supported by SonarQube are documented at // http://docs.sonarqube.org/display/DEV/Build+plugin PluginManifest pluginDefn = new PluginManifest(); pluginDefn.Description = GetValidManifestString(package.Description); pluginDefn.Developers = GetValidManifestString(ListToString(package.Authors)); pluginDefn.Homepage = GetValidManifestString(package.ProjectUrl?.ToString()); pluginDefn.Key = PluginKeyUtilities.GetValidKey(package.Id); if (!String.IsNullOrWhiteSpace(package.Title)) { pluginDefn.Name = GetValidManifestString(package.Title); } else { // Process the package ID to replace dot separators with spaces for use as a fallback pluginDefn.Name = GetValidManifestString(package.Id.Replace(".", " ")); } // Fall back to using the authors if owners is empty string organisation; if (package.Owners.Any()) { organisation = ListToString(package.Owners); } else { organisation = ListToString(package.Authors); } pluginDefn.Organization = GetValidManifestString(organisation); pluginDefn.Version = GetValidManifestString(package.Version?.ToNormalizedString()); // The TermsConditionsUrl is only displayed in the "Update Center - Available" page // i.e. for plugins that are available through the public Update Center. // If the property has a value then the link will be displayed with a checkbox // for acceptance. // It is not used when plugins are directly dropped into the extensions\plugins // folder of the SonarQube server. pluginDefn.TermsConditionsUrl = GetValidManifestString(package.LicenseUrl?.ToString()); // Packages from the NuGet website may have friendly short licensenames heuristically assigned, but this requires a downcast DataServicePackage dataServicePackage = package as DataServicePackage; if (!String.IsNullOrWhiteSpace(dataServicePackage?.LicenseNames)) { pluginDefn.License = GetValidManifestString(dataServicePackage.LicenseNames); } else { // Fallback - use a raw URL. Not as nice-looking in the UI, but acceptable. pluginDefn.License = pluginDefn.TermsConditionsUrl; } return pluginDefn; }
public async Task CheckAndUpdate(PluginManifest manifest, bool force = false) { Log.Info($"Checking for update at {manifest.Repository}"); var split = manifest.Repository.Split('/'); if (split.Length != 2) { Log.Warn($"Manifest has an invalid repository name: {manifest.Repository}"); return; } var gitClient = new GitHubClient(new ProductHeaderValue("Torch")); var releases = await gitClient.Repository.Release.GetAll(split[0], split[1]); if (releases.Count == 0) { Log.Debug("No releases in repo"); return; } Version currentVersion; Version latestVersion; try { currentVersion = new Version(manifest.Version); latestVersion = new Version(releases[0].TagName); } catch (Exception e) { Log.Warn("Invalid version number on manifest or GitHub release"); return; } if (force || latestVersion > currentVersion) { var webClient = new WebClient(); var assets = await gitClient.Repository.Release.GetAllAssets(split[0], split[1], releases[0].Id); foreach (var asset in assets) { if (asset.Name.EndsWith(".zip")) { Log.Debug(asset.BrowserDownloadUrl); var localPath = Path.Combine(Path.GetTempPath(), asset.Name); await webClient.DownloadFileTaskAsync(new Uri(asset.BrowserDownloadUrl), localPath); UnzipPlugin(localPath); Log.Info($"Downloaded update for {manifest.Repository}"); return; } } } else { Log.Info($"{manifest.Repository} is up to date."); } }
public static void UninstallData(DiscoDataContext database, PluginManifest manifest, ScheduledTaskStatus status) { status.UpdateStatus("Removing Plugin Configuration"); new ConfigurationStore(database) { EmailConfiguration = null }; database.SaveChanges(); }
private bool ValidateManifest(PluginManifest pluginManifest) { return(pluginManifest != null && pluginManifest.GetType().GetProperties() .Where(pi => pi.PropertyType == typeof(string)) .Select(pi => (string)pi.GetValue(pluginManifest)) .All(value => !string.IsNullOrEmpty(value)) && pluginManifest.Type.Equals(WellKnownData.PluginUploadType, StringComparison.OrdinalIgnoreCase)); }
private void DownloadPluginUpdates() { //TODO _log.Warn("Automatic plugin updates are disabled in this build of Torch while the system is reworked."); return; _log.Info("Checking for plugin updates..."); var count = 0; var pluginItems = Directory.EnumerateFiles(PluginDir, "*.zip").Union(Directory.EnumerateDirectories(PluginDir)); Parallel.ForEach(pluginItems, async item => { PluginManifest manifest = null; try { var path = Path.Combine(PluginDir, item); var isZip = item.EndsWith(".zip", StringComparison.CurrentCultureIgnoreCase); manifest = isZip ? GetManifestFromZip(path) : GetManifestFromDirectory(path); if (manifest == null) { _log.Warn($"Item '{item}' is missing a manifest, skipping update check."); return; } manifest.Version.TryExtractVersion(out Version currentVersion); var latest = await GetLatestArchiveAsync(manifest.Repository).ConfigureAwait(false); if (currentVersion == null || latest.Item1 == null) { _log.Error($"Error parsing version from manifest or GitHub for plugin '{manifest.Name}.'"); return; } if (latest.Item1 <= currentVersion) { _log.Debug($"{manifest.Name} {manifest.Version} is up to date."); return; } _log.Info($"Updating plugin '{manifest.Name}' from {currentVersion} to {latest.Item1}."); await UpdatePluginAsync(path, latest.Item2).ConfigureAwait(false); count++; } catch (NotFoundException) { _log.Warn($"GitHub repository not found for {manifest.Name}"); } catch (Exception e) { _log.Warn($"An error occurred updating the plugin {manifest.Name}."); _log.Warn(e); } }); _log.Info($"Updated {count} plugins."); }
private static FsRegistryItem MapToFsRegistryItem(PluginManifest m, FsRegistryItem useExistingRegistryItem = null) { var ri = useExistingRegistryItem ?? new FsRegistryItem(); ri.PluginId = m.PluginId; ri.IsActivated = m.RegistrationInfo.IsActivated; ri.ActivatedOn = m.RegistrationInfo.ActivatedOn; ri.InstalledOn = m.RegistrationInfo.InstalledOn.GetValueOrDefault(DateTime.Now); return(ri); }
public PluginHost(PluginManifest manifest, IPlugin instance, string rootDirectory, bool enabledByDefault, bool updatesEveryFrame, bool isIpcEnabled) { Manifest = manifest; Instance = instance; RootDirectory = rootDirectory; Enabled = enabledByDefault; UpdatesEveryFrame = updatesEveryFrame; IsIPCEnabled = isIpcEnabled; }
public static PluginManifest GetPluginManifest(string path, string pluginInternalName) { try { CultureInfo ci = CultureInfo.CurrentUICulture; var languageCode = ci.TwoLetterISOLanguageName.ToLower(); var xml = XDocument.Load(Path.Combine(path, "PluginManifest.xml")); // Query the data and write out a subset of contacts var query = from c in xml.Root.Descendants("DescriptionSet") where ((string)c.Attribute("lang")).ToLower() == languageCode select c; if (query.FirstOrDefault() == null) { // Specified language not found -> try to find English language. query = from c in xml.Root.Descendants("DescriptionSet") where ((string)c.Attribute("lang")).ToLower() == "en" || ((string)c.Attribute("lang")).ToLower() == "en-us" select c; } if (query.FirstOrDefault() == null) { // English language not found -> just take the first description set. query = from c in xml.Root.Descendants("DescriptionSet") select c; } XElement item = query.FirstOrDefault(); if (item != null) { var pluginNamifest = new PluginManifest(); var queryPluginName = from i in item.Descendants("PluginName") select i.Value; string pluginName = queryPluginName.First(); var queryDescription = from i in item.Descendants("Description") select i.Value; string pluginDescription = queryDescription.First(); var queryAuthorName = from i in item.Descendants("AuthorName") select i.Value; string authorName = queryAuthorName.First(); return(new PluginManifest(pluginName, pluginDescription, authorName)); } } catch (Exception) { throw; //throw new WsapmException(Resources.Wsapm_Core.PluginManifestReader_ManifestMissingError, ex); } throw new WsapmException(Resources.Wsapm_Core.PluginManifestReader_InvalidManifestError); }
public static void UninstallData(DiscoDataContext Database, PluginManifest Manifest, ScheduledTaskStatus Status) { Status.UpdateStatus("Removing Configuration"); var config = new ConfigurationStore(Database); config.CustomerEntityId = null; config.CustomerUsername = null; Database.SaveChanges(); // Storage Location will be cleared by the framework if requested by the user }
public void RoslynPlugin_Test() { // Arrange string testDir = TestUtils.CreateTestDirectory(this.TestContext); string workingDir = TestUtils.CreateTestDirectory(this.TestContext, ".working"); string outputJarFilePath = Path.Combine(testDir, "created.jar"); string dummyRulesFile = TestUtils.CreateTextFile("rules.txt", testDir, "<rules />"); string dummySqaleFile = TestUtils.CreateTextFile("sqale.txt", testDir, "<sqale />"); string dummyZipFile = TestUtils.CreateTextFile("payload.txt", testDir, "zip"); PluginManifest manifest= new PluginManifest() { Key = "pluginkey", Description = "description", Name = "name" }; // Act RoslynPluginJarBuilder builder = new RoslynPluginJarBuilder(new TestLogger()); builder.SetLanguage("cs") .SetRepositoryKey("repo.key") .SetRepositoryName("repo.name") .SetRulesFilePath(dummyRulesFile) .SetSqaleFilePath(dummySqaleFile) .SetPluginManifestProperties(manifest) .AddResourceFile(dummyZipFile, "static\\foo.zip") .SetJarFilePath(outputJarFilePath); builder.BuildJar(workingDir); // Assert ZipFileChecker checker = new ZipFileChecker(this.TestContext, outputJarFilePath); checker.AssertZipContainsFiles( "META-INF\\MANIFEST.MF", "static\\foo.zip", "org\\sonar\\plugins\\roslynsdk\\configuration.xml", "org\\sonar\\plugins\\roslynsdk\\sqale.xml", "org\\sonar\\plugins\\roslynsdk\\rules.xml" ); }
private void BuildPlugin(NuGetReference analyzeRef, string sqaleFilePath, string language, PluginManifest pluginDefn, string rulesFilePath, string tempDirectory, IPackage package) { this.logger.LogInfo(UIResources.APG_GeneratingPlugin); string fullJarPath = Path.Combine(Directory.GetCurrentDirectory(), analyzeRef.PackageId + "-plugin." + pluginDefn.Version + ".jar"); PluginBuilder builder = new PluginBuilder(logger); RulesPluginBuilder.ConfigureBuilder(builder, pluginDefn, language, rulesFilePath, sqaleFilePath); AddRoslynMetadata(tempDirectory, builder, package); builder.SetJarFilePath(fullJarPath); builder.Build(); this.logger.LogInfo(UIResources.APG_PluginGenerated, fullJarPath); }
public RoslynPluginJarBuilder SetPluginManifestProperties(PluginManifest definition) { if (definition == null) { throw new ArgumentNullException(nameof(definition)); } SetNonNullManifestProperty(WellKnownPluginProperties.License, definition.License); SetNonNullManifestProperty(WellKnownPluginProperties.OrganizationUrl, definition.OrganizationUrl); SetNonNullManifestProperty(WellKnownPluginProperties.Version, definition.Version); SetNonNullManifestProperty(WellKnownPluginProperties.Homepage, definition.Homepage); SetNonNullManifestProperty(WellKnownPluginProperties.SourcesUrl, definition.SourcesUrl); SetNonNullManifestProperty(WellKnownPluginProperties.Developers, definition.Developers); SetNonNullManifestProperty(WellKnownPluginProperties.IssueTrackerUrl, definition.IssueTrackerUrl); SetNonNullManifestProperty(WellKnownPluginProperties.TermsAndConditionsUrl, definition.TermsConditionsUrl); SetNonNullManifestProperty(WellKnownPluginProperties.OrganizationName, definition.Organization); SetNonNullManifestProperty(WellKnownPluginProperties.PluginName, definition.Name); SetNonNullManifestProperty(WellKnownPluginProperties.Description, definition.Description); string key = definition.Key; PluginKeyUtilities.ThrowIfInvalid(key); this.SetManifestProperty(WellKnownPluginProperties.Key, key); return this; }
private static PluginManifest CreatePluginDefinition(IPackage package) { PluginManifest pluginDefn = new PluginManifest(); pluginDefn.Description = GetValidManifestString(package.Description); pluginDefn.Developers = GetValidManifestString(ListToString(package.Authors)); pluginDefn.Homepage = GetValidManifestString(package.ProjectUrl?.ToString()); pluginDefn.Key = GetValidManifestString(package.Id) + PluginKeySuffix; pluginDefn.Name = GetValidManifestString(package.Title) ?? pluginDefn.Key; pluginDefn.Organization = GetValidManifestString(ListToString(package.Owners)); pluginDefn.Version = GetValidManifestString(package.Version.ToNormalizedString()); //pluginDefn.IssueTrackerUrl //pluginDefn.License; //pluginDefn.SourcesUrl; //pluginDefn.TermsConditionsUrl; return pluginDefn; }
private void BuildPlugin(IPackage package, string language, string rulesFilePath, string sqaleFilePath, PluginManifest pluginDefn, string baseTempDirectory, string outputDirectory) { this.logger.LogInfo(UIResources.APG_GeneratingPlugin); // Make the .jar name match the format [artefactid]-[version].jar // i.e. the format expected by Maven Directory.CreateDirectory(outputDirectory); string fullJarPath = Path.Combine(outputDirectory, package.Id + "-plugin-" + pluginDefn.Version + ".jar"); PluginBuilder builder = new PluginBuilder(logger); RulesPluginBuilder.ConfigureBuilder(builder, pluginDefn, language, rulesFilePath, sqaleFilePath); AddRoslynMetadata(baseTempDirectory, builder, package); builder.SetJarFilePath(fullJarPath); builder.Build(); this.logger.LogInfo(UIResources.APG_PluginGenerated, fullJarPath); }