evilstudio/composer-parser

Compare Composer dependencies across repositories and export consolidated reports

Maintainers

Package info

github.com/evilprophet/composer-parser

Type:project

pkg:composer/evilstudio/composer-parser

Transparency log

Statistics

Installs: 11

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v2.19.2 2026-07-20 14:47 UTC

README

Introduction

Composer Parser is a Symfony Console application for comparing Composer dependencies across multiple repositories and publishing one consolidated report.

It loads repositories through Git or the GitLab API, reads composer.json and optionally composer.lock, groups packages by configurable rules, and writes the result to XLSX, JSON, HTML, or Google Sheets.

โœจ Key Features

  • Multiple repository sources: use a local Git checkout flow or download files and archives through the GitLab API.
  • Three parser modes: compare declared constraints, installed versions, or the latest available versions reported by Composer.
  • Four report formats: generate XLSX, JSON, HTML, or Google Sheets output from the same normalized data.
  • Configurable package groups: match require, require-dev, replace, patchset, and explicitly observed packages with regular expressions.
  • Configurable report styling: apply version- and package-based colors to XLSX, HTML, and Google Sheets reports.
  • Complete report snapshots: repository and parser failures stop the run before the writer replaces the previous complete report.

๐Ÿ“ Project Structure

.
โ”œโ”€โ”€ bin/                 # CLI entrypoint
โ”œโ”€โ”€ config/              # Parameters template and service configuration
โ”œโ”€โ”€ src/                 # Application source code
โ”‚   โ”œโ”€โ”€ Api/             # Public contracts
โ”‚   โ”œโ”€โ”€ Command/         # Console commands
โ”‚   โ”œโ”€โ”€ Exception/       # Domain exceptions
โ”‚   โ”œโ”€โ”€ Model/           # Configuration and report models
โ”‚   โ””โ”€โ”€ Service/         # Providers, parsers, writers, validation, and application services
โ”œโ”€โ”€ tests/               # Unit and integration tests
โ”œโ”€โ”€ var/                 # Generated repositories, reports, and logs
โ”œโ”€โ”€ composer.json        # PHP dependencies and project scripts
โ””โ”€โ”€ phpunit.xml          # PHPUnit suites and strict failure rules

๐Ÿ› ๏ธ Requirements

  • PHP 8.4+
  • Composer 2+
  • PHP extensions required by the locked dependencies, including ext-curl, ext-gd, ext-json, and ext-zip
  • Git available in PATH when using gitRepository
  • Composer available in PATH when using composerFull
  • GitLab URL and API token when using a GitLab provider
  • Google Cloud service account JSON when using googleSheets

๐Ÿš€ Quick Start

Clone the repository, install dependencies, and create the local parameters file:

git clone https://github.com/evilprophet/composer-parser.git
cd composer-parser
composer install
cp config/parameters.yaml.template config/parameters.yaml

Update config/parameters.yaml for your repositories and selected provider, parser, and writer. The template provides the supported values and a complete example configuration.

Run cleanup before every report generation so providers work with fresh repository data:

# Remove repositories downloaded by the previous run.
bin/console app:cleanup

# Download repositories, parse dependencies, and write the report.
bin/console app:run

Use a different parameters file without changing the default configuration:

bin/console app:cleanup -p config/parameters.custom.yaml
bin/console app:run -p config/parameters.custom.yaml

-p, --parameters-file <path>, and --parameters-file=<path> are equivalent. Relative paths are resolved from the current working directory.

โš™๏ธ Configuration

config/parameters.yaml.template is the configuration reference. Every report run requires these base keys:

  • app.config.timezone
  • app.config.providerType
  • app.config.parserType
  • app.config.writerType
  • package.config.includeInstalledVersion
  • package.config.installedVersionDisplayedIn
  • package.config.packageGroups
  • repository.config.repositoryList
  • writer.config.local.fileName
  • writer.config.local.fileDirectory
  • writer.config.shared.sheetName

Providers

  • gitRepository clones the configured remote or reuses an existing checkout, then checks out the configured branch without running fetch or pull.
  • gitlabApiFiles downloads composer.json and the optional composer.lock directly from GitLab.
  • gitlabApiArchive downloads a GitLab repository archive and optionally decrypts auth.json.encrypted with app.config.ansibleVaultPassword.

