Skip to content

Commit

Permalink
Merge pull request #9396 from drewnoakes/no-yellow-triangles-on-dtb-f…
Browse files Browse the repository at this point in the history
…ailure

Don't show yellow triangles when DTB fails
  • Loading branch information
drewnoakes authored Feb 16, 2024
2 parents 3b5c822 + 10212e9 commit bb7ae1e
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 15 deletions.
4 changes: 0 additions & 4 deletions docs/dependencies-tree.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,3 @@ Resolved items are produced by MSBuild targets. The target to inspect depends up
Inspecting a design-time build's `.binlog` with the [MSBuild Structured Log Viewer](https://msbuildlog.com/) and tracing back from the relevant target will reveal why the original reference was not produces as a resolved reference. Some familiarity with [MSBuild concepts](https://learn.microsoft.com/visualstudio/msbuild/msbuild-concepts) is required to do this.

Note that for package references, you may also look in the `obj` folder for the `project.assets.json` file. Towards the end of that file there may be some messages in the `logs` property that provide insight into why packages were not resolved, though this information should be displayed in the Dependencies tree directly, along with the Package pane of the Output window, and the Error List.

## My whole tree has yellow triangles!

If all dependencies in the tree appear with a yellow triangle, it's most likely that the [design-time build](design-time-builds.md) failed completely. As above, [capture a design-time build log](design-time-builds.md#diagnosing-design-time-builds) and look for the cause of the failure. It may be something completely unrelated to your project's dependencies.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public bool TryUpdate(
return false;
}

bool hasBuildError = !evaluationProjectChange.After.IsEvaluationSucceeded() || buildProjectChange?.After.IsEvaluationSucceeded() == false;

System.Diagnostics.Debug.Assert(evaluationProjectChange.Difference.RenamedItems.Count == 0, "Evaluation ProjectChange should not contain renamed items");
System.Diagnostics.Debug.Assert(buildProjectChange?.Difference.RenamedItems.Count is null or 0, "Build ProjectChange should not contain renamed items");

