Custom Composer Update on Laravel
Tags: php, laravel, linux
Published: 2020-10-23 11:07:57

Hello 👋,

> UPDATE: 10, Nov, 2020. Composer 2 is out and it is very fast compared to Composer 1, most if not all comparison done here can be ignored, I highy recommend switching to Composer v2 If you're using Linux use `composer self-update --2` to update

So I was updating some Laravel application to version 8 and kept getting errors with the package and version constraints,

## Using `composer update`

If a package is constrained with a Next Significant Release Operators like Tilde Version Range (~) or Caret Version Range (^)

Using `composer update` won't update to a MAJOR version. This requires a manual update.

Thus one has to know the next version to update to.

For more info check https://getcomposer.org/doc/articles/versions.md#next-significant-release-operators

Now, The [Laravel Upgrade Guide](https://laravel.com/docs/8.x/upgrade) shows the version of dependencies and first-party packages to update, for any other third-party packages consumed by your application one has to check and verify the latest version manually.

## 💡 Partial Solution

So checking the [composer versioning constraints](https://getcomposer.org/doc/articles/versions.md)  and I found a way to check the latest version of a package from here https://semver.mwl.be/

Now there are several third-party packages consumed  in the project checking one after another seemed too manual 

#### 🤔 Quick question is, Where does the https://semver.mwl.be/ check for package information?

Well turn out there is a public packagist HTTP API documented here https://packagist.org/apidoc

So this means I can check the versions of the package directly from the terminal 

#### 🤔 Can't I archive this with composer

Well, you can use composer, for example [`composer show "monolog/monolog"`](https://getcomposer.org/doc/03-cli.md#show) will give you all the information about the package

I tried it and was not happy with the time taken to get the information.

Upon running `composer show "monolog/monolog" -vvv --profile`

I ended up with results like 
```
...
...
[179.5MiB/42.39s] Memory usage: 179.49MiB (peak: 199.6MiB), time: 42.39s
```

Composer downloads several JSON files and reads to get that information required, Well, I just want to see the versions of a single package.

## 🏗 Solution implementation 

##### Stage 1: Check the version of the single package

Using BASH scripting, I made a function to check the version of a package the function prints the latest 5 release tags of the package

> Note: `curl` and `jq` are required.

```bash
function composer_check_package(){
        package=$1
        echo "Checking versions for package: $package"
        org="${package%/*}";
        pn="${package#*/}";
        curl -s echo "https://packagist.org/packages/$org/$pn.json" | jq -r '.package.versions | keys | .[-5:]';
        echo "";
}
``` 

##### Stage: Check versions for all packages in composer.json


> This BASH script function checks for if `composer.json` exists then extracts then required packages and for each package, it checks and prints the latest version

```bash
function composer_check_all(){
[[ -e composer.json ]] && cat composer.json| jq -r '.require| keys | .[]' | while read package; do
        if [[ -z "php" ]]; then break; fi
        echo $package;
        org="${package%/*}";
        pn="${package#*/}";
        curl -s echo "https://packagist.org/packages/$org/$pn.json" | jq -r '.package.versions | keys | .[-5:]';
        echo "";
done

}
```

## Other solution

[Laravel Shift](https://laravelshift.com/) is automated, instant Laravel upgrade services by an army of thorough bots and friendly humans too. Laravel shift supports more functionalities listed below.
- Update versions
- Modernize code
- Check dependencies
- Generate tests
Laravel shift is a commercial service.

### Lastly

There are plenty of improvements to this approach, please share in the comments below.