Restructure solution layout by module

This commit is contained in:
master
2025-10-28 15:10:40 +02:00
parent 95daa159c4
commit d870da18ce
4103 changed files with 192899 additions and 187024 deletions

View File

@@ -0,0 +1,110 @@
[
{
"analyzerId": "python",
"componentKey": "purl::pkg:pypi/layered@2.0",
"purl": "pkg:pypi/layered@2.0",
"name": "layered",
"version": "2.0",
"type": "pypi",
"usedByEntrypoint": true,
"metadata": {
"author": "Layered Maintainer",
"authorEmail": "maintainer@example.com",
"classifier[0]": "Programming Language :: Python :: 3",
"classifiers": "Programming Language :: Python :: 3",
"distInfoPath": "layer1/usr/lib/python3.11/site-packages/layered-2.0.dist-info",
"editable": "true",
"entryPoints.console_scripts": "layered-cli=layered.cli:main",
"entryPoints.layered.hooks": "register=layered.plugins:register",
"installer": "pip",
"license": "Apache-2.0",
"license.classifier[0]": "License :: OSI Approved :: Apache Software License",
"license.file[0]": "layer2/usr/lib/python3.11/site-packages/LICENSE",
"licenseExpression": "Apache-2.0",
"name": "layered",
"normalizedName": "layered",
"projectUrl": "Documentation, https://example.com/layered/docs",
"provenance": "dist-info",
"record.hashMismatches": "0",
"record.hashedEntries": "8",
"record.ioErrors": "0",
"record.missingFiles": "0",
"record.totalEntries": "9",
"requiresDist": "requests",
"requiresPython": "\u003E=3.9",
"sourceCommit": "abc123",
"sourceSubdirectory": "src/layered",
"sourceUrl": "https://git.example.com/layered",
"sourceVcs": "git",
"summary": "Base layer metadata",
"version": "2.0",
"wheel.generator": "pip 24.0",
"wheel.rootIsPurelib": "true",
"wheel.tags": "py3-none-any",
"wheel.version": "1.0"
},
"evidence": [
{
"kind": "file",
"source": "INSTALLER",
"locator": "layer1/usr/lib/python3.11/site-packages/layered-2.0.dist-info/INSTALLER"
},
{
"kind": "file",
"source": "INSTALLER",
"locator": "layer2/usr/lib/python3.11/site-packages/layered-2.0.dist-info/INSTALLER"
},
{
"kind": "file",
"source": "METADATA",
"locator": "layer1/usr/lib/python3.11/site-packages/layered-2.0.dist-info/METADATA"
},
{
"kind": "file",
"source": "METADATA",
"locator": "layer2/usr/lib/python3.11/site-packages/layered-2.0.dist-info/METADATA"
},
{
"kind": "file",
"source": "RECORD",
"locator": "layer1/usr/lib/python3.11/site-packages/layered-2.0.dist-info/RECORD"
},
{
"kind": "file",
"source": "RECORD",
"locator": "layer2/usr/lib/python3.11/site-packages/layered-2.0.dist-info/RECORD"
},
{
"kind": "file",
"source": "WHEEL",
"locator": "layer1/usr/lib/python3.11/site-packages/layered-2.0.dist-info/WHEEL"
},
{
"kind": "file",
"source": "WHEEL",
"locator": "layer2/usr/lib/python3.11/site-packages/layered-2.0.dist-info/WHEEL"
},
{
"kind": "file",
"source": "entry_points.txt",
"locator": "layer1/usr/lib/python3.11/site-packages/layered-2.0.dist-info/entry_points.txt"
},
{
"kind": "file",
"source": "entry_points.txt",
"locator": "layer2/usr/lib/python3.11/site-packages/layered-2.0.dist-info/entry_points.txt"
},
{
"kind": "file",
"source": "license",
"locator": "layer2/usr/lib/python3.11/site-packages/LICENSE"
},
{
"kind": "metadata",
"source": "direct_url.json",
"locator": "layer2/usr/lib/python3.11/site-packages/layered-2.0.dist-info/direct_url.json",
"value": "https://git.example.com/layered"
}
]
}
]

