Skip to content

Commit c7c2b92

Browse files
committed
C#: DependabotProxy now parses replaces-base and exposes a list of URLs to replace the default NuGet feed.
1 parent b32e90c commit c7c2b92

5 files changed

Lines changed: 73 additions & 10 deletions

File tree

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependabotProxy.cs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Immutable;
23
using System.Collections.Generic;
34
using System.IO;
45
using System.Security.Cryptography.X509Certificates;
@@ -14,13 +15,39 @@ public class DependabotProxy : IDependabotProxy
1415
/// <summary>
1516
/// Represents configurations for package registries.
1617
/// </summary>
17-
/// <param name="Type">The type of package registry.</param>
18-
/// <param name="URL">The URL of the package registry.</param>
19-
public record class RegistryConfig(string Type, string URL);
18+
public class RegistryConfig
19+
{
20+
/// <summary>
21+
/// The type of the package registry.
22+
/// </summary>
23+
public string Type { get; init; } = "";
24+
25+
/// <summary>
26+
/// The URL of the package registry.
27+
/// </summary>
28+
public string URL { get; init; } = "";
29+
30+
/// <summary>
31+
/// A boolean indicating whether this registry replaces the base registry.
32+
/// </summary>
33+
[JsonProperty("replaces-base")]
34+
public bool ReplacesBase { get; init; } = false;
35+
};
2036

2137
public string Address { get; }
2238

23-
public HashSet<string> RegistryURLs { get; } = [];
39+
/// <summary>
40+
/// A dictionary mapping registry URLs to a boolean indicating whether they replace the base registry.
41+
/// </summary>
42+
private readonly Dictionary<string, bool> registryMapping = [];
43+
44+
private ImmutableHashSet<string>? registryURLs;
45+
public ImmutableHashSet<string> RegistryURLs =>
46+
registryURLs ??= registryMapping.Keys.ToImmutableHashSet();
47+
48+
private ImmutableHashSet<string>? registryBaseURLs;
49+
public ImmutableHashSet<string> RegistryBaseURLs =>
50+
registryBaseURLs ??= registryMapping.Where(kvp => kvp.Value).Select(kvp => kvp.Key).ToImmutableHashSet();
2451

2552
public string? CertificatePath { get; private set; }
2653

@@ -65,7 +92,7 @@ private DependabotProxy(IDependabotProxyConfiguration config, ILogger logger, Te
6592
}
6693

6794
logger.LogInfo($"Found private registry at '{registry.URL}'");
68-
RegistryURLs.Add(registry.URL);
95+
registryMapping.AddOrUpdateToLatest(registry.URL, registry.ReplacesBase);
6996
}
7097
}
7198
}

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/FeedManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public FeedManager(ILogger logger, IDotNet dotnet, IDependabotProxy? dependabotP
7878
this.dotnet = dotnet;
7979
this.fileProvider = fileProvider;
8080
this.feedManagerIo = feedManagerIo;
81-
privateRegistryFeeds = dependabotProxy?.RegistryURLs.ToImmutableHashSet() ?? [];
81+
privateRegistryFeeds = dependabotProxy?.RegistryURLs ?? [];
8282
HasPrivateRegistryFeeds = privateRegistryFeeds.Count > 0;
8383
emptyPackageDirectory = new DependencyDirectory("empty", "empty package", logger);
8484

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDependabotProxy.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System;
2-
using System.Collections.Generic;
2+
using System.Collections.Immutable;
33
using System.Security.Cryptography.X509Certificates;
44

55
namespace Semmle.Extraction.CSharp.DependencyFetching
@@ -14,7 +14,12 @@ public interface IDependabotProxy : IDisposable
1414
/// <summary>
1515
/// The URLs of package registries that are configured for the proxy.
1616
/// </summary>
17-
HashSet<string> RegistryURLs { get; }
17+
ImmutableHashSet<string> RegistryURLs { get; }
18+
19+
/// <summary>
20+
/// The URLs of package registries that replace the base registry.
21+
/// </summary>
22+
ImmutableHashSet<string> RegistryBaseURLs { get; }
1823

1924
/// <summary>
2025
/// The path to the temporary file where the certificate is stored.

csharp/extractor/Semmle.Extraction.Tests/DependabotProxy.cs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ public void TestDependabotRegistryUrls1()
135135

136136
// Verify
137137
Assert.NotNull(proxy);
138-
Assert.Equal([], proxy.RegistryURLs);
138+
Assert.Empty(proxy.RegistryURLs);
139+
Assert.Empty(proxy.RegistryBaseURLs);
139140
}
140141

141142
[Fact]
@@ -158,6 +159,7 @@ public void TestDependabotRegistryUrls2()
158159
Assert.Equal([
159160
"https://nuget.pkg.github.com/org/index.json"
160161
], proxy.RegistryURLs);
162+
Assert.Empty(proxy.RegistryBaseURLs);
161163
}
162164

163165
[Fact]
@@ -180,6 +182,33 @@ public void TestDependabotRegistryUrls3()
180182
Assert.Equal([
181183
"https://example.com/org/index.json"
182184
], proxy.RegistryURLs);
185+
Assert.Empty(proxy.RegistryBaseURLs);
186+
}
187+
188+
[Fact]
189+
public void TestDependabotReplacesBase1()
190+
{
191+
// Setup
192+
var config = new DependabotConfigurationStub
193+
{
194+
Port = "8080",
195+
Host = "localhost",
196+
RegistryURLs = "[ { \"type\": \"nuget_feed\", \"url\": \"https://example.com/org/index.json\", \"replaces-base\": true }, { \"type\": \"nuget_feed\", \"url\": \"https://example2.com/org/index.json\", \"replaces-base\": false } ]"
197+
};
198+
199+
// Execute
200+
using var tempWorkingDirectory = MakeTemporaryDirectory();
201+
using var proxy = DependabotProxy.Make(config, new LoggerStub(), new DiagnosticsWriterStub(), tempWorkingDirectory);
202+
203+
// Verify
204+
Assert.NotNull(proxy);
205+
Assert.Equal([
206+
"https://example.com/org/index.json",
207+
"https://example2.com/org/index.json"
208+
], proxy.RegistryURLs);
209+
Assert.Equal([
210+
"https://example.com/org/index.json",
211+
], proxy.RegistryBaseURLs);
183212
}
184213
}
185214
}

csharp/extractor/Semmle.Extraction.Tests/FeedManager.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
using System.IO;
55
using System.Linq;
66
using Semmle.Extraction.CSharp.DependencyFetching;
7+
using System.Collections.Immutable;
78

89
namespace Semmle.Extraction.Tests
910
{
1011
public class DependabotProxyStub : IDependabotProxy
1112
{
1213
public string Address { get; } = "";
13-
public HashSet<string> RegistryURLs { get; } = ["https://example.com/registry1", "https://example.com/registry2"];
14+
public ImmutableHashSet<string> RegistryURLs { get; } = ["https://example.com/registry1", "https://example.com/registry2"];
15+
public ImmutableHashSet<string> RegistryBaseURLs { get; } = [];
1416
public string? CertificatePath { get; } = null;
1517
public System.Security.Cryptography.X509Certificates.X509Certificate2? Certificate { get; } = null;
1618

0 commit comments

Comments
 (0)