mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
C#: Generate source files from .cshtml files in standalone
This commit is contained in:
@@ -23,13 +23,14 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
private readonly IDictionary<string, string> unresolvedReferences = new ConcurrentDictionary<string, string>();
|
||||
private int failedProjects;
|
||||
private int succeededProjects;
|
||||
private readonly string[] allSources;
|
||||
private readonly List<string> allSources;
|
||||
private int conflictedReferences = 0;
|
||||
private readonly IDependencyOptions options;
|
||||
private readonly DirectoryInfo sourceDir;
|
||||
private readonly DotNet dotnet;
|
||||
private readonly FileContent fileContent;
|
||||
private readonly TemporaryDirectory packageDirectory;
|
||||
private readonly TemporaryDirectory? razorWorkingDirectory;
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -60,7 +61,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
packageDirectory = new TemporaryDirectory(ComputeTempDirectory(sourceDir.FullName));
|
||||
|
||||
this.fileContent = new FileContent(packageDirectory, progressMonitor, () => GetFiles("*.*"));
|
||||
this.allSources = GetFiles("*.cs").ToArray();
|
||||
this.allSources = GetFiles("*.cs").ToList();
|
||||
var allProjects = GetFiles("*.csproj");
|
||||
var solutions = options.SolutionFile is not null
|
||||
? new[] { options.SolutionFile }
|
||||
@@ -131,6 +132,32 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
progressMonitor.UnresolvedReference(r.Key, r.Value);
|
||||
}
|
||||
|
||||
var views = GetFiles("*.cshtml")
|
||||
.Concat(GetFiles("*.razor"))
|
||||
.ToArray();
|
||||
|
||||
if (views.Length > 0)
|
||||
{
|
||||
// TODO: use SDK specified in global.json
|
||||
// TODO: add feature flag to control razor generation
|
||||
var sdk = new Sdk(dotnet).GetNewestSdk();
|
||||
if (sdk != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var razor = new Razor(sdk, dotnet, progressMonitor);
|
||||
razorWorkingDirectory = new TemporaryDirectory(ComputeTempDirectory(sourceDir.FullName, "razor"));
|
||||
var generatedFiles = razor.GenerateFiles(views, usedReferences.Keys, razorWorkingDirectory.ToString());
|
||||
this.allSources.AddRange(generatedFiles);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// It's okay, we tried our best to generate source files from cshtml files.
|
||||
progressMonitor.LogInfo($"Failed to generate source files from cshtml files: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
progressMonitor.Summary(
|
||||
AllSourceFiles.Count(),
|
||||
ProjectSourceFiles.Count(),
|
||||
@@ -156,9 +183,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
/// Computes a unique temp directory for the packages associated
|
||||
/// with this source tree. Use a SHA1 of the directory name.
|
||||
/// </summary>
|
||||
/// <param name="srcDir"></param>
|
||||
/// <returns>The full path of the temp directory.</returns>
|
||||
private static string ComputeTempDirectory(string srcDir)
|
||||
private static string ComputeTempDirectory(string srcDir, string subfolderName = "packages")
|
||||
{
|
||||
var bytes = Encoding.Unicode.GetBytes(srcDir);
|
||||
var sha = SHA1.HashData(bytes);
|
||||
@@ -166,7 +192,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
foreach (var b in sha.Take(8))
|
||||
sb.AppendFormat("{0:x2}", b);
|
||||
|
||||
return Path.Combine(Path.GetTempPath(), "GitHub", "packages", sb.ToString());
|
||||
return Path.Combine(Path.GetTempPath(), "GitHub", subfolderName, sb.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -392,6 +418,10 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
});
|
||||
}
|
||||
|
||||
public void Dispose() => packageDirectory?.Dispose();
|
||||
public void Dispose()
|
||||
{
|
||||
packageDirectory?.Dispose();
|
||||
razorWorkingDirectory?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,14 +5,6 @@ using Semmle.Util;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal interface IDotNet
|
||||
{
|
||||
bool RestoreToDirectory(string project, string directory, string? pathToNugetConfig = null);
|
||||
bool New(string folder);
|
||||
bool AddPackage(string folder, string package);
|
||||
IList<string> GetListedRuntimes();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Utilities to run the "dotnet" command.
|
||||
/// </summary>
|
||||
@@ -76,23 +68,33 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
return RunCommand(args);
|
||||
}
|
||||
|
||||
public IList<string> GetListedRuntimes()
|
||||
public IList<string> GetListedRuntimes() => GetListed("--list-runtimes", "runtime");
|
||||
|
||||
public IList<string> GetListedSdks() => GetListed("--list-sdks", "SDK");
|
||||
|
||||
private IList<string> GetListed(string args, string artifact)
|
||||
{
|
||||
const string args = "--list-runtimes";
|
||||
progressMonitor.RunningProcess($"{dotnet} {args}");
|
||||
var pi = new ProcessStartInfo(dotnet, args)
|
||||
{
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false
|
||||
};
|
||||
var exitCode = pi.ReadOutput(out var runtimes);
|
||||
var exitCode = pi.ReadOutput(out var artifacts);
|
||||
if (exitCode != 0)
|
||||
{
|
||||
progressMonitor.CommandFailed(dotnet, args, exitCode);
|
||||
return new List<string>();
|
||||
}
|
||||
progressMonitor.LogInfo($"Found runtimes: {string.Join("\n", runtimes)}");
|
||||
return runtimes;
|
||||
progressMonitor.LogInfo($"Found {artifact}s: {string.Join("\n", artifacts)}");
|
||||
return artifacts;
|
||||
}
|
||||
|
||||
public bool Exec(string execArgs)
|
||||
{
|
||||
// TODO: we might need to swallow the stdout of the started process to not pollute the logs of the extraction.
|
||||
var args = $"exec {execArgs}";
|
||||
return RunCommand(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,5 +108,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
|
||||
internal void NoTopLevelNugetConfig() =>
|
||||
LogInfo("Could not find a top-level nuget.config file.");
|
||||
|
||||
internal void RazorSourceGeneratorMissing(string fullPath) =>
|
||||
LogInfo($"Razor source generator folder {fullPath} does not exist.");
|
||||
|
||||
internal void CscMissing(string cscPath) =>
|
||||
LogInfo($"Csc.exe not found at {cscPath}.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
private const string aspNetCoreApp = "Microsoft.AspNetCore.App";
|
||||
|
||||
private readonly IDotNet dotNet;
|
||||
private readonly Lazy<Dictionary<string, RuntimeVersion>> newestRuntimes;
|
||||
private Dictionary<string, RuntimeVersion> NewestRuntimes => newestRuntimes.Value;
|
||||
private readonly Lazy<Dictionary<string, DotnetVersion>> newestRuntimes;
|
||||
private Dictionary<string, DotnetVersion> NewestRuntimes => newestRuntimes.Value;
|
||||
private static string ExecutingRuntime => RuntimeEnvironment.GetRuntimeDirectory();
|
||||
|
||||
public Runtime(IDotNet dotNet)
|
||||
@@ -27,58 +27,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
this.newestRuntimes = new(GetNewestRuntimes);
|
||||
}
|
||||
|
||||
internal record RuntimeVersion : IComparable<RuntimeVersion>
|
||||
{
|
||||
private readonly string dir;
|
||||
private readonly Version version;
|
||||
private readonly Version? preReleaseVersion;
|
||||
private readonly string? preReleaseVersionType;
|
||||
private bool IsPreRelease => preReleaseVersionType is not null && preReleaseVersion is not null;
|
||||
public string FullPath
|
||||
{
|
||||
get
|
||||
{
|
||||
var preRelease = IsPreRelease ? $"-{preReleaseVersionType}.{preReleaseVersion}" : "";
|
||||
var version = this.version + preRelease;
|
||||
return Path.Combine(dir, version);
|
||||
}
|
||||
}
|
||||
|
||||
public RuntimeVersion(string dir, string version, string preReleaseVersionType, string preReleaseVersion)
|
||||
{
|
||||
this.dir = dir;
|
||||
this.version = Version.Parse(version);
|
||||
if (!string.IsNullOrEmpty(preReleaseVersion) && !string.IsNullOrEmpty(preReleaseVersionType))
|
||||
{
|
||||
this.preReleaseVersionType = preReleaseVersionType;
|
||||
this.preReleaseVersion = Version.Parse(preReleaseVersion);
|
||||
}
|
||||
}
|
||||
|
||||
public int CompareTo(RuntimeVersion? other)
|
||||
{
|
||||
var c = version.CompareTo(other?.version);
|
||||
if (c == 0 && IsPreRelease)
|
||||
{
|
||||
if (!other!.IsPreRelease)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Both are pre-release like runtime versions.
|
||||
// The pre-release version types are sorted alphabetically (e.g. alpha, beta, preview, rc)
|
||||
// and the pre-release version types are more important that the pre-release version numbers.
|
||||
return preReleaseVersionType != other!.preReleaseVersionType
|
||||
? preReleaseVersionType!.CompareTo(other!.preReleaseVersionType)
|
||||
: preReleaseVersion!.CompareTo(other!.preReleaseVersion);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public override string ToString() => FullPath;
|
||||
}
|
||||
|
||||
[GeneratedRegex(@"^(\S+)\s(\d+\.\d+\.\d+)(-([a-z]+)\.(\d+\.\d+\.\d+))?\s\[(.+)\]$")]
|
||||
private static partial Regex RuntimeRegex();
|
||||
|
||||
@@ -88,16 +36,17 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
/// It is assume that the format of a listed runtime is something like:
|
||||
/// Microsoft.NETCore.App 7.0.2 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
|
||||
/// </summary>
|
||||
private static Dictionary<string, RuntimeVersion> ParseRuntimes(IList<string> listed)
|
||||
private static Dictionary<string, DotnetVersion> ParseRuntimes(IList<string> listed)
|
||||
{
|
||||
// Parse listed runtimes.
|
||||
var runtimes = new Dictionary<string, RuntimeVersion>();
|
||||
var runtimes = new Dictionary<string, DotnetVersion>();
|
||||
var regex = RuntimeRegex();
|
||||
listed.ForEach(r =>
|
||||
{
|
||||
var match = RuntimeRegex().Match(r);
|
||||
var match = regex.Match(r);
|
||||
if (match.Success)
|
||||
{
|
||||
runtimes.AddOrUpdateToLatest(match.Groups[1].Value, new RuntimeVersion(match.Groups[6].Value, match.Groups[2].Value, match.Groups[4].Value, match.Groups[5].Value));
|
||||
runtimes.AddOrUpdateToLatest(match.Groups[1].Value, new DotnetVersion(match.Groups[6].Value, match.Groups[2].Value, match.Groups[4].Value, match.Groups[5].Value));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -107,7 +56,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
/// <summary>
|
||||
/// Returns a dictionary mapping runtimes to their newest version.
|
||||
/// </summary>
|
||||
internal Dictionary<string, RuntimeVersion> GetNewestRuntimes()
|
||||
internal Dictionary<string, DotnetVersion> GetNewestRuntimes()
|
||||
{
|
||||
var listed = dotNet.GetListedRuntimes();
|
||||
return ParseRuntimes(listed);
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Standalone
|
||||
{
|
||||
internal record DotnetVersion : IComparable<DotnetVersion>
|
||||
{
|
||||
private readonly string dir;
|
||||
private readonly Version version;
|
||||
private readonly Version? preReleaseVersion;
|
||||
private readonly string? preReleaseVersionType;
|
||||
private bool IsPreRelease => preReleaseVersionType is not null && preReleaseVersion is not null;
|
||||
public string FullPath
|
||||
{
|
||||
get
|
||||
{
|
||||
var preRelease = IsPreRelease ? $"-{preReleaseVersionType}.{preReleaseVersion}" : "";
|
||||
var version = this.version + preRelease;
|
||||
return Path.Combine(dir, version);
|
||||
}
|
||||
}
|
||||
|
||||
public DotnetVersion(string dir, string version, string preReleaseVersionType, string preReleaseVersion)
|
||||
{
|
||||
this.dir = dir;
|
||||
this.version = Version.Parse(version);
|
||||
if (!string.IsNullOrEmpty(preReleaseVersion) && !string.IsNullOrEmpty(preReleaseVersionType))
|
||||
{
|
||||
this.preReleaseVersionType = preReleaseVersionType;
|
||||
this.preReleaseVersion = Version.Parse(preReleaseVersion);
|
||||
}
|
||||
}
|
||||
|
||||
public int CompareTo(DotnetVersion? other)
|
||||
{
|
||||
var c = version.CompareTo(other?.version);
|
||||
if (c == 0 && IsPreRelease)
|
||||
{
|
||||
if (!other!.IsPreRelease)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Both are pre-release like runtime versions.
|
||||
// The pre-release version types are sorted alphabetically (e.g. alpha, beta, preview, rc)
|
||||
// and the pre-release version types are more important that the pre-release version numbers.
|
||||
return preReleaseVersionType != other!.preReleaseVersionType
|
||||
? preReleaseVersionType!.CompareTo(other!.preReleaseVersionType)
|
||||
: preReleaseVersion!.CompareTo(other!.preReleaseVersion);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public override string ToString() => FullPath;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Semmle.BuildAnalyser
|
||||
{
|
||||
internal interface IDotNet
|
||||
{
|
||||
bool RestoreToDirectory(string project, string directory, string? pathToNugetConfig = null);
|
||||
bool New(string folder);
|
||||
bool AddPackage(string folder, string package);
|
||||
IList<string> GetListedRuntimes();
|
||||
IList<string> GetListedSdks();
|
||||
bool Exec(string execArgs);
|
||||
}
|
||||
}
|
||||
108
csharp/extractor/Semmle.Extraction.CSharp.Standalone/Razor.cs
Normal file
108
csharp/extractor/Semmle.Extraction.CSharp.Standalone/Razor.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Semmle.BuildAnalyser;
|
||||
using Semmle.Util;
|
||||
using System.Text;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Standalone
|
||||
{
|
||||
internal class Razor
|
||||
{
|
||||
private readonly DotnetVersion sdk;
|
||||
private readonly ProgressMonitor progressMonitor;
|
||||
private readonly DotNet dotNet;
|
||||
private readonly string sourceGeneratorFolder;
|
||||
private readonly string cscPath;
|
||||
|
||||
public Razor(DotnetVersion sdk, DotNet dotNet, ProgressMonitor progressMonitor)
|
||||
{
|
||||
this.sdk = sdk;
|
||||
this.progressMonitor = progressMonitor;
|
||||
this.dotNet = dotNet;
|
||||
|
||||
sourceGeneratorFolder = Path.Combine(this.sdk.FullPath, "Sdks/Microsoft.NET.Sdk.Razor/source-generators");
|
||||
if (!Directory.Exists(sourceGeneratorFolder))
|
||||
{
|
||||
this.progressMonitor.RazorSourceGeneratorMissing(sourceGeneratorFolder);
|
||||
throw new Exception($"Razor source generator folder {sourceGeneratorFolder} does not exist.");
|
||||
}
|
||||
|
||||
cscPath = Path.Combine(this.sdk.FullPath, "Roslyn/bincore/csc.dll");
|
||||
if (!File.Exists(cscPath))
|
||||
{
|
||||
this.progressMonitor.CscMissing(cscPath);
|
||||
throw new Exception($"csc.dll {cscPath} does not exist.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void GenerateAnalyzerConfig(IEnumerable<string> cshtmls, string analyzerConfigPath)
|
||||
{
|
||||
using var sw = new StreamWriter(analyzerConfigPath);
|
||||
sw.WriteLine("is_global = true");
|
||||
|
||||
foreach (var f in cshtmls)
|
||||
{
|
||||
sw.WriteLine($"\n[{f}]");
|
||||
var base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(f)); // TODO: this should be the relative path of the file.
|
||||
sw.WriteLine($"build_metadata.AdditionalFiles.TargetPath = {base64}");
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> GenerateFiles(IEnumerable<string> cshtmls, IEnumerable<string> references, string workingDirectory)
|
||||
{
|
||||
// TODO: the below command might be too long. It should be written to a temp file and passed to csc via @.
|
||||
|
||||
var name = Guid.NewGuid().ToString("N").ToUpper();
|
||||
var analyzerConfig = Path.Combine(Path.GetTempPath(), name + ".txt");
|
||||
var dllPath = Path.Combine(Path.GetTempPath(), name + ".dll");
|
||||
var outputFolder = Path.Combine(workingDirectory, name);
|
||||
Directory.CreateDirectory(outputFolder);
|
||||
|
||||
try
|
||||
{
|
||||
GenerateAnalyzerConfig(cshtmls, Path.Combine(sourceGeneratorFolder, analyzerConfig));
|
||||
|
||||
var args = new StringBuilder();
|
||||
args.Append($"\"{cscPath}\" /target:exe /generatedfilesout:\"{outputFolder}\" /out:\"{dllPath}\" /analyzerconfig:\"{analyzerConfig}\" ");
|
||||
|
||||
// TODO: quote paths:
|
||||
foreach (var f in Directory.GetFiles(sourceGeneratorFolder, "*.dll"))
|
||||
{
|
||||
args.Append($"/analyzer:\"{f}\" ");
|
||||
}
|
||||
|
||||
foreach (var f in cshtmls)
|
||||
{
|
||||
args.Append($"/additionalfile:\"{f}\" ");
|
||||
}
|
||||
|
||||
foreach (var f in references)
|
||||
{
|
||||
args.Append($"/reference:\"{f}\" ");
|
||||
}
|
||||
|
||||
dotNet.Exec(args.ToString());
|
||||
|
||||
return Directory.GetFiles(outputFolder, "*.*", new EnumerationOptions { RecurseSubdirectories = true });
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeleteFile(analyzerConfig);
|
||||
DeleteFile(dllPath);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DeleteFile(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
41
csharp/extractor/Semmle.Extraction.CSharp.Standalone/Sdk.cs
Normal file
41
csharp/extractor/Semmle.Extraction.CSharp.Standalone/Sdk.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System.Collections.Generic;
|
||||
using Semmle.BuildAnalyser;
|
||||
using Semmle.Util;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Linq;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Standalone
|
||||
{
|
||||
internal partial class Sdk
|
||||
{
|
||||
private readonly IDotNet dotNet;
|
||||
|
||||
public Sdk(IDotNet dotNet) => this.dotNet = dotNet;
|
||||
|
||||
[GeneratedRegex(@"^(\d+\.\d+\.\d+)(-([a-z]+)\.(\d+\.\d+\.\d+))?\s\[(.+)\]$")]
|
||||
private static partial Regex SdkRegex();
|
||||
|
||||
private static HashSet<DotnetVersion> ParseSdks(IList<string> listed)
|
||||
{
|
||||
var sdks = new HashSet<DotnetVersion>();
|
||||
var regex = SdkRegex();
|
||||
listed.ForEach(r =>
|
||||
{
|
||||
var match = regex.Match(r);
|
||||
if (match.Success)
|
||||
{
|
||||
sdks.Add(new DotnetVersion(match.Groups[5].Value, match.Groups[1].Value, match.Groups[3].Value, match.Groups[4].Value));
|
||||
}
|
||||
});
|
||||
|
||||
return sdks;
|
||||
}
|
||||
|
||||
public DotnetVersion? GetNewestSdk()
|
||||
{
|
||||
var listed = dotNet.GetListedSdks();
|
||||
var sdks = ParseSdks(listed);
|
||||
return sdks.OrderByDescending(s => s).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,13 @@ namespace Semmle.Extraction.Tests
|
||||
internal class DotNetStub : IDotNet
|
||||
{
|
||||
private readonly IList<string> runtimes;
|
||||
private readonly IList<string> sdks;
|
||||
|
||||
public DotNetStub(IList<string> runtimes) => this.runtimes = runtimes;
|
||||
|
||||
public DotNetStub(IList<string> runtimes, IList<string> sdks)
|
||||
{
|
||||
this.runtimes = runtimes;
|
||||
this.sdks = sdks;
|
||||
}
|
||||
public bool AddPackage(string folder, string package) => true;
|
||||
|
||||
public bool New(string folder) => true;
|
||||
@@ -17,6 +21,10 @@ namespace Semmle.Extraction.Tests
|
||||
public bool RestoreToDirectory(string project, string directory, string? pathToNugetConfig = null) => true;
|
||||
|
||||
public IList<string> GetListedRuntimes() => runtimes;
|
||||
|
||||
public IList<string> GetListedSdks() => sdks;
|
||||
|
||||
public bool Exec(string execArgs) => true;
|
||||
}
|
||||
|
||||
public class RuntimeTests
|
||||
@@ -37,7 +45,7 @@ namespace Semmle.Extraction.Tests
|
||||
"Microsoft.NETCore.App 7.0.0 [/path/dotnet/shared/Microsoft.NETCore.App]",
|
||||
"Microsoft.NETCore.App 7.0.2 [/path/dotnet/shared/Microsoft.NETCore.App]"
|
||||
};
|
||||
var dotnet = new DotNetStub(listedRuntimes);
|
||||
var dotnet = new DotNetStub(listedRuntimes, null!);
|
||||
var runtime = new Runtime(dotnet);
|
||||
|
||||
// Execute
|
||||
@@ -63,7 +71,7 @@ namespace Semmle.Extraction.Tests
|
||||
"Microsoft.NETCore.App 8.0.0-preview.5.43280.8 [/path/dotnet/shared/Microsoft.NETCore.App]",
|
||||
"Microsoft.NETCore.App 8.0.0-preview.5.23280.8 [/path/dotnet/shared/Microsoft.NETCore.App]"
|
||||
};
|
||||
var dotnet = new DotNetStub(listedRuntimes);
|
||||
var dotnet = new DotNetStub(listedRuntimes, null!);
|
||||
var runtime = new Runtime(dotnet);
|
||||
|
||||
// Execute
|
||||
@@ -86,7 +94,7 @@ namespace Semmle.Extraction.Tests
|
||||
"Microsoft.NETCore.App 8.0.0-rc.4.43280.8 [/path/dotnet/shared/Microsoft.NETCore.App]",
|
||||
"Microsoft.NETCore.App 8.0.0-preview.5.23280.8 [/path/dotnet/shared/Microsoft.NETCore.App]"
|
||||
};
|
||||
var dotnet = new DotNetStub(listedRuntimes);
|
||||
var dotnet = new DotNetStub(listedRuntimes, null!);
|
||||
var runtime = new Runtime(dotnet);
|
||||
|
||||
// Execute
|
||||
@@ -115,7 +123,7 @@ namespace Semmle.Extraction.Tests
|
||||
@"Microsoft.WindowsDesktop.App 6.0.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]",
|
||||
@"Microsoft.WindowsDesktop.App 7.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]"
|
||||
};
|
||||
var dotnet = new DotNetStub(listedRuntimes);
|
||||
var dotnet = new DotNetStub(listedRuntimes, null!);
|
||||
var runtime = new Runtime(dotnet);
|
||||
|
||||
// Execute
|
||||
@@ -131,4 +139,56 @@ namespace Semmle.Extraction.Tests
|
||||
Assert.Equal(@"C:/Program Files/dotnet/shared/Microsoft.NETCore.App/7.0.2", FixExpectedPathOnWindows(netCoreApp.FullPath));
|
||||
}
|
||||
}
|
||||
|
||||
public class SdkTests
|
||||
{
|
||||
private static string FixExpectedPathOnWindows(string path) => path.Replace('\\', '/');
|
||||
|
||||
[Fact]
|
||||
public void TestSdk1()
|
||||
{
|
||||
// Setup
|
||||
var listedSdks = new List<string>
|
||||
{
|
||||
"6.0.413 [/usr/local/share/dotnet/sdk1]",
|
||||
"7.0.102 [/usr/local/share/dotnet/sdk2]",
|
||||
"7.0.302 [/usr/local/share/dotnet/sdk3]",
|
||||
"7.0.400 [/usr/local/share/dotnet/sdk4]",
|
||||
"5.0.402 [/usr/local/share/dotnet/sdk5]",
|
||||
"6.0.102 [/usr/local/share/dotnet/sdk6]",
|
||||
"6.0.301 [/usr/local/share/dotnet/sdk7]",
|
||||
};
|
||||
var dotnet = new DotNetStub(null!, listedSdks);
|
||||
var sdk = new Sdk(dotnet);
|
||||
|
||||
// Execute
|
||||
var version = sdk.GetNewestSdk();
|
||||
|
||||
// Verify
|
||||
Assert.NotNull(version);
|
||||
Assert.Equal("/usr/local/share/dotnet/sdk4/7.0.400", FixExpectedPathOnWindows(version.FullPath));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSdk2()
|
||||
{
|
||||
// Setup
|
||||
var listedSdks = new List<string>
|
||||
{
|
||||
"6.0.413 [/usr/local/share/dotnet/sdk1]",
|
||||
"7.0.102 [/usr/local/share/dotnet/sdk2]",
|
||||
"8.0.100-preview.7.23376.3 [/usr/local/share/dotnet/sdk3]",
|
||||
"7.0.400 [/usr/local/share/dotnet/sdk4]",
|
||||
};
|
||||
var dotnet = new DotNetStub(null!, listedSdks);
|
||||
var sdk = new Sdk(dotnet);
|
||||
|
||||
// Execute
|
||||
var version = sdk.GetNewestSdk();
|
||||
|
||||
// Verify
|
||||
Assert.NotNull(version);
|
||||
Assert.Equal("/usr/local/share/dotnet/sdk3/8.0.100-preview.7.23376.3", FixExpectedPathOnWindows(version.FullPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,6 +150,8 @@ function RegisterExtractorPack(id)
|
||||
end
|
||||
|
||||
local windowsMatchers = {
|
||||
CreatePatternMatcher({ '^semmle%.extraction%.csharp%.standalone%.exe$' },
|
||||
MatchCompilerName, nil, { trace = false }),
|
||||
DotnetMatcherBuild,
|
||||
MsBuildMatcher,
|
||||
CreatePatternMatcher({ '^csc.*%.exe$' }, MatchCompilerName, extractor, {
|
||||
@@ -191,6 +193,9 @@ function RegisterExtractorPack(id)
|
||||
end
|
||||
}
|
||||
local posixMatchers = {
|
||||
-- The compiler name is case sensitive on Linux and lower cased on MacOS
|
||||
CreatePatternMatcher({ '^semmle%.extraction%.csharp%.standalone$', '^Semmle%.Extraction%.CSharp%.Standalone$' },
|
||||
MatchCompilerName, nil, { trace = false }),
|
||||
DotnetMatcherBuild,
|
||||
CreatePatternMatcher({ '^mcs%.exe$', '^csc%.exe$' }, MatchCompilerName,
|
||||
extractor, {
|
||||
|
||||
Reference in New Issue
Block a user