77
88namespace Semmle . Extraction . CSharp . DependencyFetching
99{
10- internal interface IPackagesConfigRestore : IDisposable
10+ internal interface IPackagesConfigRestore
1111 {
1212 /// <summary>
1313 /// The number of packages.config files found in the source tree.
@@ -33,11 +33,11 @@ internal interface IPackagesConfigRestore : IDisposable
3333 /// </summary>
3434 internal class PackagesConfigRestoreFactory
3535 {
36- public static IPackagesConfigRestore Create ( FileProvider fileProvider , DependencyDirectory packageDirectory , Semmle . Util . Logging . ILogger logger , FeedManager feedManager )
36+ public static IPackagesConfigRestore Create ( FileProvider fileProvider , DependencyDirectory packageDirectory , Semmle . Util . Logging . ILogger logger , FeedManager feedManager , HashSet < string > reachableFeeds )
3737 {
3838 if ( SystemBuildActions . Instance . IsWindows ( ) || SystemBuildActions . Instance . IsMonoInstalled ( ) )
3939 {
40- return new NugetExeWrapper ( fileProvider , packageDirectory , logger , feedManager ) ;
40+ return new NugetExeWrapper ( fileProvider , packageDirectory , logger , feedManager , reachableFeeds ) ;
4141 }
4242
4343 return new NoOpPackagesConfig ( fileProvider . PackagesConfigs , logger ) ;
@@ -55,8 +55,6 @@ private class NugetExeWrapper : IPackagesConfigRestore
5555
5656 public int PackageCount => fileProvider . PackagesConfigs . Count ;
5757
58- private readonly string ? backupNugetConfig ;
59- private readonly string ? nugetConfigPath ;
6058 private readonly FileProvider fileProvider ;
6159
6260 /// <summary>
@@ -66,58 +64,31 @@ private class NugetExeWrapper : IPackagesConfigRestore
6664 /// </summary>
6765 private readonly DependencyDirectory packageDirectory ;
6866 private readonly FeedManager feedManager ;
67+ private readonly HashSet < string > reachableFeeds ;
6968
7069 private bool IsWindows => SystemBuildActions . Instance . IsWindows ( ) ;
7170
71+ private bool ? isDefaultFeedReachable ;
72+ private bool IsDefaultFeedReachable =>
73+ isDefaultFeedReachable ??= feedManager . IsDefaultFeedReachable ( ) ;
74+
75+
76+
7277 /// <summary>
7378 /// Create the package manager for a specified source tree.
7479 /// </summary>
75- public NugetExeWrapper ( FileProvider fileProvider , DependencyDirectory packageDirectory , Semmle . Util . Logging . ILogger logger , FeedManager feedManager )
80+ public NugetExeWrapper ( FileProvider fileProvider , DependencyDirectory packageDirectory , Semmle . Util . Logging . ILogger logger , FeedManager feedManager , HashSet < string > reachableFeeds )
7681 {
7782 this . fileProvider = fileProvider ;
7883 this . packageDirectory = packageDirectory ;
7984 this . logger = logger ;
8085 this . feedManager = feedManager ;
86+ this . reachableFeeds = reachableFeeds ;
8187
8288 if ( fileProvider . PackagesConfigs . Count > 0 )
8389 {
8490 logger . LogInfo ( $ "Found packages.config files, trying to use nuget.exe for package restore") ;
8591 nugetExe = ResolveNugetExe ( ) ;
86- if ( ! HasPackageSource ( ) && feedManager . IsDefaultFeedReachable ( ) )
87- {
88- // We only modify or add a top level nuget.config file
89- nugetConfigPath = Path . Join ( fileProvider . SourceDir . FullName , "nuget.config" ) ;
90- try
91- {
92- if ( File . Exists ( nugetConfigPath ) )
93- {
94- var tempFolderPath = FileUtils . GetTemporaryWorkingDirectory ( out _ ) ;
95-
96- do
97- {
98- backupNugetConfig = Path . Join ( tempFolderPath , Path . GetRandomFileName ( ) ) ;
99- }
100- while ( File . Exists ( backupNugetConfig ) ) ;
101- File . Copy ( nugetConfigPath , backupNugetConfig , true ) ;
102- }
103- else
104- {
105- File . WriteAllText ( nugetConfigPath ,
106- """
107- <?xml version="1.0" encoding="utf-8"?>
108- <configuration>
109- <packageSources>
110- </packageSources>
111- </configuration>
112- """ ) ;
113- }
114- AddDefaultPackageSource ( nugetConfigPath ) ;
115- }
116- catch ( Exception e )
117- {
118- logger . LogError ( $ "Failed to add default package source to { nugetConfigPath } : { e } ") ;
119- }
120- }
12192 }
12293 }
12394
@@ -200,6 +171,20 @@ private bool TryRestoreNugetPackage(string packagesConfig)
200171 {
201172 logger . LogInfo ( $ "Restoring file \" { packagesConfig } \" ...") ;
202173
174+ var sourcesArgument = "" ;
175+ var feedsToUse = feedManager . FeedsToUse ( packagesConfig , reachableFeeds ) . ToList ( ) ;
176+ var useDefaultFeed = feedsToUse . Count == 0 && IsDefaultFeedReachable ;
177+
178+ // Explicitly construct the sources to be used for the restore command if any of the following is true:
179+ if ( feedManager . CheckNugetFeedResponsiveness || feedManager . HasPrivateRegistryFeeds || useDefaultFeed )
180+ {
181+ if ( useDefaultFeed )
182+ {
183+ feedsToUse . Add ( FeedManager . PublicNugetOrgFeed ) ;
184+ }
185+ sourcesArgument = feedManager . FeedsToRestoreArgument ( feedsToUse , "-Source" ) ;
186+ }
187+
203188 /* Use nuget.exe to install a package.
204189 * Note that there is a clutch of NuGet assemblies which could be used to
205190 * invoke this directly, which would arguably be nicer. However they are
@@ -210,12 +195,12 @@ private bool TryRestoreNugetPackage(string packagesConfig)
210195 if ( RunWithMono )
211196 {
212197 exe = "mono" ;
213- args = $ "\" { nugetExe } \" install -OutputDirectory \" { packageDirectory } \" \" { packagesConfig } \" ";
198+ args = $ "\" { nugetExe } \" install -OutputDirectory \" { packageDirectory } \" { sourcesArgument } \" { packagesConfig } \" ";
214199 }
215200 else
216201 {
217202 exe = nugetExe ! ;
218- args = $ "install -OutputDirectory \" { packageDirectory } \" \" { packagesConfig } \" ";
203+ args = $ "install -OutputDirectory \" { packageDirectory } \" { sourcesArgument } \" { packagesConfig } \" ";
219204 }
220205
221206 var pi = new ProcessStartInfo ( exe , args )
@@ -248,98 +233,6 @@ public int InstallPackages()
248233 {
249234 return fileProvider . PackagesConfigs . Count ( TryRestoreNugetPackage ) ;
250235 }
251-
252- private bool HasPackageSource ( )
253- {
254- if ( IsWindows )
255- {
256- return true ;
257- }
258-
259- try
260- {
261- logger . LogInfo ( "Checking if default package source is available..." ) ;
262- RunMonoNugetCommand ( "sources list -ForceEnglishOutput" , out var stdout ) ;
263- if ( stdout . All ( line => line != "No sources found." ) )
264- {
265- return true ;
266- }
267-
268- return false ;
269- }
270- catch ( Exception e )
271- {
272- logger . LogWarning ( $ "Failed to check if default package source is added: { e } ") ;
273- return true ;
274- }
275- }
276-
277- private void RunMonoNugetCommand ( string command , out IList < string > stdout )
278- {
279- string exe , args ;
280- if ( RunWithMono )
281- {
282- exe = "mono" ;
283- args = $ "\" { nugetExe } \" { command } ";
284- }
285- else
286- {
287- exe = nugetExe ! ;
288- args = command ;
289- }
290-
291- var pi = new ProcessStartInfo ( exe , args )
292- {
293- RedirectStandardOutput = true ,
294- RedirectStandardError = true ,
295- UseShellExecute = false
296- } ;
297-
298- var threadId = Environment . CurrentManagedThreadId ;
299- void onOut ( string s ) => logger . LogDebug ( s , threadId ) ;
300- void onError ( string s ) => logger . LogError ( s , threadId ) ;
301- pi . ReadOutput ( out stdout , onOut , onError ) ;
302- }
303-
304- private void AddDefaultPackageSource ( string nugetConfig )
305- {
306- logger . LogInfo ( "Adding default package source..." ) ;
307- RunMonoNugetCommand ( $ "sources add -Name DefaultNugetOrg -Source { FeedManager . PublicNugetOrgFeed } -ConfigFile \" { nugetConfig } \" ", out _ ) ;
308- }
309-
310- public void Dispose ( )
311- {
312- if ( nugetConfigPath is null )
313- {
314- return ;
315- }
316-
317- try
318- {
319- if ( backupNugetConfig is null )
320- {
321- logger . LogInfo ( "Removing nuget.config file" ) ;
322- File . Delete ( nugetConfigPath ) ;
323- return ;
324- }
325-
326- logger . LogInfo ( "Reverting nuget.config file content" ) ;
327- // The content of the original nuget.config file is reverted without changing the file's attributes or casing:
328- using ( var backup = File . OpenRead ( backupNugetConfig ) )
329- using ( var current = File . OpenWrite ( nugetConfigPath ) )
330- {
331- current . SetLength ( 0 ) ; // Truncate file
332- backup . CopyTo ( current ) ; // Restore original content
333- }
334-
335- logger . LogInfo ( "Deleting backup nuget.config file" ) ;
336- File . Delete ( backupNugetConfig ) ;
337- }
338- catch ( Exception exc )
339- {
340- logger . LogError ( $ "Failed to restore original nuget.config file: { exc } ") ;
341- }
342- }
343236 }
344237
345238 private class NoOpPackagesConfig : IPackagesConfigRestore
@@ -363,8 +256,6 @@ public int InstallPackages()
363256 }
364257 return 0 ;
365258 }
366-
367- public void Dispose ( ) { }
368259 }
369260 }
370261}
0 commit comments