Can't replace a package with Composer - composer-php

I made an improvement (PR not merged yet) to an upstream library, guzzlehttp/psr-7, that's a dependency of another package that I depend on, spatie/crawler.
To force Composer to use my package instead of the upstream package, I tried the following:
I branched my fork of the library (branch name: cache-to-string) and updated its composer.json:
"name": "benmorel/guzzle-psr7",
"replace": {
"guzzlehttp/psr7": "1.6.*"
}
I updated my project's composer.json to use my fork instead:
"repositories": [
{
"type": "vcs",
"url": "https://github.com/BenMorel/psr7"
}
],
"require": {
"benmorel/guzzle-psr7": "dev-cache-to-string"
}
And ran composer update, which fails with the following error:
Your requirements could not be resolved to an installable set of packages.
Problem 1
The requested package benmorel/guzzle-psr7 could not be found in any version, there may be a typo in the package name.
How to fix this?

You don't need to change package name in your fork. You don't need to change composer.json of your fork at all. All you need is to add your fork to repositories section and change constraint of required package to use your dev branch:
"repositories": [
{
"type": "vcs",
"url": "https://github.com/BenMorel/psr7"
}
],
"require": {
"guzzlehttp/psr7": "dev-cache-to-string as 1.6.1"
}
Composer will override original guzzlehttp/psr7 package by version from your repository.
Using alias for branch may be required if some other package require guzzlehttp/psr7 - dev-cache-to-string will not match ^1.4. If you use dev-cache-to-string as 1.6.1 as a constraint, your branch will be detected as 1.6.1 release.

Related

How to add internal public repository to satis.json?

Need some help in understanding a scenario with satis.json , My question is we have already a package named as ""xamin/handlebars.php" used in our project as a composer dependency and recently this package is abandoned, so we have planned to fork the repository to our internal github and added patches to it. Now it's time to tell my satis.json to use the latest version from our github internal repo.
So I have updated repositories section as
"repositories": [
{"name": "xamin/handlebars.php",
"type": "git",
"url": "git#github.corp.test.com:BE/XaminProject-handlebars.php.git"}
],
and I just kept as it is in require section :
"require": {
"xamin/handlebars.php": "0.10.5",
}
Now if I try to do composer update from my local dev:
It says :
Loading composer repositories with package information
Warning: Accessing satis-new.test.com over http which is an insecure protocol.
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
- The requested package xamin/handlebars.php ^0.10.5 exists as xamin/handlebars.php[v0.10.4, v0.10.0, v0.10.1, v0.10.2, v0.10.3] but these are rejected by your constraint.

Nested dependencies and private repositories with composer

At the company I'm currently working we've recently started to move our code into different private repositories so that it's more maintainable and reusable (and also to make it easier to open-source it later).
Every PHP repository is also a Composer package that can be required in our project whenever we need it.
At the moment there's an issue with this approach: every time we need a package that depends on other packages we need to specify those also in the root composer.json.
For example, let's say that the in the root composer.json we need to require two packages company\b and company\c, and that the package company\c needs another package company\d. Then the resulting root composer.json will look like this:
{
"require": {
"company/b": "dev-master",
"company/c": "dev-master",
"company/d": "dev-master"
},
"autoload": {
"psr-4": {
"Company\\" : "src\Company"
}
},
"repositories": [
{
"type": "vcs",
"url": "git#bitbucket.org:company/b.git"
},
{
"type": "vcs",
"url": "git#bitbucket.org:company/c.git"
},
{
"type": "vcs",
"url": "git#bitbucket.org:company/d.git"
}
]
}
Is there a way to avoid specifying nested dependencies in the root composer.json and use the ones specified in the composer.json in every package?
Edit:
Everything I stated before is valid only for the private packages. If a package, let's say company\b, needs a public package that can be found on Packagist then that dependency CAN be specified in the company\b composer.json and it will be imported.
As you correctly found out, only the root package can add repository metadata to the collection of known packages.
I would suggest you take a look at Satis to create a local Composer repository. This would only require you to add this single repository to all your composer.json files of all packages, and it will be used as an updatable source of knowledge about all your private repositories. You no longer have to add a list of Git repos everywhere.
I am successfully hosting around 120 internal packages for our IT enterprise that way. Take this as a sign that once you start splitting isolated tasks into a package, you will get more of them pretty fast.
Also note that it is important to take versioning seriously. Stop depending on branches - tag your software, make releases, use semantic versioning. If you don't, things will break at some point, and people will curse you (correct) or Composer (incorrect) for not working or messing things up.
After a quick search and a look at the Composer documentation I discovered that the repositories can only be specified in the root composer.json.
Additionally it's possible to specify in the root composer.json whether to allow or not development versions of the packages using:
"minimum-stability": "dev",
"prefer-stable": true
Also this issue on GitHub was really useful.

