Example #1
0
        public int Run(MergeOptions mergeOptions)
        {
            try
            {
                string outputDirectory = mergeOptions.OutputDirectoryPath ?? Environment.CurrentDirectory;
                string outputFilePath  = Path.Combine(outputDirectory, GetOutputFileName(mergeOptions));

                if (mergeOptions.SplittingStrategy == 0)
                {
                    if (!DriverUtilities.ReportWhetherOutputFileCanBeCreated(outputFilePath, mergeOptions.Force, _fileSystem))
                    {
                        return(FAILURE);
                    }
                }

                HashSet <string> sarifFiles = CreateTargetsSet(mergeOptions.TargetFileSpecifiers, mergeOptions.Recurse, _fileSystem);

                IEnumerable <SarifLog> allRuns = ParseFiles(sarifFiles);

                // Build one SarifLog with all the Runs.
                SarifLog mergedLog = allRuns
                                     .Merge(mergeOptions.MergeEmptyLogs)
                                     .InsertOptionalData(mergeOptions.DataToInsert.ToFlags())
                                     .RemoveOptionalData(mergeOptions.DataToInsert.ToFlags());

                // If there were no input files, the Merge operation set combinedLog.Runs to null. Although
                // null is valid in certain error cases, it is not valid here. Here, the correct value is
                // an empty list. See the SARIF spec, ยง3.13.4, "runs property".
                mergedLog.Runs ??= new List <Run>();
                mergedLog.Version   = SarifVersion.Current;
                mergedLog.SchemaUri = mergedLog.Version.ConvertToSchemaUri();

                if (mergeOptions.SplittingStrategy != SplittingStrategy.PerRule)
                {
                    _fileSystem.DirectoryCreate(outputDirectory);

                    // Write output to file.
                    WriteSarifFile(_fileSystem, mergedLog, outputFilePath, mergeOptions.Formatting);
                    return(0);
                }

                var ruleToRunsMap = new Dictionary <string, HashSet <Run> >();

                foreach (Run run in mergedLog.Runs)
                {
                    IList <Result> cachedResults = run.Results;

                    run.Results = null;

                    if (mergeOptions.MergeRuns)
                    {
                        run.Tool.Driver.Rules = null;
                        run.Artifacts         = null;
                        run.Invocations       = null;
                    }

                    Run emptyRun = run.DeepClone();
                    run.Results = cachedResults;

                    var idToRunMap = new Dictionary <string, Run>();

                    if (run.Results != null)
                    {
                        foreach (Result result in run.Results)
                        {
                            if (!idToRunMap.TryGetValue(result.RuleId, out Run splitRun))
                            {
                                splitRun = idToRunMap[result.RuleId] = emptyRun.DeepClone();
                            }
                            splitRun.Results ??= new List <Result>();

                            if (!ruleToRunsMap.TryGetValue(result.RuleId, out HashSet <Run> runs))
                            {
                                IEqualityComparer <Run> comparer = Microsoft.CodeAnalysis.Sarif.Run.ValueComparer;
                                runs = ruleToRunsMap[result.RuleId] = new HashSet <Run>(comparer);
                            }
                            runs.Add(splitRun);
                        }
                    }
                }

                foreach (string ruleId in ruleToRunsMap.Keys)
                {
                    HashSet <Run> runs       = ruleToRunsMap[ruleId];
                    var           perRuleLog = new SarifLog
                    {
                        Runs = new List <Run>(runs)
                    };

                    if (mergeOptions.MergeRuns)
                    {
                        new FixupVisitor().VisitSarifLog(perRuleLog);
                    }

                    _fileSystem.DirectoryCreate(outputDirectory);

                    outputFilePath = Path.Combine(outputDirectory, GetOutputFileName(mergeOptions, ruleId));

                    if (!DriverUtilities.ReportWhetherOutputFileCanBeCreated(outputFilePath, mergeOptions.Force, _fileSystem))
                    {
                        return(FAILURE);
                    }

                    WriteSarifFile(_fileSystem, perRuleLog, outputFilePath, mergeOptions.Formatting);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return(FAILURE);
            }
            return(SUCCESS);
        }
Example #2
0
 internal static string GetOutputFileName(MergeOptions mergeOptions)
 {
     return(!string.IsNullOrEmpty(mergeOptions.OutputFileName)
         ? mergeOptions.OutputFileName
         : "combined.sarif");
 }
Example #3
0
 internal static string GetOutputFileName(MergeOptions mergeOptions, string prefix = null)
 {
     return(string.IsNullOrEmpty(mergeOptions.OutputFileName) == false
         ? GetPrefix(prefix) + mergeOptions.OutputFileName
         : GetPrefix("merged.sarif"));
 }