Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions src/Shared.CLI/BaseTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,72 @@ protected void SelectOutput(string outputFile)
}
}

protected void ConfigureLogging(BaseToolOptions options)
{
var config = NLog.LogManager.Configuration;
var rule = config.LoggingRules.FirstOrDefault();

if (rule != null)
{
NLog.LogLevel? targetLevel = ParseLogLevel(options.LogLevel);

if (targetLevel != null)
{
rule.SetLoggingLevels(targetLevel, NLog.LogLevel.Fatal);
NLog.LogManager.ReconfigExistingLoggers();
Logger.Debug("Log level set to: {0}", targetLevel);
}
else
{
Logger.Warn("Invalid log level '{0}'. Using default (Info). Valid values: Trace(0), Debug(1), Info(2), Warn(3), Error(4), Fatal(5), Off(6)", options.LogLevel);
}
}
}

/// <summary>
/// Parses a log level from either a string name or numeric value.
/// Supports NLog log levels: Trace, Debug, Info, Warn, Error, Fatal, Off (case-insensitive).
/// Also supports numeric values: 0=Trace, 1=Debug, 2=Info, 3=Warn, 4=Error, 5=Fatal, 6=Off.
/// </summary>
/// <param name="logLevel">The log level as a string or number.</param>
/// <returns>The corresponding NLog.LogLevel, or null if invalid.</returns>
private NLog.LogLevel? ParseLogLevel(string logLevel)
{
if (string.IsNullOrWhiteSpace(logLevel))
{
return null;
}

// Try parsing as a number first
if (int.TryParse(logLevel, out int numericLevel))
{
return numericLevel switch
{
0 => NLog.LogLevel.Trace,
1 => NLog.LogLevel.Debug,
2 => NLog.LogLevel.Info,
3 => NLog.LogLevel.Warn,
4 => NLog.LogLevel.Error,
5 => NLog.LogLevel.Fatal,
6 => NLog.LogLevel.Off,
_ => null
};
}

// Try parsing as a string (case-insensitive)
return logLevel.ToLowerInvariant() switch
{
"trace" => NLog.LogLevel.Trace,
"debug" => NLog.LogLevel.Debug,
"info" => NLog.LogLevel.Info,
"warn" or "warning" => NLog.LogLevel.Warn,
"error" => NLog.LogLevel.Error,
"fatal" => NLog.LogLevel.Fatal,
"off" or "none" => NLog.LogLevel.Off,
_ => null
};
}

private bool redirectConsole = false;
}
}
3 changes: 3 additions & 0 deletions src/Shared.CLI/Options/BaseToolOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ namespace Microsoft.CST.OpenSource.OssGadget.Options;

public class BaseToolOptions
{
[Option('l', "log-level", Required = false, Default = "Info",
HelpText = "Set the logging level (Trace=0, Debug=1, Info=2, Warn=3, Error=4, Fatal=5, Off=6). Can use name or number.")]
public string LogLevel { get; set; } = "Info";
}
2 changes: 2 additions & 0 deletions src/Shared.CLI/Tools/DownloadTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public DownloadTool(ProjectManagerFactory projectManagerFactory)

