Data class that exposes simple data that can be accessed from any thread. The class itself is not thread safe and assumes only one thread accessing it at any given time.
Example #1
0
        public void Prepare(CancellationToken token)
        {
            Debug.Assert(this.SolutionFullPath != null, "Expected to be initialized");

            var ruleSetSerializer = this.serviceProvider.GetService <IRuleSetSerializer>();

            ruleSetSerializer.AssertLocalServiceIsNotNull();

            foreach (var keyValue in this.ruleSetsInformationMap)
            {
                if (token.IsCancellationRequested)
                {
                    return;
                }

                RuleSetInformation info = keyValue.Value;
                Debug.Assert(!string.IsNullOrWhiteSpace(info.NewRuleSetFilePath), "Expected to be set during registration time");

                this.sourceControlledFileSystem.QueueFileWrite(info.NewRuleSetFilePath, () =>
                {
                    string ruleSetDirectoryPath = Path.GetDirectoryName(info.NewRuleSetFilePath);

                    this.sourceControlledFileSystem.CreateDirectory(ruleSetDirectoryPath); // will no-op if exists

                    // Create or overwrite existing rule set
                    ruleSetSerializer.WriteRuleSetFile(info.RuleSet, info.NewRuleSetFilePath);

                    return(true);
                });

                Debug.Assert(this.sourceControlledFileSystem.FileExistOrQueuedToBeWritten(info.NewRuleSetFilePath), "Expected a rule set to pend pended");
            }

            foreach (IBindingOperation binder in this.childBinder)
            {
                if (token.IsCancellationRequested)
                {
                    return;
                }

                binder.Prepare(token);
            }
        }
        /// <summary>
        /// Queues a write to a project-level SonarQube <see cref="RuleSet"/> file in the <param name="projectRoot"/> directory.
        /// </summary>
        /// <param name="projectFullPath">The absolute full path to the project</param>
        /// <param name="ruleSetFileName">The rule set file name</param>
        /// <param name="solutionRuleSet\">Full path of the parent solution-level SonarQube rule set</param>
        /// <param name="existingRuleSetPath">Existing project rule set</param>
        /// <returns>Full file path of the file that we expect to write to</returns>
        internal /*for testing purposes*/ string QueueWriteProjectLevelRuleSet(string projectFullPath, string ruleSetFileName, RuleSetInformation solutionRuleSet, string currentRuleSetPath)
        {
            Debug.Assert(!string.IsNullOrWhiteSpace(projectFullPath));
            Debug.Assert(!string.IsNullOrWhiteSpace(ruleSetFileName));
            Debug.Assert(solutionRuleSet != null);

            string projectRoot = Path.GetDirectoryName(projectFullPath);
            string ruleSetRoot = PathHelper.ForceDirectoryEnding(projectRoot);

            string existingRuleSetPath;
            RuleSet existingRuleSet;
            if (this.TryUpdateExistingProjectRuleSet(solutionRuleSet.NewRuleSetFilePath, ruleSetRoot, currentRuleSetPath, out existingRuleSetPath, out existingRuleSet))
            {
                Debug.Assert(existingRuleSetPath != null);
                Debug.Assert(existingRuleSet != null);

                // Pend update
                this.sourceControlledFileSystem.QueueFileWrite(existingRuleSetPath, () =>
                {
                    existingRuleSet.WriteToFile(existingRuleSetPath);
                    return true;
                });

                return existingRuleSetPath;
            }

            // Create a new project level rule set
            string solutionIncludePath = PathHelper.CalculateRelativePath(ruleSetRoot, solutionRuleSet.NewRuleSetFilePath);
            RuleSet newRuleSet = GenerateNewProjectRuleSet(solutionIncludePath, currentRuleSetPath, solutionRuleSet.RuleSet.DisplayName);
            string newRuleSetPath = this.GenerateNewProjectRuleSetPath(ruleSetRoot, ruleSetFileName);

            // Pend new
            this.sourceControlledFileSystem.QueueFileWrite(newRuleSetPath, () =>
            {
                this.ruleSetSerializer.WriteRuleSetFile(newRuleSet, newRuleSetPath);
                return true;
            });

            return newRuleSetPath;
        }
