PHPackages                             atoolo/channel-diff - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. atoolo/channel-diff

ActiveProject

atoolo/channel-diff
===================

CLI tool to compare two IES publication channels.

01↑2900%

Since Jul 22Compare

[ Source](https://github.com/sitepark/atoolo-channel-diff)[ Packagist](https://packagist.org/packages/atoolo/channel-diff)[ RSS](/packages/atoolo-channel-diff/feed)WikiDiscussions Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

[![codecov](https://camo.githubusercontent.com/b05b8efed906c29993321bd46398671856d7fe65ac993bd9156c2e94029b0d1f/68747470733a2f2f636f6465636f762e696f2f67682f736974657061726b2f6368616e6e656c2d646966662f67726170682f62616467652e737667)](https://codecov.io/gh/sitepark/channel-diff)[![Verify](https://github.com/sitepark/channel-diff/actions/workflows/verify.yml/badge.svg)](https://github.com/sitepark/channel-diff/actions/workflows/verify.yml)[![phpstan](https://camo.githubusercontent.com/ff3c7f8c8667ce643f47e74532748f673482a5f95d7d4269f925f2eebbe5117e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c253230382d627269676874677265656e)](https://camo.githubusercontent.com/ff3c7f8c8667ce643f47e74532748f673482a5f95d7d4269f925f2eebbe5117e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c253230382d627269676874677265656e)[![php](https://camo.githubusercontent.com/91cb649feb797bb507583f5f4e88d0727695b25c0a7265b8b1c7448848b13ef9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322d626c7565)](https://camo.githubusercontent.com/91cb649feb797bb507583f5f4e88d0727695b25c0a7265b8b1c7448848b13ef9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322d626c7565)[![php](https://camo.githubusercontent.com/44471375dfd3bcd4fd091f24ddc5326e7d42abfb024cc764490d83ed6ef31b85/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e332d626c7565)](https://camo.githubusercontent.com/44471375dfd3bcd4fd091f24ddc5326e7d42abfb024cc764490d83ed6ef31b85/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e332d626c7565)[![php](https://camo.githubusercontent.com/b37db47746bb49d291c47c3cc8fabd15219dc271ef4a998933fcd59e950d22b3/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e342d626c7565)](https://camo.githubusercontent.com/b37db47746bb49d291c47c3cc8fabd15219dc271ef4a998933fcd59e950d22b3/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e342d626c7565)[![php](https://camo.githubusercontent.com/b0fbf30db00a472955b7eecc73201f53666af84973bf759bd15cde881ff4ce0e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e352d626c7565)](https://camo.githubusercontent.com/b0fbf30db00a472955b7eecc73201f53666af84973bf759bd15cde881ff4ce0e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e352d626c7565)

channel-diff
============

[](#channel-diff)

A command-line tool to compare two IES publication channels. It loads the PHP resource files of each channel into their nested arrays and diffs them field-by-field; binary media files are compared by hash.

Typical use cases: verifying a channel after a re-publish, a publisher change, or a migration between environments.

How it works
------------

[](#how-it-works)

- Each publication channel is a directory containing SiteKit resource PHP files. These are loaded via `atoolo/resource-bundle` into their raw nested arrays and compared.
- The three channel layouts are detected automatically:
    - **DOCUMENT\_ROOT** — everything in one directory (resources and media intermixed); the SiteKit framework subtree (`WEB-IES/`) is excluded.
    - **RESOURCE, URL-based** — separate `objects/` and `media/public/` trees.
    - **RESOURCE, ID-based** — same as above, with an ID-bucketed `objects/` tree.
- Resources and media are **matched by their relative file path**. Volatile fields (`version`, `created`, `changed`, `generated`, `changedBy`, `cacheInfo`) are ignored by default.

> **Note:** Because matching is by physical path, both channels should use the **same layout**. Comparing channels of different layouts will report every resource as "only in A / only in B".

Requirements
------------

[](#requirements)

- PHP &gt;= 8.2 with the `intl` and `json` extensions
- [Composer](https://getcomposer.org/) 2.x
- [phive](https://phar.io/) (for the QA tools; only needed for `composer test`and `composer analyse`)

Installation
------------

[](#installation)

```
git clone  channel-diff
cd channel-diff
composer install
```

`atoolo/resource-bundle` is resolved from Packagist like any other dependency.

`composer install` runs a `post-install-cmd` that installs the QA PHAR tools (PHPUnit, PHPStan, PHP-CS-Fixer, composer-normalize) into `tools/` via [phive](https://phar.io/). phplint is installed as a regular Composer dev dependency.

Contributors should enable the shared git hooks (Conventional Commit check) once after cloning:

```
git config core.hooksPath .githooks
```

Usage
-----

[](#usage)

```
php bin/console channel:diff   [options]
```

`` and `` are the base directories of the two publication channels, for example:

- DOCUMENT\_ROOT: `.../publications//www`
- RESOURCE: `.../publications//www/resources`

### Options

[](#options)

OptionDescription`-f`, `--format=console|json`Output format (default: `console`).`-i`, `--ignore=`Additional dot-notation field path to ignore. Supports wildcards (see below). Repeatable.`--ignore-config=`PHP file returning a list of dot-notation field paths to ignore.`--no-media`Skip the binary media comparison.`--strict-null`Treat a null field and a missing field as different. By default, a field that is `null` in one channel and absent in the other is considered equal.`--strict-empty-string`Treat an empty-string field and a missing field as different. By default, a field that is `""` in one channel and absent in the other is considered equal.`--strict-empty-array`Treat an empty-array field and a missing field as different. By default, a field that is an empty array in one channel and absent in the other is considered equal. Emptiness is recursive: an array whose (nested) values are all empty counts as empty (e.g. `['features' => ['primary' => []]]`).`--strict-uuid-keys`Treat UUID array keys as significant. By default, an array whose keys are all UUIDs is matched by the content of its values instead of by the (volatile, regenerated) keys, and inner values equal to the key (e.g. a mirrored `id`) are neutralized so entries pair up.### Ignore path wildcards

[](#ignore-path-wildcards)

Ignore paths may contain wildcard segments:

- `*` matches exactly one key segment. A `*` in the middle of a path is a field ignore, e.g. `a.b.*.id` ignores the `id` field of every child of `a.b`.
- `**` matches any number of segments (including none), so a structure that occurs at many depths can be addressed once, e.g. `**.geo.features.*`.
- A **terminal** `*`, e.g. `**.geo.features.*`, is a *key-normalization* marker: the matched array is compared by the content of its values, not by their keys (useful for arrays keyed by volatile values, when UUID auto-detection does not apply).

### Exit codes

[](#exit-codes)

CodeMeaning`0`Channels are identical.`1`Differences were found.`2`An error occurred (e.g. an invalid path).### Examples

[](#examples)

Compare two channels with human-readable output:

```
php bin/console channel:diff \
    ~/ies-environments/site/data/publications/host/www/resources \
    ~/ies-environments/site/data/publications/host/preview/resources
```

Produce a machine-readable report for CI:

```
php bin/console channel:diff /path/to/A /path/to/B --format=json > diff.json
```

Ignore additional fields, both inline and via a config file:

```
php bin/console channel:diff /path/to/A /path/to/B \
    --ignore=ies \
    --ignore=base.germanCourse.venue.link \
    --ignore-config=ignore.php
```

An `ignore.php` config file simply returns a list of field paths:

```
