-1

I'm currently experimenting with the Satis. I would like to be able to get the exact version of my private packages somewhere, so everything that is normally in the composer.lock. I always commit the composer.lock via Git.

But if I understand that correctly, the Satis in its packages.json always only includes the require parts, i.e. the sections from my composer.json and thus of course only version ranges.

Is there a way to configure the Satis so that the composer.locks are also stored or how do I get the exact "snapshot" of my packages?

+++ Example +++

Ok, I try to explain a bit more.

Let's say I have a package my/package. Here I add several files, including a composer.json, in which I define that symfony/console should be installed in a version greater than or equal to 4. Now I do a "composer install" and Symfony is installed in version 4.4. I commit all files, including composer.lock and create a release 1.0.

Now I'm going to the Satis. Here I add my/package and the corresponding repository URL for my/package to satis.json and update it. The Satis checks out my package correctly and in packages.json or more precisely the all*.json my package is listed with version 1.0. So far everything is fine.

But if I now take a look at the metadata that Satis stores for my package in all*.json, I see here practically my specified requirements, i.e. that symfony/console should be installed in a version greater than or equal to 4. So Satis takes a snapshot of the composer.json and apparently ignores the composer.lock. So I have no chance to see that my release 1.0 works with the exact version 4.4 of Symfony, while for example a release 1.1 works with symfony/console 4.5. But this information is interesting for me.

altralaser
  • 2,035
  • 5
  • 36
  • 55
  • Where do you want to store anything? Composer only **reads** packages from Satis and does not store anything there – Nico Haase Jul 29 '20 at 14:55
  • I.e. I call https://example.com/packages.json and parse it. – altralaser Jul 29 '20 at 20:13
  • Sounds fine - and what's the problem with parsing that package file? – Nico Haase Jul 30 '20 at 08:22
  • The problem is that there are no version numbers. It seems that Satis only saves the requirements, but not the actually installed versions and I would have liked to know them. – altralaser Jul 30 '20 at 14:18
  • Satis does not install anything. Can you clarify what **exactly** you are looking for? Which data would you like to get, and what's the problem in reading that data from `composer.lock`? – Nico Haase Jul 30 '20 at 14:20
  • I changed my post. – altralaser Aug 01 '20 at 21:42
  • 1
    If release 1.1 of your package works with symfony/console 4.5 and does not work with symfony/console 4.4, you should update constraint in `composer.json` of your package. That is the point of constraint - it provides versions range for dependencies. The wider the range is, the less like you end up with dependency conflicts. Using precise version from `composer.lock` basically guarantees conflicts, because every package may have some minor differences. – rob006 Aug 02 '20 at 10:13

2 Answers2

0

When installing a package, Composer recalculates all dependencies on the fly. This is based on the composer.json of your application and the composer.json files of all dependencies.

A composer.lock should not be part of any package, and it is not taken into account when a package is installed.

Nico Haase
  • 11,420
  • 35
  • 43
  • 69
  • You can have `composer.lock` in your package (and it is often useful), it just won't be used when you're installing this package as dependency. – rob006 Aug 02 '20 at 10:17
  • @rob006 can you share some examples where this could be useful? I've just had a look at some packages (Symfony, Laravel, Guzzle, Google's API Client SDK, PHPUnit) and none of these repositories list their lock file. Searching through the list of popular packages, Doctrine folks were the first where I could find a lock file – Nico Haase Aug 02 '20 at 10:21
  • @rob006 to put this in a seperate question, I've opened https://stackoverflow.com/questions/63214966 - and I'd be very happy to hear from you :) – Nico Haase Aug 02 '20 at 10:35
  • 1
    It speeds up installation (for example for CI tests) and provides stable state of dependencies, so if your PR fails the tests, it is PR fault, not some unrelated BC break in one of dependencies (you still needs some process to update this lock regularly). But this is mostly useful for private packages with known environment - Symfony needs to support multiple PHP versions, so they can't really use one lock, so it is not that popular in OS projects. – rob006 Aug 02 '20 at 11:08
  • As Rob says, it makes sense to keep a stable release. When you run a Composer Install, you always get the latest versions and may make breaking changes in your project, or at least untested stands. So it's actually a very common way. – altralaser Aug 03 '20 at 11:49
  • @altralaser can you share examples for that "common way"? As I've written, out of a list of some very popular packages, only Doctrine uses this. And usually, you don't want to use stable versions when developing a library that is not used in combination with a static set of other packages – Nico Haase Aug 03 '20 at 13:20
  • If you want to use a **static** set of dependencies in your library, you are free to use very exact version numbers in your `composer.json`, but that will make it pretty hard for others to use your library – Nico Haase Aug 03 '20 at 13:21
  • Sorry, but I don't know what other examples to give ... – altralaser Aug 03 '20 at 16:14
  • Addendum: I guess you have never created private packages that can then be integrated into larger applications. The release version is very important here to avoid errors in live systems. And of course it is a common way to check in the composer.lock in the private packages. You won't find that at Doctrine & Co., that's for sure. Or take deployments. Here you want to roll out the version that you have tested, so you basically only do a composer install with existing composer.lock. – altralaser Aug 04 '20 at 14:17
  • I guess you don't know which projects I've worked on, even if this does not help to resolve your problem. Can you clarify why there should be a different between private and public **packages**? What makes you think that Composer knows about this difference and handles them different? – Nico Haase Aug 04 '20 at 14:26
  • So, can you provide any example where installing a package uses the `composer.lock` present in that package's repository, and **not** recalculate the dependencies needed to install that package? – Nico Haase Aug 04 '20 at 14:27
  • I think I explained it in detail. What else can I say ... – altralaser Aug 04 '20 at 18:34
0

So, I've now built a workaround. The whole thing is not quite perfect, since the runtime for large repositories is relatively long, which is why I have to run it as a cron once a day. But it works fine.

  • I have created a new Satis console command.
  • This command uses the PackageSelection class to determine all existing packages.
  • I iterate over the package list and look for the paths and names to the dist files.
  • I extract the ZIP files in memory and look for the composer.lock. If there is one, I parse it and read the exact version numbers of the dependent packages.
  • I summarize the information in a separate JSON file and store it in parallel to packages.json under htdocs. From there I can call it up and integrate it into my own application or process it further.
altralaser
  • 2,035
  • 5
  • 36
  • 55