C#: Read from dependency directory from extractor option.

This commit is contained in:
Michael Nebel
2025-11-13 14:31:02 +01:00
parent 14f9997eb3
commit e76e7ab26a
4 changed files with 81 additions and 9 deletions

View File

@@ -0,0 +1,62 @@
using System;
using System.IO;
using Semmle.Util;
using Semmle.Util.Logging;
namespace Semmle.Extraction.CSharp.DependencyFetching
{
/// <summary>
/// A directory used for storing fetched dependencies.
/// When a specific directory is set via the dependency directory extractor option,
/// we store dependencies in that directory for caching purposes.
/// Otherwise, we create a temporary directory that is deleted upon disposal.
/// </summary>
public sealed class DependencyDirectory : IDisposable
{
private readonly string userReportedDirectoryPurpose;
private readonly ILogger logger;
private readonly bool attemptCleanup;
public DirectoryInfo DirInfo { get; }
public DependencyDirectory(string subfolderName, string userReportedDirectoryPurpose, ILogger logger)
{
this.logger = logger;
this.userReportedDirectoryPurpose = userReportedDirectoryPurpose;
string path;
if (EnvironmentVariables.GetBuildlessDependencyDir() is string dir)
{
path = dir;
attemptCleanup = false;
}
else
{
path = FileUtils.GetTemporaryWorkingDirectory(out _);
attemptCleanup = true;
}
DirInfo = new DirectoryInfo(Path.Join(path, subfolderName));
DirInfo.Create();
}
public void Dispose()
{
if (!attemptCleanup)
{
logger.LogInfo($"Keeping {userReportedDirectoryPurpose} directory {DirInfo.FullName} for possible caching purposes.");
return;
}
try
{
DirInfo.Delete(true);
}
catch (Exception exc)
{
logger.LogInfo($"Couldn't delete {userReportedDirectoryPurpose} directory {exc.Message}");
}
}
public override string ToString() => DirInfo.FullName.ToString();
}
}

View File

@@ -25,15 +25,15 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// <summary>
/// The computed packages directory.
/// This will be in the Temp location
/// This will be in the Cached or Temp location
/// so as to not trample the source tree.
/// </summary>
private readonly TemporaryDirectory packageDirectory;
private readonly DependencyDirectory packageDirectory;
/// <summary>
/// Create the package manager for a specified source tree.
/// </summary>
public NugetExeWrapper(FileProvider fileProvider, TemporaryDirectory packageDirectory, Semmle.Util.Logging.ILogger logger)
public NugetExeWrapper(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger)
{
this.fileProvider = fileProvider;
this.packageDirectory = packageDirectory;

View File

@@ -24,12 +24,12 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private readonly IDotNet dotnet;
private readonly DependabotProxy? dependabotProxy;
private readonly IDiagnosticsWriter diagnosticsWriter;
private readonly TemporaryDirectory legacyPackageDirectory;
private readonly TemporaryDirectory missingPackageDirectory;
private readonly DependencyDirectory legacyPackageDirectory;
private readonly DependencyDirectory missingPackageDirectory;
private readonly ILogger logger;
private readonly ICompilationInfoContainer compilationInfoContainer;
public TemporaryDirectory PackageDirectory { get; }
public DependencyDirectory PackageDirectory { get; }
public NugetPackageRestorer(
FileProvider fileProvider,
@@ -48,9 +48,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
this.logger = logger;
this.compilationInfoContainer = compilationInfoContainer;
PackageDirectory = new TemporaryDirectory(ComputeTempDirectoryPath("packages"), "package", logger);
legacyPackageDirectory = new TemporaryDirectory(ComputeTempDirectoryPath("legacypackages"), "legacy package", logger);
missingPackageDirectory = new TemporaryDirectory(ComputeTempDirectoryPath("missingpackages"), "missing package", logger);
PackageDirectory = new DependencyDirectory("packages", "package", logger);
legacyPackageDirectory = new DependencyDirectory("legacypackages", "legacy package", logger);
missingPackageDirectory = new DependencyDirectory("missingpackages", "missing package", logger);
}
public string? TryRestore(string package)

View File

@@ -76,5 +76,15 @@ namespace Semmle.Util
{
return Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_OVERLAY_BASE_METADATA_OUT");
}
/// <summary>
/// If set, returns the directory where buildless dependencies should be stored.
/// This is needed for caching dependencies.
/// </summary>
/// <returns></returns>
public static string? GetBuildlessDependencyDir()
{
return Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_OPTION_BUILDLESS_DEPENDENCY_DIR");
}
}
}