@@ -215,17 +215,90 @@ class BaseNuGet extends Exec {
215215 // Set deduplicated args
216216 setArgs(normalizedArgs)
217217
218- if (isFamily(FAMILY_WINDOWS )) {
219- executable = localNuget. absolutePath
220- } else {
221- executable = " mono"
222- // Prepend nuget.exe path to args for mono execution
223- setArgs([localNuget. absolutePath] + normalizedArgs)
218+ // Check if we should use dotnet restore instead of nuget.exe on non-Windows
219+ // Only use dotnet restore if explicitly enabled via useDotnetRestore property
220+ def useDotnetRestore = false
221+ if (! isFamily(FAMILY_WINDOWS ) && this instanceof NuGetRestore ) {
222+ try {
223+ if (this . hasProperty(' useDotnetRestore' ) && this . useDotnetRestore) {
224+ def dotnetPath = findDotnetPath()
225+ if (dotnetPath) {
226+ useDotnetRestore = true
227+ } else {
228+ project. logger. warn(" useDotnetRestore is enabled but 'dotnet' command not found. Falling back to nuget.exe with Mono." )
229+ }
230+ }
231+ } catch (Exception e) {
232+ project. logger. debug(" Could not check useDotnetRestore property: ${ e.message} " )
233+ }
234+
235+ if (useDotnetRestore) {
236+ executable = dotnetPath
237+ // Convert nuget.exe restore args to dotnet restore args
238+ def dotnetArgs = [' restore' ]
239+ // Add solution file if present
240+ if (this . hasProperty(' solutionFile' ) && this . solutionFile) {
241+ def solutionPath = this . solutionFile instanceof File ? this . solutionFile. absolutePath : project. file(this . solutionFile). absolutePath
242+ dotnetArgs. add(solutionPath)
243+ }
244+ // Add packages.config file if present (dotnet restore doesn't support this directly, but we'll try)
245+ if (this . hasProperty(' packagesConfigFile' ) && this . packagesConfigFile) {
246+ project. logger. warn(" packages.config files are not directly supported by 'dotnet restore'. Consider migrating to PackageReference format." )
247+ }
248+ // Add sources
249+ if (this . hasProperty(' sources' ) && ! this . sources. isEmpty()) {
250+ this . sources. each { source ->
251+ dotnetArgs. add(' --source' )
252+ dotnetArgs. add(source)
253+ }
254+ }
255+ // Add config file
256+ if (this . hasProperty(' configFile' ) && this . configFile) {
257+ dotnetArgs. add(' --configfile' )
258+ dotnetArgs. add(this . configFile. absolutePath)
259+ }
260+ // Add packages directory
261+ if (this . hasProperty(' packagesDirectory' ) && this . packagesDirectory) {
262+ dotnetArgs. add(' --packages' )
263+ dotnetArgs. add(this . packagesDirectory)
264+ }
265+ // Add solution directory
266+ if (this . hasProperty(' solutionDirectory' ) && this . solutionDirectory) {
267+ dotnetArgs. add(' --solution-directory' )
268+ dotnetArgs. add(this . solutionDirectory. absolutePath)
269+ }
270+ // Disable parallel processing
271+ if (this . hasProperty(' disableParallelProcessing' ) && this . disableParallelProcessing) {
272+ dotnetArgs. add(' --no-parallel' )
273+ }
274+ setArgs(dotnetArgs)
275+ project. logger. info(" Using 'dotnet restore' instead of 'nuget.exe' (dotnet SDK detected)" )
276+ }
224277 }
225278
226- // Add flags after setting the base args
227- args ' -NonInteractive'
228- args ' -Verbosity' , (verbosity ?: getNugetVerbosity())
279+ if (! useDotnetRestore) {
280+ if (isFamily(FAMILY_WINDOWS )) {
281+ executable = localNuget. absolutePath
282+ } else {
283+ executable = " mono"
284+ // Prepend nuget.exe path to args for mono execution
285+ setArgs([localNuget. absolutePath] + normalizedArgs)
286+ }
287+
288+ // Add nuget.exe-specific flags (not needed for dotnet restore)
289+ args ' -NonInteractive'
290+ args ' -Verbosity' , (verbosity ?: getNugetVerbosity())
291+ } else {
292+ // For dotnet restore, add verbosity if needed (different format)
293+ def verbosityLevel = verbosity ?: getNugetVerbosity()
294+ if (verbosityLevel == ' detailed' ) {
295+ args ' --verbosity' , ' detailed'
296+ } else if (verbosityLevel == ' normal' ) {
297+ args ' --verbosity' , ' normal'
298+ } else if (verbosityLevel == ' quiet' ) {
299+ args ' --verbosity' , ' quiet'
300+ }
301+ }
229302
230303 project. logger. info(" Final args before execution: ${ getArgs().toList()} " )
231304
@@ -359,4 +432,20 @@ class BaseNuGet extends Exec {
359432 if (logger. infoEnabled) return ' normal'
360433 return ' quiet'
361434 }
435+
436+ /**
437+ * Find the dotnet executable path (for use with dotnet restore)
438+ */
439+ protected String findDotnetPath () {
440+ try {
441+ def process = [' which' , ' dotnet' ]. execute()
442+ process. waitFor()
443+ if (process. exitValue() == 0 ) {
444+ return process. text. trim()
445+ }
446+ } catch (Exception e) {
447+ // dotnet not found
448+ }
449+ return null
450+ }
362451}
0 commit comments