Refactor code structure for improved readability and maintainability
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-12-06 21:48:12 +02:00
parent f6c22854a4
commit dd0067ea0b
105 changed files with 12662 additions and 427 deletions

View File

@@ -0,0 +1,88 @@
using System;
using System.Collections.Generic;
using System.Linq;
using StellaOps.Scanner.Analyzers.Lang;
using StellaOps.Scanner.Core.Contracts;
namespace StellaOps.Scanner.Worker.Processing.Surface;
internal static class BunPackageInventoryBuilder
{
private const string AnalyzerId = "bun";
public static IReadOnlyList<BunPackageArtifact> Build(LanguageAnalyzerResult result)
{
ArgumentNullException.ThrowIfNull(result);
var artifacts = new List<BunPackageArtifact>();
foreach (var component in result.Components)
{
if (!component.AnalyzerId.Equals(AnalyzerId, StringComparison.OrdinalIgnoreCase))
{
continue;
}
if (!string.Equals(component.Type, "npm", StringComparison.OrdinalIgnoreCase))
{
continue;
}
var metadata = component.Metadata ?? new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);
var metadataCopy = new Dictionary<string, string?>(metadata, StringComparer.OrdinalIgnoreCase);
var source = GetString(metadataCopy, "source");
var resolved = GetString(metadataCopy, "resolved");
var integrity = GetString(metadataCopy, "integrity");
var lockfile = GetString(metadataCopy, "lockfile");
var artifactLocator = GetString(metadataCopy, "artifact");
var isDev = TryParseBool(metadataCopy, "isDev");
var isDirect = TryParseBool(metadataCopy, "isDirect");
var isPatched = TryParseBool(metadataCopy, "isPatched");
var provenance = (source is not null || lockfile is not null || artifactLocator is not null)
? new BunPackageProvenance(source, lockfile, artifactLocator ?? lockfile)
: null;
artifacts.Add(new BunPackageArtifact(
component.ComponentKey,
component.Name,
component.Version,
source,
resolved,
integrity,
isDev,
isDirect,
isPatched,
provenance,
metadataCopy));
}
return artifacts;
}
private static bool? TryParseBool(IReadOnlyDictionary<string, string?> metadata, string key)
{
if (!metadata.TryGetValue(key, out var value) || string.IsNullOrWhiteSpace(value))
{
return null;
}
if (bool.TryParse(value, out var parsed))
{
return parsed;
}
return null;
}
private static string? GetString(IReadOnlyDictionary<string, string?> metadata, string key)
{
if (!metadata.TryGetValue(key, out var value) || string.IsNullOrWhiteSpace(value))
{
return null;
}
return value.Trim();
}
}

View File

@@ -43,6 +43,7 @@ internal sealed class SurfaceManifestStageExecutor : IScanStageExecutor
private readonly ILogger<SurfaceManifestStageExecutor> _logger;
private readonly ICryptoHash _hash;
private readonly IRubyPackageInventoryStore _rubyPackageStore;
private readonly IBunPackageInventoryStore _bunPackageStore;
private readonly Determinism.DeterminismContext _determinism;
private readonly IDsseEnvelopeSigner _dsseSigner;
private readonly string _componentVersion;
@@ -56,6 +57,7 @@ internal sealed class SurfaceManifestStageExecutor : IScanStageExecutor
ILogger<SurfaceManifestStageExecutor> logger,
ICryptoHash hash,
IRubyPackageInventoryStore rubyPackageStore,
IBunPackageInventoryStore bunPackageStore,
Determinism.DeterminismContext determinism,
IDsseEnvelopeSigner dsseSigner)
{
@@ -67,6 +69,7 @@ internal sealed class SurfaceManifestStageExecutor : IScanStageExecutor
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_hash = hash ?? throw new ArgumentNullException(nameof(hash));
_rubyPackageStore = rubyPackageStore ?? throw new ArgumentNullException(nameof(rubyPackageStore));
_bunPackageStore = bunPackageStore ?? throw new ArgumentNullException(nameof(bunPackageStore));
_determinism = determinism ?? throw new ArgumentNullException(nameof(determinism));
_dsseSigner = dsseSigner ?? throw new ArgumentNullException(nameof(dsseSigner));
_componentVersion = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "unknown";
@@ -80,6 +83,7 @@ internal sealed class SurfaceManifestStageExecutor : IScanStageExecutor
var payloads = CollectPayloads(context);
await PersistRubyPackagesAsync(context, cancellationToken).ConfigureAwait(false);
await PersistBunPackagesAsync(context, cancellationToken).ConfigureAwait(false);
var determinismPayloads = BuildDeterminismPayloads(context, payloads, out var merkleRoot);
if (determinismPayloads is not null && determinismPayloads.Count > 0)
@@ -491,6 +495,33 @@ internal sealed class SurfaceManifestStageExecutor : IScanStageExecutor
await _rubyPackageStore.StoreAsync(inventory, cancellationToken).ConfigureAwait(false);
}
private async Task PersistBunPackagesAsync(ScanJobContext context, CancellationToken cancellationToken)
{
if (!context.Analysis.TryGet<ReadOnlyDictionary<string, LanguageAnalyzerResult>>(ScanAnalysisKeys.LanguageAnalyzerResults, out var results))
{
return;
}
if (!results.TryGetValue("bun", out var bunResult) || bunResult is null)
{
return;
}
var packages = BunPackageInventoryBuilder.Build(bunResult);
if (packages.Count == 0)
{
return;
}
var inventory = new BunPackageInventory(
context.ScanId,
ResolveImageDigest(context),
context.TimeProvider.GetUtcNow(),
packages);
await _bunPackageStore.StoreAsync(inventory, cancellationToken).ConfigureAwait(false);
}
private async Task PersistPayloadsToSurfaceCacheAsync(
ScanJobContext context,
string tenant,

View File

@@ -106,6 +106,7 @@ builder.Services.AddSingleton<IDsseEnvelopeSigner, HmacDsseEnvelopeSigner>();
else
{
builder.Services.TryAddSingleton<IRubyPackageInventoryStore, NullRubyPackageInventoryStore>();
builder.Services.TryAddSingleton<IBunPackageInventoryStore, NullBunPackageInventoryStore>();
}
builder.Services.TryAddSingleton<IScanJobSource, NullScanJobSource>();