Composer VCS repository not loading dependancies

I'm including a private git repository via composer, and it's loading as expected from bitbucket, however I have codeception defined as a public dependency in my private package.
My private package is loaded, but none of it's dependencies are added. I have read that composer does not support recursive loading of dependancies when using repositories: https://getcomposer.org/doc/faqs/why-can%27t-composer-load-repositories-recursively.md
However my understanding of this is that my private repository can't define another private repository, but should still be able to make use of public repositories defined on packagist.org
Private repositories composer.json:
{
"name": "private/dependancy",
"description": "Private git dependency",
"type" : "library",
"require-dev": {
"codeception/codeception": "*"
}
}
Project's composer.json (Trimmed down to relevant sections)
{
"name": "primary/project",
"description": "Main project including a vcs dependancy",
"require": {
"private/dependancy" : "0.0.*"
},
"repositories":[
{
"type" : "vcs",
"url" : "some repo",
"options": {
"ssh2": "some crednetials"
}
}
]
}
Any guidance on this would be greatly appreciated.
Composer will not install dev-dependencies of the packages you require yourself.
Your primary/project requires private/dependency, which does not require anything else. Anything listed as require-dev is not installed, because that is considered to be used when developing private/dependency, not when using it.
Another thing that only get's evaluated when running Composer on the primary composer.json and not explicitly excluding dev dependencies is "autoload-dev".
composer install --no-dev
will not install ANY dev dependencies and not create autoloading for dev.
composer install
will install dev dependencies of the primary project, and create autoloading for dev - it will never install dev dependencies of any of the packages added via require or require-dev, and not add their autoload-dev.

composer.json not loading forked repo

I used How to require a fork with composer and https://getcomposer.org/doc/05-repositories.md#vcs to come up with the composer.json file below. I forked a lib to update the composer.json file and it is not loading mine. It is loading the original repo.
"repositories": [{
"type": "vcs",
"url": "https://github.com/Dylan-Buth/gopher"
}],
"require": {
"laravel/framework": "~5.0",
"indatus/gopher": "1.*"
},
Even after you fork the repository, composer will still try to resolve version 1.*. So it will get your forked repository, but it will look up the latest 1.* version. Even if you put * as the version requirement, it will still get the latest tag, not the latest commit.
If you want the latest commit, you can put dev-master as the required version string. Alternatively you could modify the composer.json in your forked package to "alias" the version you want:
{
"extra": {
"branch-alias": {
"dev-master": "1.1"
}
}
}

Can I use Composer to clone git repo of a package unavailable in Packagist?

I would like to use jquery DataTables within my project. Since the package is not available in Packagist, I am trying to use composer to clone the git repo of DataTables but it fails. Please advise how to proceed:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/DataTables/DataTables"
}
],
"require": {
"DataTables/DataTables": "master"
}
}
Then composer update returns:
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
- The requested package datatables could not be found in any version, there
may be a typo in the package name.
Potential causes:
- A typo in the package name
- The package is not available in a stable-enough version according to your min
imum-stability setting
see <https://groups.google.com/d/topic/composer-dev/_g3ASeIFlrc/discussion> f
or more details.
Read <http://getcomposer.org/doc/articles/troubleshooting.md> for further common
problems.
I would further like to clone/download a specific version of the repo.
Old question and answer, however:
The error is not in the name of the package (that is indeed DataTables/DataTables) but in the indication of the stability. If you want the 'master' branch, you need to write 'dev-master' in composer and the stability level is dev. Otherwise require a specific tag.
In your case:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/DataTables/DataTables"
}
],
"require": {
"DataTables/DataTables": "dev-master"
}
}
will work as expected:
root#erme:/usr/local/munk_php/jquerydatatables# composer install
Loading composer repositorInstalling dependencies (including require-dev)
- Installing datatables/datatables (dev-master 96b7ef9)
Cloning 96b7ef9176543bbf1f1488c0f9538ad9dcc9bc01
Writing lock file
Generating autoload files
The package name in https://github.com/DataTables/DataTables/blob/master/component.json isn't DataTables/DataTables
Try
"require": {
"DataTables": "dev-master"
}

Resources