Skip to content

Commit

Permalink
Add --format and --output-file flags to oss-characterstics (#106)
Browse files Browse the repository at this point in the history
* Add --format and --output-file flags to oss-characterstics
  • Loading branch information
jacobmsft authored Jun 8, 2020
1 parent adffe81 commit 458d4e4
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 49 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ project.lock.json
project.fragment.lock.json
artifacts/

# launchsettings
*launchSettings.json

# StyleCop
StyleCopReport.xml

Expand Down
4 changes: 2 additions & 2 deletions src/Shared/Helpers/OutputBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class OutputBuilder
/// </summary>
protected static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();

enum OutputFormat
public enum OutputFormat
{
sarifv1,
sarifv2 ,
Expand Down Expand Up @@ -85,7 +85,7 @@ public void AppendOutput(List<Result> results)
/// <returns>Location list with single location object</returns>
public static List<Location> BuildPurlLocation(PackageURL purl)
{
var projectManager = ProjectManagerFactory.CreateProjectManager(purl, null);
BaseProjectManager? projectManager = ProjectManagerFactory.CreateProjectManager(purl, null);
if (projectManager == null)
{
Logger.Error("Cannot determine the package type");
Expand Down
157 changes: 131 additions & 26 deletions src/oss-characteristics/CharacteristicTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
using System.Text;
using System.Threading.Tasks;
using Microsoft.ApplicationInspector.Commands;
using Microsoft.CodeAnalysis.Sarif;
using Microsoft.CST.OpenSource.Shared;
using SarifResult = Microsoft.CodeAnalysis.Sarif.Result;

namespace Microsoft.CST.OpenSource
{
public class CharacteristicTool
public class CharacteristicTool : OSSGadget
{
/// <summary>
/// Name of this tool.
Expand All @@ -22,11 +24,6 @@ public class CharacteristicTool
/// </summary>
private static readonly string VERSION = typeof(CharacteristicTool).Assembly?.GetName().Version?.ToString() ?? string.Empty;

/// <summary>
/// Logger for this class
/// </summary>
private static NLog.ILogger Logger { get; set; } = NLog.LogManager.GetCurrentClassLogger();

/// <summary>
/// Command line options
/// </summary>
Expand All @@ -36,7 +33,9 @@ public class CharacteristicTool
{ "disable-default-rules", false },
{ "custom-rule-directory", null },
{ "download-directory", null },
{ "use-cache", false }
{ "use-cache", false },
{ "format", "text" },
{ "output-file", null }
};

/// <summary>
Expand All @@ -49,6 +48,31 @@ static void Main(string[] args)
Logger?.Debug($"Microsoft OSS Gadget - {TOOL_NAME} {VERSION}");
characteristicTool.ParseOptions(args);

// output to console or file?
bool redirectConsole = !string.IsNullOrEmpty((string?)characteristicTool.Options["output-file"]);
if (redirectConsole)
{
if (!ConsoleHelper.RedirectConsole((string?)characteristicTool.Options["output-file"] ??
string.Empty))
{
Logger?.Error("Could not switch output from console to file");
// continue with current output
}
}

// select output format
OutputBuilder? outputBuilder;
try
{
outputBuilder = new OutputBuilder((string?)characteristicTool.Options["format"] ??
OutputBuilder.OutputFormat.text.ToString());
}
catch (ArgumentOutOfRangeException)
{
Logger?.Error("Invalid output format");
return;
}

if (characteristicTool.Options["target"] is IList<string> targetList && targetList.Count > 0)
{
foreach (var target in targetList)
Expand All @@ -60,37 +84,25 @@ static void Main(string[] args)
(string?)characteristicTool.Options["download-directory"],
(bool?)characteristicTool.Options["use-cache"] == true).Result;

var sb = new StringBuilder();
sb.AppendLine(target);
foreach (var key in analysisResult.Keys)
{
var metadata = analysisResult[key]?.Metadata;

if (metadata != null)
{
sb.AppendFormat("Programming Language: {0}\n", string.Join(", ", metadata.Languages.Keys));
sb.AppendLine("Unique Tags: ");
foreach (var tag in metadata.UniqueTags)
{
sb.AppendFormat($" * {tag}\n");
}
}
}

Logger?.Info(sb.ToString());
characteristicTool.AppendOutput(outputBuilder, purl, analysisResult);
}
catch (Exception ex)
{
Logger?.Warn(ex, "Error processing {0}: {1}", target, ex.Message);
}
}
}
outputBuilder.PrintOutput();
}
else
{
Logger?.Warn("No target provided; nothing to analyze.");
CharacteristicTool.ShowUsage();
Environment.Exit(1);
}
if (redirectConsole)
{
ConsoleHelper.RestoreConsole();
}
}

public CharacteristicTool() : base()
Expand Down Expand Up @@ -167,6 +179,91 @@ public CharacteristicTool() : base()
return analysisResult;
}

/// <summary>
/// Convert charactersticTool results into output format
/// </summary>
/// <param name="outputBuilder"></param>
/// <param name="purl"></param>
/// <param name="results"></param>
void AppendOutput(OutputBuilder outputBuilder, PackageURL purl, Dictionary<string, AnalyzeResult?> analysisResults)
{
if (outputBuilder.isTextFormat())
{
outputBuilder.AppendOutput(GetTextResults(purl, analysisResults));
}
else
{
outputBuilder.AppendOutput(GetSarifResults(purl, analysisResults));
}
}