public override async Task<ErrorCode> RunAsync(DownloadToolOptions options)
{
ConfigureLogging(options);

if (options.Targets is IEnumerable<string> targetList && targetList.Any())
{
foreach (string? target in targetList)
Expand Down
17 changes: 17 additions & 0 deletions src/Shared/PackageManagers/BaseProjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,23 @@ public async Task<Dictionary<PackageURL, double>> IdentifySourceRepositoryAsync(
/// </summary>
protected static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();

/// <summary>
/// Logs the download operation with package details and download URL.
/// </summary>
/// <param name="purl">The PackageURL being downloaded.</param>
/// <param name="downloadUrl">The actual download URL.</param>
protected static void LogDownload(PackageURL? purl, string? downloadUrl)
{
if (string.IsNullOrWhiteSpace(downloadUrl))
{
Logger.Debug("Downloading {0}...", purl?.ToString());
}
else
{
Logger.Debug("Downloading {0} from {1}", purl?.ToString(), downloadUrl);
}
}

/// <summary>
/// Rank the source repo entry candidates by their edit distance.
/// </summary>
Expand Down
3 changes: 2 additions & 1 deletion src/Shared/PackageManagers/CPANProjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,10 @@ public override async Task<IEnumerable<string>> DownloadVersionAsync(PackageURL

string binaryUrl = root.GetProperty("download_url").GetString();

LogDownload(purl, binaryUrl);

HttpResponseMessage result = await httpClient.GetAsync(binaryUrl);
result.EnsureSuccessStatusCode();
Logger.Debug("Downloading {0}...", purl);

string targetName = $"cpan-{packageName}@{packageVersion}";
string extractionPath = Path.Combine(TopLevelExtractionDirectory, targetName);
Expand Down
4 changes: 2 additions & 2 deletions src/Shared/PackageManagers/CRANProjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public override async Task<IEnumerable<string>> DownloadVersionAsync(PackageURL
string url = $"{ENV_CRAN_ENDPOINT}/src/contrib/{packageName}_{packageVersion}.tar.gz";
System.Net.Http.HttpResponseMessage? result = await httpClient.GetAsync(url);
result.EnsureSuccessStatusCode();
Logger.Debug("Downloading {0}...", purl);
LogDownload(purl, url);

string targetName = $"cran-{packageName}@{packageVersion}";
string extractionPath = Path.Combine(TopLevelExtractionDirectory, targetName);
Expand Down Expand Up @@ -96,7 +96,7 @@ public override async Task<IEnumerable<string>> DownloadVersionAsync(PackageURL
string url = $"{ENV_CRAN_ENDPOINT}/src/contrib/Archive/{packageName}/{packageName}_{packageVersion}.tar.gz";
System.Net.Http.HttpResponseMessage? result = await httpClient.GetAsync(url);
result.EnsureSuccessStatusCode();
Logger.Debug("Downloading {0}...", purl);
LogDownload(purl, url);

string targetName = $"cran-{packageName}@{packageVersion}";
string extractionPath = Path.Combine(TopLevelExtractionDirectory, targetName);
Expand Down
2 changes: 1 addition & 1 deletion src/Shared/PackageManagers/CargoProjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ await retryPolicy.ExecuteAsync(async () =>
downloadedPaths.Add(extractionPath);
return;
}
Logger.Debug("Downloading {0}", url);
LogDownload(purl, url.ToString());

HttpClient httpClient = CreateHttpClient();

Expand Down
3 changes: 2 additions & 1 deletion src/Shared/PackageManagers/CocoapodsProjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ public override async Task<IEnumerable<string>> DownloadVersionAsync(PackageURL

if (url != null)
{
Logger.Debug("Downloading {0}...", purl);
//Logger.Debug("Downloading {0}...", purl);
LogDownload(purl, url);
System.Net.Http.HttpResponseMessage result = await httpClient.GetAsync(url);
result.EnsureSuccessStatusCode();

Expand Down
2 changes: 1 addition & 1 deletion src/Shared/PackageManagers/ComposerProjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public override async Task<IEnumerable<string>> DownloadVersionAsync(PackageURL
string? url = versionObject.Value.GetProperty("dist").GetProperty("url").GetString();
System.Net.Http.HttpResponseMessage? result = await httpClient.GetAsync(url);
result.EnsureSuccessStatusCode();
Logger.Debug("Downloading {0}...", purl);
LogDownload(purl, url);

string fsNamespace = OssUtilities.NormalizeStringForFileSystem(packageNamespace);
string fsName = OssUtilities.NormalizeStringForFileSystem(packageName);
Expand Down
2 changes: 1 addition & 1 deletion src/Shared/PackageManagers/GemProjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public override async Task<IEnumerable<string>> DownloadVersionAsync(PackageURL

System.Net.Http.HttpResponseMessage result = await httpClient.GetAsync(url);
result.EnsureSuccessStatusCode();
Logger.Debug("Downloading {0}...", purl);
LogDownload(purl, url);

string targetName = $"rubygems-{packageName}@{packageVersion}";
string extractionPath = Path.Combine(TopLevelExtractionDirectory, targetName);
Expand Down
2 changes: 1 addition & 1 deletion src/Shared/PackageManagers/GolangProjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public override async Task<IEnumerable<string>> DownloadVersionAsync(PackageURL

System.Net.Http.HttpResponseMessage result = await httpClient.GetAsync(url);
result.EnsureSuccessStatusCode();
Logger.Debug("Downloading {0}...", purl);
LogDownload(purl, url.ToString());

string targetName = $"golang-{packageNamespace}-{packageName}-{packageSubpath}@{packageVersion}";
string extractionPath = Path.Combine(TopLevelExtractionDirectory, targetName);
Expand Down
2 changes: 1 addition & 1 deletion src/Shared/PackageManagers/HackageProjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public override async Task<IEnumerable<string>> DownloadVersionAsync(PackageURL

System.Net.Http.HttpResponseMessage result = await httpClient.GetAsync(url);
result.EnsureSuccessStatusCode();
Logger.Debug("Downloading {0}...", purl.ToString());
LogDownload(purl, url);

string targetName = $"hackage-{packageName}@{packageVersion}";
string extractionPath = Path.Combine(TopLevelExtractionDirectory, targetName);
Expand Down
3 changes: 2 additions & 1 deletion src/Shared/PackageManagers/MavenProjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ public override async Task<IEnumerable<string>> DownloadVersionAsync(PackageURL

System.Net.Http.HttpResponseMessage result = await httpClient.GetAsync(artifact.Uri);
result.EnsureSuccessStatusCode();
Logger.Debug($"Downloading {purl}...");
LogDownload(purl, artifact.Uri.ToString());


string targetName = $"maven-{packageNamespace}-{packageName}{artifact.Type}@{packageVersion}";
targetName = targetName.Replace('/', '-');
Expand Down
3 changes: 2 additions & 1 deletion src/Shared/PackageManagers/NPMProjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ public override async Task<IEnumerable<string>> DownloadVersionAsync(PackageURL
string? tarball = doc.RootElement.GetProperty("versions").GetProperty(packageVersion).GetProperty("dist").GetProperty("tarball").GetString();
HttpResponseMessage result = await httpClient.GetAsync(tarball);
result.EnsureSuccessStatusCode();
Logger.Debug("Downloading {0}...", purl?.ToString());
LogDownload(purl, tarball);
//Logger.Debug("Downloading {0}...", purl?.ToString());
string targetName = $"npm-{packageName}@{packageVersion}";
string extractionPath = Path.Combine(TopLevelExtractionDirectory, targetName);
if (doExtract && Directory.Exists(extractionPath) && cached == true)
Expand Down
5 changes: 4 additions & 1 deletion src/Shared/PackageManagers/PyPIProjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ public override async Task<IEnumerable<string>> DownloadVersionAsync(PackageURL
continue; // Missing a package type
}

System.Net.Http.HttpResponseMessage result = await httpClient.GetAsync(release.GetProperty("url").GetString());
string? downloadUrl = release.GetProperty("url").GetString();
LogDownload(purl, downloadUrl);

System.Net.Http.HttpResponseMessage result = await httpClient.GetAsync(downloadUrl);
result.EnsureSuccessStatusCode();
string targetName = $"pypi-{packageType}-{packageName}@{packageVersion}";
string extension = ".tar.gz";
Expand Down
5 changes: 4 additions & 1 deletion src/Shared/PackageManagers/VSMProjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,10 @@ public override async Task<IEnumerable<string>> DownloadVersionAsync(PackageURL

try
{
HttpResponseMessage downloadResult = await httpClient.GetAsync(source.GetString());
string? downloadUrl = source.GetString();
LogDownload(purl, downloadUrl);

HttpResponseMessage downloadResult = await httpClient.GetAsync(downloadUrl);
downloadResult.EnsureSuccessStatusCode();
string? targetName = $"vsm-{packageName}@{packageVersion}-{assetType}";
string extractionPath = Path.Combine(TopLevelExtractionDirectory, targetName);
Expand Down