Add PHP Analyzer Plugin and Composer Lock Data Handling
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

- Implemented the PhpAnalyzerPlugin to analyze PHP projects.
- Created ComposerLockData class to represent data from composer.lock files.
- Developed ComposerLockReader to load and parse composer.lock files asynchronously.
- Introduced ComposerPackage class to encapsulate package details.
- Added PhpPackage class to represent PHP packages with metadata and evidence.
- Implemented PhpPackageCollector to gather packages from ComposerLockData.
- Created PhpLanguageAnalyzer to perform analysis and emit results.
- Added capability signals for known PHP frameworks and CMS.
- Developed unit tests for the PHP language analyzer and its components.
- Included sample composer.lock and expected output for testing.
- Updated project files for the new PHP analyzer library and tests.
This commit is contained in:
StellaOps Bot
2025-11-22 14:02:49 +02:00
parent a7f3c7869a
commit b6b9ffc050
158 changed files with 16272 additions and 809 deletions

View File

@@ -0,0 +1,33 @@
{
"content-hash": "e01f9b7d7f4b23a6d1ad3b8e91c1c4ae",
"plugin-api-version": "2.6.0",
"packages": [
{
"name": "laravel/framework",
"version": "10.48.7",
"type": "library",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "0123456789abcdef0123456789abcdef01234567"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/0123456789abcdef0123456789abcdef01234567",
"shasum": "6f1b4c0908a5c2fdc3fbc0351d1a8f5f"
}
}
],
"packages-dev": [
{
"name": "phpunit/phpunit",
"version": "10.5.5",
"type": "library",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "9c9d4e1c8b62f9142fe995c3d76343d6330f0e36"
}
}
]
}

View File

@@ -0,0 +1,58 @@
[
{
"analyzerId": "php",
"componentKey": "purl::pkg:composer/laravel/framework@10.48.7",
"purl": "pkg:composer/laravel/framework@10.48.7",
"name": "laravel/framework",
"version": "10.48.7",
"type": "composer",
"usedByEntrypoint": false,
"metadata": {
"composer.content_hash": "e01f9b7d7f4b23a6d1ad3b8e91c1c4ae",
"composer.dev": "false",
"composer.dist.sha256": "6f1b4c0908a5c2fdc3fbc0351d1a8f5f",
"composer.dist.url": "https://api.github.com/repos/laravel/framework/zipball/0123456789abcdef0123456789abcdef01234567",
"composer.plugin_api_version": "2.6.0",
"composer.source.ref": "0123456789abcdef0123456789abcdef01234567",
"composer.source.type": "git",
"composer.type": "library",
"php.capability.framework": "laravel"
},
"evidence": [
{
"kind": "file",
"source": "composer.lock",
"locator": "composer.lock",
"value": "laravel/framework@10.48.7",
"sha256": "469f987fef544c06365b59539ec5e48d5356011ff829b36b96ec1336be2de9d1"
}
]
},
{
"analyzerId": "php",
"componentKey": "purl::pkg:composer/phpunit/phpunit@10.5.5",
"purl": "pkg:composer/phpunit/phpunit@10.5.5",
"name": "phpunit/phpunit",
"version": "10.5.5",
"type": "composer",
"usedByEntrypoint": false,
"metadata": {
"composer.content_hash": "e01f9b7d7f4b23a6d1ad3b8e91c1c4ae",
"composer.dev": "true",
"composer.plugin_api_version": "2.6.0",
"composer.source.ref": "9c9d4e1c8b62f9142fe995c3d76343d6330f0e36",
"composer.source.type": "git",
"composer.type": "library",
"php.capability.test": "phpunit"
},
"evidence": [
{
"kind": "file",
"source": "composer.lock",
"locator": "composer.lock",
"value": "phpunit/phpunit@10.5.5",
"sha256": "469f987fef544c06365b59539ec5e48d5356011ff829b36b96ec1336be2de9d1"
}
]
}
]

View File

@@ -0,0 +1,27 @@
using StellaOps.Scanner.Analyzers.Lang.Php;
using StellaOps.Scanner.Analyzers.Lang.Tests.Harness;
using StellaOps.Scanner.Analyzers.Lang.Tests.TestUtilities;
namespace StellaOps.Scanner.Analyzers.Lang.Php.Tests;
public sealed class PhpLanguageAnalyzerTests
{
[Fact]
public async Task ComposerLockPackagesAreEmittedAsync()
{
var cancellationToken = TestContext.Current.CancellationToken;
var fixturePath = TestPaths.ResolveFixture("lang", "php", "basic");
var goldenPath = Path.Combine(fixturePath, "expected.json");
var analyzers = new ILanguageAnalyzer[]
{
new PhpLanguageAnalyzer()
};
await LanguageAnalyzerTestHarness.AssertDeterministicAsync(
fixturePath,
goldenPath,
analyzers,
cancellationToken);
}
}

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.Php/StellaOps.Scanner.Analyzers.Lang.Php.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>