eNeRGy164 / LivingDocumentation

Generate documentation based on your dotnet source code!
MIT License
54 stars 8 forks source link

ArgumentNullException on InvocationDescription #56

Open AndreasKim opened 1 year ago

AndreasKim commented 1 year ago

First, thank you for this great tool!

When I run your tool on the eshop on containers as in your description, I get the following error:

D:\C#\Test\LivingDoc\eShopOnContainers>livingdoc-analyze --solution src/eShopOnContainers-ServicesAndWebApps.sln --output analysis.json Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'containingType') at LivingDocumentation.InvocationDescription..ctor(String containingType, String name) in //src/LivingDocumentation.Descriptions/InvocationDescription.cs:line 14 at LivingDocumentation.InvocationsAnalyzer.VisitInvocationExpression(InvocationExpressionSyntax node) in //src/LivingDocumentation.Analyzer/Analyzers/InvocationsAnalyzer.cs:line 95 at Microsoft.CodeAnalysis.CSharp.Syntax.InvocationExpressionSyntax.Accept(CSharpSyntaxVisitor visitor) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitEqualsValueClause(EqualsValueClauseSyntax node) at Microsoft.CodeAnalysis.CSharp.Syntax.EqualsValueClauseSyntax.Accept(CSharpSyntaxVisitor visitor) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitVariableDeclarator(VariableDeclaratorSyntax node) at Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclaratorSyntax.Accept(CSharpSyntaxVisitor visitor) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitVariableDeclaration(VariableDeclarationSyntax node) at Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax.Accept(CSharpSyntaxVisitor visitor) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node) at Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax.Accept(CSharpSyntaxVisitor visitor) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitBlock(BlockSyntax node) at Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax.Accept(CSharpSyntaxVisitor visitor) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node) at LivingDocumentation.BranchingAnalyzer.VisitIfStatement(IfStatementSyntax node) in //src/LivingDocumentation.Analyzer/Analyzers/BranchingAnalyzer.cs:line 25 at Microsoft.CodeAnalysis.CSharp.Syntax.IfStatementSyntax.Accept(CSharpSyntaxVisitor visitor) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node) at LivingDocumentation.InvocationsAnalyzer.VisitIfStatement(IfStatementSyntax node) in //src/LivingDocumentation.Analyzer/Analyzers/InvocationsAnalyzer.cs:line 51 at Microsoft.CodeAnalysis.CSharp.Syntax.IfStatementSyntax.Accept(CSharpSyntaxVisitor visitor) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitBlock(BlockSyntax node) at Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax.Accept(CSharpSyntaxVisitor visitor) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node) at LivingDocumentation.SourceAnalyzer.ExtractBaseMethodDeclaration(BaseMethodDeclarationSyntax node, IHaveAMethodBody method) in //src/LivingDocumentation.Analyzer/Analyzers/SourceAnalyzer.cs:line 326 at LivingDocumentation.SourceAnalyzer.VisitMethodDeclaration(MethodDeclarationSyntax node) in //src/LivingDocumentation.Analyzer/Analyzers/SourceAnalyzer.cs:line 203 at Microsoft.CodeAnalysis.CSharp.Syntax.MethodDeclarationSyntax.Accept(CSharpSyntaxVisitor visitor) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitClassDeclaration(ClassDeclarationSyntax node) at LivingDocumentation.SourceAnalyzer.VisitClassDeclaration(ClassDeclarationSyntax node) in //src/LivingDocumentation.Analyzer/Analyzers/SourceAnalyzer.cs:line 22 at Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax.Accept(CSharpSyntaxVisitor visitor) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitFileScopedNamespaceDeclaration(FileScopedNamespaceDeclarationSyntax node) at Microsoft.CodeAnalysis.CSharp.Syntax.FileScopedNamespaceDeclarationSyntax.Accept(CSharpSyntaxVisitor visitor) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.DefaultVisit(SyntaxNode node) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitCompilationUnit(CompilationUnitSyntax node) at Microsoft.CodeAnalysis.CSharp.Syntax.CompilationUnitSyntax.Accept(CSharpSyntaxVisitor visitor) at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxWalker.Visit(SyntaxNode node) at LivingDocumentation.Program.AnalyzeProjectAsyc(List`1 types, Project project) in //src/LivingDocumentation.Analyzer/Program.cs:line 113 at LivingDocumentation.Program.AnalyzeSolutionFileAsync(List`1 types, String solutionFile) in //src/LivingDocumentation.Analyzer/Program.cs:line 67 at LivingDocumentation.Program.RunApplicationAsync(Options options) in //src/LivingDocumentation.Analyzer/Program.cs:line 33 at LivingDocumentation.Program.Main(String[] args) in /_/src/LivingDocumentation.Analyzer/Program.cs:line 18 at LivingDocumentation.Program.

