Symfony Flex for all frameworks? The Composer Synchronizer plugin makes that possible!

4 min June 09, 2018

Package installation without further configuration. How does it sounds? Symfony solved it with the amazing symfony/flex package. Composer Synchronizer is an upcoming alternative for every other framework.

Symfony Flex for all frameworks? The Composer Synchronizer plugin makes that possible!

For those who don't know, the Symfony/Flex package simply installs and setups all the necessary things for you during the package installation. Because I have sometime missed this cool feature during the work with different frameworks I have decided to create a solution that would be possible to use in every other framework.

First a small example

Let's say you use one of the actually upcoming supported frameworks like the Nette Framework, CakePhp or the Yii framework and you wan't to install a package.

In the following example I am using the Nette Framework and I have decided to install the machy8/webloader package. To make it works I need to do 3 steps: Install the synchronizer, configure the project and install the selected package.

(For CakePhp you can try it too with the cakephp/elastic-search:1.5.0 and for the Yii framework with the yiisoft/yii2-twig:2.2.0 package).

1. Installing the synchronizer


composer require composer-synchronizer/composer-synchronizer

(For the CakePhp and Yii framework you need to use the @dev version because synchronizers for those frameworks are for now available only in the master branch.)

2. Configuring the project

The required minimal configuration is just setting the project type (that is different for each framework) of the framework you use in the extra section in the composer.json file in your project root directory.

(The project type for CakePhp is cakePhp and for the Yii framework is yii.)


"extra": {
    "composer-synchronizer": {
        "project-type": "nette"
    }
}

3. Installing the package


composer require machy8/webloader

Thats it. During the installation the minimal correct configuration have been copied into the configuration directory and the webtemp directory with the gitignore file was created. Now I can use it without any configuration.

Note

Based on framework you use, during the first installation the synchronizer performs initialization processes like copying the required files on the appropriate places.

(See documentation for the CakePhp and the Yii framework.)

How does it works?

During the installation synchronizer looks for the project type in the composer.json file in the extra section. If the project type is set, then the synchronizer is enabled and if some package that contains the synchronizer configuration (local or remote) is installed then the synchronizer will process the configuration sections so it can for example copy files, make directories, update the project root .gitignore file and etc.

As mentioned above, configuration can be local (preferred) so it comes directly with the installed package or remote. The possibility to add a remote configuration into the Github repository is intended for those packages whose author didnt add the configuration but you want to use it anyway 😃.

Should I add a configuration to my package?

Yes. Why? Because you can deliver the minimal configuration for your package directly and it can simplify the whole package installation.

How can I configure my package?

If you want to configure your package, you need to read the documentation for you framework synchronizer.

Also see the configuration examples and use the playground for the configuration development and testing.

Configuration examples:

Remote - for the webloader package:


{
    "resources": {
        "webloader.neon": "%configDir%/webloader/",
        "webtemp/": "%wwwDir%/webtemp/"
    },
    "includes": [
        "webloader/webloader.neon"
    ]
}

Local - used in the machy8/macdom package:


"composer-synchronizer": {
    "nette2": {
        "resources": {
            "composer-synchronizer/nette2/": "%configDir%/macdom/"
        },
        "includes": [
            "macdom/macdom.neon"
        ]
    }
}

Synchronizer for my favorite framework is missing!

A few simple steps, one pull request and the synchronizer for your favorite framework is done! The [documentation] contains the necessary info for the synchronizer development and for example the Nette synchronizer can serve as an example. The minimal synchronizer without any extra features can looks like this:


final class Nette2Synchronizer extends AbstractSynchronizer
{
    private const CONFIGURATION_FILE = 'composer-synchronizer.neon';
    private const CONFIGURATION_FILE_INDENTATION_CHARACTER = "\t";
    private const PATHS_PLACEHOLDERS = [
        'appDir' => 'app',
        'configDir' => 'app/config',
        'logDir' => 'log',
        'tempDir' => 'temp',
        'wwwDir' => 'www',
    ];

    public static function getAliases(): array
    {
        return ['nette'];
    }

    public static function getVersionedName(): string
    {
        return 'nette2';
    }

    protected function getPathsPlaceholders(): array
    {
        return self::PATHS_PLACEHOLDERS;
    }
}

Let me know what do you think!