Expand Down Expand Up @@ -99,7 +101,7 @@ evaluationProjectChange.Difference.ChangedItems.Count is 0 &&
if (_dependencyById.TryGetValue(id, out MSBuildDependency? dependency))
{
// Updating an existing dependency.
if (_factory.TryUpdate(dependency, update.Evaluation, update.Build, projectFullPath, isEvaluationOnlySnapshot: buildProjectChange is null, out MSBuildDependency? updated))
if (_factory.TryUpdate(dependency, update.Evaluation, update.Build, projectFullPath, isEvaluationOnlySnapshot: buildProjectChange is null, hasBuildError, out MSBuildDependency? updated))
{
if (updated is not null)
{
Expand All @@ -116,7 +118,7 @@ evaluationProjectChange.Difference.ChangedItems.Count is 0 &&
else
{
// Creating a new dependency.
dependency = _factory.CreateDependency(id, update.Evaluation, update.Build, projectFullPath, isEvaluationOnlySnapshot: buildProjectChange is null);
dependency = _factory.CreateDependency(id, update.Evaluation, update.Build, projectFullPath, hasBuildError, isEvaluationOnlySnapshot: buildProjectChange is null);

if (dependency is not null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,12 +182,12 @@ protected internal virtual ProjectTreeFlags UpdateTreeFlags(string id, ProjectTr
/// <param name="properties">The properties of the item.</param>
/// <param name="defaultLevel">The diagnostic level to use when the property is either missing or empty. Intended to receive a dependency's current diagnostic level when an evaluation-only update is being processed.</param>
/// <returns></returns>
protected internal virtual DiagnosticLevel GetDiagnosticLevel(bool? isResolved, IImmutableDictionary<string, string> properties, DiagnosticLevel defaultLevel = DiagnosticLevel.None)
protected internal virtual DiagnosticLevel GetDiagnosticLevel(bool? isResolved, bool hasBuildError, IImmutableDictionary<string, string> properties, DiagnosticLevel defaultLevel = DiagnosticLevel.None)
{
return (isResolved, properties.GetDiagnosticLevel(defaultLevel)) switch
return (isResolved, hasBuildError, properties.GetDiagnosticLevel(defaultLevel)) switch
{
(false, DiagnosticLevel.None) => DiagnosticLevel.Warning,
(_, DiagnosticLevel level) => level
(false, false, DiagnosticLevel.None) => DiagnosticLevel.Warning,
(_, _, DiagnosticLevel level) => level
};
}

Expand All @@ -203,6 +203,7 @@ protected internal virtual DiagnosticLevel GetDiagnosticLevel(bool? isResolved,
/// <param name="evaluation">Evaluation item data, if present.</param>
/// <param name="build">Evaluation item data, if present.</param>
/// <param name="projectFullPath">Full path to the project file.</param>
/// <param name="hasBuildError">Whether the evaluation or build that produced this update ended with an error.</param>
/// <param name="isEvaluationOnlySnapshot">
/// Whether this update contained only evaluation data. If <see langword="false"/>, this update
/// came from the JointRule source.
Expand All @@ -215,6 +216,7 @@ protected internal virtual DiagnosticLevel GetDiagnosticLevel(bool? isResolved,
(string ItemSpec, IImmutableDictionary<string, string> Properties)? evaluation,
(string ItemSpec, IImmutableDictionary<string, string> Properties)? build,
string projectFullPath,
bool hasBuildError,
bool isEvaluationOnlySnapshot)
{
if (build is not null)
Expand Down Expand Up @@ -246,7 +248,7 @@ protected internal virtual DiagnosticLevel GetDiagnosticLevel(bool? isResolved,

// This is a resolved dependency.
bool isImplicit = IsImplicit(projectFullPath, evaluation?.Properties, properties);
DiagnosticLevel diagnosticLevel = GetDiagnosticLevel(isResolved: true, properties);
DiagnosticLevel diagnosticLevel = GetDiagnosticLevel(isResolved: true, hasBuildError, properties);
string caption = GetResolvedCaption(itemSpec, id, properties);
ProjectImageMoniker icon = GetIcon(isImplicit, diagnosticLevel);
ProjectTreeFlags flags = UpdateTreeFlags(itemSpec, FlagCache.Get(isResolved: true, isImplicit));
Expand Down Expand Up @@ -280,7 +282,7 @@ protected internal virtual DiagnosticLevel GetDiagnosticLevel(bool? isResolved,
#endif

bool isImplicit = IsImplicit(projectFullPath, properties, buildProperties: null);
DiagnosticLevel diagnosticLevel = GetDiagnosticLevel(isResolved: isEvaluationOnlySnapshot, properties);
DiagnosticLevel diagnosticLevel = GetDiagnosticLevel(isResolved: isEvaluationOnlySnapshot, hasBuildError, properties);
string caption = GetUnresolvedCaption(itemSpec, properties);
ProjectImageMoniker icon = GetIcon(isImplicit, diagnosticLevel);
ProjectTreeFlags flags = UpdateTreeFlags(itemSpec, FlagCache.Get(isResolved: false, isImplicit));
Expand Down Expand Up @@ -315,6 +317,7 @@ protected internal virtual DiagnosticLevel GetDiagnosticLevel(bool? isResolved,
/// Whether this update contained only evaluation data. If <see langword="false"/>, this update
/// came from the JointRule source.
/// </param>
/// <param name="hasBuildError">Whether the evaluation or build that produced this update ended with an error.</param>
/// <param name="updated">
/// The updated dependency. May be <see langword="null"/> if <paramref name="dependency"/>
/// should be removed for whatever reason. May be the same object as <paramref name="dependency"/>
Expand All @@ -327,6 +330,7 @@ internal bool TryUpdate(
(string ItemSpec, IImmutableDictionary<string, string> Properties)? build,
string projectFullPath,
bool isEvaluationOnlySnapshot,
bool hasBuildError,
out MSBuildDependency? updated)
{
Assumes.True(evaluation is not null || build is not null);
Expand All @@ -349,7 +353,7 @@ internal bool TryUpdate(
bool isResolved = true;

bool isImplicit = IsImplicit(projectFullPath, properties, evaluation?.Properties);
DiagnosticLevel diagnosticLevel = GetDiagnosticLevel(isResolved, properties);
DiagnosticLevel diagnosticLevel = GetDiagnosticLevel(isResolved, hasBuildError, properties);
string caption = GetResolvedCaption(itemSpec, dependency.Id, properties);
ProjectImageMoniker icon = GetIcon(isImplicit, diagnosticLevel);
ProjectTreeFlags flags = UpdateTreeFlags(dependency.Id, FlagCache.Get(isResolved, isImplicit));
Expand Down Expand Up @@ -381,7 +385,7 @@ internal bool TryUpdate(
bool? isResolved = isEvaluationOnlySnapshot ? dependency.IsResolved : false;

bool isImplicit = IsImplicit(projectFullPath, evaluationProperties: null, properties);
DiagnosticLevel diagnosticLevel = GetDiagnosticLevel(isResolved, properties, defaultLevel: dependency.DiagnosticLevel);
DiagnosticLevel diagnosticLevel = GetDiagnosticLevel(isResolved, hasBuildError, properties, defaultLevel: dependency.DiagnosticLevel);
string caption = GetUnresolvedCaption(itemSpec, properties);
ProjectImageMoniker icon = GetIcon(isImplicit, diagnosticLevel);
ProjectTreeFlags flags = UpdateTreeFlags(itemSpec, FlagCache.Get(isResolved ?? true, isImplicit));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ private MSBuildDependencyCollection Create()
factory.Setup(f => f.GetUnresolvedCaption("Item1", It.IsAny<ImmutableDictionary<string, string>>())).Returns("UnresolvedCaption");
factory.Setup(f => f.GetResolvedCaption("ResolvedItem1", "Item1", It.IsAny<ImmutableDictionary<string, string>>())).Returns("ResolvedCaption");
factory.Setup(f => f.UpdateTreeFlags(It.IsAny<string>(), It.IsAny<ProjectTreeFlags>())).Returns((string id, ProjectTreeFlags f) => f);
factory.Setup(f => f.GetDiagnosticLevel(It.IsAny<bool?>(), It.IsAny<ImmutableDictionary<string, string>>(), It.IsAny<DiagnosticLevel>())).CallBase();
factory.Setup(f => f.GetDiagnosticLevel(It.IsAny<bool?>(), It.IsAny<bool>(), It.IsAny<ImmutableDictionary<string, string>>(), It.IsAny<DiagnosticLevel>())).CallBase();

return new MSBuildDependencyCollection(factory.Object);
}
Expand Down

0 comments on commit bb7ae1e

Please sign in to comment.