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

@@ -1,6 +1,8 @@
using System.IO.Compression;
using System.Text;
using StellaOps.Scanner.Analyzers.Lang.Deno.Internal;
namespace StellaOps.Scanner.Analyzers.Lang.Deno.Tests.TestFixtures;
namespace StellaOps.Scanner.Analyzers.Lang.Deno.Fixtures;
internal static class BundleFixtureBuilder
{
@@ -8,6 +10,10 @@ internal static class BundleFixtureBuilder
{
Directory.CreateDirectory(directory);
var bundlePath = Path.Combine(directory, "sample.eszip");
if (File.Exists(bundlePath))
{
File.Delete(bundlePath);
}
using (var archive = ZipFile.Open(bundlePath, ZipArchiveMode.Create))
{
@@ -52,6 +58,10 @@ internal static class BundleFixtureBuilder
{
Directory.CreateDirectory(directory);
var binaryPath = Path.Combine(directory, "sample.deno");
if (File.Exists(binaryPath))
{
File.Delete(binaryPath);
}
var eszipPath = CreateSampleEszip(directory);
var eszipBytes = File.ReadAllBytes(eszipPath);

View File

@@ -1,3 +1,4 @@
using StellaOps.Scanner.Analyzers.Lang.Deno.Fixtures;
using StellaOps.Scanner.Analyzers.Lang.Tests.TestUtilities;
namespace StellaOps.Scanner.Analyzers.Lang.Deno.Tests.TestFixtures;
@@ -19,106 +20,7 @@ internal static class DenoWorkspaceTestFixture
private static void CreateDenoFixture(string root, out string envDenoDir)
{
Directory.CreateDirectory(root);
File.WriteAllText(Path.Combine(root, "deno.jsonc"), """
// sample deno config
{
"importMap": "./import_map.json",
"lock": {
"enabled": true,
"path": "./deno.lock"
},
"vendor": {
"enabled": true,
"path": "./vendor"
},
"nodeModulesDir": false,
"imports": {
"$std/": "https://deno.land/std@0.207.0/",
"app/": "./src/app/",
"data": "./data/data.json",
"npmDynamic": "npm:dayjs@1",
"nodeFs": "node:fs"
},
"scopes": {
"https://deno.land/": {
"fmt/": "https://deno.land/std@0.207.0/fmt/"
}
}
}
""");
Directory.CreateDirectory(Path.Combine(root, "src", "app"));
Directory.CreateDirectory(Path.Combine(root, "data"));
File.WriteAllText(Path.Combine(root, "data", "data.json"), "{ \"ok\": true }");
File.WriteAllText(
Path.Combine(root, "import_map.json"),
"""
{
"imports": {
"app/": "./src/app/main.ts",
"vendor/": "https://deno.land/std@0.207.0/"
}
}
""");
File.WriteAllText(
Path.Combine(root, "deno.lock"),
"""
{
"version": "4",
"remote": {
"https://deno.land/std@0.207.0/http/server.ts": "sha256-deadbeef",
"https://example.com/mod.ts": "sha256-feedface",
"node:fs": "builtin"
},
"redirects": {
"https://deno.land/std/http/server.ts": "https://deno.land/std@0.207.0/http/server.ts"
},
"npm": {
"specifiers": {
"npm:dayjs@1": "dayjs@1.11.12"
},
"packages": {
"dayjs@1.11.12": {
"integrity": "sha512-sample",
"dependencies": {
"tslib": "tslib@2.6.3"
}
},
"tslib@2.6.3": {
"integrity": "sha512-tslib",
"dependencies": {}
}
}
}
}
""");
var vendorRoot = Path.Combine(root, "vendor", "https", "deno.land", "std@0.207.0", "http");
Directory.CreateDirectory(vendorRoot);
File.WriteAllText(Path.Combine(vendorRoot, "server.ts"), "export const vendor = true;");
var vendorBase = Path.Combine(root, "vendor");
File.WriteAllText(
Path.Combine(vendorBase, "import_map.json"),
"""
{
"imports": {
"std/http/server.ts": "https://deno.land/std@0.207.0/http/server.ts"
}
}
""");
File.WriteAllText(
Path.Combine(vendorBase, "deno.lock"),
"""
{
"version": "1",
"remote": {}
}
""");
CreateDenoDir(Path.Combine(root, ".deno"), "workspace.ts", includeRegistry: true);
CopyTemplateWorkspace(root);
envDenoDir = Path.Combine(root, "env-deno");
CreateDenoDir(envDenoDir, "env.ts");
@@ -130,6 +32,39 @@ internal static class DenoWorkspaceTestFixture
var layerVendor = Path.Combine(layerFs, "vendor", "https", "layer.example");
Directory.CreateDirectory(layerVendor);
File.WriteAllText(Path.Combine(layerFs, "vendor", "import_map.json"), "{\"imports\":{\"layer/\": \"https://layer.example/\"}}");
var bundlesRoot = Path.Combine(root, "bundles");
Directory.CreateDirectory(bundlesRoot);
BundleFixtureBuilder.CreateSampleEszip(bundlesRoot);
BundleFixtureBuilder.CreateSampleCompiledBinary(bundlesRoot);
}
private static void CopyTemplateWorkspace(string destination)
{
var template = TestPaths.ResolveFixture("lang", "deno", "full");
CopyDirectory(template, destination);
}
private static void CopyDirectory(string source, string destination)
{
foreach (var directory in Directory.EnumerateDirectories(source, "*", SearchOption.AllDirectories))
{
var relative = Path.GetRelativePath(source, directory);
Directory.CreateDirectory(Path.Combine(destination, relative));
}
foreach (var file in Directory.EnumerateFiles(source, "*", SearchOption.AllDirectories))
{
if (file.EndsWith(".actual", StringComparison.OrdinalIgnoreCase))
{
continue;
}
var relative = Path.GetRelativePath(source, file);
var target = Path.Combine(destination, relative);
Directory.CreateDirectory(Path.GetDirectoryName(target)!);
File.Copy(file, target, overwrite: true);
}
}
private static void CreateDenoDir(string root, string fileName, bool includeRegistry = false)
@@ -142,7 +77,7 @@ internal static class DenoWorkspaceTestFixture
Directory.CreateDirectory(npm);
File.WriteAllText(Path.Combine(deps, fileName), "export const cache = true;");
File.WriteAllText(Path.Combine(gen, $"{Path.GetFileNameWithoutExtension(fileName)}.js"), "console.log('gen');");
File.WriteAllText(Path.Combine(gen, $"{Path.GetFileNameWithoutExtension(fileName)}.js"), "console.log(gen);");
File.WriteAllText(Path.Combine(npm, "package.json"), "{}");
if (includeRegistry)