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

Design for allowing restore of multiple equivalent frameworks #12124

Draft
wants to merge 5 commits into
base: dev
Choose a base branch
from

Conversation

nkolev92
Copy link
Member

@nkolev92 nkolev92 commented Oct 3, 2022

Design for #5154

Rendered

cc @dsplaisted

Copy link

@Nirmal4G Nirmal4G left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some ideas and suggestions. Feel free to ignore it. 😅🙃

@nkolev92
Copy link
Member Author

nkolev92 commented Oct 4, 2022

Thanks for taking a look @Nirmal4G

For context, this is design I'm still working on, I'd say it's at about 50%.

Hoping to add more details about the scenarios and just in general provide more concrete proposals soon.

@Nirmal4G
Copy link

Nirmal4G commented Oct 4, 2022

@nkolev92 These are some of my observations and preliminary suggestions, ideas and takeaways from this draft. I'm not taking this as a concrete proposal. I'm just viewing this from a 10-foot view (or design perspective) of the proposal to see how it could impact normal as well as advanced users. In that mindset, read through my comments again. You would then see what I was talking about.

@Nirmal4G
Copy link

Nirmal4G commented Oct 4, 2022

Hoping to add more details about the scenarios and just in general provide more concrete proposals soon.

Sure, Will look though once you mark this ready for review. Sorry for the uninvited comments. I'll stop now.

@nkolev92
Copy link
Member Author

nkolev92 commented Oct 4, 2022

Hoping to add more details about the scenarios and just in general provide more concrete proposals soon.

Sure, Will look though once you mark this ready for review. Sorry for the uninvited comments. I'll stop now.

Oh no worries. I appreciate the feedback as this is a large doc so getting feedback early on is always great.

My comment was more about that fact that I'll be adding even more info to the doc, setting expectations about when something like this would even be close to happening :)

@JonDouglas
Copy link
Contributor

@ViktorHofer & @ericstj

@zivkan zivkan self-assigned this Nov 13, 2023
@zivkan zivkan marked this pull request as ready for review November 15, 2023 13:27
@zivkan zivkan requested a review from a team as a code owner November 15, 2023 13:27
However, PackageReference is also supported by non-SDK style projects, which use [dotnet/NuGet.BuildTools](https://github.com/NuGet.BuildTools) which, despite the name, is owned by the non-SDK project system team, not NuGet.
Their implementation parses the JSON file directly, rather than using NuGet.ProjectModel.
Therefore, if we can implement the assets file changes without breaking changes to the NuGet.ProjectModel APIs, the .NET SDK may "just work" when the newer version of NuGet is inserted into the .NET SDK.
However, the non-SDK project system will fail.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we say that it's a non-goal to support TargetFramework aliases from non SDK-style projects (and hence from NuGet.BuildTools), does that simplify things? NuGet.BuildTools might generate an error if it encounters a newer assets file format without any changes to it, so we might not need as much synchronization.

NuGet could require read a `RestoreAssetsFileVersion` property on each project, defaulting to 3 when not specified.
This allows project systems that have not yet adapted to the new assets file schema to keep working as before.

1. Use the newer assets file automatically when a project multi-targets

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use the new format only when the project multi-targets and there are multiple aliases that map to the same TargetFrameworkMoniker/TargetPlatformMoniker combination? That might avoid existing projects breaking with older tools.

<!-- What parts of the proposal need to be resolved before the proposal is stabilized? -->
<!-- What related issues would you consider out of scope for this proposal but can be addressed in the future? -->

### TargetFramework alias to block `/` character

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should try to support / in the TargetFramewrok alias. One of the scenarios we hope to eventually support is multi-targeting over RuntimeIdentifiers. It would be natural to express that with the / character, for example <TargetFrameworks>net8.0-windows10.0.19041.0/x64;net8.0-ios/arm64;net8.0-android/arm64</TargetFrameworks>.


Currently `GetReferenceNearestTargetFrameworkTask` is implemented by running NuGet's "nearest match" algorithm.
This feature would extend it to first try nearest match, and if there is more than one matching `TargetFramework`, then look for a `TargetFramework` that has an exact name match in both projects.
If there are more than one "nearest" framework, but no exact name match, then for the first version of this feature, NuGet will report an error.
Copy link

@ericstj ericstj Dec 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm interpreting this as supporting a case where you have a project that uses aliases referencing a project that's not using alias.

So if I have project 1 with TFs: net6.0-a;net6.0-b (where both are aliases for net6.0) and it referenced project 2 with TFs: net6.0;netstandard2.0 project1 could reference project 2 and select net6.0 because there is a single nearest framework.

If that's true this is a great middle ground for enabling aliases in a way that isn't viral.

Copy link

@ViktorHofer ViktorHofer Dec 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec would benefit from an example to make the intent clear. I agree with your observation. Here are other examples that would work or not work with this algorithm:

Example 1

project1 net6.0-a;net6.0-b references project2 that references the same TFMs. Even though the GetReferenceNearestTargetFrameworkTask algorithm returns two matches, there's a single direct name match so it would choose net6.0-a from project2 for net6.0-a from project1 and same for net6.0-b.

Example 2

project1 net6.0 references project2 that references net6.0-a;net6.0-b. The GetReferenceNearestTargetFrameworkTask would algorithm returns two matches, there's no direct name match so the algorithm would fail and NuGet would report an error.

Comment on lines +391 to +393
It seems feasible that if a single project can target multiple versions of Visual Studio, through a new Visual Studio Extensibility SDK, that someone will also want to create a package that supports multiple versions of Visual Studio.

Designing how this could work is out of scope for this spec, and can be introduced in a different spec.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just writing down what we discussed in yesterday's meeting. For runtime to not be broken by this change, we need to keep supporting what works today.

In runtime, we set IncludeBuildOutput=false and SuppressDependenciesWhenPacking=true for custom TFMs (one that use a TPM not known by the SDK -> i.e. net8.0-unix).

Now if NuGet starts emitting an error for TFM aliases it would break runtime. It would be good to only emit an error when the TFM is included in the package (either the build output or the dependencies section). So in technical terms, only emit an error when TFM == alias && (IncludeBuildOutput == true or SuppressDependenciesWhenPackaging == false)

@ghost
Copy link

ghost commented Jan 11, 2024

This PR has been automatically marked as stale because it has no activity for 30 days. It will be closed if no further activity occurs within another 15 days of this comment, unless it has a "Status:Do not auto close" label. If it is closed, you may reopen it anytime when you're ready again, as long as you don't delete the branch.

@zivkan
Copy link
Member

zivkan commented Jan 26, 2024

oops, vacation and other priorities has kept this feature on the backburner, but it's still planned.

@Nigusu-Allehu Nigusu-Allehu added the Status:Do not auto close Do not auto close for PRs needs long review process label Jun 4, 2024
@zivkan zivkan marked this pull request as draft July 23, 2024 22:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status:Do not auto close Do not auto close for PRs needs long review process
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants