public override bool Execute()
        {
            ProjectInfo pi = new ProjectInfo();
            pi.ProjectType = this.IsTest ? ProjectType.Test : ProjectType.Product;
            pi.IsExcluded = this.IsExcluded;

            pi.ProjectName = this.ProjectName;
            pi.FullPath = this.FullProjectPath;
            pi.ProjectLanguage = this.ProjectLanguage;

            Guid projectId;
            if (Guid.TryParse(this.ProjectGuid, out projectId))
            {
                pi.ProjectGuid = projectId;
                pi.AnalysisResults = TryCreateAnalysisResults(this.AnalysisResults);
                pi.AnalysisSettings = TryCreateAnalysisSettings(this.AnalysisSettings);

                string outputFileName = Path.Combine(this.OutputFolder, FileConstants.ProjectInfoFileName);
                pi.Save(outputFileName);
            }
            else
            {
                this.Log.LogWarning(Resources.WPIF_MissingOrInvalidProjectGuid, this.FullProjectPath);
            }
            return true;
        }
        /// <summary>
        /// Checks that the project info contains the expected values
        /// </summary>
        public static void AssertExpectedValues(
            string expectedFullProjectPath,
            string expectedProjectLanguage,
            ProjectType expectedProjectType,
            Guid expectedProjectGuid,
            string expectedProjectName,
            bool expectedIsExcluded,
            ProjectInfo actualProjectInfo)
        {
            Assert.IsNotNull(actualProjectInfo, "Supplied ProjectInfo should not be null");

            Assert.AreEqual(expectedFullProjectPath, actualProjectInfo.FullPath, "Unexpected FullPath");
            Assert.AreEqual(expectedProjectLanguage, actualProjectInfo.ProjectLanguage, "Unexpected ProjectLanguage");
            Assert.AreEqual(expectedProjectType, actualProjectInfo.ProjectType, "Unexpected ProjectType");
            Assert.AreEqual(expectedProjectGuid, actualProjectInfo.ProjectGuid, "Unexpected ProjectGuid");
            Assert.AreEqual(expectedProjectName, actualProjectInfo.ProjectName, "Unexpected ProjectName");
            Assert.AreEqual(expectedIsExcluded, actualProjectInfo.IsExcluded, "Unexpected IsExcluded");
        }
        private static string TryGetFxCopReport(ProjectInfo project, ILogger logger)
        {
            string fxCopReport = project.TryGetAnalysisFileLocation(AnalysisType.FxCop);
            if (fxCopReport != null)
            {
                if (!File.Exists(fxCopReport))
                {
                    fxCopReport = null;
                    logger.LogWarning(Resources.WARN_FxCopReportNotFound, fxCopReport);
                }
            }

            return fxCopReport;
        }
 private static bool HasDuplicateGuid(ProjectInfo projectInfo, IEnumerable<ProjectInfo> projects)
 {
     return projects.Count(p => !p.IsExcluded && p.ProjectGuid == projectInfo.ProjectGuid) > 1;
 }
        private static ProjectInfoValidity ClassifyProject(ProjectInfo projectInfo, IEnumerable<ProjectInfo> projects, ILogger logger)
        {
            if (projectInfo.IsExcluded)
            {
                logger.LogInfo(Resources.MSG_ProjectIsExcluded, projectInfo.FullPath);
                return ProjectInfoValidity.ExcludeFlagSet;
            }

            if (!IsProjectGuidValue(projectInfo))
            {
                logger.LogWarning(Resources.WARN_InvalidProjectGuid, projectInfo.ProjectGuid, projectInfo.FullPath);
                return ProjectInfoValidity.InvalidGuid;
            }

            if (HasDuplicateGuid(projectInfo, projects))
            {
                logger.LogWarning(Resources.WARN_DuplicateProjectGuid, projectInfo.ProjectGuid, projectInfo.FullPath);
                return ProjectInfoValidity.DuplicateGuid;
            }

            return ProjectInfoValidity.Valid;
        }
        private void AssertHasProjectBaseDir(string expectedProjectDir, string fallback, params string[] projectPaths)
        {
            var config = new AnalysisConfig();
            config.SonarOutputDir = fallback;
            var writer = new PropertiesWriter(config);

            using (new AssertIgnoreScope())
            {
                foreach (string projectPath in projectPaths)
                {
                    var projectInfo = new ProjectInfo { FullPath = projectPath, ProjectLanguage = ProjectLanguages.VisualBasic };
                    writer.WriteSettingsForProject(projectInfo, Enumerable.Empty<string>(), "", "");
                }
                var actual = writer.Flush();
                var expected = "\r\nsonar.projectBaseDir=" + PropertiesWriter.Escape(expectedProjectDir);

                Console.WriteLine(actual);

                Assert.IsTrue(actual.Contains(expected));
            }
        }
        public void FileGen_MissingFilesAreSkipped()
        {
            // Create project info with a managed file list and a content file list.
            // Each list refers to a file that does not exist on disk.
            // The missing files should not appear in the generated properties file.

            // Arrange
            string testDir = TestUtils.CreateTestSpecificFolder(this.TestContext);
            string projectBaseDir = TestUtils.CreateTestSpecificFolder(TestContext, "Project1");
            string projectFullPath = CreateEmptyFile(projectBaseDir, "project1.proj");

            string existingManagedFile = CreateEmptyFile(projectBaseDir, "File1.cs");
            string existingContentFile = CreateEmptyFile(projectBaseDir, "Content1.txt");

            string missingManagedFile = Path.Combine(projectBaseDir, "MissingFile1.cs");
            string missingContentFile = Path.Combine(projectBaseDir, "MissingContent1.txt");

            ProjectInfo projectInfo = new ProjectInfo()
            {
                FullPath = projectFullPath,
                AnalysisResults = new List<AnalysisResult>(),
                IsExcluded = false,
                ProjectGuid = Guid.NewGuid(),
                ProjectName = "project1.proj",
                ProjectType = ProjectType.Product
            };

            string analysisFileList = CreateFileList(projectBaseDir, "filesToAnalyze.txt", existingManagedFile, missingManagedFile, existingContentFile, missingContentFile);
            projectInfo.AddAnalyzerResult(AnalysisType.FilesToAnalyze, analysisFileList);

            string projectInfoDir = TestUtils.CreateTestSpecificFolder(this.TestContext, "ProjectInfo1Dir");
            string projectInfoFilePath = Path.Combine(projectInfoDir, FileConstants.ProjectInfoFileName);
            projectInfo.Save(projectInfoFilePath);

            TestLogger logger = new TestLogger();
            AnalysisConfig config = new AnalysisConfig()
            {
                SonarProjectKey = "my_project_key",
                SonarProjectName = "my_project_name",
                SonarProjectVersion = "1.0",
                SonarOutputDir = testDir
            };

            // Act
            ProjectInfoAnalysisResult result = PropertiesFileGenerator.GenerateFile(config, logger);

            string actual = File.ReadAllText(result.FullPropertiesFilePath);

            // Assert
            AssertFileIsReferenced(existingContentFile, actual);
            AssertFileIsReferenced(existingManagedFile, actual);

            AssertFileIsNotReferenced(missingContentFile, actual);
            AssertFileIsNotReferenced(missingManagedFile, actual);

            logger.AssertSingleWarningExists(missingManagedFile);
            logger.AssertSingleWarningExists(missingContentFile);
        }
        private static void AssertAnalysisSettingExists(ProjectInfo actual, string expectedId, string expectedValue)
        {
            Assert.IsNotNull(actual, "Supplied project info should not be null");
            Assert.IsNotNull(actual.AnalysisSettings, "AnalysisSettings should not be null");

            Property setting = actual.AnalysisSettings.FirstOrDefault(ar => expectedId.Equals(ar.Id, StringComparison.InvariantCulture));
            Assert.IsNotNull(setting, "AnalysisSetting with the expected id does not exist. Id: {0}", expectedId);

            Assert.AreEqual(expectedValue, setting.Value, "Setting does not have the expected value");
        }
        private void VerifyProjectBaseDir(string expectedValue, string teamBuildValue, string userValue, string[] projectPaths)
        {
            AnalysisConfig config = new AnalysisConfig();
            PropertiesWriter writer = new PropertiesWriter(config);
            config.SonarOutputDir = TestSonarqubeOutputDir;

            config.SourcesDirectory = teamBuildValue;
            config.SetConfigValue(SonarProperties.ProjectBaseDir, userValue);

            using (new AssertIgnoreScope())
            {
                foreach (string projectPath in projectPaths)
                {
                    var projectInfo = new ProjectInfo { FullPath = projectPath, ProjectLanguage = ProjectLanguages.CSharp };
                    writer.WriteSettingsForProject(projectInfo, Enumerable.Empty<string>(), "", "");
                }

                var actual = writer.Flush();
                var expected = "\r\nsonar.projectBaseDir=" + PropertiesWriter.Escape(expectedValue);

                Assert.IsTrue(actual.Contains(expected));
            }
        }
        private void CheckProjectInfo(ProjectInfo expected, string projectOutputFolder)
        {
            string fullName = AssertFileExists(projectOutputFolder, FileConstants.ProjectInfoFileName); // should always exist

            ProjectInfo actualProjectInfo = ProjectInfo.Load(fullName);

            TestUtilities.ProjectInfoAssertions.AssertExpectedValues(expected, actualProjectInfo);
        }
        private void AssertSettingExists(ProjectInfo projectInfo, string expectedId, string expectedValue)
        {
            Property actualSetting;
            bool found = projectInfo.TryGetAnalysisSetting(expectedId, out actualSetting);
            Assert.IsTrue(found, "Expecting the analysis setting to be found. Id: {0}", expectedId);

            // Check the implementation of TryGetAnalysisSetting
            Assert.IsNotNull(actualSetting, "The returned setting should not be null if the function returned true");
            Assert.AreEqual(expectedId, actualSetting.Id, "TryGetAnalysisSetting returned a setting with an unexpected id");

            Assert.AreEqual(expectedValue, actualSetting.Value, "Setting has an unexpected value. Id: {0}", expectedId);
        }
        private void AssertResultFileExists(ProjectInfo projectInfo, AnalysisType resultType, params string[] expected)
        {
            AnalysisResult result;
            bool found = projectInfo.TryGetAnalyzerResult(resultType, out result);

            Assert.IsTrue(found, "Analysis result not found: {0}", resultType);
            Assert.IsTrue(File.Exists(result.Location), "Analysis result file not found");

            this.TestContext.AddResultFile(result.Location);

            string[] actualFiles = File.ReadAllLines(result.Location);

            try
            {
                CollectionAssert.AreEquivalent(expected, actualFiles, "The analysis result file does not contain the expected entries");
            }
            catch (AssertFailedException)
            {
                this.TestContext.WriteLine("Expected files: {1}{0}", Environment.NewLine, string.Join("\t" + Environment.NewLine, expected));
                this.TestContext.WriteLine("Actual files: {1}{0}", Environment.NewLine, string.Join("\t" + Environment.NewLine, actualFiles));
                throw;
            }
        }
        private void AssertResultFileDoesNotExist(ProjectInfo projectInfo, AnalysisType resultType)
        {
            AnalysisResult result;
            bool found = projectInfo.TryGetAnalyzerResult(resultType, out result);

            if (found)
            {
                this.TestContext.AddResultFile(result.Location);
            }

            Assert.IsFalse(found, "Analysis result found unexpectedly. Result type: {0}", resultType);
        }
 private static void AssertProjectIsNotExcluded(ProjectInfo projectInfo)
 {
     Assert.IsFalse(projectInfo.IsExcluded, "Not expecting the project to be excluded");
 }
 /// <summary>
 /// Adds an analysis result of the specified type
 /// </summary>
 /// <remarks>The method does not check whether an analysis result with the same id already exists i.e. duplicate results are allowed</remarks>
 public static void AddAnalyzerResult(this ProjectInfo projectInfo, AnalysisType analyzerType, string location)
 {
     AddAnalyzerResult(projectInfo, analyzerType.ToString(), location);
 }
 /// <summary>
 /// Attempts to find and return the analyzer result with the specified id
 /// </summary>
 /// <returns>True if the analyzer result was found, otherwise false</returns>
 public static bool TryGetAnalyzerResult(this ProjectInfo projectInfo, AnalysisType analyzerType, out AnalysisResult result)
 {
     return(TryGetAnalyzerResult(projectInfo, analyzerType.ToString(), out result));
 }
        /// <summary>
        /// Checks that the project info contains the expected values
        /// </summary>
        public static void AssertExpectedValues(ProjectInfo expected, ProjectInfo actual)
        {
            AssertExpectedValues(expected.FullPath, expected.ProjectLanguage, expected.ProjectType, expected.ProjectGuid, expected.ProjectName, expected.IsExcluded, actual);

            CompareAnalysisResults(expected, actual);
        }
 private static void AddProjectInfoToResult(ProjectInfoAnalysisResult result, ProjectInfoValidity validity, ProjectType type = ProjectType.Product, uint count = 1)
 {
     for (int i = 0; i < count; i++)
     {
         ProjectInfo pi = new ProjectInfo() { ProjectType = type };
         result.Projects[pi] = validity;
     }
 }
        private static void AssertAnalysisResultExists(ProjectInfo actual, string expectedId, string expectedLocation)
        {
            Assert.IsNotNull(actual, "Supplied project info should not be null");
            Assert.IsNotNull(actual.AnalysisResults, "AnalysisResults should not be null");

            AnalysisResult result = actual.AnalysisResults.FirstOrDefault(ar => expectedId.Equals(ar.Id, StringComparison.InvariantCulture));
            Assert.IsNotNull(result, "AnalysisResult with the expected id does not exist. Id: {0}", expectedId);

            Assert.AreEqual(expectedLocation, result.Location, "Analysis result does not have the expected location");
        }
        public ProjectInfo CreateProjectInfo()
        {
            ProjectInfo info = new ProjectInfo()
            {
                FullPath = this.FullFilePath,
                ProjectLanguage = this.ProjectLanguage,
                ProjectGuid = this.ProjectGuid,
                ProjectName = this.ProjectName,
                ProjectType = this.IsTestProject ? ProjectType.Test : ProjectType.Product,
                IsExcluded = this.IsExcluded,
                AnalysisResults = new List<AnalysisResult>(this.AnalysisResults)
            };

            return info;
        }
        private static void AssertExpectedAnalysisSettingsCount(int count, ProjectInfo actual)
        {
            Assert.IsNotNull(actual, "Supplied project info should not be null");
            Assert.IsNotNull(actual.AnalysisSettings, "AnalysisSettings should not be null");

            Assert.AreEqual(count, actual.AnalysisSettings.Count, "Unexpected number of AnalysisSettings items");
        }
        public void WriteSettingsForProject(ProjectInfo project, IEnumerable<string> files, string fxCopReportFilePath, string codeCoverageFilePath)
        {
            if (this.FinishedWriting)
            {
                throw new InvalidOperationException();
            }

            if (project == null)
            {
                throw new ArgumentNullException("project");
            }
            if (files == null)
            {
                throw new ArgumentNullException("files");
            }

            Debug.Assert(files.Any(), "Expecting a project to have files to analyze");
            Debug.Assert(files.All(f => File.Exists(f)), "Expecting all of the specified files to exist");

            this.projects.Add(project);

            string guid = project.GetProjectGuidAsString();

            AppendKeyValue(sb, guid, "sonar.projectKey", this.config.SonarProjectKey + ":" + guid);
            AppendKeyValue(sb, guid, "sonar.projectName", project.ProjectName);
            AppendKeyValue(sb, guid, "sonar.projectBaseDir", project.GetProjectDirectory());

            if (fxCopReportFilePath != null)
            {
                string property = null;
                if (ProjectLanguages.IsCSharpProject(project.ProjectLanguage))
                {
                    property = "sonar.cs.fxcop.reportPath";
                }
                else if (ProjectLanguages.IsVbProject(project.ProjectLanguage))
                {
                    property = "sonar.vbnet.fxcop.reportPath";
                }

                Debug.Assert(property != null, "FxCopReportFilePath is set but the language is unrecognised. Language: " + project.ProjectLanguage);
                if (property != null)
                {
                    AppendKeyValue(sb, guid, property, fxCopReportFilePath);
                }
            }

            if (codeCoverageFilePath != null)
            {
                AppendKeyValue(sb, guid, "sonar.cs.vscoveragexml.reportsPaths", codeCoverageFilePath);
            }

            if (project.ProjectType == ProjectType.Product)
            {
                sb.AppendLine(guid + @".sonar.sources=\");
            }
            else
            {
                AppendKeyValue(sb, guid, "sonar.sources", "");
                sb.AppendLine(guid + @".sonar.tests=\");
            }

            IEnumerable<string> escapedFiles = files.Select(f => Escape(f));
            sb.AppendLine(string.Join(@",\" + Environment.NewLine, escapedFiles));

            sb.AppendLine();

            if (project.AnalysisSettings != null && project.AnalysisSettings.Any())
            {
                foreach(Property setting in project.AnalysisSettings)
                {
                    sb.AppendFormat("{0}.{1}={2}", guid, setting.Id, Escape(setting.Value));
                    sb.AppendLine();
                }
                sb.AppendLine();
            }
        }
        /// <summary>
        /// Creates a new project info file in a new subdirectory.
        /// </summary>
        private static string CreateProjectInfoInSubDir(string parentDir,
            string projectName, Guid projectGuid, ProjectType projectType, bool isExcluded, string fullProjectPath)
        {
            string newDir = Path.Combine(parentDir, Guid.NewGuid().ToString());
            Directory.CreateDirectory(newDir); // ensure the directory exists

            ProjectInfo project = new ProjectInfo()
            {
                FullPath = fullProjectPath,
                ProjectName = projectName,
                ProjectGuid = projectGuid,
                ProjectType = projectType,
                IsExcluded = isExcluded,
            };

            string filePath = Path.Combine(newDir, FileConstants.ProjectInfoFileName);
            project.Save(filePath);
            return filePath;
        }
 public static void AssertNoAnalysisResultsExist(ProjectInfo projectInfo)
 {
     Assert.IsTrue(projectInfo.AnalysisResults == null || projectInfo.AnalysisResults.Count == 0,
         "Not expecting analysis results to exist. Count: {0}", projectInfo.AnalysisResults.Count);
 }
        private static ProjectInfo CreateProjectInfo(string name, string projectId, string fullFilePath, bool isTest, IEnumerable<string> files, string fileListFilePath, string fxCopReportPath, string coverageReportPath, string language)
        {
            ProjectInfo projectInfo = new ProjectInfo()
            {
                ProjectName = name,
                ProjectGuid = Guid.Parse(projectId),
                FullPath = fullFilePath,
                ProjectType = isTest ? ProjectType.Test : ProjectType.Product,
                AnalysisResults = new List<AnalysisResult>(),
                ProjectLanguage = language
            };

            if (fxCopReportPath != null)
            {
                projectInfo.AddAnalyzerResult(AnalysisType.FxCop, fxCopReportPath);
            }
            if (coverageReportPath != null)
            {
                projectInfo.AddAnalyzerResult(AnalysisType.VisualStudioCodeCoverage, coverageReportPath);
            }

            if (files != null && files.Any())
            {
                Assert.IsTrue(!string.IsNullOrWhiteSpace(fileListFilePath), "Test setup error: must supply the managedFileListFilePath as a list of files has been supplied");
                File.WriteAllLines(fileListFilePath, files);

                projectInfo.AddAnalyzerResult(AnalysisType.FilesToAnalyze, fileListFilePath);
            }

            return projectInfo;
        }
 public static void AssertAnalysisResultDoesNotExists(ProjectInfo projectInfo, string resultId)
 {
     Assert.IsNotNull(projectInfo.AnalysisResults, "AnalysisResults should not be null");
     AnalysisResult result;
     bool found = SonarQube.Common.ProjectInfoExtensions.TryGetAnalyzerResult(projectInfo, resultId, out result);
     Assert.IsFalse(found, "Not expecting to find an analysis result for id. Id: {0}", resultId);
 }
 private static bool IsProjectGuidValue(ProjectInfo project)
 {
     return project.ProjectGuid != Guid.Empty;
 }
 public static AnalysisResult AssertAnalysisResultExists(ProjectInfo projectInfo, string resultId)
 {
     Assert.IsNotNull(projectInfo.AnalysisResults, "AnalysisResults should not be null");
     AnalysisResult result;
     bool found = SonarQube.Common.ProjectInfoExtensions.TryGetAnalyzerResult(projectInfo, resultId, out result);
     Assert.IsTrue(found, "Failed to find an analysis result with the expected id. Id: {0}", resultId);
     Assert.IsNotNull(result, "Returned analysis result should not be null. Id: {0}", resultId);
     return result;
 }
        /// <summary>
        /// Returns all of the valid files that can be analyzed. Logs warnings/info about
        /// files that cannot be analyzed.
        /// </summary>
        private static IEnumerable<string> GetFilesToAnalyze(ProjectInfo projectInfo, ILogger logger)
        {
            // We're only interested in files that exist and that are under the project root
            var result = new List<string>();
            var baseDir = projectInfo.GetProjectDirectory();

            foreach (string file in projectInfo.GetAllAnalysisFiles())
            {
                if (File.Exists(file))
                {
                    if (IsInFolder(file, baseDir))
                    {
                        result.Add(file);
                    }
                    else
                    {
                        logger.LogWarning(Resources.WARN_FileIsOutsideProjectDirectory, file, projectInfo.FullPath);
                    }
                }
                else
                {
                    logger.LogWarning(Resources.WARN_FileDoesNotExist, file);
                }
            }
            return result;

        }
 public static AnalysisResult AssertAnalysisResultExists(ProjectInfo projectInfo, string resultId, string expectedLocation)
 {
     AnalysisResult result = AssertAnalysisResultExists(projectInfo, resultId);
     Assert.AreEqual(expectedLocation, result.Location,
         "Analysis result exists but does not have the expected location. Id: {0}, expected: {1}, actual: {2}",
             resultId, expectedLocation, result.Location);
     return result;
 }
 private static string TryGetCodeCoverageReport(ProjectInfo project, ILogger logger)
 {
     string vsCoverageReport = project.TryGetAnalysisFileLocation(AnalysisType.VisualStudioCodeCoverage);
     if (vsCoverageReport != null)
     {
         if (!File.Exists(vsCoverageReport))
         {
             vsCoverageReport = null;
             logger.LogWarning(Resources.WARN_CodeCoverageReportNotFound, vsCoverageReport);
         }
     }
     return vsCoverageReport;
 }
        private static void CompareAnalysisResults(ProjectInfo expected, ProjectInfo actual)
        {
            // We're assuming the actual analysis results have been reloaded by the serializer
            // so they should never be null
            Assert.IsNotNull(actual.AnalysisResults, "actual AnalysisResults should not be null");

            if (expected.AnalysisResults == null || !expected.AnalysisResults.Any())
            {
                Assert.AreEqual(0, actual.AnalysisResults.Count, "actual AnalysisResults should be empty");
            }
            else
            {
                foreach(AnalysisResult expectedResult in expected.AnalysisResults)
                {
                    AssertAnalysisResultExists(actual, expectedResult.Id, expectedResult.Location);
                }
                Assert.AreEqual(expected.AnalysisResults.Count, actual.AnalysisResults.Count, "Unexpected additional analysis results found");
            }
        }