Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component Detection v5 Major Version [DO NOT MERGE] #1141

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
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
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json",
"name": "Component Detection",
"image": "mcr.microsoft.com/vscode/devcontainers/dotnet:6.0",
"image": "mcr.microsoft.com/vscode/devcontainers/dotnet:8.0",
"runArgs": ["--init"],
"extensions": [
"eamodio.gitlens",
Expand Down
19 changes: 19 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,25 @@ dotnet_diagnostic.CA1848.severity = suggestion
# JSON002: Probable JSON string detected
dotnet_diagnostic.JSON002.severity = suggestion

# IDE0290: Use primary constructor
dotnet_diagnostic.IDE0290.severity = suggestion

# IDE0305: Simplify collection initialization
dotnet_diagnostic.IDE0305.severity = suggestion

# SYSLIB1045: Convert to 'GeneratedRegexAttribute'.
dotnet_diagnostic.SYSLIB1045.severity = suggestion

# CA1859: Use concrete types when possible for improved performance
dotnet_diagnostic.CA1859.severity = suggestion

# CA1851: Possible multiple enumerations of 'IEnumerable' collection
dotnet_diagnostic.CA1851.severity = suggestion

# CA1861: Avoid constant arrays as arguments
dotnet_diagnostic.CA1861.severity = suggestion


# Workaround for https://github.com/dotnet/roslyn-analyzers/issues/5628
[Program.cs]
dotnet_diagnostic.ca1812.severity = none
20 changes: 14 additions & 6 deletions .github/workflows/smoke-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
{ name: "Go", repo: "kubernetes/kubernetes" },
{ name: "Maven", repo: "apache/kafka" },
{ name: "NPM", repo: "axios/axios" },
{ name: "NuGet", repo: "Radarr/Radarr" },
{ name: "NuGet", repo: "dotnet/aspire" },
{ name: "Pip", repo: "django/django" },
{ name: "Pnpm", repo: "pnpm/pnpm" },
{ name: "Poetry", repo: "Textualize/rich" },
Expand All @@ -41,9 +41,6 @@ jobs:
- name: Checkout Component Detection
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6

- name: Setup .NET
uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4.0.0

- name: Install Apache Ivy
run: curl https://downloads.apache.org/ant/ivy/2.5.2/apache-ivy-2.5.2-bin.tar.gz | tar xOz apache-ivy-2.5.2/ivy-2.5.2.jar > /usr/share/ant/lib/ivy.jar

Expand All @@ -53,10 +50,21 @@ jobs:
repository: ${{ matrix.language.repo }}
path: smoke-test-repo

- name: Setup .NET
uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4.0.0
with:
dotnet-version: '8.0.x'

- name: Setup Python
uses: actions/setup-python@v5
if: ${{ matrix.language.name == 'Pip'}}
with:
python-version: '3.10'

- name: Restore Smoke Test NuGet Packages
if: ${{ matrix.language.name == 'NuGet'}}
working-directory: smoke-test-repo/src
run: dotnet restore
working-directory: smoke-test-repo
run: dotnet restore Aspire.sln

- name: Run Smoke Test
working-directory: src/Microsoft.ComponentDetection
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>

<PropertyGroup Label="Build">
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
Expand Down
30 changes: 15 additions & 15 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
</ItemDefinitionGroup>
<ItemGroup>
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
<PackageVersion Include="coverlet.collector" Version="6.0.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.2" />
<PackageVersion Include="Docker.DotNet" Version="3.125.15" />
<PackageVersion Include="FluentAssertions" Version="6.12.0" />
<PackageVersion Include="FluentAssertions.Analyzers" Version="0.26.0" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="7.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageVersion Include="FluentAssertions.Analyzers" Version="0.32.0" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.8.14" />
<PackageVersion Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.10.48" />
<PackageVersion Include="DotNet.Glob" Version="2.1.1" />
<PackageVersion Include="MinVer" Version="5.0.0" />
<PackageVersion Include="Moq" Version="4.18.4" />
Expand All @@ -34,21 +34,21 @@
<PackageVersion Include="Polly" Version="8.4.0" />
<PackageVersion Include="SemanticVersioning" Version="2.0.2" />
<PackageVersion Include="Serilog" Version="3.1.1" />
<PackageVersion Include="Serilog.Extensions.Logging" Version="7.0.0" />
<PackageVersion Include="Serilog.Extensions.Logging" Version="8.0.0" />
<PackageVersion Include="Serilog.Sinks.Async" Version="1.5.0" />
<PackageVersion Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageVersion Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageVersion Include="Serilog.Sinks.Map" Version="1.0.2" />
<PackageVersion Include="Spectre.Console" Version="0.48.0" />
<PackageVersion Include="Spectre.Console.Cli" Version="0.48.0" />
<PackageVersion Include="Spectre.Console" Version="0.49.1" />
<PackageVersion Include="Spectre.Console.Cli" Version="0.49.1" />
<PackageVersion Include="Spectre.Console.Cli.Extensions.DependencyInjection" Version="0.2.0" />
<PackageVersion Include="Spectre.Console.Testing" Version="0.48.0" />
<PackageVersion Include="Spectre.Console.Testing" Version="0.49.1" />
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
<PackageVersion Include="System.Memory" Version="4.5.5" />
<PackageVersion Include="System.Reactive" Version="6.0.0" />
<PackageVersion Include="System.Reactive" Version="6.0.1" />
<PackageVersion Include="System.Runtime.Loader" Version="4.3.0" />
<PackageVersion Include="System.Text.Json" Version="6.0.9" />
<PackageVersion Include="System.Threading.Tasks.Dataflow" Version="7.0.0" />
<PackageVersion Include="System.Text.Json" Version="8.0.3" />
<PackageVersion Include="System.Threading.Tasks.Dataflow" Version="8.0.0" />
<PackageVersion Include="Tomlyn.Signed" Version="0.17.0" />
<PackageVersion Include="yamldotnet" Version="15.1.6" />
<PackageVersion Include="Faker.net" Version="2.0.163" />
Expand Down
2 changes: 1 addition & 1 deletion docs/detector-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ dotnet run --project "src\Microsoft.ComponentDetection\Microsoft.ComponentDetect
```

--DirectoryExclusionList Filters out specific directories following a
minimatch pattern.
semicolon separated list of minimatch patterns.

--IgnoreDirectories Filters out specific directories, providing
individual directory paths separated by semicolon.
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "6.0.422",
"version": "8.0.300",
"rollForward": "latestMinor"
}
}
10 changes: 2 additions & 8 deletions src/Microsoft.ComponentDetection.Common/AsyncExecution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ public static class AsyncExecution
/// <exception cref="TimeoutException">Thrown when the execution does not complete within the timeout.</exception>
public static async Task<T> ExecuteWithTimeoutAsync<T>(Func<Task<T>> toExecute, TimeSpan timeout, CancellationToken cancellationToken)
{
if (toExecute == null)
{
throw new ArgumentNullException(nameof(toExecute));
}
ArgumentNullException.ThrowIfNull(toExecute);

var work = Task.Run(toExecute);

Expand All @@ -48,10 +45,7 @@ public static async Task<T> ExecuteWithTimeoutAsync<T>(Func<Task<T>> toExecute,
/// <exception cref="TimeoutException">Thrown when the execution does not complete within the timeout.</exception>
public static async Task ExecuteVoidWithTimeoutAsync(Action toExecute, TimeSpan timeout, CancellationToken cancellationToken)
{
if (toExecute == null)
{
throw new ArgumentNullException(nameof(toExecute));
}
ArgumentNullException.ThrowIfNull(toExecute);

var work = Task.Run(toExecute, cancellationToken);
var completedInTime = await Task.Run(() => work.Wait(timeout));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ public class CommandLineInvocationService : ICommandLineInvocationService
/// <inheritdoc/>
public async Task<bool> CanCommandBeLocatedAsync(string command, IEnumerable<string> additionalCandidateCommands = null, DirectoryInfo workingDirectory = null, params string[] parameters)
{
additionalCandidateCommands ??= Enumerable.Empty<string>();
parameters ??= Array.Empty<string>();
additionalCandidateCommands ??= [];
parameters ??= [];
var allCommands = new[] { command }.Concat(additionalCandidateCommands);
if (!this.commandLocatableCache.TryGetValue(command, out var validCommand))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ IEnumerator IEnumerable.GetEnumerator()
return this.GetEnumerator();
}

private Stream SafeOpenFile(FileInfo file)
private FileStream SafeOpenFile(FileInfo file)
{
try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

public class ComponentRecorder : IComponentRecorder
{
private readonly ConcurrentBag<SingleFileComponentRecorder> singleFileRecorders = new ConcurrentBag<SingleFileComponentRecorder>();
private readonly ConcurrentBag<SingleFileComponentRecorder> singleFileRecorders = [];

private readonly bool enableManualTrackingOfExplicitReferences;

Expand All @@ -38,7 +38,7 @@
IEnumerable<DetectedComponent> detectedComponents;
if (this.singleFileRecorders == null)
{
return Enumerable.Empty<DetectedComponent>();
return [];

Check warning on line 41 in src/Microsoft.ComponentDetection.Common/DependencyGraph/ComponentRecorder.cs

View check run for this annotation

Codecov / codecov/patch

src/Microsoft.ComponentDetection.Common/DependencyGraph/ComponentRecorder.cs#L41

Added line #L41 was not covered by tests
}

detectedComponents = this.singleFileRecorders
Expand Down Expand Up @@ -68,7 +68,7 @@
{
if (this.singleFileRecorders == null)
{
return Enumerable.Empty<string>();
return [];

Check warning on line 71 in src/Microsoft.ComponentDetection.Common/DependencyGraph/ComponentRecorder.cs

View check run for this annotation

Codecov / codecov/patch

src/Microsoft.ComponentDetection.Common/DependencyGraph/ComponentRecorder.cs#L71

Added line #L71 was not covered by tests
}

return this.singleFileRecorders
Expand Down Expand Up @@ -162,18 +162,15 @@
bool? isDevelopmentDependency = null,
DependencyScope? dependencyScope = null)
{
if (detectedComponent == null)
{
throw new ArgumentNullException(paramName: nameof(detectedComponent));
}
ArgumentNullException.ThrowIfNull(detectedComponent);

if (detectedComponent.Component == null)
{
throw new ArgumentException(Resources.MissingComponentId);
}

#if DEBUG
if (detectedComponent.DependencyRoots?.Any() ?? false)
if (detectedComponent.DependencyRoots?.Count == 0)
{
this.logger.LogWarning("Detector should not populate DetectedComponent.DependencyRoots!");
}
Expand All @@ -195,10 +192,7 @@

public void RegisterPackageParseFailure(string skippedComponent)
{
if (skippedComponent == null)
{
throw new ArgumentNullException(paramName: nameof(skippedComponent));
}
ArgumentNullException.ThrowIfNull(skippedComponent);

_ = this.skippedComponentsInternal[skippedComponent] = default;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections.Immutable;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using Microsoft.ComponentDetection.Contracts;
using Microsoft.ComponentDetection.Contracts.BcdeModels;

Expand All @@ -13,6 +14,8 @@ namespace Microsoft.ComponentDetection.Common.DependencyGraph;

internal class DependencyGraph : IDependencyGraph
{
private static readonly CompositeFormat MissingNodeFormat = CompositeFormat.Parse(Resources.MissingNodeInDependencyGraph);

private readonly ConcurrentDictionary<string, ComponentRefNode> componentNodes;

private readonly bool enableManualTrackingOfExplicitReferences;
Expand All @@ -27,14 +30,11 @@ public DependencyGraph(bool enableManualTrackingOfExplicitReferences)

public void AddComponent(ComponentRefNode componentNode, string parentComponentId = null)
{
if (componentNode == null)
{
throw new ArgumentNullException(nameof(componentNode));
}
ArgumentNullException.ThrowIfNull(componentNode);

if (string.IsNullOrWhiteSpace(componentNode.Id))
{
throw new ArgumentNullException(nameof(componentNode.Id), "Invalid component node id");
throw new ArgumentNullException(nameof(componentNode), "Invalid component node id");
}

this.componentNodes.AddOrUpdate(componentNode.Id, componentNode, (key, currentNode) =>
Expand Down Expand Up @@ -77,10 +77,10 @@ public ICollection<string> GetExplicitReferencedDependencyIds(string componentId

if (!this.componentNodes.TryGetValue(componentId, out var componentRef))
{
throw new ArgumentException(string.Format(Resources.MissingNodeInDependencyGraph, componentId), paramName: nameof(componentId));
throw new ArgumentException(string.Format(null, MissingNodeFormat, componentId), paramName: nameof(componentId));
}

IList<string> explicitReferencedDependencyIds = new List<string>();
IList<string> explicitReferencedDependencyIds = [];

this.GetExplicitReferencedDependencies(componentRef, explicitReferencedDependencyIds, new HashSet<string>());

Expand All @@ -97,7 +97,7 @@ public void AddAdditionalRelatedFile(string additionalRelatedFile)

public HashSet<string> GetAdditionalRelatedFiles()
{
return this.AdditionalRelatedFiles.Keys.ToImmutableHashSet().ToHashSet();
return [.. this.AdditionalRelatedFiles.Keys];
}

public bool HasComponents()
Expand Down Expand Up @@ -129,7 +129,7 @@ public ICollection<string> GetAncestors(string componentId)
if (!this.componentNodes.TryGetValue(componentId, out var componentRef))
{
// this component isn't in the graph, so it has no ancestors
return new List<string>();
return [];
}

// store the component id and the depth we found it at
Expand Down Expand Up @@ -189,7 +189,7 @@ private void AddDependency(string componentId, string parentComponentId)

if (!this.componentNodes.TryGetValue(parentComponentId, out var parentComponentRefNode))
{
throw new ArgumentException(string.Format(Resources.MissingNodeInDependencyGraph, parentComponentId), nameof(parentComponentId));
throw new ArgumentException(string.Format(null, MissingNodeFormat, parentComponentId), nameof(parentComponentId));
}

parentComponentRefNode.DependencyIds.Add(componentId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public static DockerReference ParseFamiliarName(string name)
remoteName = remainder;
}

if (remoteName.ToLower() != remoteName)
if (!remoteName.ToLower().Equals(remoteName))
{
throw new ReferenceNameContainsUppercaseException(name);
}
Expand Down
20 changes: 10 additions & 10 deletions src/Microsoft.ComponentDetection.Common/DockerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ public async Task<ContainerDetails> InspectImageAsync(string image, Cancellation
CreatedAt = imageInspectResponse.Created,
BaseImageDigest = baseImageDigest,
BaseImageRef = baseImageRef,
Layers = layers ?? Enumerable.Empty<DockerLayer>(),
Layers = layers ?? [],
};
}
catch (Exception e)
Expand Down Expand Up @@ -188,19 +188,19 @@ private static async Task<CreateContainerResponse> CreateContainerAsync(
NetworkDisabled = true,
HostConfig = new HostConfig
{
CapDrop = new List<string>
{
CapDrop =
[
"all",
},
SecurityOpt = new List<string>
{
],
SecurityOpt =
[
"no-new-privileges",
},
Binds = new List<string>
{
],
Binds =
[
$"{Path.GetTempPath()}:/tmp",
"/var/run/docker.sock:/var/run/docker.sock",
},
],
},
};
return await Client.Containers.CreateContainerAsync(parameters, cancellationToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public string GetEnvironmentVariable(string name)
}

public List<string> GetListEnvironmentVariable(string name, string delimiter)
=> (this.GetEnvironmentVariable(name) ?? string.Empty).Split(delimiter, StringSplitOptions.RemoveEmptyEntries).ToList();
=> [.. (this.GetEnvironmentVariable(name) ?? string.Empty).Split(delimiter, StringSplitOptions.RemoveEmptyEntries)];

public bool IsEnvironmentVariableValueTrue(string name)
{
Expand Down
Loading