Home » Php » php – How to move composer dependency from require-dev to require?

php – How to move composer dependency from require-dev to require?

Posted by: admin July 12, 2020 Leave a comment

Questions:

I have two projects on my git repo server. The first one is a library I wrote, let’s call it foo/lib-bar. The second is an application which uses that library foo/app-bar. Currently the library is in development version, so the composer.json file of the library looks like this:

{
    "name": "foo/lib-bar",
    "description": "Bar library",
    "version": "1.0.0-dev",
    "type": "library",
    "require": {
        "php": ">=5.4",
        "ext-posix": "*"
    }
}

The application uses this library, so it contains the necessary requirement:

{
    "name": "foo/app-bar",
    "description": "Bar application",
    "version": "0.5.0-dev",
    "type": "application",
    "repositories": [
        {
            "type": "vcs",
            "url": "ssh://[email protected]/lib-foo"
        }
    ],
    "require-dev": {
        "foo/lib-bar": ">=1.0.0-dev",
    },
    "require": {
        "php": ">=5.5.3"
    }
}

And everything is smooth up to this point: both composer install and composer update run as expected, install the dependency and I can see it in vendor/

Now, the docs says that

require#

Lists packages required by this package. The package will not be installed unless those requirements can be met.

And for the steps which lead to the issue in question:

So ok, my library is ready to be deployed and come out of the development phase. It also happens to be required in production version of my application. I remove the dev suffix from the composer.json file of my library, commit and push the file, and am ready to update the application.

With the application’s composer.json I move the library dependency from require-dev section to require and remove the dev suffix (everything is copy-pasted, so there is no typo – I’ve checked and rechecked again):

    "require-dev": {},
    "require": {
        "php": ">=5.5.3",
        "foo/lib-bar": ">=1.0.0"
    }

Now I run composer update and I get:

$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)                     
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for foo/lib-bar >=1.0.0 -> satisfiable by foo/lib-bar[dev-master].
    - Removal request for foo/lib-bar == 9999999-dev

I assumed it did not find the new version, so I deleted the old library manually:

$ rm composer.lock
$ rm -rf vendor/foo/

and tried to install it from scratch

$ composer install

but this time it gives me:

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - The requested package foo/lib-bar could not be found in any version, there may be a typo in the package name.

So it seems like require-dev does work, but require doesn’t. Any suggestions on what may have gone wrong here?

How to&Answers:

require-dev is not the place to develop dependencies. It is meant for software that is used only in development, like PHPUnit, Mockery etc., or for dependencies that are useful by themselves, but in this case only used for development, like the client library for the service a software package is about (to make some real requests in a test scenario).

So your library shouldn’t have been “require-dev” from the beginning.

Another thing is: Composer will deduct the version if use appropriate branches and tags, i.e. a branch named “1.0.x” in your repository will be detected as being the development branch for all 1.0 versions, and any requirements for such versions could possibly be satisfied by this branch – provided you allow for development versions either by setting "minimum-stability": "dev" (which would allow development versions for ALL software – rather unintended), or when you require version "[email protected]" for your software.

The one thing that might currently break your composer setup is that you mention a version in the librarys composer.json explicitly, and this is a development version. Have you removed that version indicator? You should remove it, because life is easier if Composer can detect the versions from the tags in a repository, not by having them explicitly mentioned in composer.json.

Finally please make sure that when using Git you tag the commit with appropriate version. The required version should correspond to the git tagged version.