Example #3
0
        /// <summary>
        /// Queues a write to a project-level SonarQube <see cref="RuleSet"/> file in the <param name="projectRoot"/> directory.
        /// </summary>
        /// <param name="projectFullPath">The absolute full path to the project</param>
        /// <param name="ruleSetFileName">The rule set file name</param>
        /// <param name="solutionRuleSet\">Full path of the parent solution-level SonarQube rule set</param>
        /// <param name="existingRuleSetPath">Existing project rule set</param>
        /// <returns>Full file path of the file that we expect to write to</returns>
        internal /*for testing purposes*/ string QueueWriteProjectLevelRuleSet(string projectFullPath, string ruleSetFileName, RuleSetInformation solutionRuleSet, string currentRuleSetPath)
        {
            Debug.Assert(!string.IsNullOrWhiteSpace(projectFullPath));
            Debug.Assert(!string.IsNullOrWhiteSpace(ruleSetFileName));
            Debug.Assert(solutionRuleSet != null);

            string projectRoot = Path.GetDirectoryName(projectFullPath);
            string ruleSetRoot = PathHelper.ForceDirectoryEnding(projectRoot);

            string  existingRuleSetPath;
            RuleSet existingRuleSet;

            if (this.TryUpdateExistingProjectRuleSet(solutionRuleSet.NewRuleSetFilePath, ruleSetRoot, currentRuleSetPath, out existingRuleSetPath, out existingRuleSet))
            {
                Debug.Assert(existingRuleSetPath != null);
                Debug.Assert(existingRuleSet != null);

                // Pend update
                this.sourceControlledFileSystem.QueueFileWrite(existingRuleSetPath, () =>
                {
                    existingRuleSet.WriteToFile(existingRuleSetPath);
                    return(true);
                });

                return(existingRuleSetPath);
            }

            // Create a new project level rule set
            string  solutionIncludePath = PathHelper.CalculateRelativePath(ruleSetRoot, solutionRuleSet.NewRuleSetFilePath);
            RuleSet newRuleSet          = GenerateNewProjectRuleSet(solutionIncludePath, currentRuleSetPath, solutionRuleSet.RuleSet.DisplayName);
            string  newRuleSetPath      = this.GenerateNewProjectRuleSetPath(ruleSetRoot, ruleSetFileName);

            // Pend new
            this.sourceControlledFileSystem.QueueFileWrite(newRuleSetPath, () =>
            {
                this.ruleSetSerializer.WriteRuleSetFile(newRuleSet, newRuleSetPath);
                return(true);
            });

            return(newRuleSetPath);
        }
        public void ProjectBindingOperation_QueueWriteProjectLevelRuleSet_NewBinding()
        {
            // Setup
            ProjectBindingOperation testSubject = this.CreateTestSubject();

            const string ruleSetFileName = "Happy";
            const string projectFullPath = @"X:\SolutionDir\ProjectDir\My Project.proj";
            const string solutionRuleSetPath = @"X:\SolutionDir\RuleSets\sonar1.ruleset";

            string expectedSolutionRuleSetInclude = PathHelper.CalculateRelativePath(projectFullPath, solutionRuleSetPath);
            RuleSet expectedRuleSet = TestRuleSetHelper.CreateTestRuleSet
            (
                numRules: 0,
                includes: new[] { expectedSolutionRuleSetInclude }
            );

            var ruleSetInfo = new RuleSetInformation(Language.CSharp, expectedRuleSet) { NewRuleSetFilePath = solutionRuleSetPath };

            List<string> filesPending = new List<string>();
            foreach (var currentRuleSet in new[] { null, string.Empty, ProjectBindingOperation.DefaultProjectRuleSet })
            {
                // Act
                string actualPath = testSubject.QueueWriteProjectLevelRuleSet(projectFullPath, ruleSetFileName, ruleSetInfo, currentRuleSet);
                filesPending.Add(actualPath);

                // Verify
                this.ruleSetFS.AssertRuleSetNotExists(actualPath);
                Assert.AreNotEqual(solutionRuleSetPath, actualPath, "Expecting a new rule set to be created once pending were written");
            }

            // Act (write pending)
            this.sccFileSystem.WritePendingNoErrorsExpected();

            // Verify
            foreach (var pending in filesPending)
            {
                // Verify
                this.ruleSetFS.AssertRuleSetsAreEqual(pending, expectedRuleSet);
            }
        }
        public void ProjectBindingOperation_QueueWriteProjectLevelRuleSet_ProjectHasExistingRuleSet_RuleSetIsNotFound()
        {
            // Setup
            ProjectBindingOperation testSubject = this.CreateTestSubject();

            const string projectName = "My Project";
            const string ruleSetFileName = "Happy";

            const string solutionRoot = @"X:\SolutionDir";
            string projectRoot = Path.Combine(solutionRoot, "ProjectDir");
            string projectFullPath = Path.Combine(projectRoot, $"{projectName}.proj");
            string currentNonExistingRuleSet = "my-non-existingproject.ruleset";

            string newSolutionRuleSetPath = Path.Combine(solutionRoot, "RuleSets", "sonar2.ruleset");
            string newSolutionRuleSetInclude = PathHelper.CalculateRelativePath(projectFullPath, newSolutionRuleSetPath);

            RuleSet expectedRuleSet = TestRuleSetHelper.CreateTestRuleSet
            (
                numRules: 0,
                includes: new[] { currentNonExistingRuleSet, newSolutionRuleSetInclude }
            );

            var ruleSetInfo = new RuleSetInformation(Language.CSharp, expectedRuleSet) { NewRuleSetFilePath = newSolutionRuleSetPath };

            // Act
            string actualPath = testSubject.QueueWriteProjectLevelRuleSet(projectFullPath, ruleSetFileName, ruleSetInfo, currentNonExistingRuleSet);

            // Verify
            this.ruleSetFS.AssertRuleSetNotExists(actualPath);
            Assert.AreNotEqual(currentNonExistingRuleSet, actualPath, "Expecting a new rule set to be created once written pending");

            // Act (write pending)
            this.sccFileSystem.WritePendingNoErrorsExpected();

            // Verify
            this.ruleSetFS.AssertRuleSetsAreEqual(actualPath, expectedRuleSet);
        }
        public void ProjectBindingOperation_QueueWriteProjectLevelRuleSet_ProjectHasExistingRuleSet_RelativePathRuleSetIsFound_ButNotUnderTheSProject()
        {
            // Setup
            ProjectBindingOperation testSubject = this.CreateTestSubject();

            const string ruleSetName = "Happy";

            const string projectFullPath = @"X:\SolutionDir\ProjectDir\My Project.proj";
            const string solutionRuleSetPath = @"X:\SolutionDir\RuleSets\sonar1.ruleset";
            const string existingProjectRuleSetPath = @"x:\SolutionDir\myexistingproject.ruleset";

            this.ruleSetFS.RegisterRuleSet(new RuleSet("NotOurRuleSet") { FilePath = existingProjectRuleSetPath });
            this.ruleSetFS.RegisterRuleSet(new RuleSet("SolutionRuleSet") { FilePath = solutionRuleSetPath });

            string relativePathToExistingProjectRuleSet = PathHelper.CalculateRelativePath(existingProjectRuleSetPath, projectFullPath);

            RuleSet expectedRuleSet = TestRuleSetHelper.CreateTestRuleSet
            (
                numRules: 0,
                includes: new[]
                {
                    relativePathToExistingProjectRuleSet, // The project exists, but not ours so we should keep it as it was previously specified
                    PathHelper.CalculateRelativePath(projectFullPath, solutionRuleSetPath)
                }
            );

            var ruleSetInfo = new RuleSetInformation(Language.CSharp, expectedRuleSet) { NewRuleSetFilePath = solutionRuleSetPath };

            // Act
            string actualPath = testSubject.QueueWriteProjectLevelRuleSet(projectFullPath, ruleSetName, ruleSetInfo, relativePathToExistingProjectRuleSet);

            // Verify
            this.ruleSetFS.AssertRuleSetNotExists(actualPath);
            Assert.AreNotEqual(existingProjectRuleSetPath, actualPath, "Expecting a new rule set to be created once written pending");

            // Act (write pending)
            this.sccFileSystem.WritePendingNoErrorsExpected();

            // Verify
            this.ruleSetFS.AssertRuleSetsAreEqual(actualPath, expectedRuleSet);
        }
        public void ProjectBindingOperation_QueueWriteProjectLevelRuleSet_ProjectHasExistingRuleSet_RelativePathRuleSetIsFound_UnderTheProject()
        {
            // Setup
            ProjectBindingOperation testSubject = this.CreateTestSubject();

            const string ruleSetName = "Happy";
            const string projectFullPath = @"X:\SolutionDir\ProjectDir\My Project.proj";
            const string solutionRuleSetPath = @"X:\SolutionDir\RuleSets\sonar1.ruleset";
            const string existingProjectRuleSetPath = @"X:\SolutionDir\ProjectDir\ExistingRuleSet.ruleset";

            RuleSet existingRuleSet = TestRuleSetHelper.CreateTestRuleSet
            (
                numRules: 0,
                includes: new[] { PathHelper.CalculateRelativePath(projectFullPath, solutionRuleSetPath) }
            );
            existingRuleSet.FilePath = existingProjectRuleSetPath;

            this.ruleSetFS.RegisterRuleSet(existingRuleSet);
            this.ruleSetFS.RegisterRuleSet(new RuleSet("SolutionRuleSet") { FilePath = solutionRuleSetPath });


            string newSolutionRuleSetPath = Path.Combine(Path.GetDirectoryName(solutionRuleSetPath), "sonar2.ruleset");
            string newSolutionRuleSetInclude = PathHelper.CalculateRelativePath(projectFullPath, newSolutionRuleSetPath);

            RuleSet expectedRuleSet = TestRuleSetHelper.CreateTestRuleSet
            (
                numRules: 0,
                includes: new[] { newSolutionRuleSetInclude }
            );

            var ruleSetInfo = new RuleSetInformation(Language.CSharp, expectedRuleSet) { NewRuleSetFilePath = newSolutionRuleSetPath };

            // Act
            string actualPath = testSubject.QueueWriteProjectLevelRuleSet(projectFullPath, ruleSetName, ruleSetInfo, PathHelper.CalculateRelativePath(projectFullPath, existingProjectRuleSetPath));

            // Verify
            this.ruleSetFS.AssertRuleSetsAreEqual(actualPath, expectedRuleSet);
            Assert.AreEqual(existingProjectRuleSetPath, actualPath, "Expecting the rule set to be updated");
        }