View File

@@ -0,0 +1,8 @@
Metadata-Version: 2.1
Name: layered
Version: 2.0
Summary: Base layer metadata
License: Apache-2.0
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.9
Requires-Dist: requests

View File

@@ -0,0 +1,9 @@
layered/__init__.py,sha256=3Q3bv/BWCZLW2p2dVYw8QfAfBYV2YBtuYtT9TIJCmFM=,139
layered/core.py,sha256=izBXI4cRE/cgf7hgc/gHfTp1OyIIJ23NgUJXaHWVFpU=,80
layered/cli.py,sha256=xQrTznF7ch6C9qyQALJpsqRTIh9DVCRG4IXoQ1eLLnY=,126
../../../bin/layered-cli,sha256=6IGTGCEapolFoAUnXGNrWIfPSXU8W7bsZ07DYF/wmNc=,91
layered-2.0.dist-info/METADATA,sha256=jNEi7xsj4V+SSzOJJToxMoZmZ7gxyto7zuKxCjxUFjk=,193
layered-2.0.dist-info/WHEEL,sha256=m8MHT7vQnqC5W8H/y4uJdEpx9ijH0jJGpuoaxRbcsQg=,79
layered-2.0.dist-info/entry_points.txt,sha256=hm8bgJUYe2zoYNATyAsQzQKQTdQtFe4ctbf5kSlxFj0=,47
layered-2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ+UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg=,4
layered-2.0.dist-info/RECORD,,

View File

@@ -0,0 +1,4 @@
Wheel-Version: 1.0
Generator: pip 24.0
Root-Is-Purelib: true
Tag: py3-none-any

View File

@@ -0,0 +1,5 @@
"""Layered package demonstrating merged metadata across layers."""
from .core import get_version # noqa: F401
__all__ = ["get_version"]

View File

@@ -0,0 +1,7 @@
from __future__ import annotations
from .core import get_version
def main() -> None:
print(f"layered {get_version()}")

View File

@@ -0,0 +1,5 @@
from __future__ import annotations
def get_version() -> str:
return "2.0"

View File

@@ -0,0 +1,10 @@
Metadata-Version: 2.1
Name: layered
Version: 2.0
Summary: Overlay metadata adding direct URL information
License-Expression: Apache-2.0
License-File: LICENSE
Author: Layered Maintainer
Author-email: maintainer@example.com
Project-URL: Documentation, https://example.com/layered/docs
Classifier: License :: OSI Approved :: Apache Software License

View File

@@ -0,0 +1,9 @@
layered/plugins/__init__.py,sha256=hMd8TidtznWDaiA4biHZ04ZoVXcAc7z/p77bIdAsPyE=,53
layered/plugins/plugin.py,sha256=PBVqd9coVIzSBTQ2qdL5qxoK0fnsRZZ1DkhqnaVySPA=,87
LICENSE,sha256=cXKP+wQk9Jyqh8mUi7nURl9jOOjojDqrabZ119S2EzM=,27
layered-2.0.dist-info/METADATA,sha256=V09W93ILksWKLP8My6UatmScZ+5MCLiQ/5ieWzb585M=,346
layered-2.0.dist-info/WHEEL,sha256=m8MHT7vQnqC5W8H/y4uJdEpx9ijH0jJGpuoaxRbcsQg=,79
layered-2.0.dist-info/entry_points.txt,sha256=JYpkYczwozo6Ek7diDPgPj8ReYv5wTpaW0pFjL82bGU=,50
layered-2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ+UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg=,4
layered-2.0.dist-info/direct_url.json,sha256=8NtnZQZq2S5tcEn+P5fH6/EpABJ9+Ha5aIq8Sn2szig=,189
layered-2.0.dist-info/RECORD,,

View File

@@ -0,0 +1,4 @@
Wheel-Version: 1.0
Generator: pip 24.0
Root-Is-Purelib: true
Tag: py3-none-any

View File

