How to stop wasting time updating dependencies with composer? - php

I am building a small app with some dependencies and my back-end is in PHP with composer and I use many dependencies.
I used to keep the project up-to-date but sometimes, composer update is just to long!
Anyone have some good tips to help me updating my dependencies? any automated service that can run them for me without breaking my code?

I built Dependabot to do exactly this. Every morning it will check with packagist whether there are any new versions, and if there are it will create a pull request to update you to the latest and greatest.
The core of the app is open source here and it's relatively popular with Ruby and JavaScript programmers. The PHP beta is fully functional, and I'm looking for more people to give it a try!

I use prestissimo for a much faster composer update/install process.
It's a composer plugin aka composer global require hirak/prestissimo
and you are done.
It downloads all ur packages simultaneously and installs them!
This will make composer insanely fast.
Benchmark on a Laravel install without prestissimo 288s =>
with prestissimo 26s!!!
For automating ur Process you could set up a cronjob and let it run a bash script with something like this inside:
Filename in example = composer_update.sh. Content:
#!/bin/bash
composer update --no-progress --profile --prefer-stable
For not breaking ur code I recommend setting a minimum stability in ur composer.json
The cronjob for updating once a month could look like this
*/0 0 1 * * /PROJECT_ROOT/composer_update.sh >> update.log
This article might further help you with cron.
Hope I could help you.

I heard a currently work in progress project wanted to solve this issue.
They link to your github account (you must have one in order for this to work) they want to keep your libraries up-to-date if you're using composer, npm or gem I think.
The thing is, they create a pull-request showing you what will be updated and show you the changelog if there is one for the update.
Take a look at upgator.io

Related

Multiple projects - 1 package

I'm working with multiple projects, each one separated from the others in my server. So my problem is that I have a Core project that have all the functions I need, and in Laravel projects it's annoying to copy/paste everything every time. I was thinking to create a package and install it in all my Laravel projects via composer, but it bothers me the fact that every time I want to add a feature or perform a minor bug fix, I will have to do a composer update in every project (I have more than 20 actually).
I just came up with some ideas, let me know what do you think about it and if you will use some different idea:
Create a Model/Class that includes my main php core library directly from the server (Remember that I have all the projects in the same server). I will just need to call the Model/class and it will import all the functions. I will just need to keep updated the main library code every time I perform a minor bug fix or any new implementation.
Create a package where inside will have all code I could need to use in all projects (main library). This would be perfect, since I want just use the composer install command get the package installed in my project. I'm not concerned at all with this solution, because I have more than 20 diferent projects and I will need to do more than 20 composer update every time I perform a minor bug fix or new implementation.
The last one is to do a generic composer where it contains all the packages I would need (almost all the projects use the same composer.json) and create a symlink between all the projects. I will install the packages in one folder and keep that updated everytime I perform some new task, and the symlink will keep the folders updated in every project.
What do you think about that options? I think I will go for the 3rd one, but wanna know your opinions or if you have the same problem and works with other solutions.
Or you could create a bash script that runs composer update for all of your projects.
#!/bin/bash
cd /var/www/website.com && composer update package/name
cd /var/www/website2.com && composer update package/name
cd /var/www/website3.com && composer update package/name

How to update CakePHP?

I have to update CakePHP from current, outdated version (2.7.7) to latest on 2 branch, because of PHP7 support.
While I've done numerous framework upgrades before, I found book.cakephp.org a more than a cryptic about key things which I ask here:
can it be done by replacing directoris
which directories are intended to be replaced (never edit dirs, like system in Codeigniter)
which directories are partially replaced if any
is there SQL commands that should be run?
is there other commands that should be run?
Any clue is appreciated, but 2 and 3 are of most value I guess. Thanks in advance.
Depending on how you've installed CakePHP, you either use composer to update the CakePHP core dependency:
$ composer update
or require a specific constraint/version if your current constraint doesn't allow upgrading:
$ composer require cakephp/cakephp:^2.10.3
If you're not using composer (I'd suggest to switch to using it), then you download the latest release package manually, and completely replace the /lib/Cake directory. With respect to the core, the upgrade is then complete.
Then read the migration guides to figure the possible changes that you have to apply to your application code or database schemas, and also compare the "application template" changes (/app/) to your local application and apply changes in case necessary. After this, run your test suite to ensure that everything works as expected.
With that being said, the upgrade from 2.7 to the latest 2.10 should be pretty easy, as it is said to be fully API compatible.
I recommend you to use composer to manage your framework and extensions.
With composer installed, it would be much easier to update. If you decide to use composer, let me know if you need any more help by installation, setup or update.

PHP packages installed by Composer - should they be in source control?

