Search code examples
dependenciescomposer-phpupdates

Update Composer dependencies to latest despite static version numbers?


Is it possible to update all my Composer dependencies to the latest versions via one command if I have used static version numbers? I'd like to keep the static version numbers but have them updated.

Thanks,


Solution

  • Is it possible to update all my Composer dependencies to the latest versions via one command, if I have used static version numbers?

    In short: No, there is no command to automatically raise to the latest version for a given static version in composer.json, yet.

    The closest you get is composer outdated -D (root package), which shows you the list of outdated packages on the root package, including package, current version and latest version. The next step would be to manually transfer the latest version numbers into the composer.json file.


    If you want to automate this with a PHP script, then the following lines should get you started. The script raises all version numbers to latest, not only static ones. That means, you might want to add an additional check for static numbers, if you want to raise only those.

    The script requires to run composer outdated --direct > outdated.txt on the CLI to produce the input file (or adjust the script to use exec/system/passthru/whatever and work on the the returned output directly).

    !! Be careful and test this on an a standalone composer.json or a file under version control, where you can easily revert any unwanted modifications.

    update-composer-json-version-numbers-to-latest-version.php or just uv.php:

    <?php
    /**
     * Raise/update static version numbers in composer.json.
     *
     * Run on the CLI: "composer outdated --direct > outdated.txt"
     */
    $composerJson = json_decode(file_get_contents('composer.json'), true);
    
    $listOfOutdatedPackages = file('outdated.txt');
    
    foreach($listOfOutdatedPackages as $line) {
    
        $regexp = '/(?P<package>[\w-]+\/[\w-]+).*(?P<currentVersion>\d.\d.\d).*(?P<latestVersion>\d.\d.\d)/';
        preg_match($regexp, $line, $matches);
        $matches = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
    
        if(isset($matches['package']))
        {
            $package = $matches['package'];
    
            if(isset($composerJson['require'][$package])) 
            {
                $currentVersion = $composerJson['require'][$package];
                echo sprintf('Updating %s from %s to %s', $package, $currentVersion, $matches['latestVersion']);
                $composerJson['require'][$package] = $matches['latestVersion']; 
            } 
            if(isset($composerJson['require-dev'][$package])) 
            {
                $currentVersion = $composerJson['require-dev'][$package];
                echo sprintf('Updating %s from %s to %s', $package, $currentVersion, $matches['latestVersion']);
                $composerJson['require-dev'][$package] = $matches['latestVersion']; 
            }              
        }
    }
    
    file_put_contents('composer.json', json_encode($composerJson, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
    

    And now someone posts a nifty one-liner using grep/awk/sed... right? :)