Skip to content

Consider adding a composer.lock file in the repository #1095

@drupol

Description

@drupol

Hi,

I'm opening this PR to try to get the file composer.lock live in the repository and be part of the Grumphp sources.

Summary

The composer.lock file, though sometimes overlooked, is key for project reproducibility, performance, and security.

Rationale

Composer is the dependency manager for PHP. It allows you to declare the libraries your project depends on and it will manage (install/update) them for you. In a composer.json file, you specify the dependencies for your project. For example, you might need a certain library, and that library might need another library, and so on.

When you run composer install for the first time, it resolves dependencies and then downloads all of them and writes all of the packages and the exact versions of them that it downloaded to the composer.lock file, locking the project to those specific versions.

Committing this file in this repo is important for many reasons:

  1. Reproducibility: Reproducibility is one of the foundational aspects of software engineering. It ensures that all team members and the deployment system are using the exact same versions of the dependencies. This eliminates the potential issues that may arise from differences in versions used, such as function deprecations, changes in behavior, etc. Without the composer.lock file, running composer install would fetch the latest versions of the dependencies you defined in composer.json, which could cause inconsistencies between environments.

  2. Security: It helps ensure that you're using the versions of dependencies that you have tested and reviewed. Without a composer.lock file, there's a risk that a malicious person could find a vulnerability in one of your dependencies, fix that vulnerability, bump the version number, and if you run composer install or composer update, you could be pulling in un-reviewed/un-tested code since you do not control anymore the dependency resolution and delegate it to the host system.

  3. Speed: Having a composer.lock file speeds up the composer installation process. Composer no longer needs to resolve dependencies (which can take some time) and can just download the version of each dependency specified in the composer.lock.

Inclusion of composer.lock in this repository also promotes the following advantages (but I won't go into the details, this post is already too long):

  1. Less time spending in debugging,
  2. Increased reliability,
  3. Enhanced collaboration and scalability,
  4. Effective version control,
  5. Streamlined Continuous Integration and Continuous Deployment,
  6. Efficient auditing and compliance,
  7. Reliable scientific and data-driven applications.

Conclusion

While the composer.lock file may appear nonessential and is sometimes overlooked, its inclusion is critical for ensuring the reproducibility, speed, and security of your project. By including the composer.lock file in your project's repository, you are effectively shifting the responsibility of specifying correct dependencies from the end-users to the project's author.

Consequently, the author takes charge of determining the precise dependencies to install, sparing the users from this task. This approach streamlines the installation process and fosters a consistent project environment.

By including the composer.lock file in the repository, not only does it improve the development experience for contributors, but it also provides users with an assurance of quality, security, and reliability. The presence of the composer.lock file signifies that the project's dependencies are carefully managed and tested. It confirms that the project operates effectively with the locked versions of dependencies, thus reducing the risk of compatibility issues, unexpected behavior and bugs.

The composer.lock file ultimately serves as a testament to the project's stability. It safeguards users against potential risks associated with untested updates or patches in dependencies. Therefore, both contributors and users can benefit from the project author's meticulous dependency management reflected in the committed composer.lock file. This can enhance the overall confidence in the project's robustness and reliability.

Further Considerations

While Grumphp is developed in PHP, it can also be viewed as a binary, not solely a PHP library. Given this, it's imperative that it retains reproducibility across various environments. composer.lock is our most effective asset to ensure this within the PHP ecosystem. Considering the reasons outlined here, I strongly believe it deserves a place in the project.

What others are doing ?

It's often beneficial to consider practices in other projects. Composer, the PHP package manager itself, follows this practice. There are many more such examples in the ecosystem.

Application, binaries, libraries

A PHP application or binary is a standalone piece of software intended to be installed and run as is, and the composer.lock file should be included. This is because the application or binary needs to ensure that it is using the exact versions of its dependencies that it was developed and tested with. If the dependencies were to change unpredictably, the application could break. Therefore, the composer.lock file, which specifies the exact versions of the dependencies, is essential.

On the other hand, a PHP library is a piece of software intended to be included as a dependency of other projects. In this case, the composer.lock file is typically not included in version control. This is because the library should be compatible with a range of versions of its own dependencies. The library doesn't control the exact versions of its dependencies - the parent project that uses the library does. As such, the dependency resolving mechanism should indeed be handled by the project that requires the library, not the library itself.

Relation with Nix

Reproducibility is a hard requirement when bundling packages in Nix. To build a reproducible version of Grumphp, we need to ensure all inputs are accurately provided to Composer. We currently provide the composer.lock ourselves to ensure consistent use of the same dependencies, and I believe we should not do that. Making developers aware of the significance of this file would be beneficial.

Practical, hands on

To ensure reproducibility with a Grumphp build, containing composer.lock:

  1. git clone https://github.com/phpro/grumphp
  2. cd grumphp

This next step is mandatory to prevent Composer to generate random class names for the Autoloader:

  1. composer config autoloader-suffix FooBar

Let's install the required dependencies only:

  1. composer install --no-dev

The next command will compute a checksum of the grumphp directory containing now the vendor directory:

  1. cd -; dir=grumphp find "$dir" -type f -not -path '*/\.git/*' -exec sha256sum {} \; | LC_ALL=C sort -d | sha256sum; cd -

When the composer.lock is available, there is a guarantee of reproducibility, you could run this on any platform and you will always get the same checksum.

When the composer.lock is not available, the checksum might be different from a day to another, there is absolutely no guarantee of reproducibility.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions