-
Notifications
You must be signed in to change notification settings - Fork 182
Produce a DGML graph from the ApiPort data #695
Conversation
c707ddf
to
72a18d5
Compare
Ping? |
@@ -38,6 +40,61 @@ public DependencyFinderEngineHelper(IDependencyFilter assemblyFilter, MetadataRe | |||
_currentAssemblyName = _reader.GetString(assemblyDefinition.Name); | |||
} | |||
|
|||
private IList<AssemblyReferenceInformation> ComputeAssemblyReferences(MetadataReader metadataReader) | |||
{ | |||
List<AssemblyReferenceInformation> refs = new List<AssemblyReferenceInformation>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's a VS code fix, but we usually use var
when the types are obvious.
Same for the other variables below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not a fan of style, but I will change to match the project style!
return refs; | ||
} | ||
|
||
private static string FormatPublicKeyToken(MetadataReader metadataReader, BlobHandle handle) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have extension methods that provide this: MetadataReaderExtensions.FormatAssemblyInfo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sweet!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove this?
|
||
namespace Microsoft.Fx.Portability.Reports.DGML | ||
{ | ||
class ReferenceGraph |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@twsouthwick I thought we had stylecop analysers that forced us to specify the access modifier as public, internal, etc?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll go and modify the ruleset. :)
FileExtension = ".dgml" | ||
}; | ||
|
||
private DGMLManager dgml = new DGMLManager(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: private readonly
{ | ||
private readonly Dictionary<string, Guid> _nodesDictionary = new Dictionary<string, Guid>(); | ||
|
||
private XElement nodes; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: private readonly
var refNode = rg.GetOrAddNodeForAssembly(new ReferenceNode(reference.ToString())); | ||
|
||
// if the reference is missing, flag it as such. | ||
if (unresolvedAssemblies.Contains(reference.ToString())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refNode.IsMissing = unresolvedAssemblies.Contains(reference.ToString());
{ | ||
class ReferenceGraph | ||
{ | ||
public Dictionary<ReferenceNode, ReferenceNode> Nodes { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this Nodes member set else where? If not, we can make this:
public Dictionary<ReferenceNode, ReferenceNode> Nodes { get; }
|
||
public List<TargetUsageInfo> UsageData { get; set; } | ||
|
||
public string Assembly { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public string Assembly { get; }
and same with any other members below that are only set in the constructor
public ReferenceNode(string AssemblyName, bool unresolved = false) | ||
{ | ||
Assembly = AssemblyName; | ||
this.Unresolved = unresolved; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary this.
and naming of AssemblyName
to assemblyName
{ | ||
Assembly = AssemblyName; | ||
this.Unresolved = unresolved; | ||
Nodes = new HashSet<ReferenceNode>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we also need to pass in your ReferenceNodeComparer
for the HashSet? Might be better to have a ReferenceNodeComparer.Instance
so we don't have to create multiple instances of this comparer.
I apologise for the delayed response. I don't get emails from github for some reason. Thanks for this! Excited to have another ReportFormatter |
Thanks for the review @conniey! I will try and address the comments this week! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple comments, but I need to understand why the breaking change on the IReportWriter. This will cause the change to have some ripple effects on the service
src/lib/Microsoft.Fx.Portability.MetadataReader/DependencyFinderEngineHelper.cs
Outdated
Show resolved
Hide resolved
return refs; | ||
} | ||
|
||
private static string FormatPublicKeyToken(MetadataReader metadataReader, BlobHandle handle) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove this?
@@ -0,0 +1,131 @@ | |||
// Copyright (c) Microsoft. All rights reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be easier with the public class below. Construct a request and a response and check if outputs the expectedc structure. Usually easiest to create a simple project, run the tool, and dump those values
@@ -26,7 +26,7 @@ public ExcelReportWriter(ITargetMapper targetMapper) | |||
|
|||
public ResultFormatInformation Format { get { return _formatInformation; } } | |||
|
|||
public void WriteStream(Stream stream, AnalyzeResponse response) | |||
public void WriteStream(Stream stream, AnalyzeResponse response, AnalyzeRequest request) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What information do you need from the AnalyzeRequest? This may make it difficult to incorporate into the service
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I use that information to create the assembly reference graph. When we first analyze the assemblies (before we send them back) we capture enough information about their dependencies to allow us to generate the DGML graph.
That information can be computed before we send the request as well -- and we can probably stash it somewhere in order for the information to survive the round-trip.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep in mind that the writers are inserted as output formatters in the MVC pipeline, so it just gets the output. If you can find a way to have it go through the AnalyzeResponse, that would be ideal, as I'm not sure how we could easily get the request without some jumping through hoops (maybe accessing the HttpContext or something, but I'm not as familiar with ASP.NET as ASP.NET Core). You can annotate it with [JsonIgnore] so it won't be serialized down if application/json is requested
In order to pass the required information to the report generator we are going to pass the AnalyzeRequest to the report generator.
This is used to display the data as-is.
…ed (available and not) This is the information required to add information about the references into the data.
1171982
to
78453bc
Compare
@@ -6,6 +6,7 @@ | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Reflection.Metadata; | |||
using System.Security.Cryptography; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you still need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will double check and fix this and the other comment from Connie! Thanks a lot!!!
|
||
public ReferenceGraph() | ||
{ | ||
Nodes = new Dictionary<ReferenceNode, ReferenceNode>(new ReferenceNodeComparer()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ReferenceNodeComparer.Instance
297b19d
to
fdff46d
Compare
I have resolved the last issues you mentioned. Thanks for the review! I have rebased some of the changes away to keep the history in a better spot (ie. remove all the 'address feedback' commits). |
Thanks @AlexGhiondea! |
Create a mechanism to create a DGLM graph from the ApiPort data that will show the dependencies of the input assemblies.
This is how the DGML document looks like. Each node has 2 indexes (one for itself in isolation and one that describes the portability of the references).
/cc @twsouthwick @conniey