Skip to content

Feat: Add composer graph - #457

Draft
mromeike wants to merge 2 commits into
FriendsOfShopware:mainfrom
mromeike:feat/composer-graph
Draft

Feat: Add composer graph#457
mromeike wants to merge 2 commits into
FriendsOfShopware:mainfrom
mromeike:feat/composer-graph

Conversation

@mromeike

@mromeike mromeike commented Aug 21, 2026

Copy link
Copy Markdown

Example:

With vulnerable twig/twig:3.25.0 as 3.26.0 installed through platform's composer.json:

image

Details

The /api/_action/frosh-tools/composer-graph endpoint provides an SVG dependency graph of shopware core packages and any additionally provided packages.

The dev-dependencies are not included by default. Caches are used if possible, SVG results are cached for 3800s, refresh may be forced. Standard cache compression is supported.

Some vendors are always included to keep the graph meaningful: shopware/*, frosh/* and store.shopware.com/*.

Any vulnerable packages are marked red in the dependency graph generated through dot (graphviz).

A new configuration parameter composer.graphviz_path can be used to set a custom dist path (useful for non-PATH setups).

A Shopware 6.6 compatible Dockerfile with graphwiz support is provided.

**Details**:

The `/api/_action/frosh-tools/composer-graph` endpoint provides an SVG dependency graph of shopware core packages and any additionally provided `packages`.

The dev-dependencies are not included by default. Caches are used if possible, SVG results are cached for `3800s`, refresh may be forced. Standard cache compression is supported.

Any vulnerable packages are marked red in the dependency graph generated through `dot` (graphviz).

A new configuration parameter `composer.graphviz_path` can be used to set a custom dist path (useful for non-PATH setups).

A Shopware 6.6 compatible Dockerfile with `graphwiz` support is provided.
@pullfrog

pullfrog Bot commented Aug 21, 2026

Copy link
Copy Markdown

no API key found — this repo is configured to use openai/gpt-5.6-luna, which needs OPENAI_API_KEY, but the runner has no key for it.

To fix: add the key as a GitHub Actions secret (referenced from your workflow's env: block) or as a Pullfrog secret in the console — or switch this repo to a different model (free models need no key).

Open repo secrets → · Configure model → · Setup docs → · Ask in Discord →

Pullfrog  | Rerun failed job ➔View workflow run | via Pullfrog | Using GPT Luna𝕏

@mromeike
mromeike marked this pull request as draft August 21, 2026 07:37
@greptile-apps

greptile-apps Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds an ACL-protected API and administration UI for generating, caching, and displaying Graphviz Composer dependency graphs with vulnerable packages highlighted.

  • Introduces Composer graph generation, filtering, cache compression, and configurable Graphviz executable selection.
  • Adds administration controls to load, hide, and reload the generated SVG.
  • Adds Graphviz-enabled development container configuration and the graph-composer dependency.

Confidence Score: 3/5

The PR should not merge until graph reloads actually invalidate the cache and graph styling safely handles audited packages absent from the generated dependency graph.

The reload path cannot transmit the backend’s refresh input, and a reachable advisory shape can make the new endpoint throw during an unconditional graph vertex lookup.

Files Needing Attention: src/Components/ComposerAudit/ComposerGraphService.php, src/Resources/app/administration/src/api/frosh-tools.js, src/Resources/app/administration/src/module/frosh-tools/component/frosh-tools-security-dependencies/template.twig

Important Files Changed

Filename Overview
src/Components/ComposerAudit/ComposerGraphService.php Adds graph generation and caching, but advisory styling can throw when an audited package is absent from the root dependency graph.
src/Controller/ComposerAuditController.php Adds the ACL-scoped SVG endpoint and consumes refresh, strict, development-dependency, and package query inputs.
src/Resources/app/administration/src/api/frosh-tools.js Adds the graph request wrapper, but sends forceRefresh rather than the refresh parameter expected by the endpoint.
src/Resources/app/administration/src/module/frosh-tools/component/frosh-tools-security-dependencies/index.js Adds graph loading and data-URI state, while its refresh flag is not activated by the UI.
src/Resources/app/administration/src/module/frosh-tools/component/frosh-tools-security-dependencies/template.twig Adds graph display and controls, but the reload-labelled action performs a normal cached load.
composer.json Adds the graph-composer fork and PHP 8.3 resolution platform while changing the package’s declared development version.

Sequence Diagram

sequenceDiagram
    participant Admin as Administration UI
    participant API as ComposerAuditController
    participant Service as ComposerGraphService
    participant Audit as ComposerAuditService
    participant Cache as Cache
    participant Dot as Graphviz
    Admin->>API: GET /composer-graph
    API->>Service: graph(packages, dev, strict, refresh)
    Service->>Audit: audit(refresh)
    Service->>Cache: get graph cache key
    alt cache miss or invalidated
        Service->>Dot: render dependency graph
        Dot-->>Service: SVG file
        Service->>Cache: store compressed SVG
    end
    Cache-->>Service: SVG data
    Service-->>API: SVG
    API-->>Admin: image/svg+xml
Loading

Fix all with Greploop Fix All in Claude Code

Reviews (1): Last reviewed commit: "Add experimental composer graph in admin..." | Re-trigger Greptile

return this.httpClient
.get(apiRoute, {
headers: this.getBasicHeaders(),
params: { packages, withDevDependencies, strict, forceRefresh },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Graph reload bypass is broken

When an administrator reloads the dependency graph, the client either leaves forceRefresh false or sends it under that name while the controller reads refresh, causing the backend to return the cached SVG instead of reflecting dependency or vulnerability changes.

Fix in Claude Code

private function setGraphLayout(Graph $graph, array $advisory, array $layout): void
{
$packageName = $advisory['packageName'];
$vertex = $graph->getVertex($packageName);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Missing graph vertices throw

When the audit reports a vulnerable package from an additional Composer installed dataset that is absent from the root dependency graph, this unconditional getVertex lookup throws an OutOfBoundsException, causing the graph endpoint to return an error instead of an SVG.

Fix in Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant