Skip to content

Packages ​

This repository is a monorepo. The code is split into packages, and everything else, including this site, is shared at the root.

DirectoryPackageNamespacePurpose
packages/coredpi/namespace-shortener-coreDpi\NamespaceShortener\CoreThe rule itself, working on plain strings. It knows nothing about any tool
packages/php-cs-fixerdpi/namespace-shortener-php-cs-fixerDpi\NamespaceShortener\PhpCsFixerThe adapter for PHP-CS-Fixer
packages/php-codesnifferdpi/namespace-shortener-phpcsDpi\NamespaceShortener\PhpCodeSnifferThe adapter for PHP_CodeSniffer, including its standard

Each adapter depends on the core package and its own tool. Neither depends on the other, so installing one never brings in the other's tool.

At the root ​

PathPurpose
docsThis site
tests/FixturesFixtures shared by the core tests and the adapters
tests/SupportHelpers shared by every package's tests
tests/DocumentationTest.phpChecks that the docs and the code agree
composer.jsonThe development environment, including the autoloading for every package's tests
.php-cs-fixer.dist.php, phpstan.neon, phpunit.xml.distTool configuration, covering every package

Working on it ​

Run composer install at the root, and run everything from there. There's one vendor directory, and vendor/dpi holds symlinks to packages, so a change to a package takes effect immediately. Packages don't have a vendor directory or a lock file of their own.

Adding a tool ​

  1. Create packages/<tool>, with a composer.json requiring the core package at self.version and the tool, and with the dev keyword, so that composer require recommends --dev. Give it the LICENSE and .gitattributes the others have.
  2. Add it to require-dev in the root composer.json at @dev, and to the autoload-dev section for its tests.
  3. Add its src and tests to phpstan.neon, and add a test suite to phpunit.xml.dist.
  4. Translate the conflicts and other exceptions from Rewriter into the tool's failures. Use Rewriter::rewrite() if the tool takes a whole file, or Rewriter::plan() if it reports each change.
  5. Add a tool page, a tab in each guide page that has them, and a row in the table above.
  6. Create its repository, give the SPLIT_TOKEN secret access to it, add it to the matrix in .github/workflows/split.yml, and register it on Packagist.

Versions ​

The packages share one version number, and the Git tag is the only place it's set. Each adapter requires the core package at self.version, which means exactly the adapter's own version, so nothing needs raising before you tag.

Locally, Composer takes the packages' version from Git, such as dev-main, and the root composer.json accepts it with @dev. Running composer update on another branch changes those versions in composer.lock, so don't commit that part of the change.

Publishing ​

Composer needs each package's composer.json at the root of its own repository, so .github/workflows/split.yml uses splitsh-lite to split each directory in packages out to a read-only repository, each registered on Packagist:

DirectoryRepository
packages/coredpi/namespace-shortener-core
packages/php-cs-fixerdpi/namespace-shortener-php-cs-fixer
packages/php-codesnifferdpi/namespace-shortener-phpcs

Every push to main updates each repository's main, so make changes here, not there. Pushing a tag starting with v to this repository creates the same tag in all of them, which publishes that version of every package:

sh
git tag v1.0.0-beta2
git push origin v1.0.0-beta2

The workflow pushes with the SPLIT_TOKEN secret, a fine-grained personal access token with read and write access to the contents of those repositories. It never force pushes, so its run fails if a repository has diverged, or if a tag already exists there on a different commit.