@@ -0,0 +1,11 @@
{
"url": "https://git.example.com/layered",
"dir_info": {
"editable": true,
"subdirectory": "src/layered"
},
"vcs_info": {
"vcs": "git",
"commit_id": "abc123"
}
}

View File

@@ -0,0 +1,5 @@
from __future__ import annotations
def register() -> str:
return "layer2-plugin"

View File

@@ -0,0 +1,87 @@
[
{
"analyzerId": "python",
"componentKey": "purl::pkg:pypi/cache-pkg@1.2.3",
"purl": "pkg:pypi/cache-pkg@1.2.3",
"name": "Cache-Pkg",
"version": "1.2.3",
"type": "pypi",
"usedByEntrypoint": true,
"metadata": {
"classifier[0]": "Intended Audience :: Developers",
"classifier[1]": "License :: OSI Approved :: BSD License",
"classifier[2]": "Programming Language :: Python :: 3",
"classifiers": "Intended Audience :: Developers;License :: OSI Approved :: BSD License;Programming Language :: Python :: 3",
"distInfoPath": "lib/python3.11/site-packages/cache_pkg-1.2.3.dist-info",
"entryPoints.console_scripts": "cache-tool=cache_pkg:main",
"installer": "pip",
"license": "BSD-3-Clause",
"license.classifier[0]": "License :: OSI Approved :: BSD License",
"license.file[0]": "LICENSE",
"name": "Cache-Pkg",
"normalizedName": "cache-pkg",
"projectUrl": "Source, https://example.com/cache-pkg",
"provenance": "dist-info",
"record.hashMismatches": "1",
"record.hashedEntries": "9",
"record.ioErrors": "0",
"record.missingFiles": "2",
"record.totalEntries": "12",
"record.unsupportedAlgorithms": "md5",
"requiresDist": "click",
"requiresPython": "\u003E=3.8",
"summary": "Cache test package for hashed RECORD coverage",
"version": "1.2.3",
"wheel.generator": "pip 24.0",
"wheel.rootIsPurelib": "true",
"wheel.tags": "py3-none-any",
"wheel.version": "1.0"
},
"evidence": [
{
"kind": "derived",
"source": "RECORD",
"locator": "../etc/passwd",
"value": "outside-root"
},
{
"kind": "derived",
"source": "RECORD",
"locator": "lib/python3.11/site-packages/cache_pkg/LICENSE",
"value": "sha256 mismatch expected=pdUY6NGoyWCpcK8ThpBPUIVXbLvU9PzP8lsXEVEnFd0= actual=pdUY6NGoyWCpcK8ThpBPUIVXbLvU9PzP8lsXEVEnFdk=",
"sha256": "pdUY6NGoyWCpcK8ThpBPUIVXbLvU9PzP8lsXEVEnFdk="
},
{
"kind": "derived",
"source": "RECORD",
"locator": "lib/python3.11/site-packages/cache_pkg/missing/data.json",
"value": "missing"
},
{
"kind": "file",
"source": "INSTALLER",
"locator": "lib/python3.11/site-packages/cache_pkg-1.2.3.dist-info/INSTALLER"
},
{
"kind": "file",
"source": "METADATA",
"locator": "lib/python3.11/site-packages/cache_pkg-1.2.3.dist-info/METADATA"
},
{
"kind": "file",
"source": "RECORD",
"locator": "lib/python3.11/site-packages/cache_pkg-1.2.3.dist-info/RECORD"
},
{
"kind": "file",
"source": "WHEEL",
"locator": "lib/python3.11/site-packages/cache_pkg-1.2.3.dist-info/WHEEL"
},
{
"kind": "file",
"source": "entry_points.txt",
"locator": "lib/python3.11/site-packages/cache_pkg-1.2.3.dist-info/entry_points.txt"
}
]
}
]

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env python3
from cache_pkg import main
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,12 @@
Metadata-Version: 2.1
Name: Cache-Pkg
Version: 1.2.3
Summary: Cache test package for hashed RECORD coverage
License: BSD-3-Clause
License-File: LICENSE
Classifier: Programming Language :: Python :: 3
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Requires-Python: >=3.8
Requires-Dist: click
Project-URL: Source, https://example.com/cache-pkg

