Elliot Chance
Elliot Chance

Reputation: 5736

How to test if composer.lock is up to date?

During development (multiple people in the team) sometimes composer install returns:

Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them.

Is there a way to check for this very quickly (in milliseconds, without making any changes)?

I understand how composer works. However when code merges in it doesn't necessarily cause merge conflicts on the composer.json or composer.lock file and it's not fun to run composer install all the time when there's almost never any changes and that command takes several minutes.

If I'm able to quick test if the lock fail has fallen out of sync I can build it into the bash environment to notify every command. Similar to how people like their git status to be built into their bash prompt.

Further more this makes sense in CI to make sure it does sneak it's way into the stable branch.

Upvotes: 17

Views: 17402

Answers (5)

lifeofguenter
lifeofguenter

Reputation: 1181

on newer versions (I suppose 1.3+) you can run the following:

$ composer validate --no-check-all --no-check-publish

Which might output something like this (with a catchable error exit code):

./composer.json is valid for simple usage with composer but has strict errors that make it unable to be published as a package: See https://getcomposer.org/doc/04-schema.md for details on the schema
The lock file is not up to date with the latest changes in composer.json, it is recommended that you run composer update.

Upvotes: 29

binhdt2611
binhdt2611

Reputation: 17

I have another solution for this by using Sha1sum and Bash script. We can run composer install only when composer.json or composer.lock files in your project are changed. I'm using this way for CI model.

  1. Create a script file called /usr/local/bin/git-update.sh with the content below
#!/bin/bash

git pull -q --ff-only

repoName=${PWD##*/} # Get current folder name
checkFile=/tmp/composer_hash_${repoName}.sha12
if [[ ! -f $checkFile || $(sha1sum -c ${checkFile} 2> /dev/null | grep FAILED | awk "{print \$2}") == *"FAILED"* ]]; then
    composer install
    retVal=$?
    if [[ $retVal -eq 0 ]]; then
        sha1sum composer.json composer.lock > ${checkFile}
    fi
fi

Explanation:

  • When running this script for the first time. sha1sum command output to /tmp/composer_hash_${repoName}.sha12 with content looks similar below
 20379304c5944d13ef62f01edefa6ee3277a9e8c  composer.json
 afb0f4db50c81e0981e39dcb5b775fdd309319fe  composer.lock
  • At the next runs, sha1sum -c /tmp/composer_hash_${repoName}.sha12 is checking the SHA-1 checksum in the file. If your composer.json or composer.lock files are changed. The script runs composer install and adds a new SHA-1 checksum into the file.sha12. Otherwise, it does nothing.
  1. Grant permission 700 for this script:
chmod 700 /usr/local/bin/git-update.sh
  1. I'm assuming that you're storing your code project in a central platform (like GitHub). Every time you pull your code changes from the remote repository to you local machine. Just run script in the directory of your project. E.g.
cd /data/path/to-your-project && /usr/local/bin/git-update.sh

Upvotes: 1

Dominic Scheirlinck
Dominic Scheirlinck

Reputation: 2604

For composer < 1.3.0

Yes, there is a way to check for this very quickly.

The "out-of-date" check is based on a hash of the composer.json contents, stored in the composer.lock. There's no salt, and it's a straight-forward hash of the contents, so it's very, very easy to do.

<?php

$lock = json_decode(file_get_contents('composer.lock'))->hash;
$json = md5(file_get_contents('composer.json'));

if ($lock !== $json) {
    echo "Lock file out of date\n";
    exit(1);
}

echo "Lock file up to date\n";
exit(0);

Upvotes: 12

Elliot Chance
Elliot Chance

Reputation: 5736

For composer < 1.3.0

Extending from @Domster, the solution in pure bash:

COMPOSER_IN_SYNC=$(expr "`cat composer.lock | grep '"hash":' | cut -d'"' -f4`" = "`md5sum composer.json | cut -d ' ' -f 1`")

$COMPOSER_IN_SYNC will be 0 or 1 respectively.

Upvotes: 8

Pᴇʜ
Pᴇʜ

Reputation: 57683

You can run

composer install --dry-run

--dry-run Outputs the operations but will not execute anything (implicitly enables --verbose).

This won't change anything but will show the warning if not up to date. But it will still have to check the servers for new versions of your installed packages, so if you have many installed this might still take more than milli seconds. Anyway it's faster.

Upvotes: 8

Related Questions