This question already has answers here:
What is the difference between require and require-dev sections in composer.json?
(6 answers)
Closed 4 years ago.
I would like to know the difference between require and require-dev.
The composer website doesn't offer a good explanation the difference between these two.
The part that I don't get is Lists packages required for developing this package, or running tests, etc. from Composer Official Docs.
The require-dev packages are packages that aren't necessary for your project to work and shouldn't be included in the production version of your project.
Typically, these are packages such as phpunit/phpunit that you would only use during development.
The key distinction is that Composer will only install require-dev dependencies for the "root package" – the directory where you run composer install. The documentation describes this as:
The root package is the package defined by the composer.json at the
root of your project. It is the main composer.json that defines your
project requirements.
…and the require-dev documentation specifies that it is "root-only".
In practice, this means that a package's require-dev dependencies aren't used if the package is being installed as a dependency for something else (ie it's installed to another project's vendor folder).
So if you have phpunit in the require-dev list for YourProject, and I clone down YourProject and run composer install in the yourproject/ directory, Composer will install phpunit to yourproject/vendor/, because it's likely I'm doing some development on YourProject. As part of doing development I'll probably want to run YourProject's test suite, and to do that I'll need phpunit.
But, if I add YourProject as a dependency of MyProject, installing the myproject package will install the yourproject package as well, but it will not install phpunit.
You can override this behaviour with the --dev and --no-dev options, but the default behaviour is based on whether the package concerned is the root package.
seems clear to me:
require
Lists packages required by this package. The package will not be
installed unless those requirements can be met.
require-dev (root-only)
Lists packages required for developing this package (1), or running tests,
etc. The dev requirements of the root package only will be installed
if install is run with --dev or if update is run without --no-dev.
http://getcomposer.org/doc/04-schema.md
1. the packages used to develop a package
Related
I'm currently working on a package (cms), which has a dev-dependency to a certain package (code-generator) to create code. This package is not needed in production.
However, when creating a website that uses the cms package, dev-dependencies (including the code-generator) are not installed (which is correct composer behavior btw).
But while developing the website, the code-generator is required.
Is there any way to force a certain dev-dependency to also install when the package is installed?
This is not possible. Dependency can either be required for the package to work properly (then it should be in require section and it is always installed), or required only for development of this package (then it should be in require-dev section and is installed only when package repository is root). There is nothing in between. If this code-generator dependency is required by your package to work it clearly fails into first category (require section).
Usually in this case the best solution is to split this package into 2 packages: regular package and dev package with all tools used only during development process. So it should be installed by 2 commands:
composer require myvendor/mypackage
composer require myvendor/mypackage-dev --dev
This will still require everyone to install two packages instead of one, but it should not be a big problem if it is properly documented. Result should is more clear (it should be quite obvious what is the purpose of myvendor/mypackage-dev package) and gives more control to package owner (he can easily add new dependencies for dev package) and end user (he can always skip installing myvendor/mypackage-dev if he don't want to use this code generator).
I have a Laravel App and I want to install require dependencies but I was wondering how does composer know whether to load dev dependencies or production dependencies?
just got confused by this concept so if somebody could clarify this concept for me than that would be of great help.
When you run composer install --dev, composer installs all packages including require-dev. This is the default behaviour, exclusion of the flag would result in the same action.
When you run composer install --no-dev, composer skips the require-dev packages.
Also, composer will not install the require-dev package of a required package unless you specifically ask it to do so
The regular require dependencies are such packages that you will ALWAYS use, meaning that the framework itself (in this case Laravel), your application code and/or other 3rd party code is dependent on such packages. These dependencies are often referred as prod dependencies since you use them in production (because without them, your app wouldn't run)
The require-dev dependencies are "optional", in the sense that your core application logic would run, but you would not be able to run "development" stuff, such as Unit tests (phpunit/phpunit package) and instantiate fake data (fzaninotto/faker).
I hope this helps!
I freshly installed a PHP application given with a composer.lock file.
When running composer install, command line tool is still asking for a composer.json.... I don't have.
In composer documentation, it's said that install command first look for a composer.lock and then for a composer.json.
Why composer is still asking for a file it doesn't need to install my dependencies ?
composer install > returns :
Composer could not find a composer.json file
You still need the composer.json file to install or update any dependencies.
Having a composer.lock file means that composer will not search for the latest commits of the dependencies
A few weeks ago on Twitter, I noticed that the OpenCFP project doesn’t have a composer.lock file in it’s repository. “So what,” you might say, “just composer install and away you go. You’ll get the same dependencies, right?”
Wrong.
The point of the lock file is to record the exact versions that are installed so they can be re-installed. This means that if you have a version spec of 1.* and your co-worker runs composer update which installs 1.2.4, and then commits the composer.lock file, when you composer install, you will also get 1.2.4, even if 1.3.0 has been released. This ensures everybody working on the project has the same exact version.
Source: Composer: It's all about Lock File
You must have a composer.json to install dependencies, because it's the file where dependencies theirself are listed. Refer to the documentation.
composer.lock lists dependencies which has already been installed. The composer looks first into it in order to keep versions consistent.
The (documentation states)[https://getcomposer.org/doc/01-basic-usage.md#installing-with-composer-lock]:
running install when a composer.lock file is present resolves and installs all dependencies that you listed in composer.json, but Composer uses the exact versions listed in composer.lock to ensure that the package versions are consistent for everyone working on your project.
If you have lost your composer.json you can reverse engineering your composer.lock. Open it and read all the packages installed, then create a composer.json which requires them. Not every single package will be a direct dependency for your problem: you should identify and remove those which are not.
I see I can add the following to my composer.json file:
{
"require-dev": {
"phpunit/phpunit": "4.2.*"
}
}
But I have PHPUnit installed, I can run it from the command line without the above. Why would I install it as a dependency? Does that mean I don't need to install it?
Also, the following let's me install it globally - composer global require "phpunit/phpunit=4.2.*" - where is this set? If I install it globally, can I unrequire it later if I choose to install on a project by project basis. I'm really just finding my way around the framework and don't want to set anything I can't reverse.
http://phpunit.de/manual/current/en/installation.html
You don't have to use a require-dev section for your development dependencies, if they are already on your development machines. If PHPUnit is already globally installed, there is no need to install it in your project.
When your project has a lot of developers, you can't pretend that all of them have PHPUnit installed globally. Also, the PHPUnit version used in your project might matter. By using the require-dev section you explicitly say, that this specific version is a development dependency. When working with Continuous Integration servers, some of them have PHPUnit installed globally, some of them, like Jenkins would need additional steps (like a global installation) then it becomes handy to install the dependency on a per-project level.
The command composer global require "phpunit/phpunit=4.2.*" will install PHPUnit and all its dependencies into the ~/.composer/vendor/ directory and the CLI tools into the bin folder ~/.composer/vendor/bin/. As you can see this is a per user installation (~).
You can remove it by editing the ~/.composer/composer.json file, removing the PHPUnit dependency and then running composer global update.
I've been working with the Magento Firegento custom Composer installer, and I ran into this odd bit of Composer behavior I don't understand.
Consider the following dead simple composer.json file
{
"require": {
"magento-hackathon/magento-composer-installer": "*"
}
}
If I run compser.phar install with this composer.json file, I get the following.
$ composer.phar install --no-dev
Loading composer repositories with package information
Installing dependencies
- Installing aoepeople/composer-installers (v0.0.1)
Loading from cache
Writing lock file
Generating autoload files
From my mostly lay-person's understanding composer.phar, I've said
Hey, composer, please install the magento-hackathon/magento-composer-installer package from packagist.org
And composer has said back to me
Sir, yes sir! Here's the aoepeople/composer-installers package
I don't understand why composer installed aoepeople/composer-installers, when I asked for magento-hackathon/magento-composer-installer.
To be clear: I understand the reason magento-hackathon/magento-composer-installer wasn't installed is this is a package that lives in a different composer repository. My original mistake was not including this repository in my composer.json file.
However, it doesn't make sense to me that composer would install a different package than the one I asked for. When I search packagist there's no magento-hackathon/magento-composer-installer extension.
Why does packagist install a different extension? What's happening behind the scenes to make magento-hackathon/magento-composer-installer resolve to aoepeople/composer-installers? How/where in the composer source could I debug this sort of thing myself in the future?
Vinai published a great writeup on Magento and Composer here.
Quoting from there
Composer will use packagist.org to look where to get the libraries. Because Magento modules aren’t listed there, you will have to add the packages.firegento.org repository to the configuration as follows [...]
So you will need the repository
"repositories":[
{
"type":"composer",
"url":"http://packages.firegento.com"
}
],
to get the magento composer installer.
And yes composer offers replacements. On the packaging entry for aoepeople/composer-installers you will notice the replaces section:
And since magento-hackathon/magento-composer-installer is not available on packagist composer will deliver you aoepeople/composer-installers.
OK, so that's a weird behavior :) I'm the author of the aoepeople/composer-installers package and the idea behind this is that this package provides an alternative (very basic and simplified implementation of the composer package-type magento-module - and adds another type magento-source. I only want the installer to put the package in the right place - keeping it simple. That's why I decided to come up with an alternative package.
The reason why the aoepeople/composer-installer replaces the magento-hackathon/magento-composer-installer is because many Magento modules already come with a composer.json that requires the magento-hackathon/magento-composer-installer. In order to be able to seamlessly use the simpler installer that one is "pretending" to be the hackathon-installer. But unless you actively require aoepeople/composer-installers in your project's composer.json you should continue using the original installer as no Magento module's composer.json out there (not even ours) is directly referring to aoepeople/composer-installers.
The fact that packagist tries to be "smart" and returns a package that replaces a package that's not registered is new to me and - to be honest - very disturbing. While this might be intended behavior I share the opinion that this could easily be abused. I start liking Alan's idea to bypass packagist completely using "packagist":"disabled". Especially in the case of Magento modules this seems to happen easily because most of the Magento modules are unknown to packagist while being registered at packages.firegento.com only.
A simple quickfix/workaround to this specific situation could be to register magento-hackathon/magento-composer-installer on packagist.org.
The Packagist package at https://packagist.org/packages/aoepeople/composer-installers has metadata saying that it replaces the magento-hackathon/magento-composer-installer package. Packagist would then install this as it's the package that replaces what you asked for.
Docs here: https://getcomposer.org/doc/04-schema.md#replace