(String[] args)

eNeRGy164 commented 1 year ago

Thanks for reporting this. It reminds me I haven't run the tool against the eShop example for a while now.

I'll have to run with the debugger to check why it is failing. Often, this is because the symbols can not be resolved, or the construction in the code requires an additional path to discover the right symbol that I didn't encounter before.

rabazit commented 1 year ago

Same issue with me

eNeRGy164 commented 1 year ago

The issue is that the compilation is not completely successful. I suspect this is an issue with Buildalyzer not being able to resolve the solution correctly.

If you run the analyzer with the --verbose switch you can see the compilation errors:

The following errors occured during compilation of project 'C:\Git\GitHub\eNeRGy164\eShopOnContainers\src\Services\Basket\Basket.API\Basket.API.csproj'
- C:\Git\GitHub\eNeRGy164\eShopOnContainers\src\Services\Basket\Basket.API\IntegrationEvents\EventHandling\ProductPriceChangedIntegrationEventHandler.cs(3,59): error CS0246: The type or namespace name 'IIntegrationEventHandler<>' could not be found (are you missing a using directive or an assembly reference?)
- C:\Git\GitHub\eNeRGy164\eShopOnContainers\src\Services\Basket\Basket.API\IntegrationEvents\Events\ProductPriceChangedIntegrationEvent.cs(6,53): error CS0246: The type or namespace name 'IntegrationEvent' could not be found (are you missing a using directive or an assembly reference?)
- C:\Git\GitHub\eNeRGy164\eShopOnContainers\src\Services\Basket\Basket.API\IntegrationEvents\EventHandling\OrderStartedIntegrationEventHandler.cs(3,52): error CS0246: The type or namespace name 'IIntegrationEventHandler<>' could not be found (are you missing a using directive or an assembly reference?)
- C:\Git\GitHub\eNeRGy164\eShopOnContainers\src\Services\Basket\Basket.API\IntegrationEvents\Events\OrderStartedIntegrationEvent.cs(6,46): error CS0246: The type or namespace name 'IntegrationEvent' could not be found (are you missing a using directive or an assembly reference?)
- C:\Git\GitHub\eNeRGy164\eShopOnContainers\src\Services\Basket\Basket.API\IntegrationEvents\Events\UserCheckoutAcceptedIntegrationEvent.cs(3,54): error CS0246: The type or namespace name 'IntegrationEvent' could not be found (are you missing a using directive or an assembly reference?)
- C:\Git\GitHub\eNeRGy164\eShopOnContainers\src\Services\Basket\Basket.API\GlobalUsings.cs(12,42): error CS0234: The type or namespace name 'BuildingBlocks' does not exist in the namespace 'Microsoft.eShopOnContainers' (are you missing an assembly reference?)
- C:\Git\GitHub\eNeRGy164\eShopOnContainers\src\Services\Basket\Basket.API\GlobalUsings.cs(13,42): error CS0234: The type or namespace name 'BuildingBlocks' does not exist in the namespace 'Microsoft.eShopOnContainers' (are you missing an assembly reference?)
- C:\Git\GitHub\eNeRGy164\eShopOnContainers\src\Services\Basket\Basket.API\Controllers\BasketController.cs(10,22): error CS0246: The type or namespace name 'IEventBus' could not be found (are you missing a using directive or an assembly reference?)
- C:\Git\GitHub\eNeRGy164\eShopOnContainers\src\Services\Basket\Basket.API\Controllers\BasketController.cs(17,9): error CS0246: The type or namespace name 'IEventBus' could not be found (are you missing a using directive or an assembly reference?)
- C:\Git\GitHub\eNeRGy164\eShopOnContainers\src\Services\Basket\Basket.API\IntegrationEvents\EventHandling\OrderStartedIntegrationEventHandler.cs(18,115): error CS1061: 'OrderStartedIntegrationEvent' does not contain a definition for 'Id' and no accessible extension method 'Id' accepting a first argument of type 'OrderStartedIntegrationEvent' could be found (are you missing a using directive or an assembly reference?)
- C:\Git\GitHub\eNeRGy164\eShopOnContainers\src\Services\Basket\Basket.API\IntegrationEvents\EventHandling\OrderStartedIntegrationEventHandler.cs(20,119): error CS1061: 'OrderStartedIntegrationEvent' does not contain a definition for 'Id' and no accessible extension method 'Id' accepting a first argument of type 'OrderStartedIntegrationEvent' could be found (are you missing a using directive or an assembly reference?)
- C:\Git\GitHub\eNeRGy164\eShopOnContainers\src\Services\Basket\Basket.API\Program.cs(25,48): error CS0246: The type or namespace name 'IEventBus' could not be found (are you missing a using directive or an assembly reference?)
- C:\Git\GitHub\eNeRGy164\eShopOnContainers\src\Services\Basket\Basket.API\IntegrationEvents\EventHandling\ProductPriceChangedIntegrationEventHandler.cs(18,115): error CS1061: 'ProductPriceChangedIntegrationEvent' does not contain a definition for 'Id' and no accessible extension method 'Id' accepting a first argument of type 'ProductPriceChangedIntegrationEvent' could be found (are you missing a using directive or an assembly reference?)
- C:\Git\GitHub\eNeRGy164\eShopOnContainers\src\Services\Basket\Basket.API\IntegrationEvents\EventHandling\ProductPriceChangedIntegrationEventHandler.cs(20,119): error CS1061: 'ProductPriceChangedIntegrationEvent' does not contain a definition for 'Id' and no accessible extension method 'Id' accepting a first argument of type 'ProductPriceChangedIntegrationEvent' could be found (are you missing a using directive or an assembly reference?)
- C:\Git\GitHub\eNeRGy164\eShopOnContainers\src\Services\Basket\Basket.API\Controllers\BasketController.cs(72,107): error CS1061: 'UserCheckoutAcceptedIntegrationEvent' does not contain a definition for 'Id' and no accessible extension method 'Id' accepting a first argument of type 'UserCheckoutAcceptedIntegrationEvent' could be found (are you missing a using directive or an assembly reference?)

