Have you ever needed to modify composer.json
with PHP code? Then you're family $json['require']['php'] ?? null
structures.
They're hell to work with as any other array - verify the value if it's null, how deeply nested it is, etc.
This is typical use case for a monorepo, where we need to merge many nested composer.json
files into a root composer.json
.
With an array, it's mission impossible. What about intuitive methods on simple value object? You'd expect such package to exist in PHP world - but there is none. So we made an object wrapper that handles all your worries:
/** @var \Symplify\ComposerJsonManipulator\ValueObject\ComposerJson $composerJson */
$composerJson = ...;
// get directories that should exists
$composerJson->getAbsoluteAutoloadDirectories();
// get minimum stability
$composerJson->getMinimumStability();
// it's ready for print
$composerJson->getJsonArray();
// change value
$composerJson->setLicense('MIT');
We've been testing the symplify/composer-json-manipulator package for a couple of weeks months, just to be sure it works well in practise.
It has over 240 000 downloads now.
ComposerJson
objectcomposer require symplify/composer-json-manipulator --dev
Register bundle:
// config/bundles.php
declare(strict_types=1);
return [
Symplify\ComposerJsonManipulator\ComposerJsonManipulatorBundle::class => [
'all' => true,
],
];
ComposerJson
with a Factorydeclare(strict_types=1);
namespace App;
use Symplify\ComposerJsonManipulator\ComposerJsonFactory;
use Symplify\ComposerJsonManipulator\ValueObject\ComposerJson;
use Symplify\SmartFileSystem\SmartFileInfo;
final class SomeClass
{
/**
* @var ComposerJsonFactory
*/
private $composerJsonFactory;
public function __construct(ComposerJsonFactory $composerJsonFactory)
{
$this->composerJsonFactory = $composerJsonFactory;
}
public function createFromExisting(): ComposerJson
{
$fileInfo = new SmartFileInfo(getcwd() . '/composer.json');
$composerJson = $this->composerJsonFactory->createFromFileInfo($fileInfo);
// analyse/modify $composerJson
return $composerJson;
}
public function createNew(): ComposerJson
{
$composerJson = $this->composerJsonFactory->createEmpty();
$composerJson->setPreferStable(true);
return $composerJson;
}
}
ComposerJson
namespace App;
use Symplify\ComposerJsonManipulator\Printer\ComposerJsonPrinter;
class SomeClass
{
/**
* @var ComposerJsonPrinter
*/
private $composerJsonPrinter;
public function __construct(ComposerJsonPrinter $composerJsonPrinter)
{
$this->composerJsonPrinter = $composerJsonPrinter;
}
public function printAndReport(ComposerJson $composerJson)
{
// the file is saved + printed content returned
$printedContent = $this->composerJsonPrinter->print(
$composerJson,
getcwd() . '/composer.json'
);
// show it to user $printedContent, so they know what was printed
}
}
That's it! The ComposerJson
is not 1:1 to full composer schema. That would be a mess full of methods and constants that are rarely used in practice. Instead, it has only the method we used.
Do you miss some method? No problem, send a pull-request to add it. That way, we'll know someone will use it and we'll be happy to merge it.
Happy coding!