Skip to content

Commit 1efb54e

Browse files
authored
Merge branch 'main' into users/ferojo/alignVerification
2 parents c48ff65 + 9f24dfc commit 1efb54e

File tree

66 files changed

+5858
-605
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+5858
-605
lines changed

docs/detectors/nuget.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ NuGet Detection is performed by parsing any `*.nuspec`, `*.nupkg`, `*.packages.c
2020

2121
## Known Limitations
2222

23-
- The NuGet detector is currently overreporting because the global NuGet cache gets searched. This is because of NuGet's [restore behaviour][4] which downloads all possible dependencies before [resolving the final dependency graph][5]. To solve this overreporting a new NuGet Detector approach will be rolled out. This new approach will now only parse `*.packages.config` and `*.project.assets` (`*.csproj`) files. This means any components that are only found in `*.nuspec` or `*.nupkg` files will not be detected with the new NuGet Detector approach.
24-
- There are also dependencies from the .NET SDK that are underreported. The list of dependencies can be found [here][6].
23+
- Any components that are only found in `*.nuspec` or `*.nupkg` files will not be detected with the latest NuGet Detector approach, because the NuGet detector that scans `*.nuspec` or `*.nupkg` files overreports. This is due to of NuGet's [restore behaviour][4] which downloads all possible dependencies before [resolving the final dependency graph][5].
24+
- Dependencies from the .NET SDK that are underreported. The list of dependencies can be found [here][6].
2525

2626
[4]: https://learn.microsoft.com/en-us/nuget/consume-packages/package-restore#package-restore-behavior
2727
[5]: https://learn.microsoft.com/en-us/nuget/concepts/dependency-resolution

docs/update-syft.md

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,40 @@ To do this:
1212
```
1313
1414
2. Find the [latest version of Syft][2]
15-
3. Install [Skopeo][3]
16-
4. Use [`skopeo`][4] to copy the manifest and images to our Azure Container Registry:
15+
3. Pull the latest container image
1716
1817
```
19-
skopeo copy --all docker://docker.io/anchore/syft:{LATEST} docker://governancecontainerregistry.azurecr.io/syft:{LATEST}
18+
$ docker pull docker.io/anchore/syft:v{LATEST}
19+
v0.53.4: Pulling from anchore/syft
20+
0d60d5ab2113: Pull complete
21+
26136f3e3dd3: Pull complete
22+
497aa7f04842: Pull complete
23+
Digest: sha256:37e85e8efdeaabb1b6f65c5bc175b664cb05d1aaddd0d922130b8e25d6e49726
24+
Status: Downloaded newer image for anchore/syft:v{LATEST}
25+
docker.io/anchore/syft:v{LATEST}
2026
```
2127
22-
5. Update the container reference in [`LinuxScanner`][5]
23-
6. Update [the models][6] that map the Syft output
28+
4. Retag the container image
29+
30+
```
31+
$ docker tag docker.io/anchore/syft:v{LATEST} governancecontainerregistry.azurecr.io/syft:v{LATEST}
32+
```
33+
34+
5. Push the new image to the registry
35+
36+
```
37+
$ docker push governancecontainerregistry.azurecr.io/syft:v{LATEST}
38+
The push refers to repository [governancecontainerregistry.azurecr.io/syft]
39+
9c858c120b14: Pushed
40+
840f3b941d62: Pushed
41+
21ce82bb7448: Pushed
42+
v{LATEST}: digest: sha256:04ed9c717a814fdccf52758b67333632a0ff16840fc393f5fba5864285eaebbe size: 945
43+
```
44+
45+
6. Update the container reference in [`LinuxScanner`][3]
46+
7. Update [the models][4] that map the Syft output
2447
2548
[1]: https://github.com/anchore/syft
2649
[2]: https://github.com/anchore/syft/releases/latest
27-
[3]: https://github.com/containers/skopeo/blob/main/install.md
28-
[4]: https://github.com/containers/skopeo
29-
[5]: https://github.com/microsoft/component-detection/blob/aaf865e38112fb2448f5866ab06d5898358403f6/src/Microsoft.ComponentDetection.Detectors/linux/LinuxScanner.cs#L20
30-
[6]: https://github.com/microsoft/component-detection/blob/main/src/Microsoft.ComponentDetection.Detectors/linux/Contracts/SyftOutput.cs
50+
[3]: https://github.com/microsoft/component-detection/blob/aaf865e38112fb2448f5866ab06d5898358403f6/src/Microsoft.ComponentDetection.Detectors/linux/LinuxScanner.cs#L20
51+
[4]: https://github.com/microsoft/component-detection/blob/main/src/Microsoft.ComponentDetection.Detectors/linux/Contracts/SyftOutput.cs

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ public void RegisterUsage(
160160
bool isExplicitReferencedDependency = false,
161161
string parentComponentId = null,
162162
bool? isDevelopmentDependency = null,
163-
DependencyScope? dependencyScope = null)
163+
DependencyScope? dependencyScope = null,
164+
string targetFramework = null)
164165
{
165166
ArgumentNullException.ThrowIfNull(detectedComponent);
166167

@@ -186,6 +187,12 @@ public void RegisterUsage(
186187
lock (this.registerUsageLock)
187188
{
188189
storedComponent = this.detectedComponentsInternal.GetOrAdd(componentId, detectedComponent);
190+
191+
if (!string.IsNullOrWhiteSpace(targetFramework))
192+
{
193+
storedComponent.TargetFrameworks.Add(targetFramework.Trim());
194+
}
195+
189196
this.AddComponentToGraph(this.ManifestFileLocation, detectedComponent, isExplicitReferencedDependency, parentComponentId, isDevelopmentDependency, dependencyScope);
190197
}
191198
}

src/Microsoft.ComponentDetection.Contracts/BcdeModels/ScannedComponent.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,6 @@ public class ScannedComponent
2626
public IEnumerable<int> ContainerDetailIds { get; set; }
2727

2828
public IDictionary<int, IEnumerable<int>> ContainerLayerIds { get; set; }
29+
30+
public ISet<string> TargetFrameworks { get; set; }
2931
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
namespace Microsoft.ComponentDetection.Contracts;
2+
3+
using System.Collections;
4+
using System.Collections.Concurrent;
5+
using System.Collections.Generic;
6+
7+
/// <summary>Represents a thread-safe set of values.</summary>
8+
/// <typeparam name="T">The type of elements in the hash set.</typeparam>
9+
public class ConcurrentHashSet<T> : IEnumerable<T>
10+
{
11+
private readonly ConcurrentDictionary<T, byte> dictionary;
12+
13+
// Create different constructors for different equality comparers
14+
public ConcurrentHashSet() => this.dictionary = new ConcurrentDictionary<T, byte>();
15+
16+
public ConcurrentHashSet(IEqualityComparer<T> comparer) => this.dictionary = new ConcurrentDictionary<T, byte>(comparer);
17+
18+
/// <summary>Adds the specific element to the <see cref="ConcurrentHashSet{T}"/> object.</summary>
19+
/// <param name="item">The element to add to the set.</param>
20+
/// <returns>true if element was added to <see cref="ConcurrentHashSet{T}"/> object; false, if item was already present.</returns>
21+
public bool Add(T item)
22+
{
23+
return this.dictionary.TryAdd(item, 0);
24+
}
25+
26+
/// <summary>Removes the specific element to the <see cref="ConcurrentHashSet{T}"/> object.</summary>
27+
/// <param name="item">The element to be removed from the set.</param>
28+
/// <returns>true if element was successfully found and removed; otherwise, false.</returns>
29+
public bool Remove(T item)
30+
{
31+
return this.dictionary.TryRemove(item, out _);
32+
}
33+
34+
/// <summary>Determines whether the <see cref="ConcurrentHashSet{T}"/> contains the specified element.</summary>
35+
/// <param name="item">The element to locate in the <see cref="ConcurrentHashSet{T}"/> object.</param>
36+
/// <returns>true if the <see cref="ConcurrentHashSet{T}"/> object contains the specified element; otherwise, false.</returns>
37+
public bool Contains(T item)
38+
{
39+
return this.dictionary.ContainsKey(item);
40+
}
41+
42+
/// <summary>Removes all elements from a <see cref="ConcurrentHashSet{T}"/> object.</summary>
43+
public void Clear() => this.dictionary.Clear();
44+
45+
public ISet<T> ToHashSet()
46+
{
47+
return new HashSet<T>(this.dictionary.Keys);
48+
}
49+
50+
/// <summary>Returns an enumerator that iterates through the <see cref="ConcurrentHashSet{T}"/>.</summary>
51+
/// <returns>An enumerator for the <see cref="ConcurrentHashSet{T}"/>.</returns>
52+
public IEnumerator<T> GetEnumerator()
53+
{
54+
return this.dictionary.Keys.GetEnumerator();
55+
}
56+
57+
/// <summary>Returns an enumerator that iterates through the <see cref="ConcurrentHashSet{T}"/>.</summary>
58+
/// <returns>An enumerator for the <see cref="ConcurrentHashSet{T}"/>.</returns>
59+
IEnumerator IEnumerable.GetEnumerator()
60+
{
61+
return this.GetEnumerator();
62+
}
63+
}

src/Microsoft.ComponentDetection.Contracts/DetectedComponent.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ public DetectedComponent(TypedComponent.TypedComponent component, IComponentDete
2222
this.DetectedBy = detector;
2323
this.ContainerDetailIds = [];
2424
this.ContainerLayerIds = new Dictionary<int, IEnumerable<int>>();
25+
this.TargetFrameworks = [];
26+
2527
if (containerDetailsId.HasValue)
2628
{
2729
this.ContainerDetailIds.Add(containerDetailsId.Value);
@@ -62,6 +64,9 @@ public DetectedComponent(TypedComponent.TypedComponent component, IComponentDete
6264
/// <summary> Gets or sets Dependency Scope of the component.</summary>
6365
public DependencyScope? DependencyScope { get; set; }
6466

67+
/// <summary> Gets Target Frameworks where the component was consumed.</summary>
68+
public ConcurrentHashSet<string> TargetFrameworks { get; set; }
69+
6570
private string DebuggerDisplay => $"{this.Component.DebuggerDisplay}";
6671

6772
/// <summary>Adds a filepath to the FilePaths hashset for this detected component.

src/Microsoft.ComponentDetection.Contracts/IComponentRecorder.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,22 @@ public interface ISingleFileComponentRecorder
2323
IDependencyGraph DependencyGraph { get; }
2424

2525
/// <summary>
26-
/// Add or Update a component. In case that a parent componentId is specified
27-
/// an edge is created between those components in the dependency graph.
26+
/// Add or Update a component. In case that a parent componentId is specified an edge is created between those components in the dependency graph.
27+
/// Metadata provided to this method specifies how the component was consumed, not uniquely identifying details about the component itself.
2828
/// </summary>
2929
/// <param name="detectedComponent">Component to add.</param>
3030
/// <param name="isExplicitReferencedDependency">The value define if the component was referenced manually by the user in the location where the scanning is taking place.</param>
3131
/// <param name="parentComponentId">Id of the parent component.</param>
3232
/// <param name="isDevelopmentDependency">Boolean value indicating whether or not a component is a development-time dependency. Null implies that the value is unknown.</param>
3333
/// <param name="dependencyScope">Enum value indicating scope of the component. </param>
34+
/// <param name="targetFramework">Optional value to determine the framework where the component was consumed.</param>
3435
void RegisterUsage(
3536
DetectedComponent detectedComponent,
3637
bool isExplicitReferencedDependency = false,
3738
string parentComponentId = null,
3839
bool? isDevelopmentDependency = null,
39-
DependencyScope? dependencyScope = null);
40+
DependencyScope? dependencyScope = null,
41+
string targetFramework = null);
4042

4143
/// <summary>
4244
/// Register that a package was unable to be processed.

src/Microsoft.ComponentDetection.Detectors/ivy/IvyDetector.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ namespace Microsoft.ComponentDetection.Detectors.Ivy;
3535
/// in the project's build.xml, or if they use any file inclusion mechanism, it will fail.
3636
///
3737
/// The file written out by the custom Ant task is a simple JSON file representing a series of calls to be made to
38-
/// the <see cref="ISingleFileComponentRecorder.RegisterUsage(DetectedComponent, bool, string, bool?, DependencyScope?)"/> method.
38+
/// the <see cref="ISingleFileComponentRecorder.RegisterUsage(DetectedComponent, bool, string, bool?, DependencyScope?, string)"/> method.
3939
/// </remarks>
4040
public class IvyDetector : FileComponentDetector, IExperimentalDetector
4141
{

0 commit comments

Comments
 (0)