-
Notifications
You must be signed in to change notification settings - Fork 249
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
Make project reference lower case in lock file #7840
Comments
Let's fix for 5.1. |
This is definitely not urgent as the workaround is to unify the casing of project names between all Visual Studio solution files and |
@jeffkl so I understand, are you asking for this so that git no longer says the file has changed, or is this causing restore failures? I'm testing some scenarios around projects with the same name but different casing on Linux to see if the proposed change would be a problem. So far it seems to be that there are several other issues that prevent same-name, different case projects working, so writing ToLowerInvariant strings to the lock file shouldn't break any currently working scenario. |
I haven't seen restore errors but I do see the lock file churning. I keep hitting #7646 so its been hard to test lock files for our use. |
I should have chat with you earlier, but I've been out all week with the flu :( I have started some discussions with others about storing the lower case project name in the lock file. The specific scenario you used when opening the issue, where the case to the csproj is different in the sln and ProjectReference, this will cause one of the two to fail building on Linux, or on Windows or Mac when filesystem case sensitivity is turned on. Therefore there's a question of correctness. If we expect a build to work the same on all platforms, but due to case-sensitivity in a specific repo, does it matter if NuGet changes the case in the lock file? If the team working on the repo fix the issue that prevents building on all platforms, then the lock file casing will no longer change. Secondly, I'm trying to understand case sensitivity requirements. Should it be allowed to have ProjectA reference ProjectB in one directory and projectb in a different directory? Assume one or both change the assembly name to avoid issues with filesystem case insensitivity when copying all assembles to the output directory. This also brings up the question if it should be allowed to reference two different projects with the same name and case, but are in different directories. This already fails for other reasons, but since the lock file is checked into source control, this has more long lasting implications compared to the files written to the build's intermediate output. Finally, I'm looking into the performance impact of checking the file system for the file's actual case, either to use in the lock file or maybe to raise a warning. But we need to be very careful about the performance impact. |
Does the case of the project matter? The value is gotten from MSBuild today which can vary because MSBuild just returns strings. I thought the lock file can be lowercase because its just an index of what projects were referenced. The full transitive closure of packages is already calculated in the other section so from my understanding the list of projects is only needed to help determine if the lock file is out of date. The projects coming in from the dependency graph could be lowercased for comparison with the projects in the lock file, regardless of the casing on disk. Again because the casing is coming from MSBuild anyway, you can't trust the case necessarily. |
I didn't want to break or prevent a scenario that would otherwise work. Having a quick chat with @nkolev92 about #7889, I think both issues can be resolved at the same time. My understanding is we'll try to align on using assembly name, not project filename, so filesytem casing will not be relevant. |
It's important to understand that the "name" of the project does not always come from the file on disk. https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Build.Tasks/NuGet.targets#L614 By default it is |
Discussing this more, we've decided that we'd like to:
keeping open while @zivkan researches the 2nd bullet. |
I confirmed that the latest .NET Core 2.2 |
@rrelyea I'm worried about the scenario where I changed one reference and the whole file is regenerated and I see a bunch of case differences instead of the single change. The casing can come from a project-to-project reference, an SLN, or the command-line. It seems like it should be normalized. |
@jeffkl @nkolev92 @rrelyea @zivkan I changed my vote 😄 What do you think? |
Lock files have a version. Perhaps if it exists and its version 1, we keep the old behavior. If it gets created the first time or I delete them all and start over they are version 2 with lowercase IDs. Kinda complicated but might be worth it. |
But this again depends on how you keep regenerating your lock file. It'll only be an issue if you keep alternating between sln file restore and project restore when adding references. It's such an edge case but our only option is a big hammer which makes things weird. |
I'm more talking about a team of people. You use solution files, I use traversal, another person restores a leaf node project. We might all get different casing. |
A restore without changing package or project dependencies doesn't change the lock file (if it does, then there's a bug), so there shouldn't be large churn of the file, only when dependencies change. Also, projects that are like this aren't cross-platform since they'll have problem on linux, or on Windows or Mac when file system case sensitivity is turned on. Although not all projects care about being xplat compatible. Finally, package ids in the lock file are cased like in the csproj. If we lower-case the project ids, we should probably lower case the package ids too. But that reduces human readability. While the main purpose of this file is to be read programatically, how human readable should it be? |
For me, one of the big draws of lock files is I can see an exact diff of what changed when someone changes a dependency. If there's a bunch of noise because of casing differences, it will lower the value of lock files
I do not understand why the casing in the lock files has to match what's on disk. We never use the lock file to look for files on disk right?
It does lower the readability a little since proper casing helps break up words like |
The casing in the lock file does not have to match what's on disk, that's correct, so if implemented it won't prevent builds on case-sensitive file systems. I'm just saying this is a feature that "only" benefits solutions that have known environment-configuration issues and therefore won't build in environments where that configuration is different. |
The first repo I tried out lock files hit it. I think its because it has ~500 projects. The teams I interact with have very large repos and will benefit greatly from lock files. But if the lock files are churning a lot they will turn it off. |
The casing for project names in lock files can change because the value comes from one of two sources:
If two project references have different casing, the list is de-duped but in a multi-proc build the order can be different.
The casing in the lock file should probably be
.ToLowerInvariant()
This should help ensure that the lock file is the same every time.
The text was updated successfully, but these errors were encountered: