Skip to content
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

NuGet Static graph restore invoked on a slnf file restores excluded projects #13097

Open
ViktorHofer opened this issue Dec 15, 2023 · 6 comments
Assignees
Labels
Area:RestoreStaticGraph Issues related to the Static Graph restore Category:Quality Week Issues that should be considered for quality week Functionality:Restore Priority:2 Issues for the current backlog. Product:dotnet.exe Type:Bug

Comments

@ViktorHofer
Copy link

NuGet Product Used

dotnet.exe

Product Version

8.0.100

Worked before?

no

Impact

I'm unable to use this version

Repro Steps & Context

Repro:
dotnet restore ttt.slnf -> only the projects listed in the slnf file are restored
dotnet restore ttt.slnf /p:RestoreUseStaticGraphEvaluation=true -> all projects listed in the sln file are restored

restorediff.zip

This impacts changes like dotnet/msbuild#9555 as when building from source, we must not restore more projects than necessary to not bring in prebuilts.

cc @jeffkl

Verbose Logs

No response

@nkolev92
Copy link
Member

nkolev92 commented Jan 8, 2024

Team Triage: @jeffkl what would be the cost of fixing this?

@jeffkl
Copy link
Contributor

jeffkl commented Jan 8, 2024

Unfortunately, MSBuild does not expose the path to the solution filter during the build (dotnet/msbuild#6162). The way it currently works for regular restore is that MSBuild generates an in-memory .metaproj that contains a <ProjectReference /> to just the projects to build. Regular restore then walks those projects.

For static graph-based restore, MSBuild only passes along the path to the solution file and the path to the in-memory .metaproj:

Image

For regular restore, since its running in the same process it has access to the in-memory .metaproj. Since static graph-based restore runs out-of-proc, it would need to either write the .metaproj to disk or pass along the path to the solution filter instead. It could also use reflection to get the path to the solution filter:

object buildRequest = BuildEngine.GetType().GetField("_requestEntry", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(BuildEngine);
object buildRequestConfiguration = buildRequest.GetType().GetProperty("RequestConfiguration", BindingFlags.Public | BindingFlags.Instance).GetValue(buildRequest);
string solutionFilterFileFullPath = buildRequestConfiguration.GetType().GetProperty("ProjectFullPath", BindingFlags.Public | BindingFlags.Instance).GetValue(buildRequestConfiguration) as string;

So we need to either:

  1. Update MSBuild to indicate the path to the solution filter being restored
  2. Use reflection to get the path to the solution filter being restored

@nkolev92
Copy link
Member

nkolev92 commented Jan 9, 2024

@jeffkl jeffkl self-assigned this Jan 18, 2024
@jeffkl jeffkl added Priority:2 Issues for the current backlog. Category:Quality Week Issues that should be considered for quality week and removed Triage:NeedsTriageDiscussion labels Jan 18, 2024
@zivkan
Copy link
Member

zivkan commented Jan 21, 2024

Can static graph restore pass the list of ProjectReferences from the metaproj to the restore task?

It's not perfect, because:

  • sln based restore will pass the full list of projects, and then waste CPU time filtering the list to what ends up being the full list of projects
  • slnf based restore will have MSBuild evaluate the full solution, but then NuGet will ignore all the projects not part of the filter

but at least there will be fewer projects that need to resolve the package graph, hopefully fewer packages to download, etc.

@jeffkl
Copy link
Contributor

jeffkl commented Jan 22, 2024

Can static graph restore pass the list of ProjectReferences from the metaproj to the restore task?

Yes, its technically possible to pass all of the necessary information along. I'm hesitant to implement it that way because we already have issues streaming global properties to the other process. I'd feel a lot more comfortable just passing the full path to the SLNF to the process instead.

@zivkan
Copy link
Member

zivkan commented Jan 22, 2024

I agree getting the slnf path is the ideal solution.

I'm just a bit worried about using reflection to get a non-public property. If MSBuild makes a change that breaks static restore, it might take us a while to notice. After all, our dev branch will be inserted into the 8.0.3xx SDK, but our build scripts are still testing against a pre-release 8.0.1xx SDK build. Therefore, our own CI pipeline wouldn't even detect the break.

Sending the long list of projects feels like a lower risk temporary solution, while we wait for MSBuild to make the request, and slnf path, a public API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area:RestoreStaticGraph Issues related to the Static Graph restore Category:Quality Week Issues that should be considered for quality week Functionality:Restore Priority:2 Issues for the current backlog. Product:dotnet.exe Type:Bug
Projects
None yet
Development

No branches or pull requests

5 participants