Interestingly enough, with verbose, you will get an output file, but it will miss the parts that are referencing the unresolved types.

hideintheclouds commented 10 months ago

I have tried the library and was getting the same exception as described above, so I ended up cloning this repo so I can investigate further. I think we are talking about 2 different problems here:

  1. this one with the exception that could happen for the eShop example (or in my case for my solution) seems to be caused by dynamic types or nameof() (See the linked bug)

It does not occur when running in verbose mode because of the following line piece of code in InvocationsAnalyzer.cs

 public override void VisitInvocationExpression(InvocationExpressionSyntax node)
    {
        var expression = this.GetExpressionWithSymbol(node);

        if (Program.RuntimeOptions.VerboseOutput && this.semanticModel.GetSymbolInfo(expression).Symbol == null)
        {
            Console.WriteLine("WARN: Could not resolve type of invocation of the following block:");
            Console.WriteLine(node.ToFullString());
            return;
        }

If removing the Program.RuntimeOptions.VerboseOutput &&, it should run without problems in non-verbose mode.

  1. A second problem that was highlighted by @eNeRGy164 above is related to the missing references. After spending a few good hours to troubleshoot, I think this is caused by the way/order in which the identified projects from a solution file are built. In reasonable-size solution there might be quite a few projects and some of them will reference other projects from the same solution. This can quickly turn into a complex dependency matrix, and the projects will need to be built in a specific order, for the solution to compile. While we do have a way to set the build order in Visual Studio and we can definetly play with the order of the projects in the solution file, it did not seem to fix the issue..

    Longer explanation below: When building the AST for a solution, the following code is used:

        var manager = new AnalyzerManager(solutionFile);
        var analysis = new AnalyzerSetup(manager);
    private AnalyzerSetup(AnalyzerManager Manager)
    {
        this.Workspace = Manager.GetWorkspace();
        this.Projects = this.Workspace.CurrentSolution.Projects;
    }

    There seems to be a problem caused by the AnalyzerManager constructor AnalyzerManager.cs

Even though we have a property called SolutionFile.ProjectsInOrder, the AnalyzerManager uses a ConcurrentDictionary.

With a concurrent dictionary, there is no guarantee of the order in which the projects are added, and the build order is crucial here.

After countless tries of running against my solution, the observation is that sometimes the project references are correctly processed (when the right build order was obtained from the ConcurrentDictionary), while most of the time there are diagnostics errors.

private readonly ConcurrentDictionary<string, IProjectAnalyzer> _projects = new ConcurrentDictionary<string, IProjectAnalyzer>();

 // Initialize all the projects in the solution
foreach (ProjectInSolution projectInSolution in SolutionFile.ProjectsInOrder)
{
    if (!SupportedProjectTypes.Contains(projectInSolution.ProjectType)
        || (options?.ProjectFilter != null && !options.ProjectFilter(projectInSolution)))
    {
        continue;
    }
    GetProject(projectInSolution.AbsolutePath, projectInSolution);
}

While the GetProject adds the project to the _project ConcurrentDictionary.

return _projects.GetOrAdd(projectFilePath, new ProjectAnalyzer(this, projectFilePath, projectInSolution));       

The order seems to be kept in the Workspace of the Buildalyzer and will determine how the solution's projects will be built. We seem to make use of the Manager.GetWorkspace(), which has the following code:

// Run builds in parallel
List<IAnalyzerResult> results = manager.Projects.Values
    .AsParallel()
    .Select(p => p.Build().FirstOrDefault())
    .Where(x => x != null)
    .ToList();

So, it might be difficult to fix without changing the code in Buildalyzer.

We could have a workaround here by either:

I ended up creating a dirty and sub-optimal method for the second option (using new AdhocWorkSpace()) that works for my solution by adding the projects to the workspace and setting the addProjectReferences=true.

Maybe somebody else has a better solution?

AndreasKim commented 10 months ago

Thats awesome! How did you find out its the build order?

I tried to implement something according to your description, where I create our own 'AnalyzerManagerExtensions':

public static class AnalyzerManagerExtensions
    {
        /// <summary>
        /// Instantiates an empty AdhocWorkspace with logging event handlers.
        /// </summary>
        internal static AdhocWorkspace CreateWorkspace(this IAnalyzerManager manager)
        {
            ILogger logger = manager.LoggerFactory?.CreateLogger<AdhocWorkspace>();
            AdhocWorkspace workspace = new AdhocWorkspace();
            workspace.WorkspaceChanged += (sender, args) => logger?.LogDebug($"Workspace changed: {args.Kind.ToString()}{System.Environment.NewLine}");
            workspace.WorkspaceFailed += (sender, args) => logger?.LogError($"Workspace failed: {args.Diagnostic}{System.Environment.NewLine}");
            return workspace;
        }

        public static AdhocWorkspace GetOrderedWorkspace(this IAnalyzerManager manager)
        {
            if (manager is null)
            {
                throw new ArgumentNullException(nameof(manager));
            }

            // Run builds in parallel
            List<IAnalyzerResult> results = manager.Projects.Values
                .AsParallel()
                .Select(p => p.Build().FirstOrDefault())
                .Where(x => x != null)
                .ToList();

            // Add each result to a new workspace
            AdhocWorkspace workspace = manager.CreateWorkspace();

            if (!string.IsNullOrEmpty(manager.SolutionFilePath))
            {
                SolutionInfo solutionInfo = SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Default, manager.SolutionFilePath);
                workspace.AddSolution(solutionInfo);

                var projectsInOrder = manager.SolutionFile.ProjectsInOrder.ToList();

                results = results
                    .OrderBy(p => projectsInOrder.FindIndex(g => g.AbsolutePath == p.ProjectFilePath))
                    .ToList();
            }

            foreach (AnalyzerResult result in results)
            {
                if (!workspace.CurrentSolution.Projects.Any(p => p.FilePath == result.ProjectFilePath))
                {
                    result.AddToWorkspace(workspace, true);
                }
            }

            return workspace;
        }
    }

Now I get less errors. However the run still fails for me. The verbose output is:

`WARN: Could not resolve type of invocation of the following block:
        ProcessLoginCallback(result, additionalLocalClaims, localSignInProps)
WARN: Could not resolve type of invocation of the following block:
_signInManager.CreateUserPrincipalAsync(user)
WARN: Could not resolve type of invocation of the following block:
        additionalLocalClaims.AddRange(principal.Claims)
WARN: Could not resolve type of invocation of the following block:
principal.FindFirst(JwtClaimTypes.Name)
WARN: Could not resolve type of invocation of the following block:
HttpContext.SignInAsync(isuser, localSignInProps)
WARN: Could not resolve type of invocation of the following block:
HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme)
WARN: Could not resolve type of invocation of the following block:
_interaction.GetAuthorizationContextAsync(returnUrl)
WARN: Could not resolve type of invocation of the following block:
this.LoadingPage("Redirect", returnUrl)
WARN: Could not resolve type of invocation of the following block:
Redirect(returnUrl)
WARN: Could not resolve type of invocation of the following block:
scopes.Where(x => x != IdentityServerConstants.StandardScopes.OfflineAccess)
WARN: Could not resolve type of invocation of the following block:
nameof(model)
WARN: Could not resolve type of invocation of the following block:
scopes.Where(x => x != IdentityServerConstants.StandardScopes.OfflineAccess)
WARN: Could not resolve type of invocation of the following block:
nameof(context.Subject)
WARN: Could not resolve type of invocation of the following block:
nameof(context.Subject)
WARN: Could not resolve type of invocation of the following block:
nameof(hubContext)
WARN: Could not resolve type of invocation of the following block:
nameof(logger)
WARN: Could not resolve type of invocation of the following block:
nameof(hubContext)
WARN: Could not resolve type of invocation of the following block:
nameof(logger)
WARN: Could not resolve type of invocation of the following block:
nameof(hubContext)
WARN: Could not resolve type of invocation of the following block:
nameof(logger)
WARN: Could not resolve type of invocation of the following block:
nameof(hubContext)
WARN: Could not resolve type of invocation of the following block:
nameof(logger)
WARN: Could not resolve type of invocation of the following block:
nameof(hubContext)
WARN: Could not resolve type of invocation of the following block:
nameof(logger)
WARN: Could not resolve type of invocation of the following block:
nameof(hubContext)
WARN: Could not resolve type of invocation of the following block:
nameof(logger)
WARN: Could not resolve type of invocation of the following block:
nameof(logger)
WARN: Could not resolve type of invocation of the following block:
nameof(GrantUrl)
WARN: Could not resolve type of invocation of the following block:
nameof(Url)
WARN: Could not resolve type of invocation of the following block:
nameof(Event)
WARN: Could not resolve type of invocation of the following block:
nameof(context)
WARN: Could not resolve type of invocation of the following block:
nameof(settings)
WARN: Could not resolve type of invocation of the following block:
nameof(eventBus)
WARN: Could not resolve type of invocation of the following block:
nameof(logger)
Living Documentation Analysis output generated in 50031ms at analysis.json`

