Exemple #1
0
        /// <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();
        }
Exemple #3
0
        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");
        }
Exemple #4
0
        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 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();
        }
Exemple #6
0
        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);
        }
Exemple #10
0
        /// <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);
        }
Exemple #11
0
        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());
        }
Exemple #12
0
        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");
        }
Exemple #14
0
        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));
            }
        }
Exemple #15
0
        /// <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();
        }
Exemple #16
0
        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;
        }
Exemple #17
0
        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);
        }
Exemple #18
0
        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");
        }
Exemple #19
0
        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);
        }
Exemple #21
0
        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();
        }
Exemple #22
0
        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");
        }
Exemple #23
0
        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));
                }
            }
        }
Exemple #24
0
        /// <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;
        }
Exemple #26
0
        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));
 }
Exemple #29
0
        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);
        }
Exemple #31
0
        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;
        }
Exemple #32
0
        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);
        }
Exemple #33
0
        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);
        }