View File

@@ -0,0 +1,12 @@
cache_pkg/__init__.py,sha256=iw2XGXcGU2Si1KAQ7o82tPSKxwEFc6UNZfITpGPh7mM=,189
cache_pkg/data/config.json,sha256=Oa/wlgi1qJHC93RF5vwoOFffyviGtm5ccL7lrI0gkeY=,49
cache_pkg/LICENSE,sha256=pdUY6NGoyWCpcK8ThpBPUIVXbLvU9PzP8lsXEVEnFd0=,73
cache_pkg/md5only.txt,md5=Zm9v,4
cache_pkg-1.2.3.data/scripts/cache-tool,sha256=2rsv/gnYOtlJZCy75Wz0rCADxYPnQAkyKvNbuoquZQ4=,89
cache_pkg-1.2.3.dist-info/METADATA,sha256=DXPSItxOR1kPkVzjyq8F50jf8FOR9brSs/TGcZmcEHo=,390
cache_pkg-1.2.3.dist-info/WHEEL,sha256=m8MHT7vQnqC5W8H/y4uJdEpx9ijH0jJGpuoaxRbcsQg=,79
cache_pkg-1.2.3.dist-info/entry_points.txt,sha256=S1tGoBGlzWL6jeECCTw1pZP09HM8voEm/qQ7DtOHPyc=,44
cache_pkg-1.2.3.dist-info/INSTALLER,sha256=zuuue4knoyJ+UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg=,4
cache_pkg-1.2.3.dist-info/RECORD,,
cache_pkg/missing/data.json,sha256=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=,12
../../../../etc/passwd,,

View File

@@ -0,0 +1,4 @@
Wheel-Version: 1.0
Generator: pip 24.0
Root-Is-Purelib: true
Tag: py3-none-any

View File

@@ -0,0 +1,4 @@
BSD 3-Clause License
Copyright (c) 2025, StellaOps
All rights reserved.

View File

@@ -0,0 +1,7 @@
"""Cache fixture package for determinism tests."""
from .data import config # noqa: F401
def main() -> None:
"""Entry point used by console script."""
print("cache-pkg running")

View File

@@ -0,0 +1,85 @@
[
{
"analyzerId": "python",
"componentKey": "purl::pkg:pypi/simple@1.0.0",
"purl": "pkg:pypi/simple@1.0.0",
"name": "simple",
"version": "1.0.0",
"type": "pypi",
"usedByEntrypoint": true,
"metadata": {
"author": "Example Dev",
"authorEmail": "dev@example.com",
"classifier[0]": "License :: OSI Approved :: Apache Software License",
"classifier[1]": "Programming Language :: Python :: 3",
"classifiers": "License :: OSI Approved :: Apache Software License;Programming Language :: Python :: 3",
"distInfoPath": "lib/python3.11/site-packages/simple-1.0.0.dist-info",
"editable": "true",
"entryPoints.console_scripts": "simple-tool=simple.core:main",
"homePage": "https://example.com/simple",
"installer": "pip",
"license": "Apache-2.0",
"license.classifier[0]": "License :: OSI Approved :: Apache Software License",
"name": "simple",
"normalizedName": "simple",
"projectUrl": "Source, https://example.com/simple/src",
"provenance": "dist-info",
"record.hashMismatches": "0",
"record.hashedEntries": "8",
"record.ioErrors": "0",
"record.missingFiles": "1",
"record.totalEntries": "10",
"requiresDist": "requests (\u003E=2.0)",
"requiresPython": "\u003E=3.9",
"sourceCommit": "abc123def",
"sourceSubdirectory": "src/simple",
"sourceUrl": "https://example.com/simple-1.0.0.tar.gz",
"sourceVcs": "git",
"summary": "Simple fixture package",
"version": "1.0.0",
"wheel.generator": "pip 24.0",
"wheel.rootIsPurelib": "true",
"wheel.tags": "py3-none-any",
"wheel.version": "1.0"
},
"evidence": [
{
"kind": "derived",
"source": "RECORD",
"locator": "bin/simple-tool",
"value": "missing"
},
{
"kind": "file",
"source": "INSTALLER",
"locator": "lib/python3.11/site-packages/simple-1.0.0.dist-info/INSTALLER"
},
{
"kind": "file",
"source": "METADATA",
"locator": "lib/python3.11/site-packages/simple-1.0.0.dist-info/METADATA"
},
{
"kind": "file",
"source": "RECORD",
"locator": "lib/python3.11/site-packages/simple-1.0.0.dist-info/RECORD"
},
{
"kind": "file",
"source": "WHEEL",
"locator": "lib/python3.11/site-packages/simple-1.0.0.dist-info/WHEEL"
},
{
"kind": "file",
"source": "entry_points.txt",
"locator": "lib/python3.11/site-packages/simple-1.0.0.dist-info/entry_points.txt"
},
{
"kind": "metadata",
"source": "direct_url.json",
"locator": "lib/python3.11/site-packages/simple-1.0.0.dist-info/direct_url.json",
"value": "https://example.com/simple-1.0.0.tar.gz"
}
]
}
]