I am reading/learning about Composer, the application-level package manager for PHP.
In this blog post written by lead dev Jordi Boggiano, he writes:
Composer on the other hand forces you to declare your project
dependencies in a one-stop location (composer.json at the root). You
just checkout the code, install dependencies, and they will sit in the
project directory, not disturbing anything else on the machine.
Another related feature is the composer.lock file that is generated
when you install or update dependencies. It stores the exact version
of every dependency that was used. If you commit it, anyone checking
out the project will be able to install exactly the same versions as
you did when you last updated that file, avoiding issues because of
minor incompatibilities or regressions in different versions of a
dependency.
If I understand Composer properly, when we're talking about packages downloaded/installed by Composer, we are talking about PHP code packages, ie, programming code written in PHP, and not system-level packages, eg, extensions to the PHP runtime installed on the server. So once these PHP code packages have been downloaded and added to a PHP project, I would have thought those packages become part of the PHP application source code, eg to be checked in to whichever version control system is being used for the project. If another developer comes along and checks out the code, why would they need to then "install the packages", as is stated in the blog post? Wouldn't they get a copy of all code packages when they check out the code from source control? This line in the blog post is confusing me, and making me think I don't understand Composer.
Any clarity on this would be greatly appreciated. Thanks.
The dependencies themselves should not be commited to source control. The composer.json and composer.lock files, on the other hand, should. There's various reasons for this, amongst them:
Every time you update the dependency you would have to commit the changes. That kind of tightly couples your code to the dependency, when it should be exactly the other way around.
The packages themselves are already in their own repository with their own history. Why repeat that in your project's history?
Those repositories can be huge, just muddling the waters around your project. Why carry around all that weight?
Instead, having each developer just run composer install (very important: not composer update) whenever they check out the project is much more efficient. Composer will install the dependencies from composer.lock, making sure everyone running the same commit is on the exact same page. The same goes for deploying.
You can read more about this here.
On the other hand, there might be situations where you have to commit your packages to get around a problem, like for example when you know you won't be able to run composer install on your production server (shared hosting)
Normally packages installed via composer don't get checked in to source control, only the code you write and the composer.json and composer.lock files.
This way the repository for your project does not get bloated with code you did not write and possibly don't really care that much about.
Yes its normal after cloning down your repository a developer will need to run the "composer install" command. The composer.lock file will ensure they get the same modules and versions of them you used when creating your project.
Not including the composer modules in your source control also allow you to easily update to the modules to get bug fixes and new features in new versions of them.

How to only keep required files when createing a dist packageget

When using composer to get dependencies a huge amount of unnecessary files are download such as documentations, test units, etc. These make the built file large. How to only include production files from composer folder?
Unfortunately, the most package developer don't exploit .gitattributes files and using or not using --prefer-dist is the same for them. I come up with the following gulp task: https://gist.github.com/salarmehr/b62703afb6617f4cacac
This isn't as easy as it looks at first glance.
Composer itself isn't the right place to fiddle with project's published code. So the next stop is .gitattributes.
Symfony tried to do this, and their experience made them revert this decision. Composer had information about using .gitattributes in the documentation, but removed it.
In essence, removing some part of a package from a distinct distribution path is likely to cause more problems than it solves. From my perspective, the CLI switch --prefer-dist and --prefer-source is a selector of either having to clone a huge repository that takes ages or download a ZIP with that exact version - but the results should be equal, i.e. I should not be forced to --prefer-source for ALL my dependencies just because one single package that decided to "optimize for deployment" decided to remove documentation and tests from their ZIP.
Yes, during development I usually look at their code and tests to help me understand what's going on - or what SHOULD go on, and isn't.
Conclusion: Composer is NOT a deployment tool. If you care about the size of your application, it is your task to remove everything you don't need or want, and probably optimize other things as well (minify JS and CSS, optimize images etc.). It should not be Composers' or any package maintainers task to do this optimization for you.

Phing and Composer, which way around?

I want to use both Phing and Composer for my applications. Phing as the build system and Composer to manage dependencies. But which way around should they be used?
Currently we're installing Phing globally on all servers. Phing is supposed to completely automate the build of our various projects. Just checkout a copy of the project, run Phing with the default target and you should be good to. This also implies that there should be a Phing target in there that calls on Composer to install all dependencies. So, Phing calling composer. But I have been unable to find anything about this setup. There's no ComposerTask or anything similar and googling around doesn't reveal anyone working that way.
But I do see a lot of it the other way around. People using Composer to install Phing as a project dependency.
So, what are the (dis)advantages of each method? Am I trying to do it from the wrong way?
I think the main advantage of installing phing via composer, is that for open source projects it's easier to make sure your users have phing installed that way. Typically in those setups phing is just a tool used by some libraries to achieve some tasks.
The other advantage is that every project can use a different version of phing, which you can't do if you have a system-wide one.
If you use phing to manage your entire project build/setup, calling composer from it might make sense, but the other way around as well. For example you could use composer scripts to fire off the phing tasks after every dependency update. That way a project setup would be:
checkout
run composer
composer runs phing after updating/installing deps
project is built
I honestly don't know if there is a right answer. You can make both ways work, but by doing it this way you at least skip having to install phing first. Obviously you need to install composer instead, but arguably that's easier and you'd need it anyway.
Additional thoughts about this topic.
Generally Seldaek is right that both are possible. There are arguments for phing first too, though. On the level of build architecture I think composer first doesn't make sense. The build process has broader scope and longer lifetime and should therefore manage the dependency manager, not vice versa.
Furthermore, if you work with Phing token replacement to determine what dependency versions you want to install in which environment, it's close to impossible to go composer first because phing will generate the composer.json and must therefore be installed before composer can run.

Categories