private SarifLog ConstructSarifLogFromMatchedResults( IEnumerable <MatchedResults> results, IEnumerable <Run> previousRuns, IEnumerable <Run> currentRuns) { if (currentRuns == null || !currentRuns.Any()) { throw new ArgumentException(nameof(currentRuns)); } // Results should all be from the same tool, so we'll pull the log from the first run. Tool tool = currentRuns.First().Tool.DeepClone(); var run = new Run { Tool = tool, AutomationDetails = currentRuns.First().AutomationDetails, }; IDictionary <string, SerializedPropertyInfo> properties = null; if (previousRuns != null && previousRuns.Count() != 0) { // We flow the baseline instance id forward (which becomes the // baseline guid for the merged log) run.BaselineGuid = previousRuns.First().AutomationDetails?.Guid; } bool initializeFromOldest = PropertyBagMergeBehavior.HasFlag(DictionaryMergeBehavior.InitializeFromOldest); if (initializeFromOldest) { // Find the 'oldest' log file and initialize properties from that log property bag properties = previousRuns.FirstOrDefault() != null ? previousRuns.First().Properties : currentRuns.First().Properties; } else { // Find the most recent log file instance and retain its property bag // Find the 'oldest' log file and initialize properties from that log property bag properties = currentRuns.Last().Properties; } var reportingDescriptors = new Dictionary <ReportingDescriptor, int>(ReportingDescriptor.ValueComparer); var indexRemappingVisitor = new RemapIndicesVisitor(currentFiles: null); properties = properties ?? new Dictionary <string, SerializedPropertyInfo>(); List <Result> newRunResults = new List <Result>(); foreach (MatchedResults resultPair in results) { Result result = resultPair.CalculateBasedlinedResult(PropertyBagMergeBehavior); IList <Artifact> files = (PropertyBagMergeBehavior.HasFlag(DictionaryMergeBehavior.InitializeFromOldest) && (result.BaselineState == BaselineState.Unchanged || result.BaselineState == BaselineState.Updated)) ? resultPair.PreviousResult.OriginalRun.Artifacts : resultPair.Run.Artifacts; indexRemappingVisitor.HistoricalFiles = files; indexRemappingVisitor.HistoricalLogicalLocations = resultPair.Run.LogicalLocations; indexRemappingVisitor.VisitResult(result); if (result.RuleIndex != -1) { ReportingDescriptor rule = resultPair.Run.Tool.Driver.Rules[0]; if (!reportingDescriptors.TryGetValue(rule, out int ruleIndex)) { reportingDescriptors[rule] = run.Tool.Driver.Rules.Count; run.Tool.Driver.Rules.Add(rule); } result.RuleIndex = ruleIndex; } newRunResults.Add(result); } run.Results = newRunResults; run.Artifacts = indexRemappingVisitor.CurrentFiles; var graphs = new List <Graph>(); //var ruleData = new Dictionary<string, ReportingDescriptor>(); var invocations = new List <Invocation>(); // TODO tool message strings are not currently handled // https://github.com/Microsoft/sarif-sdk/issues/1286 foreach (Run currentRun in currentRuns) { if (currentRun.Graphs != null) { graphs.AddRange(currentRun.Graphs); } if (currentRun.Invocations != null) { invocations.AddRange(currentRun.Invocations); } if (PropertyBagMergeBehavior == DictionaryMergeBehavior.InitializeFromMostRecent) { properties = currentRun.Properties; } } run.Graphs = graphs; run.LogicalLocations = new List <LogicalLocation>(indexRemappingVisitor.RemappedLogicalLocationIndices.Keys); //run.Resources = new Resources() { MessageStrings = messageData, Rules = ruleData }; TODO run.Invocations = invocations; if (properties != null && properties.Count > 0) { run.Properties = properties; } return(new SarifLog() { Version = SarifVersion.Current, SchemaUri = new Uri(SarifUtilities.SarifSchemaUri), Runs = new Run[] { run } }); }
private SarifLog ConstructSarifLogFromMatchedResults( IEnumerable <MatchedResults> results, IEnumerable <Run> previousRuns, IEnumerable <Run> currentRuns) { if (currentRuns == null || !currentRuns.Any()) { throw new ArgumentException(nameof(currentRuns)); } // Results should all be from the same tool, so we'll pull the log from the first run. Run firstRun = currentRuns.First(); Tool tool = firstRun.Tool.DeepClone(); // Only include the rules corresponding to matched results. tool.Driver.Rules = null; var run = new Run { Tool = tool }; // If there was only one run, we can fill in more information because we don't need to // worry about it being different from run to run. if (currentRuns.Count() == 1) { run.AutomationDetails = firstRun.AutomationDetails; run.Conversion = firstRun.Conversion; run.Taxonomies = firstRun.Taxonomies; run.Translations = firstRun.Translations; run.Policies = firstRun.Policies; run.RedactionTokens = firstRun.RedactionTokens; run.Language = firstRun.Language; } IDictionary <string, SerializedPropertyInfo> properties = null; if (previousRuns != null && previousRuns.Count() != 0) { // We flow the baseline instance id forward (which becomes the // baseline guid for the merged log). run.BaselineGuid = previousRuns.First().AutomationDetails?.Guid; } bool initializeFromOldest = PropertyBagMergeBehavior.HasFlag(DictionaryMergeBehavior.InitializeFromOldest); if (initializeFromOldest) { // Find the 'oldest' log file and initialize properties from that log property bag. properties = previousRuns.FirstOrDefault() != null ? previousRuns.First().Properties : currentRuns.First().Properties; } else { // Find the most recent log file instance and retain its property bag. // Find the 'oldest' log file and initialize properties from that log property bag. properties = currentRuns.Last().Properties; } var reportingDescriptors = new Dictionary <string, int>(); var indexRemappingVisitor = new RemapIndicesVisitor(currentArtifacts: null, currentLogicalLocations: null); properties ??= new Dictionary <string, SerializedPropertyInfo>(); List <Result> newRunResults = new List <Result>(); foreach (MatchedResults resultPair in results) { Result result = resultPair.CalculateBasedlinedResult(PropertyBagMergeBehavior); // TODO Shouldn't this just be HistoricalFiles = resultPair.Run.Artifacts? IList <Artifact> files = (PropertyBagMergeBehavior.HasFlag(DictionaryMergeBehavior.InitializeFromOldest) && (result.BaselineState == BaselineState.Unchanged || result.BaselineState == BaselineState.Updated)) ? resultPair.PreviousResult.OriginalRun.Artifacts : resultPair.Run.Artifacts; indexRemappingVisitor.HistoricalFiles = files; indexRemappingVisitor.HistoricalLogicalLocations = resultPair.Run.LogicalLocations; indexRemappingVisitor.VisitResult(result); string ruleId = result.ResolvedRuleId(resultPair.Run); if (!string.IsNullOrEmpty(ruleId)) { if (reportingDescriptors.TryGetValue(ruleId, out int ruleIndex)) { result.RuleIndex = ruleIndex; } else { ReportingDescriptor rule = result.GetRule(resultPair.Run); int newIndex = reportingDescriptors.Count; reportingDescriptors[ruleId] = newIndex; run.Tool.Driver.Rules ??= new List <ReportingDescriptor>(); run.Tool.Driver.Rules.Add(rule); result.RuleIndex = newIndex; } result.RuleId = ruleId; } newRunResults.Add(result); } run.Results = newRunResults; run.Artifacts = indexRemappingVisitor.CurrentArtifacts; run.LogicalLocations = indexRemappingVisitor.CurrentLogicalLocations; var graphs = new List <Graph>(); var invocations = new List <Invocation>(); // TODO tool message strings are not currently handled // https://github.com/Microsoft/sarif-sdk/issues/1286 foreach (Run currentRun in currentRuns) { if (currentRun.Graphs != null) { graphs.AddRange(currentRun.Graphs); } if (currentRun.Invocations != null) { invocations.AddRange(currentRun.Invocations); } if (PropertyBagMergeBehavior == DictionaryMergeBehavior.InitializeFromMostRecent) { properties = currentRun.Properties; } } run.Graphs = graphs; run.Invocations = invocations; if (properties != null && properties.Count > 0) { run.Properties = properties; } return(new SarifLog() { Version = SarifVersion.Current, SchemaUri = new Uri(SarifUtilities.SarifSchemaUri), Runs = new Run[] { run } }); }