phmonte / Buildalyzer

A utility to perform design-time builds of .NET projects without having to think too hard about it.
MIT License
606 stars 95 forks source link

.Net Core environment with --no-restore not working #154

Open bcollamore opened 3 years ago

bcollamore commented 3 years ago

Per https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-build: "Running 'dotnet build' is equivalent to running 'dotnet msbuild -restore'"

In order to not restore in a net core environment, we need to pass --no-restore.

Therefore, setting Restore = false in EnvironmentOptions does not work, as the code currently sets "/restore" when Restore == true.

Suggest using 'dotnet build' rather than 'dotnet msbuild'. In ProjectAnalyzer.GetCommand, something akin to:

        // Get the executable and the initial set of arguments
        string fileName = buildEnvironment.MsBuildExePath;
        string initialArguments = string.Empty;
        if (Path.GetExtension(buildEnvironment.MsBuildExePath).Equals(".dll", StringComparison.OrdinalIgnoreCase))
        {
            // .NET Core MSBuild .dll needs to be run with dotnet
            fileName = buildEnvironment.DotnetExePath;
            **initialArguments = "build";
            // initialArguments = $"\"{buildEnvironment.MsBuildExePath}\"";**
        }

... // Then, at the end of the same method... something akin to

        // Get the restore argument (/restore for msbuild and --no-restore for dotnet build)
        string restoreArgument = string.Empty;
        if (initialArguments == "build" && !buildEnvironment.Restore)
        {
            restoreArgument = "--no-restore";
        }
        else if (buildEnvironment.Restore)
        {
            restoreArgument = "/restore";
        }

Context: I'm trying to use Stryker.net in a dockerized GitHub Action, and I do not want to 'restore' in the CI/CD pipeline. (1) It has already been restored, and (2) Re-restoring will not work from within a GitHub Action unless credentials of (all) the private Package Feeds are flowed into the GitHub Action, which renders it specific to the project (more specifically, to the nuget.config) being built.

daveaglick commented 3 years ago

I think I understand the problem, but not sure I'm following the suggested solution. If I recall we always call MSBuild, either directly or indirectly depending on if it's a .NET Framework or .NET Core host. I.e. we'll end up calling one of these two commands:

path/to/msbuild.exe ... or dotnet path/to/msbuild.dll ...

That help unify the command line, especially for the arguments related to injecting the MSBuild logger that Buildalyzer uses to listen for build events.

In the event Restore is true and extra /restore argument gets added:

path/to/msbuild.exe ... /restore or dotnet path/to/msbuild.dll ... /restore

If Restore is false that extra argument does not get added.

The part I'm unclear on is why calling dotnet build would help here? It sounds like from the documentation you linked that since dotnet build implies -restore that using it as the command would actually make this problem worse (since the restore argument is "baked in"). Is the problem that `dotnet path/to/msbuild.dll ... without a /restore argument still performs a restore?

bcollamore commented 3 years ago

Agreed Dave. This is incorrect. After looking more into it, my problem seems more in line with https://github.com/daveaglick/Buildalyzer/issues/105.