feat(ruby): Implement RubyManifestParser for parsing gem groups and dependencies
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

feat(ruby): Add RubyVendorArtifactCollector to collect vendor artifacts

test(deno): Add golden tests for Deno analyzer with various fixtures

test(deno): Create Deno module and package files for testing

test(deno): Implement Deno lock and import map for dependency management

test(deno): Add FFI and worker scripts for Deno testing

feat(ruby): Set up Ruby workspace with Gemfile and dependencies

feat(ruby): Add expected output for Ruby workspace tests

feat(signals): Introduce CallgraphManifest model for signal processing
This commit is contained in:
master
2025-11-10 09:27:03 +02:00
parent 69c59defdc
commit 56c687253f
87 changed files with 2462 additions and 542 deletions

View File

@@ -2,38 +2,33 @@ namespace StellaOps.Scanner.Analyzers.Lang.Ruby.Internal;
internal sealed class RubyLockData
{
private RubyLockData(string? lockFilePath, IReadOnlyList<RubyLockEntry> entries, string bundledWith)
private RubyLockData(IReadOnlyList<RubyLockEntry> entries, string bundledWith)
{
LockFilePath = lockFilePath;
Entries = entries;
BundledWith = bundledWith;
BundledWith = bundledWith ?? string.Empty;
}
public string? LockFilePath { get; }
public string BundledWith { get; }
public IReadOnlyList<RubyLockEntry> Entries { get; }
public string BundledWith { get; }
public bool IsEmpty => Entries.Count == 0;
public static async ValueTask<RubyLockData> LoadAsync(string rootPath, CancellationToken cancellationToken)
public static ValueTask<RubyLockData> LoadAsync(LanguageAnalyzerContext context, CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrEmpty(rootPath);
ArgumentNullException.ThrowIfNull(context);
return RubyLockCollector.LoadAsync(context, cancellationToken);
}
var lockPath = Path.Combine(rootPath, "Gemfile.lock");
if (!File.Exists(lockPath))
public static RubyLockData Create(IReadOnlyList<RubyLockEntry> entries, string bundledWith)
{
if (entries.Count == 0 && string.IsNullOrWhiteSpace(bundledWith))
{
return Empty;
}
await using var stream = new FileStream(lockPath, FileMode.Open, FileAccess.Read, FileShare.Read);
using var reader = new StreamReader(stream);
var content = await reader.ReadToEndAsync(cancellationToken).ConfigureAwait(false);
var parser = RubyLockParser.Parse(content);
return new RubyLockData(lockPath, parser.Entries, parser.BundledWith);
return new RubyLockData(entries, bundledWith);
}
public static RubyLockData Empty { get; } = new(lockFilePath: null, Array.Empty<RubyLockEntry>(), bundledWith: string.Empty);
public static RubyLockData Empty { get; } = new(Array.Empty<RubyLockEntry>(), string.Empty);
}