What am I doing wrong?

AndreasKim commented 10 months ago

oh wait those are the ones you are referring in your point 1, correct?

hideintheclouds commented 10 months ago

Yes, one can see that 70% of them are due to nameof(), I am not sure about the others, maybe you can look through the code and confirm if it's dynamic or caused by other issues. So far, after analysing 2 solutions, I have only encountered the nameof or dynamic that cause this problem, there might be others

eNeRGy164 commented 10 months ago

Great research on this issue. I know that Buildalyzer had some issues in the past (https://github.com/daveaglick/Buildalyzer/issues/134) (https://github.com/eNeRGy164/LivingDocumentation/issues/25) so, this could be another path. If you think this could be fixed in Buildalyzer, don't hesitate to open an issue there, Dave is a nice guy. ;)

daveaglick commented 10 months ago

I was linked to this issue, and imagine my surprise and happiness when I saw it looked like @AndreasKim had already made an attempt at fixing this :). I'm totally onboard with getting a fix in upstream - do we know if the GetOrderedWorkspace code above works and resolves the ordering issue in Buildalyzer? I'm making the change now since it doesn't look like it'll hurt anything, but figured I'd check to see if anyone was able to verify that fix.

The one thing I'm confused about is that ProjectsInOrder is documented as being the order the projects appear in the solution file, not the order in which they're built or their computed order in the references graph. The current (pre-change) ordering isn't deterministic, so the solution file order is as good as anything but I'm not convinced it'll universally solve problems with the ordering of projects related to missing references.

hideintheclouds commented 10 months ago

@eNeRGy164 Since the problem with the not-found references has been fixed upstream in Buildalyzer, see this bug, I think that we should bump-up the Buildalyzer nuget package to 6.0.3