Parsers

  • composerJson reads require, require-dev, replace, and extra.patchset data from composer.json.
  • composerJsonAndLock also reads installed versions from both packages and packages-dev in composer.lock.
  • composerFull additionally runs composer outdated --no-plugins --no-scripts --format=json inside each downloaded repository to collect latest available versions.

composer.lock is optional. Without it, lock-aware parsers still report declared constraints but cannot add installed or observed package versions.

Writers

  • xlsx writes a styled workbook to writer.config.local.fileDirectory.
  • json writes a structured local report without styling.
  • html writes a standalone styled report.
  • googleSheets clears and rewrites the configured sheet through the Google Sheets API.

Styling is required for xlsx, html, and googleSheets. An XLSX sheet name cannot contain *, :, /, \, ?, [ or ].

Package groups

  • groupType accepts require, require-dev, replace, patchset, or observed.
  • Higher parserPriority claims matching require, require-dev, and replace packages first. observed and patchset entries are added to every matching group.
  • Lower writerOrder is displayed first; equal values preserve configuration order.
  • An observed group requires composerJsonAndLock or composerFull, includeInstalledVersion: true, and at least one package in observedPackages.

Repository entries

  • Every entry requires name, directory, remote, and branch; only name and directory must be unique.
  • directory must be a normalized relative child of var/repositories/ without . or .. segments or a trailing slash.
  • remote must use SCP-style SSH or an HTTP, HTTPS, or SSH URL. GitLab API providers extract the namespace/project path from this value.
  • Report columns are sorted alphabetically by repository name, independently of configuration order.
  • Standard dependency and observed package rows are sorted alphabetically; patch rows preserve their source order.

Google Sheets

  • Enable the Google Sheets API in a Google Cloud project.
  • Create a service account and download its JSON key outside the repository.
  • Share the target spreadsheet with the service account email as Editor.
  • Set writer.config.googleSheets.spreadsheetId and writer.config.googleSheets.serviceAccountJsonPath.
  • Never commit API tokens, vault passwords, or service account files.

๐Ÿ”„ Report Flow

  1. app:cleanup removes only the configured working directories below var/repositories/.
  2. The selected provider loads every configured repository into its local working directory.
  3. The selected parser builds one package matrix across all repositories.
  4. The selected writer publishes the report only after every repository has been processed successfully.
  5. A repository, parser, or validation failure returns a non-zero exit code and leaves the previous complete report untouched.

๐Ÿ’ป Commands Overview

Command Description
bin/console app:cleanup Remove configured local repository working directories.
bin/console app:run Load repositories, parse dependencies, and publish one report.
bin/console list List available commands without initializing unused integrations.

Command exit codes:

  • 0 - command completed successfully.
  • 1 - configuration, provider, parser, writer, or cleanup failed at runtime.
  • 2 - CLI bootstrap failed, for example because the parameters file does not exist.

๐Ÿงช Testing & Quality

Run the complete PHPUnit suite and the same PHP_CodeSniffer rules used by CI:

composer test
vendor/bin/phpcs --standard=PSR12 --extensions=php --warning-severity=0 src tests

GitLab CI runs the Unit and Integration PHPUnit suites separately on PHP 8.4 and rejects warnings, notices, deprecations, risky tests, and unexpected test output.

๐Ÿงญ Notes

  • Local report names use writer.config.local.fileName; {date} is replaced with the current date in Y-m-d format and the writer appends the extension.
  • Relative local output and service account paths are resolved from the current working directory.
  • Local output directories are created automatically, and existing files with the same generated name are overwritten.
  • Runtime errors handled by app:cleanup and app:run are logged to var/log/error.log; bootstrap errors are written directly to STDERR.
  • app:run does not perform cleanup automatically; the supported operational sequence is always app:cleanup followed by app:run.
  • Run cleanup and report generation sequentially. Concurrent executions against the same working directories are not supported.
  • Google Sheets output is updated in place; an API failure during the writer step can leave the target sheet empty or partially updated.