Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ IEnumerable<string> IBuildActions.EnumerateDirectories(string dir)

bool IBuildActions.IsMacOs() => IsMacOs;

public bool IsLinux { get; set; }

bool IBuildActions.IsLinux() => IsLinux;

public bool IsRunningOnAppleSilicon { get; set; }

bool IBuildActions.IsRunningOnAppleSilicon() => IsRunningOnAppleSilicon;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ IEnumerable<string> IBuildActions.EnumerateDirectories(string dir)

bool IBuildActions.IsMacOs() => IsMacOs;

public bool IsLinux { get; set; }

bool IBuildActions.IsLinux() => IsLinux;

public bool IsRunningOnAppleSilicon { get; set; }

bool IBuildActions.IsRunningOnAppleSilicon() => IsRunningOnAppleSilicon;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,43 @@ private IEnumerable<string> GetFeeds(Func<IList<string>> getNugetFeeds)
private (HashSet<string> explicitFeeds, HashSet<string> allFeeds) GetAllFeeds()
{
var nugetConfigs = fileProvider.NugetConfigs;

// On systems with case-sensitive file systems (for simplicity, we assume that is Linux), the
// filenames of NuGet configuration files must be named correctly. For compatibility with projects
// that are typically built on Windows or macOS where this doesn't matter, we accept all variants
// of `nuget.config` ourselves. However, `dotnet` does not. If we detect that incorrectly-named
// files are present, we emit a diagnostic to warn the user.
if (SystemBuildActions.Instance.IsLinux())
{
string[] acceptedNugetConfigNames = ["nuget.config", "NuGet.config", "NuGet.Config"];
var invalidNugetConfigs = nugetConfigs
.Where(path => !acceptedNugetConfigNames.Contains(Path.GetFileName(path)));

if (invalidNugetConfigs.Count() > 0)
{
this.logger.LogWarning(string.Format(
"Found incorrectly named NuGet configuration files: {0}",
string.Join(", ", invalidNugetConfigs)
));
this.diagnosticsWriter.AddEntry(new DiagnosticMessage(
Language.CSharp,
"buildless/case-sensitive-nuget-config",
"Found NuGet configuration files which are not correctly named",
visibility: new DiagnosticMessage.TspVisibility(statusPage: true, cliSummaryTable: true, telemetry: true),
markdownMessage: string.Format(
"On platforms with case-sensitive file systems, NuGet only accepts files with one of the following names: {0}.\n\n" +
"CodeQL found the following files while performing an analysis on a platform with a case-sensitive file system:\n\n" +
"{1}\n\n" +
"To avoid unexpected results, rename these files to match the casing of one of the accepted filenames.",
string.Join(", ", acceptedNugetConfigNames),
string.Join("\n", invalidNugetConfigs.Select(path => string.Format("- `{0}`", path)))
),
severity: DiagnosticMessage.TspSeverity.Warning
));
}
}

// Find feeds that are explicitly configured in the NuGet configuration files that we found.
var explicitFeeds = nugetConfigs
.SelectMany(config => GetFeeds(() => dotnet.GetNugetFeeds(config)))
.ToHashSet();
Expand Down Expand Up @@ -849,6 +886,14 @@ private IEnumerable<string> GetFeeds(Func<IList<string>> getNugetFeeds)
.Where(folder => folder != null)
.SelectMany(folder => GetFeeds(() => dotnet.GetNugetFeedsFromFolder(folder!)))
.ToHashSet();

// If we have discovered any explicit feeds, then we also expect these to be in the set of all feeds.
// Normally, it is a safe assumption to make that `GetNugetFeedsFromFolder` will include the feeds configured
// in a NuGet configuration file in the given directory. There is one exception: on a system with case-sensitive
// file systems, we may discover a configuration file such as `Nuget.Config` which is not recognised by `dotnet nuget`.
// In that case, our call to `GetNugetFeeds` will retrieve the feeds from that file (because it is accepted when
// provided explicitly as `--configfile` argument), but the call to `GetNugetFeedsFromFolder` will not.
allFeeds.UnionWith(explicitFeeds);
}
else
{
Expand Down
8 changes: 8 additions & 0 deletions csharp/extractor/Semmle.Util/BuildActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ public interface IBuildActions
/// <returns>True if we are running on macOS.</returns>
bool IsMacOs();

/// <summary>
/// Gets a value indicating whether we are running on Linux.
/// </summary>
/// <returns>True if we are running on Linux.</returns>
bool IsLinux();

/// <summary>
/// Gets a value indicating whether we are running on Apple Silicon.
/// </summary>
Expand Down Expand Up @@ -246,6 +252,8 @@ int IBuildActions.RunProcess(string cmd, string args, string? workingDirectory,

bool IBuildActions.IsMacOs() => RuntimeInformation.IsOSPlatform(OSPlatform.OSX);

bool IBuildActions.IsLinux() => RuntimeInformation.IsOSPlatform(OSPlatform.Linux);

bool IBuildActions.IsRunningOnAppleSilicon()
{
var thisBuildActions = (IBuildActions)this;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Program
{
static void Main(string[] args)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"markdownMessage": "C# analysis with build-mode 'none' completed.",
"severity": "unknown",
"source": {
"extractorName": "csharp",
"id": "csharp/autobuilder/buildless/complete",
"name": "C# analysis with build-mode 'none' completed"
},
"visibility": {
"cliSummaryTable": true,
"statusPage": false,
"telemetry": true
}
}
{
"markdownMessage": "C# was extracted with build-mode set to 'none'. This means that all C# source in the working directory will be scanned, with build tools, such as NuGet and dotnet CLIs, only contributing information about external dependencies.",
"severity": "note",
"source": {
"extractorName": "csharp",
"id": "csharp/autobuilder/buildless/mode-active",
"name": "C# was extracted with build-mode set to 'none'"
},
"visibility": {
"cliSummaryTable": true,
"statusPage": true,
"telemetry": true
}
}
{
"markdownMessage": "On platforms with case-sensitive file systems, NuGet only accepts files with one of the following names: nuget.config, NuGet.config, NuGet.Config.\n\nCodeQL found the following files while performing an analysis on a platform with a case-sensitive file system:\n\n- `<test-root-directory>/sub-project/Nuget.Config`\n\nTo avoid unexpected results, rename these files to match the casing of one of the accepted filenames.",
"severity": "warning",
"source": {
"extractorName": "csharp",
"id": "csharp/autobuilder/buildless/case-sensitive-nuget-config",
"name": "Found NuGet configuration files which are not correctly named"
},
"visibility": {
"cliSummaryTable": true,
"statusPage": true,
"telemetry": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"sdk": {
"version": "10.0.100"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
</packageSources>
</configuration>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import runs_on

@runs_on.linux
def test(codeql, csharp):
codeql.database.create(build_mode="none")