Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

composer install from two composer.json file

I have multiple composer.json having multiple seperate dependency and want to install all the dependency in the both composer.json using single composer install command.

The location is like this:

| - composer.json
| - Custom
    | - Package1
        | - composer.json

First composer.json

{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": ">=5.6.4",
        "barryvdh/laravel-debugbar": "^2.3",
        "laravel/framework": "5.4.*",
        "laravel/tinker": "~1.0",
        "laravelcollective/html": "^5.4.0"
    },
    "require-dev": {
        "fzaninotto/faker": "~1.4",
        "mockery/mockery": "0.9.*",
        "phpunit/phpunit": "~5.7",
        "symfony/css-selector": "3.1.*",
        "symfony/dom-crawler": "3.1.*"
    },
    "autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\\": "app/",
        }
    },
    "autoload-dev": {
        "psr-4": {
          "Tests\\": "tests/"
        }
    },
    "scripts": {
        "post-root-package-install": [
            "php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "php artisan key:generate"
        ],
        "post-install-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postInstall",
            "php artisan optimize"
        ],
        "post-update-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postUpdate",
            "php artisan optimize"
        ]
    },
    "config": {
        "preferred-install": "dist",
        "sort-packages": true,
        "optimize-autoloader": true
    }
}

Second composer.json inside Package1 directory

{
    "name": "custom/package1",
    "description": "",
    "require": {
        "php": ">=5.6",
        "composer/installers": "~1.0",
        "lavary/laravel-menu": "1.7.1"
    },
    "autoload": {
        "psr-4": {
            "Custom\\Package1\\": ""
        }
    }
}

I want to install the lavary/laravel-menu inside the Package1 to the main vendor directory where all the default packages are installed.

|- vendor  //<==want here
| - composer.json
    | - Custom
        | - Package1
            | - vendor  //<== not here
            | - composer.json

I have tested this solution:

https://stackoverflow.com/a/27735674

like this:

{
    "config": {
        "vendor-dir": "../../vendor/"
    }
}

This installs the packages but we need to get into the second composer.json instead of main composer.json and removes the installed package from first composer.json.

How can i install the all the dependency from the main composer.json without getting into the second or multiple composer.json in single vendor directory?

like image 291
PaladiN Avatar asked Oct 05 '17 07:10

PaladiN


1 Answers

After some research and suggestion i figured out there are multiple ways to achieve this solution.

  1. Using external package to maintain the dependency.

Thanks to rickdenhaan to let me know about

Composer Merge Plugin

https://github.com/wikimedia/composer-merge-plugin

First we need to require this package:

composer require wikimedia/composer-merge-plugin

Then my composer.json becomes like this:

{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": ">=5.6.4",
        "barryvdh/laravel-debugbar": "^2.3",
        "laravel/framework": "5.4.*",
        "laravel/tinker": "~1.0",
        "wikimedia/composer-merge-plugin": "^1.4"
    },
    "require-dev": {
        "fzaninotto/faker": "~1.4",
        "mockery/mockery": "0.9.*",
        "phpunit/phpunit": "~5.7",
        "symfony/css-selector": "3.1.*",
        "symfony/dom-crawler": "3.1.*"
    },
    "autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\\": "app/"
        }
    },
    "autoload-dev": {
        "psr-4": {
          "Tests\\": "tests/"
        }
    },
    "scripts": {
        "post-root-package-install": [
            "php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "php artisan key:generate"
        ],
        "post-install-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postInstall",
            "php artisan optimize"
        ],
        "post-update-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postUpdate",
            "php artisan optimize"
        ]
    },
    "config": {
        "preferred-install": "dist",
        "sort-packages": true,
        "optimize-autoloader": true
    },
    "extra": {
        "merge-plugin": {
            "include": [
                "Custom/*/composer.json"
            ],
            "recurse": true,
            "replace": false,
            "ignore-duplicates": true,
            "merge-dev": true,
            "merge-extra": false,
            "merge-extra-deep": false,
            "merge-scripts": true
        }
    }
}

Now, run

composer install

or

 composer update

Then your composer.json in each of the directory will be merged into default vendor directory.

  1. Next solution could be to publish the package to the packagist and require in the composer.json and during composer install all the dependency will be installed.

    Like the Asgardcms has done.

  2. Adding the private repository to the composer.json.

    Configuring composer.json with private bitbucket mercurial repository

  3. This option needs to add the composer.json of metapackage to the main composer.json file.

(I am not sure about the option but thanks to JParkinson1991 Someone who knows this solution could add explaination on this option. Adding just to let someone know this solution exists.)

Here is the example solution:

PHP & Composer, how do I combine composer.json files

In this the first solution suits my case. Hope this helps someone who spent alot of time searching.

like image 135
PaladiN Avatar answered Sep 19 '22 15:09

PaladiN