public void MergeResultsFrom(Run additional) { // Merge Results from the two Runs, building shared collections of result-referenced things var visitor = new RunMergingVisitor(); visitor.VisitRun(this); visitor.VisitRun(additional); visitor.PopulateWithMerged(this); }
private SarifLog ConstructSarifLogFromMatchedResults( IEnumerable <MatchedResults> results, IEnumerable <Run> previousRuns, IEnumerable <Run> currentRuns) { if (currentRuns == null || !currentRuns.Any()) { throw new ArgumentNullException(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; } if (previousRuns != null && previousRuns.Any()) { // We flow the baseline instance id forward (which becomes the // baseline guid for the merged log). run.BaselineGuid = previousRuns.First().AutomationDetails?.Guid; } var visitor = new RunMergingVisitor(); foreach (MatchedResults resultPair in results) { Result result = resultPair.CalculateBasedlinedResult(PropertyBagMergeBehavior); visitor.CurrentRun = result.Run; visitor.VisitResult(result); } visitor.PopulateWithMerged(run); IDictionary <string, SerializedPropertyInfo> properties = null; if (PropertyBagMergeBehavior.HasFlag(DictionaryMergeBehavior.InitializeFromOldest)) { // Find the 'oldest' log file and initialize properties from that log property bag. properties = previousRuns.FirstOrDefault()?.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; } properties ??= new Dictionary <string, SerializedPropertyInfo>(); 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; run.Properties = properties; return(new SarifLog() { Version = SarifVersion.Current, SchemaUri = new Uri(SarifUtilities.SarifSchemaUri), Runs = new Run[] { run } }); }