-
Notifications
You must be signed in to change notification settings - Fork 694
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for transitive NoWarn properties from project references #1642
Conversation
{ | ||
public static class TestExtensions | ||
{ | ||
public static int GetSubstringCount(this string str, string substr, bool ignoreCase) |
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.
This is going to show up everywhere in test projects, make this a regular static method instead of an extension method. For classes such as string
it is just too painful.
/// <param name="code">NuGetLogCode for which no warning should be thrown.</param> | ||
/// <param name="libraryId">Library for which no warning should be thrown.</param> | ||
/// <param name="frameworks">IEnumerable of Target graph for which no warning should be thrown.</param> | ||
public void AddRange(NuGetLogCode code, string libraryId, IEnumerable<NuGetFramework> frameworks) |
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.
The name AddRange is confusing here since it is doing a lot more than other AddRange methods do. I would just call this Add
or AddCode
var hashCode = new HashCodeCombiner(); | ||
|
||
// Add a constant hash for all objects | ||
hashCode.AddObject(1); |
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.
Why does this method not match Equals? They should both check the same things.
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.
This seems acceptable as per the requirements on HashCode -
- if x equals y then the hash code of x must equal the hash code of y. Equivalently: if the hash code of x does not equal the hash code of y then x and y must be unequal.
- the hash code of x must remain stable while x is in a hash table.
return true; | ||
} | ||
|
||
return Properties.Keys.OrderedEquals(other.Properties.Keys, (code) => code) && |
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.
Use EqualityUtilities
it does this same thing with additional error handling, and it has already been optimized
var targetFrameworkInformation = packageSpec | ||
.TargetFrameworks | ||
.Where(tfi => tfi.FrameworkName == framework) | ||
.First(); |
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.
You can replace Where
with First
here and it will handle both.
@@ -61,7 +70,8 @@ public bool ApplyWarningProperties(IRestoreLogMessage message) | |||
if (messageTargetFrameworks.Count == 0) | |||
{ | |||
// Suppress the warning if the code + libraryId combination is suppressed for all project frameworks. | |||
if (ProjectFrameworks.Count > 0 && | |||
if (ProjectFrameworks != null && |
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.
Why would a project not have frameworks? This should be validated earlier and WarningPropertiesCollection should not be created if the project is invalid. Having to recheck this everywhere in the code makes it seem like there are bugs here.
|
||
namespace NuGet.Commands | ||
{ | ||
internal class TransitiveNoWarnUtils |
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.
internal static
internal class TransitiveNoWarnUtils | ||
{ | ||
// static should be fine across multiple restore calls as this solely depends on the csproj file of the project. | ||
private static readonly ConcurrentDictionary<string, WarningPropertiesCollection> _warningPropertiesCache = |
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.
🔥 Statics should not be used for caching.
Users often leave VS open for weeks at a time, this is a memory leak that will continue growing until VS is closed.
I also don't see this being updated, which means that if a user changes their project and restores again it won't have the updated warning properties.
} | ||
|
||
return string.Equals(Id, other.Id, StringComparison.OrdinalIgnoreCase) && | ||
IsProject == other.IsProject && |
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.
order this by bools first
|
||
private static PackageSpec GetNodePackageSpec(LocalMatch localMatch) | ||
{ | ||
return localMatch.LocalLibrary.Items[KnownLibraryProperties.PackageSpec] as PackageSpec; |
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.
Use (PackageSpec)
instead
69bece7
to
bb16361
Compare
adfd4c6
to
2bb5484
Compare
68a828d
to
1697f19
Compare
|
||
namespace NuGet.Commands | ||
{ | ||
public class TransitiveNoWarnUtils |
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.
Could this be a static class? It seems like the only reason this isn't currently is because of the cache, but if there were a method that took all graphs at once it could just pass in a cache to the rest of the methods using it.
if (!seen.Contains(node)) | ||
{ | ||
// Add the node to seen set | ||
seen.Add(node); |
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.
Use seen.Add(node) above, it returns true if seen.Contains was false, this code is currently doing the look up twice
public class TransitiveNoWarnUtils | ||
{ | ||
// static should be fine across multiple calls as this solely depends on the csproj file of the project. | ||
private readonly ConcurrentDictionary<string, ConcurrentDictionary<NuGetFramework, WarningPropertiesCollection>> _warningPropertiesPerFrameworkCache = |
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.
Since this isn't done in parallel I this should be a normal dictionary, or a sorteddictionary
// All the packages in parent project's closure. | ||
// Once we have collected data for all of these, we can exit. | ||
var parentPackageDependencies = new HashSet<string>( | ||
targetGraph.Flattened.Where(d => d.Key.Type == LibraryType.Package).Select(d => d.Key.Name)); |
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.
This should be created as part of the flattened loop below, it isn't used until later
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.
This also looks incorrect since it is case sensitive by default, if this only checks the exact id because there can only be 1 instance of the id then it should use Ordinal instead of the culture specific default.
|
||
// All the packages in parent project's closure. | ||
// Once we have collected data for all of these, we can exit. | ||
var parentPackageDependencies = new HashSet<string>( |
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.
use StringComparer.OrdinalIgnoreCase?
Closing in the favor of #1672 |
Spec: https://github.com/NuGet/Home/wiki/%5BSpec%5D-Transitive-Warning-Properties
Fixes: NuGet/Home#5691 and NuGet/Home#5501
This change adds the capability to flow
NoWarn
properties transitively. The details are in the spec along with a high level implementation detail section.