/// <summary>
/// Convert charactersticTool results into text format
/// </summary>
/// <param name="results"></param>
/// <returns></returns>
static string GetTextResults(PackageURL purl, Dictionary<string, AnalyzeResult?> analysisResult)
{
StringBuilder stringOutput = new StringBuilder();
stringOutput.AppendLine(purl.ToString());
if (analysisResult.HasAtLeastOneNonNullValue())
{
foreach (var key in analysisResult.Keys)
{
var metadata = analysisResult?[key]?.Metadata;

stringOutput.AppendFormat("Programming Language: {0}\n", string.Join(", ", metadata.Languages.Keys));
stringOutput.AppendLine("Unique Tags: ");
foreach (var tag in metadata.UniqueTags)
{
stringOutput.AppendFormat($" * {tag}\n");
}
}
}
return stringOutput.ToString();
}

/// <summary>
/// Build and return a list of Sarif Result list from the find characterstics results
/// </summary>
/// <param name="purl"></param>
/// <param name="results"></param>
/// <returns></returns>
static List<SarifResult> GetSarifResults(PackageURL purl, Dictionary<string, AnalyzeResult?> analysisResult)
{
List<SarifResult> sarifResults = new List<SarifResult>();
if (analysisResult.HasAtLeastOneNonNullValue())
{
foreach (var key in analysisResult.Keys)
{
var metadata = analysisResult?[key]?.Metadata;
SarifResult sarifResult = new SarifResult()
{
Message = new Message()
{
Text = string.Join(", ", metadata?.Languages?.Keys ?? Array.Empty<string>()),
Id = "languages"
},
Kind = ResultKind.Informational,
Level = FailureLevel.None,
Locations = OutputBuilder.BuildPurlLocation(purl),
};

if (metadata?.UniqueTags?.HasAtLeastOneNonNullValue() ?? true)
{
#pragma warning disable CS8602 // Dereference of a possibly null reference.
foreach (var tag in metadata.UniqueTags)
#pragma warning restore CS8602 // Dereference of a possibly null reference.
{
sarifResult?.SetProperty(tag.Key, tag.Value);
}
}
sarifResults.Add(sarifResult);
}
}
return sarifResults;
}

/// <summary>
/// Parses options for this program.
/// </summary>
Expand Down Expand Up @@ -211,6 +308,14 @@ private void ParseOptions(string[] args)
Options["disable-default-rules"] = true;
break;

case "--format":
Options["format"] = args[++i];
break;

case "--output-file":
Options["output-file"] = args[++i];
break;

default:
if (Options["target"] is IList<string> targetList)
targetList.Add(args[i]);
Expand Down
7 changes: 1 addition & 6 deletions src/oss-defog/DefoggerTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace Microsoft.CST.OpenSource
{
class DefoggerTool
class DefoggerTool : OSSGadget
{
/// <summary>
/// Name of this tool.
Expand All @@ -25,11 +25,6 @@ class DefoggerTool
/// </summary>
private static readonly string VERSION = typeof(DefoggerTool).Assembly?.GetName().Version?.ToString() ?? string.Empty;

/// <summary>
/// Logger for this class
/// </summary>
private static NLog.ILogger Logger { get; set; } = NLog.LogManager.GetCurrentClassLogger();

/// <summary>
/// Regular expression that matches Base64-encoded text.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/oss-detect-backdoor/DetectBackdoorTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Microsoft.CST.OpenSource
{
public class DetectBackdoorTool
public class DetectBackdoorTool : OSSGadget
{
/// <summary>
/// Name of this tool.
Expand Down
7 changes: 1 addition & 6 deletions src/oss-download/DownloadTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Microsoft.CST.OpenSource
{
public class DownloadTool
public class DownloadTool : OSSGadget
{
/// <summary>
/// Name of this tool.
Expand All @@ -20,11 +20,6 @@ public class DownloadTool
/// </summary>
private static readonly string VERSION = typeof(DownloadTool).Assembly?.GetName().Version?.ToString() ?? string.Empty;

/// <summary>
/// Logger for this class
/// </summary>
private static NLog.ILogger Logger { get; set; } = NLog.LogManager.GetCurrentClassLogger();

/// <summary>
/// Command line options
/// </summary>
Expand Down
7 changes: 3 additions & 4 deletions src/oss-find-source/FindSourceTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,19 @@ static void Main(string[] args)
}

// select output format
string format = ((string?)findSourceTool.Options["format"] ?? string.Empty).ToLower();
OutputBuilder outputBuilder;
try
{
outputBuilder = new OutputBuilder(format);
outputBuilder = new OutputBuilder(((string?)findSourceTool.Options["format"] ??
OutputBuilder.OutputFormat.text.ToString()));
}
catch (ArgumentOutOfRangeException)
{
Logger.Error("Invalid output format");
return;
}

if (findSourceTool.Options["target"] is IList<string> targetList && targetList.Count > 0)
{
if (findSourceTool.Options["target"] is IList<string> targetList && targetList.Count > 0) {
foreach (var target in targetList)
{
try
Expand Down
7 changes: 3 additions & 4 deletions src/oss-health/HealthMetrics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,12 @@ PropertyInfo[] getHealthProperties()
}
public List<Result> toSarif()
{
List<Result> sarifResults = new List<Result>();
var projectManager = ProjectManagerFactory.CreateProjectManager(purl, null);
BaseProjectManager? projectManager = ProjectManagerFactory.CreateProjectManager(purl, null);

if (projectManager == null)
{
Logger.Error("Cannot determine the package type");
return sarifResults;
return new List<Result>();
}

Normalize();
Expand Down Expand Up @@ -125,7 +124,7 @@ public List<Result> toSarif()
{
Address = new Address()
{
FullyQualifiedName = projectManager.GetPackageAbsoluteUri(purl)?.AbsoluteUri,
FullyQualifiedName = projectManager?.GetPackageAbsoluteUri(purl)?.AbsoluteUri,
AbsoluteAddress = 1,
Name = purl.ToString()
}
Expand Down

0 comments on commit 458d4e4

Please sign in to comment.