using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Semmle.Util;
namespace Semmle.Autobuild.Shared
{
///
/// Encapsulates build options shared between C# and C++.
///
public abstract class AutobuildOptionsShared
{
public int SearchDepth { get; } = 3;
public string RootDirectory { get; }
public string? DotNetVersion { get; }
public abstract Language Language { get; }
///
/// Reads options from environment variables.
/// Throws ArgumentOutOfRangeException for invalid arguments.
///
public AutobuildOptionsShared(IBuildActions actions)
{
RootDirectory = actions.GetCurrentDirectory();
DotNetVersion = actions.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_OPTION_DOTNET_VERSION");
}
}
public static class OptionsExtensions
{
public static bool AsBool(this string? value, string param, bool defaultValue)
{
if (value is null)
return defaultValue;
return value.ToLower() switch
{
"on" or "yes" or "true" or "enabled" => true,
"off" or "no" or "false" or "disabled" => false,
_ => throw new ArgumentOutOfRangeException(param, value, "The Boolean value is invalid."),
};
}
public static string[] AsListWithExpandedEnvVars(this string? value, IBuildActions actions, string[] defaultValue)
{
if (value is null)
return defaultValue;
return value.
Split(FileUtils.NewLineCharacters, StringSplitOptions.RemoveEmptyEntries).
Select(s => AsStringWithExpandedEnvVars(s, actions)).ToArray();
}
private static readonly Regex linuxEnvRegEx = new Regex(@"\$([a-zA-Z_][a-zA-Z_0-9]*)", RegexOptions.Compiled);
public static string AsStringWithExpandedEnvVars(this string value, IBuildActions actions)
{
if (string.IsNullOrEmpty(value))
return value;
// `Environment.ExpandEnvironmentVariables` only works with Windows-style
// environment variables
var windowsStyle = actions.IsWindows()
? value
: linuxEnvRegEx.Replace(value, m => $"%{m.Groups[1].Value}%");
return actions.EnvironmentExpandEnvironmentVariables(windowsStyle);
}
}
}