mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
C#: Split AutobuildOptions into C#/C++ specific classes
This commit is contained in:
1
.github/workflows/csharp-qltest.yml
vendored
1
.github/workflows/csharp-qltest.yml
vendored
@@ -83,3 +83,4 @@ jobs:
|
||||
dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/csharp/extractor/Semmle.Util.Tests"
|
||||
dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/csharp/extractor/Semmle.Extraction.Tests"
|
||||
dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests"
|
||||
dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests"
|
||||
|
||||
@@ -257,11 +257,11 @@ namespace Semmle.Autobuild.Cpp.Tests
|
||||
Actions.GetCurrentDirectory = cwd;
|
||||
Actions.IsWindows = isWindows;
|
||||
|
||||
var options = new AutobuildOptions(Actions, Language.Cpp);
|
||||
var options = new CppAutobuildOptions(Actions);
|
||||
return new CppAutobuilder(Actions, options);
|
||||
}
|
||||
|
||||
void TestAutobuilderScript(Autobuilder autobuilder, int expectedOutput, int commandsRun)
|
||||
void TestAutobuilderScript(CppAutobuilder autobuilder, int expectedOutput, int commandsRun)
|
||||
{
|
||||
Assert.Equal(expectedOutput, autobuilder.GetBuildScript().Run(Actions, StartCallback, EndCallback));
|
||||
|
||||
@@ -299,7 +299,7 @@ namespace Semmle.Autobuild.Cpp.Tests
|
||||
{
|
||||
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test.sln -DisableParallelProcessing"] = 1;
|
||||
Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test.sln -DisableParallelProcessing"] = 0;
|
||||
Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program Files ^(x86^)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat^"" && set Platform=&& type NUL && C:\odasa\tools\odasa index --auto msbuild C:\Project\test.sln /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"" /p:MvcBuildViews=true"] = 0;
|
||||
Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program Files ^(x86^)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat^"" && set Platform=&& type NUL && msbuild C:\Project\test.sln /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"""] = 0;
|
||||
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = "";
|
||||
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = 1;
|
||||
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = 0;
|
||||
|
||||
@@ -2,9 +2,26 @@
|
||||
|
||||
namespace Semmle.Autobuild.Cpp
|
||||
{
|
||||
public class CppAutobuilder : Autobuilder
|
||||
/// <summary>
|
||||
/// Encapsulates C++ build options.
|
||||
/// </summary>
|
||||
public class CppAutobuildOptions : AutobuildOptionsShared
|
||||
{
|
||||
public CppAutobuilder(IBuildActions actions, AutobuildOptions options) : base(actions, options) { }
|
||||
public override Language Language => Language.Cpp;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reads options from environment variables.
|
||||
/// Throws ArgumentOutOfRangeException for invalid arguments.
|
||||
/// </summary>
|
||||
public CppAutobuildOptions(IBuildActions actions) : base(actions)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class CppAutobuilder : Autobuilder<CppAutobuildOptions>
|
||||
{
|
||||
public CppAutobuilder(IBuildActions actions, CppAutobuildOptions options) : base(actions, options) { }
|
||||
|
||||
public override BuildScript GetBuildScript()
|
||||
{
|
||||
|
||||
@@ -11,14 +11,14 @@ namespace Semmle.Autobuild.Cpp
|
||||
try
|
||||
{
|
||||
var actions = SystemBuildActions.Instance;
|
||||
var options = new AutobuildOptions(actions, Language.Cpp);
|
||||
var options = new CppAutobuildOptions(actions);
|
||||
try
|
||||
{
|
||||
Console.WriteLine("CodeQL C++ autobuilder");
|
||||
var builder = new CppAutobuilder(actions, options);
|
||||
return builder.AttemptBuild();
|
||||
}
|
||||
catch(InvalidEnvironmentException ex)
|
||||
catch (InvalidEnvironmentException ex)
|
||||
{
|
||||
Console.WriteLine("The environment is invalid: {0}", ex.Message);
|
||||
}
|
||||
|
||||
@@ -403,7 +403,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.GetCurrentDirectory = cwd;
|
||||
actions.IsWindows = isWindows;
|
||||
|
||||
var options = new AutobuildOptions(actions, Language.CSharp);
|
||||
var options = new CSharpAutobuildOptions(actions);
|
||||
return new CSharpAutobuilder(actions, options);
|
||||
}
|
||||
|
||||
@@ -576,7 +576,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"] = false;
|
||||
}
|
||||
|
||||
private void TestAutobuilderScript(Autobuilder autobuilder, int expectedOutput, int commandsRun)
|
||||
private void TestAutobuilderScript(CSharpAutobuilder autobuilder, int expectedOutput, int commandsRun)
|
||||
{
|
||||
Assert.Equal(expectedOutput, autobuilder.GetBuildScript().Run(actions, StartCallback, EndCallback));
|
||||
|
||||
|
||||
@@ -4,9 +4,32 @@ using Semmle.Autobuild.Shared;
|
||||
|
||||
namespace Semmle.Autobuild.CSharp
|
||||
{
|
||||
public class CSharpAutobuilder : Autobuilder
|
||||
/// <summary>
|
||||
/// Encapsulates C# build options.
|
||||
/// </summary>
|
||||
public class CSharpAutobuildOptions : AutobuildOptionsShared
|
||||
{
|
||||
public CSharpAutobuilder(IBuildActions actions, AutobuildOptions options) : base(actions, options) { }
|
||||
private const string extractorOptionPrefix = "CODEQL_EXTRACTOR_CSHARP_OPTION_";
|
||||
|
||||
public bool Buildless { get; }
|
||||
|
||||
public override Language Language => Language.CSharp;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reads options from environment variables.
|
||||
/// Throws ArgumentOutOfRangeException for invalid arguments.
|
||||
/// </summary>
|
||||
public CSharpAutobuildOptions(IBuildActions actions) : base(actions)
|
||||
{
|
||||
Buildless = actions.GetEnvironmentVariable(lgtmPrefix + "BUILDLESS").AsBool("buildless", false) ||
|
||||
actions.GetEnvironmentVariable(extractorOptionPrefix + "BUILDLESS").AsBool("buildless", false);
|
||||
}
|
||||
}
|
||||
|
||||
public class CSharpAutobuilder : Autobuilder<CSharpAutobuildOptions>
|
||||
{
|
||||
public CSharpAutobuilder(IBuildActions actions, CSharpAutobuildOptions options) : base(actions, options) { }
|
||||
|
||||
public override BuildScript GetBuildScript()
|
||||
{
|
||||
|
||||
@@ -13,9 +13,9 @@ namespace Semmle.Autobuild.CSharp
|
||||
/// A build rule where the build command is of the form "dotnet build".
|
||||
/// Currently unused because the tracer does not work with dotnet.
|
||||
/// </summary>
|
||||
internal class DotNetRule : IBuildRule
|
||||
internal class DotNetRule : IBuildRule<CSharpAutobuildOptions>
|
||||
{
|
||||
public BuildScript Analyse(Autobuilder builder, bool auto)
|
||||
public BuildScript Analyse(IAutobuilder<CSharpAutobuildOptions> builder, bool auto)
|
||||
{
|
||||
if (!builder.ProjectsOrSolutionsToBuild.Any())
|
||||
return BuildScript.Failure;
|
||||
@@ -24,7 +24,7 @@ namespace Semmle.Autobuild.CSharp
|
||||
{
|
||||
var notDotNetProject = builder.ProjectsOrSolutionsToBuild
|
||||
.SelectMany(p => Enumerators.Singleton(p).Concat(p.IncludedProjects))
|
||||
.OfType<Project>()
|
||||
.OfType<Project<CSharpAutobuildOptions>>()
|
||||
.FirstOrDefault(p => !p.DotNetProject);
|
||||
if (notDotNetProject is not null)
|
||||
{
|
||||
@@ -56,7 +56,7 @@ namespace Semmle.Autobuild.CSharp
|
||||
});
|
||||
}
|
||||
|
||||
private static BuildScript WithDotNet(Autobuilder builder, Func<string?, IDictionary<string, string>?, BuildScript> f)
|
||||
private static BuildScript WithDotNet(IAutobuilder<AutobuildOptionsShared> builder, Func<string?, IDictionary<string, string>?, BuildScript> f)
|
||||
{
|
||||
var installDir = builder.Actions.PathCombine(builder.Options.RootDirectory, ".dotnet");
|
||||
var installScript = DownloadDotNet(builder, installDir);
|
||||
@@ -92,7 +92,7 @@ namespace Semmle.Autobuild.CSharp
|
||||
/// variables needed by the installed .NET Core (<code>null</code> when no variables
|
||||
/// are needed).
|
||||
/// </summary>
|
||||
public static BuildScript WithDotNet(Autobuilder builder, Func<IDictionary<string, string>?, BuildScript> f)
|
||||
public static BuildScript WithDotNet(IAutobuilder<AutobuildOptionsShared> builder, Func<IDictionary<string, string>?, BuildScript> f)
|
||||
=> WithDotNet(builder, (_1, env) => f(env));
|
||||
|
||||
/// <summary>
|
||||
@@ -100,7 +100,7 @@ namespace Semmle.Autobuild.CSharp
|
||||
/// .NET Core SDK. The SDK(s) will be installed at <code>installDir</code>
|
||||
/// (provided that the script succeeds).
|
||||
/// </summary>
|
||||
private static BuildScript DownloadDotNet(Autobuilder builder, string installDir)
|
||||
private static BuildScript DownloadDotNet(IAutobuilder<AutobuildOptionsShared> builder, string installDir)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(builder.Options.DotNetVersion))
|
||||
// Specific version supplied in configuration: always use that
|
||||
@@ -137,7 +137,7 @@ namespace Semmle.Autobuild.CSharp
|
||||
///
|
||||
/// See https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script.
|
||||
/// </summary>
|
||||
private static BuildScript DownloadDotNetVersion(Autobuilder builder, string path, string version)
|
||||
private static BuildScript DownloadDotNetVersion(IAutobuilder<AutobuildOptionsShared> builder, string path, string version)
|
||||
{
|
||||
return BuildScript.Bind(GetInstalledSdksScript(builder.Actions), (sdks, sdksRet) =>
|
||||
{
|
||||
@@ -233,7 +233,7 @@ namespace Semmle.Autobuild.CSharp
|
||||
/// <summary>
|
||||
/// Gets the `dotnet build` script.
|
||||
/// </summary>
|
||||
private static BuildScript GetBuildScript(Autobuilder builder, string? dotNetPath, IDictionary<string, string>? environment, string projOrSln)
|
||||
private static BuildScript GetBuildScript(IAutobuilder<CSharpAutobuildOptions> builder, string? dotNetPath, IDictionary<string, string>? environment, string projOrSln)
|
||||
{
|
||||
var build = new CommandBuilder(builder.Actions, null, environment);
|
||||
var script = build.RunCommand(DotNetCommand(builder.Actions, dotNetPath)).
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Semmle.Autobuild.CSharp
|
||||
try
|
||||
{
|
||||
var actions = SystemBuildActions.Instance;
|
||||
var options = new AutobuildOptions(actions, Language.CSharp);
|
||||
var options = new CSharpAutobuildOptions(actions);
|
||||
try
|
||||
{
|
||||
Console.WriteLine("CodeQL C# autobuilder");
|
||||
|
||||
@@ -6,9 +6,9 @@ namespace Semmle.Autobuild.CSharp
|
||||
/// <summary>
|
||||
/// Build using standalone extraction.
|
||||
/// </summary>
|
||||
internal class StandaloneBuildRule : IBuildRule
|
||||
internal class StandaloneBuildRule : IBuildRule<CSharpAutobuildOptions>
|
||||
{
|
||||
public BuildScript Analyse(Autobuilder builder, bool auto)
|
||||
public BuildScript Analyse(IAutobuilder<CSharpAutobuildOptions> builder, bool auto)
|
||||
{
|
||||
BuildScript GetCommand(string? solution)
|
||||
{
|
||||
|
||||
@@ -6,12 +6,12 @@ using System.Text.RegularExpressions;
|
||||
namespace Semmle.Autobuild.Shared
|
||||
{
|
||||
/// <summary>
|
||||
/// Encapsulates build options.
|
||||
/// Encapsulates build options shared between C# and C++.
|
||||
/// </summary>
|
||||
public class AutobuildOptions
|
||||
public abstract class AutobuildOptionsShared
|
||||
{
|
||||
private const string lgtmPrefix = "LGTM_INDEX_";
|
||||
private const string extractorOptionPrefix = "CODEQL_EXTRACTOR_CSHARP_OPTION_";
|
||||
protected const string lgtmPrefix = "LGTM_INDEX_";
|
||||
|
||||
|
||||
public int SearchDepth { get; } = 3;
|
||||
public string RootDirectory { get; }
|
||||
@@ -25,16 +25,16 @@ namespace Semmle.Autobuild.Shared
|
||||
public string? BuildCommand { get; }
|
||||
public IEnumerable<string> Solution { get; }
|
||||
public bool IgnoreErrors { get; }
|
||||
public bool Buildless { get; }
|
||||
|
||||
public bool AllSolutions { get; }
|
||||
public bool NugetRestore { get; }
|
||||
public Language Language { get; }
|
||||
public abstract Language Language { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Reads options from environment variables.
|
||||
/// Throws ArgumentOutOfRangeException for invalid arguments.
|
||||
/// </summary>
|
||||
public AutobuildOptions(IBuildActions actions, Language language)
|
||||
public AutobuildOptionsShared(IBuildActions actions)
|
||||
{
|
||||
RootDirectory = actions.GetCurrentDirectory();
|
||||
VsToolsVersion = actions.GetEnvironmentVariable(lgtmPrefix + "VSTOOLS_VERSION");
|
||||
@@ -48,12 +48,8 @@ namespace Semmle.Autobuild.Shared
|
||||
Solution = actions.GetEnvironmentVariable(lgtmPrefix + "SOLUTION").AsListWithExpandedEnvVars(actions, Array.Empty<string>());
|
||||
|
||||
IgnoreErrors = actions.GetEnvironmentVariable(lgtmPrefix + "IGNORE_ERRORS").AsBool("ignore_errors", false);
|
||||
Buildless = actions.GetEnvironmentVariable(lgtmPrefix + "BUILDLESS").AsBool("buildless", false) ||
|
||||
actions.GetEnvironmentVariable(extractorOptionPrefix + "BUILDLESS").AsBool("buildless", false);
|
||||
AllSolutions = actions.GetEnvironmentVariable(lgtmPrefix + "ALL_SOLUTIONS").AsBool("all_solutions", false);
|
||||
NugetRestore = actions.GetEnvironmentVariable(lgtmPrefix + "NUGET_RESTORE").AsBool("nuget_restore", true);
|
||||
|
||||
Language = language;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,21 +9,21 @@ namespace Semmle.Autobuild.Shared
|
||||
/// <summary>
|
||||
/// A build rule analyses the files in "builder" and outputs a build script.
|
||||
/// </summary>
|
||||
public interface IBuildRule
|
||||
public interface IBuildRule<TAutobuildOptions> where TAutobuildOptions : AutobuildOptionsShared
|
||||
{
|
||||
/// <summary>
|
||||
/// Analyse the files and produce a build script.
|
||||
/// </summary>
|
||||
/// <param name="builder">The files and options relating to the build.</param>
|
||||
/// <param name="auto">Whether this build rule is being automatically applied.</param>
|
||||
BuildScript Analyse(Autobuilder builder, bool auto);
|
||||
BuildScript Analyse(IAutobuilder<TAutobuildOptions> builder, bool auto);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A delegate used to wrap a build script in an environment where an appropriate
|
||||
/// version of .NET Core is automatically installed.
|
||||
/// </summary>
|
||||
public delegate BuildScript WithDotNet(Autobuilder builder, Func<IDictionary<string, string>?, BuildScript> f);
|
||||
public delegate BuildScript WithDotNet<TAutobuildOptions>(IAutobuilder<TAutobuildOptions> builder, Func<IDictionary<string, string>?, BuildScript> f) where TAutobuildOptions : AutobuildOptionsShared;
|
||||
|
||||
/// <summary>
|
||||
/// Exception indicating that environment variables are missing or invalid.
|
||||
@@ -33,6 +33,59 @@ namespace Semmle.Autobuild.Shared
|
||||
public InvalidEnvironmentException(string m) : base(m) { }
|
||||
}
|
||||
|
||||
public interface IAutobuilder<out TAutobuildOptions> where TAutobuildOptions : AutobuildOptionsShared
|
||||
{
|
||||
/// <summary>
|
||||
/// Full file paths of files found in the project directory, as well as
|
||||
/// their distance from the project root folder. The list is sorted
|
||||
/// by distance in ascending order.
|
||||
/// </summary>
|
||||
IEnumerable<(string, int)> Paths { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets all paths matching a particular filename, as well as
|
||||
/// their distance from the project root folder. The list is sorted
|
||||
/// by distance in ascending order.
|
||||
/// </summary>
|
||||
/// <param name="name">The filename to find.</param>
|
||||
/// <returns>Possibly empty sequence of paths with the given filename.</returns>
|
||||
IEnumerable<(string, int)> GetFilename(string name) =>
|
||||
Paths.Where(p => Actions.GetFileName(p.Item1) == name);
|
||||
|
||||
/// <summary>
|
||||
/// List of project/solution files to build.
|
||||
/// </summary>
|
||||
IList<IProjectOrSolution> ProjectsOrSolutionsToBuild { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the supplied build configuration.
|
||||
/// </summary>
|
||||
TAutobuildOptions Options { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The set of build actions used during the autobuilder.
|
||||
/// Could be real system operations, or a stub for testing.
|
||||
/// </summary>
|
||||
IBuildActions Actions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Log a given build event to the console.
|
||||
/// </summary>
|
||||
/// <param name="format">The format string.</param>
|
||||
/// <param name="args">Inserts to the format string.</param>
|
||||
void Log(Severity severity, string format, params object[] args);
|
||||
|
||||
/// <summary>
|
||||
/// Value of CODEQL_EXTRACTOR_<LANG>_ROOT environment variable.
|
||||
/// </summary>
|
||||
string? CodeQLExtractorLangRoot { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Value of CODEQL_PLATFORM environment variable.
|
||||
/// </summary>
|
||||
string? CodeQlPlatform { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Main application logic, containing all data
|
||||
/// gathered from the project and filesystem.
|
||||
@@ -40,7 +93,7 @@ namespace Semmle.Autobuild.Shared
|
||||
/// The overall design is intended to be extensible so that in theory,
|
||||
/// it should be possible to add new build rules without touching this code.
|
||||
/// </summary>
|
||||
public abstract class Autobuilder
|
||||
public abstract class Autobuilder<TAutobuildOptions> : IAutobuilder<TAutobuildOptions> where TAutobuildOptions : AutobuildOptionsShared
|
||||
{
|
||||
/// <summary>
|
||||
/// Full file paths of files found in the project directory, as well as
|
||||
@@ -60,16 +113,6 @@ namespace Semmle.Autobuild.Shared
|
||||
public IEnumerable<(string, int)> GetExtensions(params string[] extensions) =>
|
||||
Paths.Where(p => extensions.Contains(Path.GetExtension(p.Item1)));
|
||||
|
||||
/// <summary>
|
||||
/// Gets all paths matching a particular filename, as well as
|
||||
/// their distance from the project root folder. The list is sorted
|
||||
/// by distance in ascending order.
|
||||
/// </summary>
|
||||
/// <param name="name">The filename to find.</param>
|
||||
/// <returns>Possibly empty sequence of paths with the given filename.</returns>
|
||||
public IEnumerable<(string, int)> GetFilename(string name) =>
|
||||
Paths.Where(p => Actions.GetFileName(p.Item1) == name);
|
||||
|
||||
/// <summary>
|
||||
/// Holds if a given path, relative to the root of the source directory
|
||||
/// was found.
|
||||
@@ -115,7 +158,7 @@ namespace Semmle.Autobuild.Shared
|
||||
/// <summary>
|
||||
/// Gets the supplied build configuration.
|
||||
/// </summary>
|
||||
public AutobuildOptions Options { get; }
|
||||
public TAutobuildOptions Options { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The set of build actions used during the autobuilder.
|
||||
@@ -123,7 +166,7 @@ namespace Semmle.Autobuild.Shared
|
||||
/// </summary>
|
||||
public IBuildActions Actions { get; }
|
||||
|
||||
private IEnumerable<IProjectOrSolution>? FindFiles(string extension, Func<string, ProjectOrSolution> create)
|
||||
private IEnumerable<IProjectOrSolution>? FindFiles(string extension, Func<string, ProjectOrSolution<TAutobuildOptions>> create)
|
||||
{
|
||||
var matchingFiles = GetExtensions(extension)
|
||||
.Select(p => (ProjectOrSolution: create(p.Item1), DistanceFromRoot: p.Item2))
|
||||
@@ -146,7 +189,7 @@ namespace Semmle.Autobuild.Shared
|
||||
/// solution file and tools.
|
||||
/// </summary>
|
||||
/// <param name="options">The command line options.</param>
|
||||
protected Autobuilder(IBuildActions actions, AutobuildOptions options)
|
||||
protected Autobuilder(IBuildActions actions, TAutobuildOptions options)
|
||||
{
|
||||
Actions = actions;
|
||||
Options = options;
|
||||
@@ -167,7 +210,7 @@ namespace Semmle.Autobuild.Shared
|
||||
foreach (var solution in options.Solution)
|
||||
{
|
||||
if (actions.FileExists(solution))
|
||||
ret.Add(new Solution(this, solution, true));
|
||||
ret.Add(new Solution<TAutobuildOptions>(this, solution, true));
|
||||
else
|
||||
Log(Severity.Error, $"The specified project or solution file {solution} was not found");
|
||||
}
|
||||
@@ -175,17 +218,17 @@ namespace Semmle.Autobuild.Shared
|
||||
}
|
||||
|
||||
// First look for `.proj` files
|
||||
ret = FindFiles(".proj", f => new Project(this, f))?.ToList();
|
||||
ret = FindFiles(".proj", f => new Project<TAutobuildOptions>(this, f))?.ToList();
|
||||
if (ret is not null)
|
||||
return ret;
|
||||
|
||||
// Then look for `.sln` files
|
||||
ret = FindFiles(".sln", f => new Solution(this, f, false))?.ToList();
|
||||
ret = FindFiles(".sln", f => new Solution<TAutobuildOptions>(this, f, false))?.ToList();
|
||||
if (ret is not null)
|
||||
return ret;
|
||||
|
||||
// Finally look for language specific project files, e.g. `.csproj` files
|
||||
ret = FindFiles(this.Options.Language.ProjectExtension, f => new Project(this, f))?.ToList();
|
||||
ret = FindFiles(this.Options.Language.ProjectExtension, f => new Project<TAutobuildOptions>(this, f))?.ToList();
|
||||
return ret ?? new List<IProjectOrSolution>();
|
||||
});
|
||||
|
||||
|
||||
@@ -7,11 +7,11 @@ namespace Semmle.Autobuild.Shared
|
||||
/// <summary>
|
||||
/// Auto-detection of build scripts.
|
||||
/// </summary>
|
||||
public class BuildCommandAutoRule : IBuildRule
|
||||
public class BuildCommandAutoRule : IBuildRule<AutobuildOptionsShared>
|
||||
{
|
||||
private readonly WithDotNet withDotNet;
|
||||
private readonly WithDotNet<AutobuildOptionsShared> withDotNet;
|
||||
|
||||
public BuildCommandAutoRule(WithDotNet withDotNet)
|
||||
public BuildCommandAutoRule(WithDotNet<AutobuildOptionsShared> withDotNet)
|
||||
{
|
||||
this.withDotNet = withDotNet;
|
||||
}
|
||||
@@ -31,7 +31,7 @@ namespace Semmle.Autobuild.Shared
|
||||
"build"
|
||||
};
|
||||
|
||||
public BuildScript Analyse(Autobuilder builder, bool auto)
|
||||
public BuildScript Analyse(IAutobuilder<AutobuildOptionsShared> builder, bool auto)
|
||||
{
|
||||
builder.Log(Severity.Info, "Attempting to locate build script");
|
||||
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
/// <summary>
|
||||
/// Execute the build_command rule.
|
||||
/// </summary>
|
||||
public class BuildCommandRule : IBuildRule
|
||||
public class BuildCommandRule : IBuildRule<AutobuildOptionsShared>
|
||||
{
|
||||
private readonly WithDotNet withDotNet;
|
||||
private readonly WithDotNet<AutobuildOptionsShared> withDotNet;
|
||||
|
||||
public BuildCommandRule(WithDotNet withDotNet)
|
||||
public BuildCommandRule(WithDotNet<AutobuildOptionsShared> withDotNet)
|
||||
{
|
||||
this.withDotNet = withDotNet;
|
||||
}
|
||||
|
||||
public BuildScript Analyse(Autobuilder builder, bool auto)
|
||||
public BuildScript Analyse(IAutobuilder<AutobuildOptionsShared> builder, bool auto)
|
||||
{
|
||||
if (builder.Options.BuildCommand is null)
|
||||
return BuildScript.Failure;
|
||||
|
||||
@@ -6,14 +6,14 @@ namespace Semmle.Autobuild.Shared
|
||||
/// <summary>
|
||||
/// A build rule using msbuild.
|
||||
/// </summary>
|
||||
public class MsBuildRule : IBuildRule
|
||||
public class MsBuildRule : IBuildRule<AutobuildOptionsShared>
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the msbuild command.
|
||||
/// </summary>
|
||||
private const string msBuild = "msbuild";
|
||||
|
||||
public BuildScript Analyse(Autobuilder builder, bool auto)
|
||||
public BuildScript Analyse(IAutobuilder<AutobuildOptionsShared> builder, bool auto)
|
||||
{
|
||||
if (!builder.ProjectsOrSolutionsToBuild.Any())
|
||||
return BuildScript.Failure;
|
||||
@@ -27,8 +27,8 @@ namespace Semmle.Autobuild.Shared
|
||||
{
|
||||
var firstSolution = builder.ProjectsOrSolutionsToBuild.OfType<ISolution>().FirstOrDefault();
|
||||
vsTools = firstSolution is not null
|
||||
? BuildTools.FindCompatibleVcVars(builder.Actions, firstSolution)
|
||||
: BuildTools.VcVarsAllBatFiles(builder.Actions).OrderByDescending(b => b.ToolsVersion).FirstOrDefault();
|
||||
? BuildTools.FindCompatibleVcVars(builder.Actions, firstSolution)
|
||||
: BuildTools.VcVarsAllBatFiles(builder.Actions).OrderByDescending(b => b.ToolsVersion).FirstOrDefault();
|
||||
}
|
||||
|
||||
if (vsTools is null && builder.Actions.IsWindows())
|
||||
@@ -123,7 +123,7 @@ namespace Semmle.Autobuild.Shared
|
||||
///
|
||||
/// Returns <code>null</code> when no version is specified.
|
||||
/// </summary>
|
||||
public static VcVarsBatFile? GetVcVarsBatFile(Autobuilder builder)
|
||||
public static VcVarsBatFile? GetVcVarsBatFile<TAutobuildOptions>(IAutobuilder<TAutobuildOptions> builder) where TAutobuildOptions : AutobuildOptionsShared
|
||||
{
|
||||
VcVarsBatFile? vsTools = null;
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace Semmle.Autobuild.Shared
|
||||
/// <summary>
|
||||
/// Returns a script for downloading `nuget.exe` from nuget.org.
|
||||
/// </summary>
|
||||
private static BuildScript DownloadNugetExe(Autobuilder builder, string path) =>
|
||||
private static BuildScript DownloadNugetExe<TAutobuildOptions>(IAutobuilder<TAutobuildOptions> builder, string path) where TAutobuildOptions : AutobuildOptionsShared =>
|
||||
BuildScript.Create(_ =>
|
||||
{
|
||||
builder.Log(Severity.Info, "Attempting to download nuget.exe");
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Semmle.Autobuild.Shared
|
||||
/// C# project files come in 2 flavours, .Net core and msbuild, but they
|
||||
/// have the same file extension.
|
||||
/// </summary>
|
||||
public class Project : ProjectOrSolution
|
||||
public class Project<TAutobuildOptions> : ProjectOrSolution<TAutobuildOptions> where TAutobuildOptions : AutobuildOptionsShared
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds if this project is for .Net core.
|
||||
@@ -23,13 +23,13 @@ namespace Semmle.Autobuild.Shared
|
||||
|
||||
public Version ToolsVersion { get; private set; }
|
||||
|
||||
private readonly Lazy<List<Project>> includedProjectsLazy;
|
||||
private readonly Lazy<List<Project<TAutobuildOptions>>> includedProjectsLazy;
|
||||
public override IEnumerable<IProjectOrSolution> IncludedProjects => includedProjectsLazy.Value;
|
||||
|
||||
public Project(Autobuilder builder, string path) : base(builder, path)
|
||||
public Project(Autobuilder<TAutobuildOptions> builder, string path) : base(builder, path)
|
||||
{
|
||||
ToolsVersion = new Version();
|
||||
includedProjectsLazy = new Lazy<List<Project>>(() => new List<Project>());
|
||||
includedProjectsLazy = new Lazy<List<Project<TAutobuildOptions>>>(() => new List<Project<TAutobuildOptions>>());
|
||||
|
||||
if (!builder.Actions.FileExists(FullPath))
|
||||
return;
|
||||
@@ -70,9 +70,9 @@ namespace Semmle.Autobuild.Shared
|
||||
}
|
||||
}
|
||||
|
||||
includedProjectsLazy = new Lazy<List<Project>>(() =>
|
||||
includedProjectsLazy = new Lazy<List<Project<TAutobuildOptions>>>(() =>
|
||||
{
|
||||
var ret = new List<Project>();
|
||||
var ret = new List<Project<TAutobuildOptions>>();
|
||||
// The documentation on `.proj` files is very limited, but it appears that both
|
||||
// `<ProjectFile Include="X"/>` and `<ProjectFiles Include="X"/>` is valid
|
||||
var mgr = new XmlNamespaceManager(projFile.NameTable);
|
||||
@@ -89,7 +89,7 @@ namespace Semmle.Autobuild.Shared
|
||||
}
|
||||
|
||||
var includePath = builder.Actions.PathCombine(include.Value.Split('\\', StringSplitOptions.RemoveEmptyEntries));
|
||||
ret.Add(new Project(builder, builder.Actions.PathCombine(DirectoryName, includePath)));
|
||||
ret.Add(new Project<TAutobuildOptions>(builder, builder.Actions.PathCombine(DirectoryName, includePath)));
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
|
||||
@@ -20,13 +20,13 @@ namespace Semmle.Autobuild.Shared
|
||||
IEnumerable<IProjectOrSolution> IncludedProjects { get; }
|
||||
}
|
||||
|
||||
public abstract class ProjectOrSolution : IProjectOrSolution
|
||||
public abstract class ProjectOrSolution<TAutobuildOptions> : IProjectOrSolution where TAutobuildOptions : AutobuildOptionsShared
|
||||
{
|
||||
public string FullPath { get; }
|
||||
|
||||
public string DirectoryName { get; }
|
||||
|
||||
protected ProjectOrSolution(Autobuilder builder, string path)
|
||||
protected ProjectOrSolution(Autobuilder<TAutobuildOptions> builder, string path)
|
||||
{
|
||||
FullPath = builder.Actions.GetFullPath(path);
|
||||
DirectoryName = builder.Actions.GetDirectoryName(path) ?? "";
|
||||
|
||||
@@ -40,11 +40,11 @@ namespace Semmle.Autobuild.Shared
|
||||
/// <summary>
|
||||
/// A solution file on the filesystem, read using Microsoft.Build.
|
||||
/// </summary>
|
||||
internal class Solution : ProjectOrSolution, ISolution
|
||||
internal class Solution<TAutobuildOptions> : ProjectOrSolution<TAutobuildOptions>, ISolution where TAutobuildOptions : AutobuildOptionsShared
|
||||
{
|
||||
private readonly SolutionFile? solution;
|
||||
|
||||
private readonly IEnumerable<Project> includedProjects;
|
||||
private readonly IEnumerable<Project<TAutobuildOptions>> includedProjects;
|
||||
|
||||
public override IEnumerable<IProjectOrSolution> IncludedProjects => includedProjects;
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Semmle.Autobuild.Shared
|
||||
public string DefaultPlatformName =>
|
||||
solution is null ? "" : solution.GetDefaultPlatformName();
|
||||
|
||||
public Solution(Autobuilder builder, string path, bool allowProject) : base(builder, path)
|
||||
public Solution(Autobuilder<TAutobuildOptions> builder, string path, bool allowProject) : base(builder, path)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -69,19 +69,19 @@ namespace Semmle.Autobuild.Shared
|
||||
// that scenario as a solution with just that one project
|
||||
if (allowProject)
|
||||
{
|
||||
includedProjects = new[] { new Project(builder, path) };
|
||||
includedProjects = new[] { new Project<TAutobuildOptions>(builder, path) };
|
||||
return;
|
||||
}
|
||||
|
||||
builder.Log(Severity.Info, $"Unable to read solution file {path}.");
|
||||
includedProjects = Array.Empty<Project>();
|
||||
includedProjects = Array.Empty<Project<TAutobuildOptions>>();
|
||||
return;
|
||||
}
|
||||
|
||||
includedProjects = solution.ProjectsInOrder
|
||||
.Where(p => p.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat)
|
||||
.Select(p => builder.Actions.PathCombine(DirectoryName, builder.Actions.PathCombine(p.RelativePath.Split('\\', StringSplitOptions.RemoveEmptyEntries))))
|
||||
.Select(p => new Project(builder, p))
|
||||
.Select(p => new Project<TAutobuildOptions>(builder, p))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user