Comparing to other package managers like npm, I find that composer has a strange behaviour when updating packages related to a given project.
According also to the documentation, update and upgrade options
Upgrades your dependencies to the latest version according to composer.json, and updates the composer.lock file.
And indeed, composer.lock is correctly updated with new packages version numbers. But composer.json instead is not modified, and lists packages with their old, outdated version numbers.
Why does this happen? Am I doing something wrong, or this is indeed how this is supposed to work? And if this is the case, what is the reasoning behind having one of thw two files up-to-date while the other is not?
That's the normal behavior.
Composer update looks for updates based on your composer.json file, so here it will look for 4.2 and above (^4.2)
If you want your composer.json to require 4.3 and above (^4.3), you can either modify it manually or call composer require once again.
Related
I'm currently experimenting with the Satis. I would like to be able to get the exact version of my private packages somewhere, so everything that is normally in the composer.lock. I always commit the composer.lock via Git.
But if I understand that correctly, the Satis in its packages.json always only includes the require parts, i.e. the sections from my composer.json and thus of course only version ranges.
Is there a way to configure the Satis so that the composer.locks are also stored or how do I get the exact "snapshot" of my packages?
+++ Example +++
Ok, I try to explain a bit more.
Let's say I have a package my/package. Here I add several files, including a composer.json, in which I define that symfony/console should be installed in a version greater than or equal to 4. Now I do a "composer install" and Symfony is installed in version 4.4. I commit all files, including composer.lock and create a release 1.0.
Now I'm going to the Satis. Here I add my/package and the corresponding repository URL for my/package to satis.json and update it. The Satis checks out my package correctly and in packages.json or more precisely the all*.json my package is listed with version 1.0. So far everything is fine.
But if I now take a look at the metadata that Satis stores for my package in all*.json, I see here practically my specified requirements, i.e. that symfony/console should be installed in a version greater than or equal to 4. So Satis takes a snapshot of the composer.json and apparently ignores the composer.lock. So I have no chance to see that my release 1.0 works with the exact version 4.4 of Symfony, while for example a release 1.1 works with symfony/console 4.5. But this information is interesting for me.
When installing a package, Composer recalculates all dependencies on the fly. This is based on the composer.json of your application and the composer.json files of all dependencies.
A composer.lock should not be part of any package, and it is not taken into account when a package is installed.
So, I've now built a workaround. The whole thing is not quite perfect, since the runtime for large repositories is relatively long, which is why I have to run it as a cron once a day. But it works fine.
I have created a new Satis console command.
This command uses the PackageSelection class to determine all existing packages.
I iterate over the package list and look for the paths and names to the dist files.
I extract the ZIP files in memory and look for the composer.lock. If there is one, I parse it and read the exact version numbers of the dependent packages.
I summarize the information in a separate JSON file and store it in parallel to packages.json under htdocs. From there I can call it up and integrate it into my own application or process it further.
I'm currently using composer for managing my projects requirements. One of the packages I use have a bug, which is fixed in the dev branch of this package, so I used "dev-dev#dev".
The problem is, the composer.json file of the given package, also requires and dev package of another package, which I dont want to install (actually I can't because of other requirements..)
Is there a way to tell composer, to ignore the requirements of my dev package, or how could I sovle this without patching the extension on my own?
need a --ignore-platform-requirements or such flag that skips those requirements while loading packages
Suppose I install package for CKEditor through Composer and manually add new skins and plugins to it. How Composer will handle this, when next update to base package will be released?
Will it overwrite entire package directory (deleting local changes) or update only listed files?
Also, I'm having problems updating one package to newest version and made that update locally, manually. Yet, composer status shows No local changes. Does this mean, that Composer itself does not check contents of each package's folder for local changes, only operates on differences between composer.json and composer.lock?
Composer will updated to newest version matched to version what you've added in composer.json and yes - it will overwrite existing package (including all of yours changes) but it will omit files which not exist in packages.
Command: "composer status" shows all changes in files what belongs to specified package. If you will change some file then it will be shown in that list, but if you will add a new one then of course not.
Generally, your approach might work in some cases but I strongly DO NOT recommend it. Problem will be when you create some file, and then will be added into package (for example in newer version).
You should just use all packages "as is" directly in your application, and within it add new stuff, or another configuration, etc.
Will it overwrite entire package directory (deleting local changes) or update only listed files?
Yes. When updating a package Composer removes the current version of the package and installs the new one.
Also, I'm having problems updating one package to newest version and made that update locally, manually. Yet, composer status shows No local changes. Does this mean, that Composer itself does not check contents of each package's folder for local changes, only operates on differences between composer.json and composer.lock?
The 1.* part in your composer.json tells Composer to only update when there is a new release available in the 1.* version range. New commits are not a new release. A new update will be available when the package owner creates a new release with a higher version number. If you want to update after each new commit you should change "1.*" to "dev-master".
I've been developing a lot of packages for composer recently, as our company is moving to composer for package management, but I'm running into issues with how to handle versions.
I've been using the git workflow, with tagged releases, but this means I can't go back to a previous major or minor release and make a patch release for it. I also have been running into issues with understanding how tagged development/beta/RC releases work with composer.
I've seen other projects use branch aliases, and I think it might solve these issues for me, but after reading the composer docs on them I still don't feel like I understand how to practically use them.
Does anyone with more experience using composer have tips/tricks on how best to version a git package repository?
1. Source Control of Composer project
I normally ignore the vendor directory using .gitignore. Indeed, this is so common that .gitignore file comes with most PHP framework would have already included the vendor directory.
Upon release, some of the steps will be:
checkout or clone from release branch/tag,
update composer ( self update )
composer install ( install all dependencies into the vendor directory )
2. Composer versoining/stability/alias confusion
Yes this is confusing, I think the most confusing part is where versions come from, and it is not easy found in the online docs. Versions come from source control's branches and tags
a Tag name is the exact version name. if you have a tag called 'xx', you can reference it in the package.json file as 'xx'. if your tag follows the semantic naming convention (e.g. 1.0.1 or v1.0.1), you can refer to it using semantic syntax like ~1.0.*.
tags are 'stable' UNLESS their semantic names contains somethings like 'RC1', 'RC2', 'alpha' etc. (e.g. 1.0.1-rc1, 1.0.1-alpha) In those cases they can be referenced by 1.0.1#RC or 1.0.1#alpha.
branches are not 'stable' by default, numbered branch will be treated as development version. e.g. branch 2.0 will be referenced as 2.0.x-dev (note the extra .x ); Non-numbered branch name will be referenced with be prefixed with 'dev-'. i.e. 'master' branch becomes dev-master and 'testing' branch becomes dev-testing.
Branch alias is used, for example, when you want to treat the master branch as 2.0.x#dev. You might want to use the dev-master branch of package ABC but it happens that one of the packages you used in your project depends on the 2.0 branch of package ABC. As you can only use one version of package ABC in your project, you basically ask all other packages to use the dev-master when they want to use the 2.0.x#dev branch
Other issues like minimum-stability and nested dependencies are clear in the online docs and I am not repeating them here.
I have an issue/workflow in a large project with quite a number of composer packages where every so often my json file needs to be updated with a new version for a package or composer will not update. Other dependency managers in other languages would handle this type of situation on the fly (for the most part) without manual interaction. Is there a convention I am missing with Composer or a better way of doing this? It sucks time manually checking the package page online and getting all packages synced again.
If you require a package with a flexible constraint, like 1.* or such, then when you run composer update it will update you to the latest version matching this constraint. What you describe is definitely not the intended workflow so I think you have a misunderstanding somewhere.