-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Support variables in #:project
directives
#51108
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
base: release/10.0.2xx
Are you sure you want to change the base?
Conversation
9ad9ae2
to
bc17aea
Compare
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.
Pull Request Overview
Adds support for MSBuild variable expansion inside #:project directives and updates tests and documentation accordingly.
- Introduces directive evaluation pass (EvaluateDirectives) to expand MSBuild variables and resolve project paths.
- Extends CSharpDirective.Project to preserve original and unresolved names for later path adjustments during project conversion.
- Adds tests covering variable usage and updates documentation about variable handling limitations.
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
File | Description |
---|---|
RunTelemetryTests.cs | Adapts tests to new CSharpDirective.Project constructor. |
RunFileTests.cs | Adds tests for variable-based project references and malformed variable syntax. |
DotnetProjectConvertTests.cs | Adds test cases for variable-containing paths; updates expectations for cross-platform separators. |
VirtualProjectBuildingCommand.cs | Adds directive evaluation, caching of source file, and enhanced project directive handling. |
ProjectConvertCommand.cs | Integrates directive evaluation and updates path rewrite logic to preserve variable intent. |
dotnet-run-file.md | Documents variable support and caveats for #:project directives. |
Co-authored-by: Copilot <[email protected]>
The linked issue has milestone 10.0.2xx, was this PR meant to target release/10.0.2xx branch? |
Definitely, I was worried there might be changes missing in the 2xx branch, but looks like it's fairly up to date wrt file-based app PRs, so I can retarget now. |
This comment was marked as outdated.
This comment was marked as outdated.
@RikkiGibson @333fred @MiYanni for reviews, thanks |
result.Add(directive); | ||
// If the path is absolute and it has some `$(..)` vars in it, | ||
// turn it into a relative path (it might be in the form `$(ProjectDir)/../Lib` | ||
// and we don't want that to be turned into an absolute path in the converted project). |
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.
Is there an ability to be more precise here? For example, what if I have #:project C:\git\$(Config)\$(Config).csproj
. Are we able to detect if the path starts with an absolute path, and is only dependent on variables for subpath elements?
public sealed class Project(in ParseInfo info) : Named(info) | ||
public sealed class Project : Named | ||
{ | ||
[SetsRequiredMembers] |
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.
Is there a parameterless constructor somewhere I'm missing? If not, please remove required
members from the type, this isn't serving any purpose.
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.
Good catch, thanks, this is a leftover from some earlier state of the code.
However, in `#:project` directives, variables might not be preserved during [grow up](#grow-up), | ||
because there is additional processing of those directives that makes it technically challenging to preserve variables in all cases | ||
(project directive values need to be resolved to be relative to the target directory | ||
and also to point to a project file rather than a directory). |
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.
I am wondering if it would be helpful to attempt to process the project path in two ways
- CLI-like.
dotnet add MyProject.csproj reference OtherProject.csproj
, etc. MSBuild variables are not respected, a relative path to a directory or project is expected. This is probably the 90% case. - MSBuild-like. A project file path is expected. Variables are expanded. Full paths are expected (e.g.
$(MSBuildThisFileDirectory)/path/to/project.csproj
).
Essentially, we first try to resolve as (1), as if it is the last argument to dotnet add MyProject.csproj reference OtherProject.csproj
, and, if we don't find it, just pass the path as written into the virtual project as case (2). I am speculating there is not a need to include both the convenience features of (1) and the expressiveness of (2). It's not something that either ordinary projects or the CLI can do today.
This would mean that the virtual project content can depend on the presence of the referenced projects on disk. I'm not sure if that introduces any major problems or not.
It's possible this is the wrong approach and would just make things more confusing, not less, but, thought I would submit it in hopes of it helping to resolve the technical challenges.
An error is reported if zero or more than one projects are found in the directory, just like `dotnet reference add` would do. | ||
|
||
Directive values support MSBuild variables (like `$(..)`) normally as they are translated literally and left to MSBuild engine to process. | ||
However, in `#:project` directives, variables might not be preserved during [grow up](#grow-up), |
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.
It seems a little odd that we're calling this concept "grow up", as it can have a derogatory nature to it, such as the statement, "You just need to grow up."
Closes #49286.