phar-io/phive

Can phive install the best version for the current PHP version?

brettmc opened this issue · 7 comments

I realise the metadata to support this might not be available, but I thought that with this phars.xml it would be able to install phpunit 11.x on PHP 8.2, and phpunit 10.x on PHP 8.1 (based on their version constraints in composer.json:

<?xml version="1.0"?>
<phive xmlns="https://phar.io/phive">
  <phar name="phpunit" version="^10.0 || ^11.0" location="./tools/phpunit" copy="false" installed="11.1.3"/>
</phive>

What actually happens is that always installes phpunit 11.x, but it won't run on PHP 8.1 because of a version check at startup.

Indeed we lack the meta information for this.

Which is also a conceptual problem: If we want to keep the flexibility of phar authors not to register anything with us or provide a repository endpoint other than a download url for the phar and signature, we cannot fix that. This is also a blocker for extensions, as we'd need meta data there as well. Looks like we might want to rethink the strategy here ;)

What I'm considering to add though is a conditional: Only install this phar when a condition - e.g. php version or os - are met. While that's technically trivial to implement itself, the CLI is questionable: How would you specify to add this without overwriting an existing entry yet allowing to modify one? That's getting quite complex and thus less easy to use. And I do not actually want people to be required to mess with the phars.xml file for a lack of a CLI option.

So, long story short: No, phive can't do that. And for now, there is nothing you can do :-(

Maybe to explain the current behavior: Phive iterates over the available versions found - in this case the phpunit repository data, selects all that match the specification and then sorts the result to find the best (read: highest) version.

So, it will always get the 11.x release.

If phpunit would contain a proper phar manifest (looking at you, @sebastianbergmann ;-) ), we could tell you that it won't run when you install using PHP 8.1.

It gets a bit worse though: If you use PHP 8.3 to install things, and then switch to PHP 8.1, you have the same problem and we can't do anything about that.

I didn't know about phar manifests, so I'll go read up and see if there's anything I can do over in phpunit's repo. Is there an example of a library which does have a proper phar manifest?

Conditionals is something I could work with, if it were an option.

<phar name="phpunit" version="^10.0" if-php="^8.1" location="./tools/phpunit" copy="false"/>
<phar name="phpunit" version="^11.0" if-php="^8.2" location="./tools/phpunit" copy="false"/>

The syntax would probably be a bit different, but yes. Again, as I wrote, this has two problems:

  • CLI: How do you envision the CLI options to look like to create this as a result?
  • Runtime: If you do not "reinstall" everything when you switch PHP Versions, we're back to square one ;)

So, I'm not convinced yet that conditionals are the answer.

TL;DR: I don't have good answers. But I will pursue the phar manifest idea :)

Runtime: If you do not "reinstall" everything when you switch PHP Versions, we're back to square one ;)

Agreed, but we have that problem anyway with many of our testing tools. Our project's solution is to wrap it all in a make target: make all = composer update + tool1 + tool2 + ...

How do you envision the CLI options to look like to create this as a result?

It doesn't look like the CLI supports installing specific versions of packages, so my hand-wavey solution would be "that only works with xml config". Having used composer heavily, I'm used to modifying config files to manage my dependencies, and so phars.xml is the most familiar to me. I appreciate that I'm just one use-case though!

You can install a specific version: phive install phpunit@^10.0 for instance. It's just not linked to any conditional.

Thanks for all your help, I think my questions have been answered. I'll come back with a new issue if I learn anything more about phpunit's phar manifest.