View File

@@ -0,0 +1,13 @@
Metadata-Version: 2.1
Name: simple
Version: 1.0.0
Summary: Simple fixture package
Home-page: https://example.com/simple
Author: Example Dev
Author-email: dev@example.com
License: Apache-2.0
Project-URL: Source, https://example.com/simple/src
Requires-Python: >=3.9
Requires-Dist: requests (>=2.0)
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: Apache Software License

View File

@@ -0,0 +1,10 @@
simple/__init__.py,sha256=03NWG/tm5eky+tnGlynp/vcyjtR944EtQMKtwrutl/U=,79
simple/__main__.py,sha256=7pHsIZX9uNTyp1e1AkmZ1vXZxw/dYB1TbR1rYDJca6c=,62
simple/core.py,sha256=8HaF+vPTo2roSP7kivqePnjG+d/WqotH269Qey/BM+s=,67
../../../bin/simple-tool,sha256=E7eVnffg2E4646m1Ml/5ixyROcpc24GJvy03sEkg6DA=,91
simple-1.0.0.dist-info/METADATA,sha256=Da/AG+nYa85WfbUSNmmRjpTeEEM8Kinf6Z197xb8X2o=,408
simple-1.0.0.dist-info/WHEEL,sha256=m8MHT7vQnqC5W8H/y4uJdEpx9ijH0jJGpuoaxRbcsQg=,79
simple-1.0.0.dist-info/entry_points.txt,sha256=A2WCkblioa0YbdUDurLzv+sIbx7TRSJ9zfBLYMYwpBQ=,49
simple-1.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ+UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg=,4
simple-1.0.0.dist-info/direct_url.json,sha256=EXd4Xj5iohEIqiF7mlR7sCLGhqXiU1/LuOPjijstKCU=,199
simple-1.0.0.dist-info/RECORD,,

View File

@@ -0,0 +1,4 @@
Wheel-Version: 1.0
Generator: pip 24.0
Root-Is-Purelib: true
Tag: py3-none-any

View File

@@ -0,0 +1,11 @@
{
"url": "https://example.com/simple-1.0.0.tar.gz",
"dir_info": {
"editable": true,
"subdirectory": "src/simple"
},
"vcs_info": {
"vcs": "git",
"commit_id": "abc123def"
}
}

View File

@@ -0,0 +1,4 @@
__all__ = ["main"]
__version__ = "1.0.0"
from .core import main # noqa: F401

View File

@@ -0,0 +1,4 @@
from .core import main
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,4 @@
import sys
def main() -> None:
print("simple core", sys.argv)

View File

