Today, dotnet build (and thus dotnet run) is separate from dotnet restore. I'd like to discuss having dotnet build (and thus dotnet run) detect if project.json has been modified since the last compilation, then perform a dotnet restore if project.json has been modified.
Two motivations:
dotnet restore after you add a NuGet package, etc.If this has already been proposed and closed, I couldn't find the issue. What's the rationale for them being separate?
@NumberByColors we wanted to have as little "magic" and orchestration in individual commands as possible to maintain clean interfaces and separation. This would be a decent enhancement, I agree, though it would have to be done carefully and only in the case of adding a dependency to project.json, not if the user adds some other data to it (for instance, runtimeOptions or general metadata). This would make dotnet build know a little bit too much magic.
/cc @piotrpMSFT @cdmihai
@davidfowl @anurse @cdmihai
We've talked about this issue a few times. There seems to be a fairly nice middle-ground solution. Restore needs to be run in two primary scenarios:
Of these, [2] is a very expensive operation (full graph evaluation) while [1] is fairly cheap (boils down to comparing two files on disk).
I think it would be great if we expanded dotnet-build to enable it to understand if the PJ is out of date with the lock file and to run a restore if that's the case, solving [1] above. This would clean up the user experience and would not significantly affect F5 experience since restore is only triggered when PJ is updated. [2] would still require a manual restore, but that feels like the right behavior.
To follow our existing convention, we would also add a flag to dotnet-build, --no-restore, which would opt out of this behavior.
Yea, I don't like it. Restore is an expensive operation and dependencies change way less often than you build. It gets more complicated when you take into account that transitive dependencies affect restore as well. If you have A -> B -> C, and you change C, and build A, does it do a restore? That's why I'd rather avoid it altogether.
@davidfowl -- do you agree with the user scenario of restoring on F5 in VS Code though? I get that it might not work well for the CLI.
Similar to my comment here: https://github.com/dotnet/cli/issues/1474#issuecomment-194963096
There should be a verb composability feature where people can build a linear sequence of commands. This way, we would not force any command to know about the others.
Also, is nuget incremental? (i.e., do not regenerate lock file if the project.json hash / timestamp did not change / is older)
If the team has no interest in implementing this, it would be useful if the dotnet exposed a command to return whether the dependencies in project.json had changed since the last dot net restore. Right now it's a black box, we can either always run dotnet restore before a build (suboptimal, slow, unnecessary 95% of the time), or we get a warning from dotnet build that you should run dotnet restore and then have to rerun dotnet build.
At least if you expose a command dotnet checkdeps we can compose the logic to determine whether we need a dotnet restore or not in a build script.
I'm moving this to 1.0.0 RTM milestone since we need to make a decision on this ask and will use this issue to track it.
/cc @piotrpMSFT @eerhardt @brthor @livarcocc
pls dont add too much magic, not everything has the same workflow.
maybe i need to run dotnet restore -f /path/to/my/packages or other command line args, instead of plain dotnet restore.
restore it's a separate step from build. that's it, is not too bad
And the build is already too entangled to nuget (the restore), and is a pain to configure/extend
I think this should be closed, since it is a dupe of dotnet/sdk#5066 and that issue was closed as "the component affected will be superseded by the new project system".
/cc @piotrpMSFT
I can't +1 @enricosada hard enough on this one. If you're building a test runner, for example, your own tests-of-self projects have to reference your freshly packed local NuGet packages rather than whatever the latest version was on nuget.org, or else dotnet test won't be able to find your runner in all cases.
Taking this from the other direction, it would be nice if there were an option to check if a restore is necessary, since a restore in our case adds an extra minute or two to the build time. It sucks having to run it from the build script even if you don't have to.
if (dotnet.exe restore -IsRequired)
(dotnet.exe restore)
// or simply
dotnet.exe restore -IfRequired
Or if there is already some way to do this, please enlighten me.
We are adding no-op restore for CLI 2.0.
Most helpful comment
pls dont add too much magic, not everything has the same workflow.
maybe i need to run
dotnet restore -f /path/to/my/packagesor other command line args, instead of plaindotnet restore.restoreit's a separate step frombuild. that's it, is not too badAnd the
buildis already too entangled to nuget (therestore), and is a pain to configure/extend