An overlay script for composer, providing support for composer.yaml
files.
This project was initiated to address the lack of support for YAML format in composer.
Indeed, YAML
has several advantages over JSON
:
-
It supports comments, natively.
In the meantime developers must use awful hacks to insert comments in theirJSON
contents, like creating fake_comment
properties... -
It's human-readable.
Ever struggled with a merge conflict on acomposer.lock
file? Tough huh?
A concrete example: the yamltools lock file.
#
# This file was generated automatically by Offenbach
# @see https://github.com/yannoff/offenbach for details
#
_readme:
- 'This file locks the dependencies of your project to a known state'
- 'Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies'
- 'This file is @generated automatically'
content-hash: bbb0e45340feb244228603615130c04f
packages:
-
name: symfony/polyfill-ctype
version: v1.19.0
source:
type: git
url: 'https://github.com/symfony/polyfill-ctype.git'
reference: aed596913b70fae57be53d86faa2e9ef85a2297b
dist:
type: zip
url: 'https://api.github.com/repos/symfony/polyfill-ctype/zipball/aed596913b70fae57be53d86faa2e9ef85a2297b'
reference: aed596913b70fae57be53d86faa2e9ef85a2297b
shasum: ''
require:
php: '>=5.3.3'
suggest:
ext-ctype: 'For best performance'
type: library
extra:
branch-alias:
dev-main: 1.19-dev
thanks:
name: symfony/polyfill
url: 'https://github.com/symfony/polyfill'
autoload:
psr-4:
Symfony\Polyfill\Ctype\: ''
files:
- bootstrap.php
notification-url: 'https://packagist.org/downloads/'
license:
- MIT
authors:
-
name: 'Gert de Pagter'
email: [email protected]
-
name: 'Symfony Community'
homepage: 'https://symfony.com/contributors'
description: 'Symfony polyfill for ctype functions'
homepage: 'https://symfony.com'
keywords:
- compatibility
- ctype
- polyfill
- portable
support:
source: 'https://github.com/symfony/polyfill-ctype/tree/v1.19.0'
funding:
-
url: 'https://symfony.com/sponsor'
type: custom
-
url: 'https://github.com/fabpot'
type: github
-
url: 'https://tidelift.com/funding/github/packagist/symfony/symfony'
type: tidelift
time: '2020-10-23T09:01:57 00:00'
-
name: symfony/yaml
version: v3.4.47
source:
type: git
url: 'https://github.com/symfony/yaml.git'
reference: 88289caa3c166321883f67fe5130188ebbb47094
dist:
type: zip
url: 'https://api.github.com/repos/symfony/yaml/zipball/88289caa3c166321883f67fe5130188ebbb47094'
reference: 88289caa3c166321883f67fe5130188ebbb47094
shasum: ''
require:
php: ^5.5.9|>=7.0.8
symfony/polyfill-ctype: ~1.8
conflict:
symfony/console: '<3.4'
require-dev:
symfony/console: ~3.4|~4.0
suggest:
symfony/console: 'For validating YAML files using the lint command'
type: library
autoload:
psr-4:
Symfony\Component\Yaml\: ''
exclude-from-classmap:
- /Tests/
notification-url: 'https://packagist.org/downloads/'
license:
- MIT
authors:
-
name: 'Fabien Potencier'
email: [email protected]
-
name: 'Symfony Community'
homepage: 'https://symfony.com/contributors'
description: 'Symfony Yaml Component'
homepage: 'https://symfony.com'
support:
source: 'https://github.com/symfony/yaml/tree/v3.4.47'
funding:
-
url: 'https://symfony.com/sponsor'
type: custom
-
url: 'https://github.com/fabpot'
type: github
-
url: 'https://tidelift.com/funding/github/packagist/symfony/symfony'
type: tidelift
time: '2020-10-24T10:57:07 00:00'
-
name: yannoff/console
version: 1.3.1
source:
type: git
url: 'https://github.com/yannoff/console.git'
reference: a81ecb24f9466684636eea4133e7c7959979220f
dist:
type: zip
url: 'https://api.github.com/repos/yannoff/console/zipball/a81ecb24f9466684636eea4133e7c7959979220f'
reference: a81ecb24f9466684636eea4133e7c7959979220f
shasum: ''
type: library
autoload:
psr-4:
Yannoff\Component\Console\: src/
notification-url: 'https://packagist.org/downloads/'
license:
- MIT
authors:
-
name: Yannoff
homepage: 'https://github.com/yannoff'
description: 'A simple, lightweight console implementation for command-line PHP applications.'
homepage: 'https://github.com/yannoff/console'
support:
issues: 'https://github.com/yannoff/console/issues'
source: 'https://github.com/yannoff/console/tree/1.3.1'
time: '2022-02-22T18:59:49 00:00'
-
name: yannoff/y-a-m-l
version: 1.1.5
source:
type: git
url: 'https://github.com/yannoff/y-a-m-l.git'
reference: 78d0dd8e0f81056ba3ed04ac6b825c3464e8fcae
dist:
type: zip
url: 'https://api.github.com/repos/yannoff/y-a-m-l/zipball/78d0dd8e0f81056ba3ed04ac6b825c3464e8fcae'
reference: 78d0dd8e0f81056ba3ed04ac6b825c3464e8fcae
shasum: ''
require:
ext-json: '*'
require-dev:
squizlabs/php_codesniffer: ^3.4
type: php-library
autoload:
psr-4:
Yannoff\Component\YAML\: src
notification-url: 'https://packagist.org/downloads/'
license:
- MIT
authors:
-
name: Yannoff
homepage: 'https://github.com/yannoff'
description: 'Y.A.M.L : Yaml Abstraction Model Layer'
homepage: 'https://github.com/yannoff/y-a-m-l'
support:
issues: 'https://github.com/yannoff/y-a-m-l/issues'
source: 'https://github.com/yannoff/y-a-m-l/tree/1.1.5'
time: '2021-09-12T13:59:09 00:00'
packages-dev: []
aliases: []
minimum-stability: stable
stability-flags: []
prefer-stable: false
prefer-lowest: false
platform:
php: '>=5.6.40'
ext-json: '*'
platform-dev: []
plugin-api-version: 2.2.0
(1) Should also work on Git Bash / MinTTY, although it has not been tested hitherto.
(2) Will be downloaded at build time by the install script if not found on the system.
The script can be executed on-the-fly, from the target install directory:
curl -L -s -o - https://github.com/yannoff/offenbach/releases/latest/download/install.sh | bash
See the examples section for customized installation examples.
The online installer script supports a few configuration options allowing for a more fine-tuned installation.
Option | Default | Description | Env var |
---|---|---|---|
--install-dir |
$PWD (ie: current directory) |
Offenbach installation directory (3) (4) | OFFENBACH_INSTALL_DIR |
--filename |
offenbach |
Name of the installed executable | OFFENBACH_FILENAME |
--version |
latest |
Alternative version to install | OFFENBACH_VERSION |
(3) For
offenbach
to be accessible globally, the install dir must be in the$PATH
system-wide variable.
(4) The script may be invoked insudo
mode if the install dir is not owned by the standard user.
curl -SL -o /tmp/install.sh https://github.com/yannoff/offenbach/releases/latest/download/install.sh
sudo /tmp/install.sh --install-dir=/usr/local/bin --filename=offenbach
url=https://github.com/yannoff/offenbach/releases/latest/download/install.sh
curl -SL -s -o - ${url} | env OFFENBACH_INSTALL_DIR=$HOME/bin OFFENBACH_VERSION=1.6.1 bash
# Fetch the sources from the repository
git clone https://github.com/yannoff/offenbach
# Enter the project's directory
cd offenbach
# Configure installation (5)
./configure bin/offenbach
# Build
make
# Install executable (6)
sudo make install
(5) The
--help
option will give a thorough overview of the possible customizations.
(6) Depending on the install directory set up,sudo
might not be used.
Offenbach works exactly as composer, indeed it is just an overlay script, acting as a pass-thru for composer commands.
The key principle is really simple: Offenbach will create 2 temporary JSON files before each operation, feed composer with them, then convert them back to YAML format.
From the user's perspective, the only difference is in the composer files:
- The
composer.json
file is replaced by acomposer.yaml
file - The
composer.lock
file is replaced by acomposer-lock.yaml
file
However, a few limitations must be considered.
offenbach
only handles project composer files (7)- projects using
offenbach
instead ofcomposer
will not be eligible for publication on packagist. - only
*.json
and*.yaml
filenames are allowed for theCOMPOSER
env var.
(7) The global composer files in
COMPOSER_HOME
are left in their original standard JSON format.
There are 2 major use cases:
⚠️ Before proceeding, be sure you have read the compatibility notice.
As for a composer project, run:
offenbach init
After prompting for the usual few questions, offenbach will create the 2 composer files:
composer.yaml
(standing for thecomposer.json
file)composer-lock.yaml
(standing for thecomposer.lock
file)
⚠️ BEWARE
Migrating from composer to offenbach is a one-way operation, there is no possible return to use composer back after the project has been migrated.
In a shell terminal, from the project root (i.e. the directory where the composer.json
reside), run:
offenbach migrate
💡 Alternatively, any call to standard composer commands, such as:
offenbach install
offenbach update --lock
will trigger a migration.
As a result, offenbach will use the initial composer.json
and composer.lock
files to build their YAML counterparts (composer.yaml
and composer-lock.yaml
, respectively), then remove them.
Since packagist analysis is based on the project metadata deduced from the composer.json
file contents,
it will fail to recognize offenbach's composer.yaml
file.
As a consequence, projects using offenbach will not be able to publish on packagist.org.
PSR-0 / PSR-4 automatic detection may not work properly on PhpStorm, as it is based on the composer.json
file contents.
Since by default the symfony Kernel::getProjectDir() method uses the composer.json
location to find out the project's root directory, it's necessary to override the method.
For instance:
<?php
// src/Kernel.php
namespace App;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
class Kernel extends BaseKernel
{
use MicroKernelTrait;
// ...
/**
* Don't use composer.json to find the project root
*
* @return string
*/
public function getProjectDir()
{
return dirname(__DIR__);
}
// ...
}
The Application::getNamespace() method (used by some artisan make:*
commands to populate PHP code auto-generated from stubs) relies on the composer.json
contents to find out the application's PSR-4 namespace, and hence must be overriden in a custom Application class.
⚠️ BEWARE
Thesymfony/yaml
component must be part of the dependencies list.
Be sure to add it before implementing the customApplication
class override:offenbach require symfony/yaml
For instance:
<?php
// app/Foundation/Application.php
namespace App\Foundation;
// Don't forget to import the Yaml class
use Symfony\Component\Yaml\Yaml;
class Application extends \Illuminate\Foundation\Application
{
/**
* Override base method to support offenbach
*
* @return string
*
* @throws \RuntimeException
*/
public function getNamespace()
{
// ...
// Original code
//$composer = json_decode(file_get_contents($this->basePath('composer.json')), true);
// Replacement: Add support for composer.yaml beside standard composer.json files
if (file_exists($this->basePath('composer.yaml'))) {
$composer = Yaml::parseFile($this->basePath('composer.yaml'));
} else {
$composer = json_decode(file_get_contents($this->basePath('composer.json')), true);
}
// ...
}
Then use the custom class:
// bootstrap/app.php
$app = App\Foundation\Application(
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);
The project is still in a high development phase. Feedbacks are welcome and encouraged!
Jacques Offenbach (1819-1880) was a German-born French composer of the 19th.
The concepts behind offenbach were highly inspired by the igorw/composer-yaml project.
Licensed under the MIT License.