@@ -0,0 +1,83 @@
using StellaOps.Scanner.Analyzers.Lang.Python;
using StellaOps.Scanner.Analyzers.Lang.Tests.Harness;
using StellaOps.Scanner.Analyzers.Lang.Tests.TestUtilities;
namespace StellaOps.Scanner.Analyzers.Lang.Python.Tests;
public sealed class PythonLanguageAnalyzerTests
{
[Fact]
public async Task SimpleVenvFixtureProducesDeterministicOutputAsync()
{
var cancellationToken = TestContext.Current.CancellationToken;
var fixturePath = TestPaths.ResolveFixture("lang", "python", "simple-venv");
var goldenPath = Path.Combine(fixturePath, "expected.json");
var usageHints = new LanguageUsageHints(new[]
{
Path.Combine(fixturePath, "bin", "simple-tool")
});
var analyzers = new ILanguageAnalyzer[]
{
new PythonLanguageAnalyzer()
};
await LanguageAnalyzerTestHarness.AssertDeterministicAsync(
fixturePath,
goldenPath,
analyzers,
cancellationToken,
usageHints);
}
[Fact]
public async Task PipCacheFixtureProducesDeterministicOutputAsync()
{
var cancellationToken = TestContext.Current.CancellationToken;
var fixturePath = TestPaths.ResolveFixture("lang", "python", "pip-cache");
var goldenPath = Path.Combine(fixturePath, "expected.json");
var usageHints = new LanguageUsageHints(new[]
{
Path.Combine(fixturePath, "lib", "python3.11", "site-packages", "cache_pkg-1.2.3.data", "scripts", "cache-tool")
});
var analyzers = new ILanguageAnalyzer[]
{
new PythonLanguageAnalyzer()
};
await LanguageAnalyzerTestHarness.AssertDeterministicAsync(
fixturePath,
goldenPath,
analyzers,
cancellationToken,
usageHints);
}
[Fact]
public async Task LayeredEditableFixtureMergesAcrossLayersAsync()
{
var cancellationToken = TestContext.Current.CancellationToken;
var fixturePath = TestPaths.ResolveFixture("lang", "python", "layered-editable");
var goldenPath = Path.Combine(fixturePath, "expected.json");
var usageHints = new LanguageUsageHints(new[]
{
Path.Combine(fixturePath, "layer1", "usr", "bin", "layered-cli")
});
var analyzers = new ILanguageAnalyzer[]
{
new PythonLanguageAnalyzer()
};
await LanguageAnalyzerTestHarness.AssertDeterministicAsync(
fixturePath,
goldenPath,
analyzers,
cancellationToken,
usageHints);
}
}

View File

@@ -0,0 +1,46 @@
<?xml version='1.0' encoding='utf-8'?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>preview</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Remove="Microsoft.NET.Test.Sdk" />
<PackageReference Remove="xunit" />
<PackageReference Remove="xunit.runner.visualstudio" />
<PackageReference Remove="Microsoft.AspNetCore.Mvc.Testing" />
<PackageReference Remove="Mongo2Go" />
<PackageReference Remove="coverlet.collector" />
<PackageReference Remove="Microsoft.Extensions.TimeProvider.Testing" />
<ProjectReference Remove="..\StellaOps.Concelier.Testing\StellaOps.Concelier.Testing.csproj" />
<Compile Remove="$(MSBuildThisFileDirectory)..\StellaOps.Concelier.Tests.Shared\AssemblyInfo.cs" />
<Compile Remove="$(MSBuildThisFileDirectory)..\StellaOps.Concelier.Tests.Shared\MongoFixtureCollection.cs" />
<Using Remove="StellaOps.Concelier.Testing" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="xunit.v3" Version="3.0.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\StellaOps.Scanner.Analyzers.Lang.Tests\StellaOps.Scanner.Analyzers.Lang.Tests.csproj" />
<ProjectReference Include="../../__Libraries/StellaOps.Scanner.Analyzers.Lang/StellaOps.Scanner.Analyzers.Lang.csproj" />
<ProjectReference Include="../../__Libraries/StellaOps.Scanner.Analyzers.Lang.Python/StellaOps.Scanner.Analyzers.Lang.Python.csproj" />
<ProjectReference Include="../../__Libraries/StellaOps.Scanner.Core/StellaOps.Scanner.Core.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="Fixtures\**\*" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
</Project>