dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.65k stars 1.06k forks source link

Using "dotnet restore" on multiple projects at once. #38326

Open SRNissen opened 7 months ago

SRNissen commented 7 months ago

Is your feature request related to a problem?

I have a C# repo that builds in docker.

Docker's use of wildcards and placeholders is... let's leave it at not good.

I was hoping to compensate by letting dotnet handle it for me, like so:

    COPY ["*/*.csproj", "projects/"]
    RUN dotnet restore projects/*.csproj

Unfortunately, that doesn't work.

Variations that I tried:

naked restore:

dotnet restore         
MSBUILD : error MSB1011: Specify which project or solution file to use because this folder contains more than one project or solution file.

Wildcard:

dotnet restore *.csproj
MSBUILD : error MSB1008: Only one project can be specified.
//several lines left out

piping in paths:

ls | dotnet restore 
MSBUILD : error MSB1011: Specify which project or solution file to use because this folder contains more than one project or solution file.

foreach:

for i in *; do dotnet restore $i; done

The last one works but it'd be nice if I didn't have to remember shell script foreach syntax

Describe the solution you'd like

It'd be nice if a naked dotnet restore restored all projects in a folder.

mcyenikoylu commented 5 months ago

Yes, I had the same problem when creating Docker and when I specified the .sln file path, everything was fixed.

Screenshot 2024-04-15 at 6 17 01 PM

SRNissen commented 5 months ago

Sure - but to make that work, you've done a naked one-shot copy of your entire solution folder structure. That trashes the cache and causes a full restore to be done on every build, which is part of what I'm trying to avoid.

MiYanni commented 4 months ago

@SRNissen

From my understanding, solution files (.sln) are supposed to be a grouping of projects. So, you could make a solution file and restore that. If you don't like solution files, you can make a "master project" using the Traversal SDK and that can wildcard all the projects. Then, you just restore that one.

Lastly, something I've done for CI builds is have it dynamically create a solution in my output directory. That globs all the projects and then I use that solution file and never commit it to the repository. This specific solution below only works on Linux/Unix.

dotnet new sln -n Temp.sln -o <output-dir> --force
dotnet sln <output-dir>/Temp.sln add **/*.csproj
dotnet restore <output-dir>/Temp.sln
SRNissen commented 4 months ago

Oh I already have a cludgy-but-functional solution, I'm past the "make it work" part of the process and moving towards "give it good UX," hence the feature request.

MiYanni commented 4 months ago

@SRNissen

Oh I already have a cludgy-but-functional solution, I'm past the "make it work" part of the process and moving towards "give it good UX," hence the feature request.

So, part of the reason this doesn't exist is that if you handed us a random assortment of .csproj files, what is the expectation for our use of MSBuild to actually run on them? Your solution (using a foreach loop) involved spinning up a new MSBuild instance per project. If we wanted this as a feature, the CLI could dynamically create a solution (similar to my suggestion) "under the hood" and then run a single MSBuild instance on that. I understand the desire here for better UX but it is more 'mechanically' kludgey because we're basically just shelling out from our CLI to another CLI (MSBuild). You can see the doc for ProjectFile in the MSBuild CLI and it really isn't designed to work on "more than one" project.