Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dependency Hell, Composer and PHIVE

Dependency Hell, Composer and PHIVE

- What is does dependency hell with Composer look like?
- What causes dependency hell?
- How can we avoid dependency hell with Composer and PHIVE?

610644ae9328059c33a272d08b90c75d?s=128

Oliver Klee

August 18, 2021
Tweet

Transcript

  1. Welcome to Dependency Hell Photo by JJ Ying on Unsplash

    https://unsplash.com/photos/YTtDxJPflqk 2021-08-18 | Oliver Klee | @oliklee
  2. Dependency Hell, Composer and PHIVE Photo by JJ Ying on

    Unsplash https://unsplash.com/photos/YTtDxJPflqk
  3. Dependency Hell 1: Symfony vs. ops tool

  4. Dependency Hell 1: Symfony vs. ops tool

  5. Dependency Hell 2: Ops tool vs. ops tool (in 2

    steps)
  6. Dependency Hell 2: Ops tool vs. ops tool (in 2

    steps)
  7. Dependency Hell 2: Ops tool vs. ops tool (in 2

    steps)
  8. Dependency Hell 2: Ops tool vs. ops tool (in 2

    steps)
  9. Dependency Hell 2: Ops tool vs. ops tool (in 2

    steps)
  10. Dependency Hell 2: Ops tool vs. ops tool (in 1

    step)
  11. Dependency Hell 2: Ops tool vs. ops tool (in 1

    step)
  12. But, why?

  13. Exihibit 1: dependency tree of cachetool __root gordalina/cachetool: 6.5.0 ^6.5

    consolidation/self-update: 1.2.0 ^1.2.0 php ^7.3|^8.0 symfony/console: v5.3.2 ^4.0|^5.0 hollodotme/fast-cgi-client: v3.1.5 ^3.0 monolog/monolog: 2.3.0 ^1.0|^2.0 psr/container: 1.0.0 1.0.0 psr/log: 1.1.4 ^1.0 symfony/dependency-injection: v5.2.11 ^4.0|^5.0 symfony/finder: v5.3.0 ^4.0|^5.0 symfony/http-client: v5.3.3 ^4.0|^5.0 symfony/http-foundation: v5.3.3 ^4.0|^5.0 symfony/process: v5.3.2 ^4.0|^5.0 symfony/yaml: v5.3.3 ^4.0|^5.0 phpunit/phpunit ^8.0|^9.0 >=5.5.0 ^2.8|^3|^4|^5 symfony/filesystem: v5.3.3 ^2.5|^3|^4|^5 >=7.2.5 ~1.0 ^4.4|^5.0 ^4.4|^5.0 symfony/deprecation-contracts: v2.4.0 ^2.1 symfony/polyfill-mbstring: v1.23.0 ~1.0 symfony/polyfill-php73: v1.23.0 ^1.8 symfony/polyfill-php80: v1.23.0 ^1.15 symfony/service-contracts: v2.2.0 ^1.1|^2 symfony/string: v5.3.3 ^5.1 symfony/config ^4.4|^5.0 symfony/event-dispatcher ^4.4|^5.0 symfony/lock ^4.4|^5.0 symfony/var-dumper ^4.4|^5.0 >=7.2.5 symfony/polyfill-ctype: v1.23.0 ~1.8 >=7.1 ext-json * ext-xdebug >=2.6.0 tm/tooly-composer-script ^1.4.1 >=7.2 ^1.0.1 ^8.5 aws/aws-sdk-php ^2.4.9 || ^3.0 doctrine/couchdb ~1.0@dev elasticsearch/elasticsearch ^7 graylog2/gelf-php ^1.4.2 mongodb/mongodb ^1.8 php-amqplib/php-amqplib ~2.4 php-console/php-console ^3.1.3 phpspec/prophecy ^1.6.1 phpstan/phpstan ^0.12.91 predis/predis ^1.1 rollbar/rollbar ^1.3 ruflin/elastica >=0.90 <7.0.1 swiftmailer/swiftmailer ^5.3|^6.0 >=5.3.0 >=5.3.0 >=7.2.5 ^1.0 ^4.4|^5.0 ^2.1 ^1.15 ^1.1.6|^2 ^5.1 symfony/expression-language ^4.4|^5.0 >=7.2.5 >=7.2.5 ^1.0 ^4.4|^5.0 ^4.4|^5.0 ^2.1 ^1.11 ^1.15 ^1.0|^2 symfony/http-client-contracts: v2.4.0 ^2.4 amphp/amp ^2.5 amphp/http-client ^4.2.1 amphp/http-tunnel ^1.0 amphp/socket ^1.1 guzzlehttp/promises ^1.4 nyholm/psr7 ^1.0 php-http/httplug ^1.0|^2.0 psr/http-client ^1.0 symfony/http-kernel ^4.4.13|^5.1.5 symfony/stopwatch ^4.4|^5.0 >=7.2.5 ~1.0 ^2.1 ~1.1 ^1.15 ^4.4|^5.0 symfony/cache ^4.4|^5.0 symfony/mime ^4.4|^5.0 >=7.2.5 ^1.15 >=7.2.5 ^4.4|^5.0 ^2.1 ~1.8 >=7.1 >=7.1 >=7.1 >=7.1 >=7.2.5 ^1.0 >=7.2.5 ^4.4|^5.0 ~1.0 ~1.15 ~1.8 symfony/polyfill-intl-grapheme: v1.23.0 ~1.0 symfony/polyfill-intl-normalizer: v1.23.0 ~1.0 symfony/error-handler ^4.4|^5.0 symfony/translation-contracts ^1.1|^2 symfony/var-exporter ^4.4|^5.0 >=7.1 >=7.2.5 >=7.1 >=7.1
  14. Exihibit 2: dependency tree of deployer __root deployer/deployer: v4.3.4 ^4.3

    elfet/pure: v3.0.0 ~2.0|~3.0 monolog/monolog: 1.26.1 ^1.21 php >=5.6.0 phpseclib/phpseclib: 2.0.32 ~2.0 pimple/pimple: v3.4.0 ~3.0 symfony/console: v3.4.47 ~2.6|~3.0 symfony/process: v3.4.47 ~2.6|~3.0 symfony/yaml: v3.4.47 ~2.6|~3.0 deployer/phar-update ~2.0 phpunit/phpunit ~5.7 symfony/finder ~2.6|~3.0 ~2.6 || ~3.0 || ~4.0 ~2.6 || ~3.0 || ~4.0 ~4.4 ~2.6 || ~3.0 || ~4.0 react/react: v0.4.2 ~0.4 symfony/debug: v4.4.25 ~2.6 || ~3.0 || ~4.0 symfony/expression-language: v4.4.25 ~2.6 || ~3.0 || ~4.0 >=5.3.0 ~4.5 psr/log: 1.1.4 ~1.0 aws/aws-sdk-php ^2.4.9 || ^3.0 doctrine/couchdb ~1.0@dev graylog2/gelf-php ~1.0 php-amqplib/php-amqplib ~2.4 php-console/php-console ^3.1.3 phpstan/phpstan ^0.12.59 ruflin/elastica >=0.90 <3.0 sentry/sentry ^0.13 swiftmailer/swiftmailer ^5.3|^6.0 >=5.3.3 ^4.8.35|^5.7|^6.0|^9.4 phing/phing ~2.7 squizlabs/php_codesniffer ~2.0 >=7.2.5 psr/container: 1.1.1 ^1.1 symfony/phpunit-bridge ^5.0 ^5.5.9|>=7.0.8 ~3.3|~4.0 ~2.8|~3.0|~4.0 ~1.0 symfony/config ~3.3|~4.0 symfony/dependency-injection ~3.4|~4.0 symfony/polyfill-mbstring: v1.23.0 ~1.0 symfony/event-dispatcher ~2.8|~3.0|~4.0 symfony/lock ~3.4|~4.0 ^5.5.9|>=7.0.8 ^5.5.9|>=7.0.8 ~3.4|~4.0 symfony/polyfill-ctype: v1.23.0 ~1.8 >=5.4.0 ~4.0 react/cache: v0.4.2 0.4.* react/promise: v2.8.0 ~2.1 react/child-process: v0.4.3 0.4.* react/event-loop: v0.4.3 0.4.* react/stream: v0.4.6 0.4.* react/dns: v0.4.17 0.4.* react/http: v0.4.4 0.4.* react/socket: v0.4.6 0.4.* react/http-client: v0.4.17 0.4.* react/socket-client: v0.4.6 0.4.* >=7.1.3 ~1.0 symfony/polyfill-php80: v1.23.0 ^1.15 symfony/http-kernel ^3.4|^4.0|^5.0 >=7.1.3 symfony/cache: v5.3.3 ^3.4|^4.0|^5.0 symfony/service-contracts: v2.4.0 ^1.1|^2 evenement/evenement: v2.1.0 >=5.4.0 ^6.0||^5.7||^4.8.35 guzzlehttp/psr7: 1.8.2 >=5.4.0 ~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10 psr/http-message: 1.0.1 ~1.0 ralouphie/getallheaders: 3.0.3 ^2.0.5 || ^3.0.0 ext-zlib * >=5.3.0 >=5.6 ^5 || ^6.5 php-coveralls/php-coveralls ^2.1 >=5.3.0 >=7.2.0 psr/cache: 2.0.0 >=8.0.0 >=5.3.0 ^6.4 || ^5.7 || ^4.8.35 ~2.0|~1.1 >=5.4.0 ^7.0 || ^6.5 || ^5.7 || ^4.8.36 >=5.3.0 ^5.0 || ^4.8.10 ^2.0 || ^1.0 ^0.4 || ^0.3 ^0.5 || ^0.4.4 sebastian/environment ~1.0 >=5.4.0 ~4.8 >=5.3.8 ^2.0|^1.0 ^2.0|^1.0 ^0.4|^0.3 clue/stream-filter ~1.2 >=5.3.0 ^7.0 || ^6.4 || ^5.7 || ^4.8.35 ^1.0 || ^0.6 || ^0.5 || ^0.4 || ^0.3 ^2.1 || ^1.2.1 ^1.0 || ^0.5 || ^0.4 || ^0.3.5 ^1.0 || ^0.7 || ^0.6 || ^0.5 || ^0.4.5 react/promise-timer: v1.6.0 ^1.2 clue/block-react ^1.2 >=5.3 ^9.0 || ^5.7 || ^4.8.35 ^3.0 || ^2.7.0 || ^1.2.1 ^1.0 || ^0.5 || ^0.4 || ^0.3.5 >=5.3.0 ^4.8.10||^5.0 ^2.0 || ^1.0 ^0.4.4 ^0.4 ringcentral/psr7: 1.3.0 ^1.2 >=5.3.0 ~4.8 ~2.0|~1.0 ^2.0 || ^1.1 0.4.*|0.3.* ^0.4.5 ^1.1 ^0.5.1 >=5.3 ~4.0 ~1.0 >=5.4.0 ^5.0 || ^4.8.10 ~2.0 ^1.0 ~2.2 0.4.* 0.4.* 0.4.* ^0.5 || ^0.4 || ^0.3 >=5.4.0 ~2.0 0.4.* 0.4.* 0.4.* >=7.2.5 ^1.1 ^1.0|^2.0 symfony/cache-contracts: v2.4.0 ^1.1.7|^2 symfony/deprecation-contracts: v2.4.0 ^2.1 ^1.15 ^1.1|^2 symfony/var-exporter: v5.3.3 ^4.4|^5.0 cache/integration-tests dev-master doctrine/cache ^1.6|^2.0 doctrine/dbal ^2.10|^3.0 predis/predis ^1.1 psr/simple-cache ^1.0 ^4.4|^5.0 ^4.4|^5.0 symfony/filesystem ^4.4|^5.0 ^4.4|^5.0 symfony/messenger ^4.4|^5.0 symfony/var-dumper ^4.4|^5.0 >=7.2.5 ^1.0|^2.0|^3.0 >=7.1 >=7.1 >=7.2.5 ^1.1 >=7.2.5 ^1.15 ^4.4.9|^5.0.9 >=7.1 >=7.1
  15. What are the causes?  Composer can install only one

    version of each package at a time.  All packages share the same „box“.  Tools tend to have more specific dependencies.
  16. What could we do?  Allow installation of multiple versions

    in parallel (npm)  2 „boxes“: install the tools globally: composer global require …  solves conflicts between code libraries and tools  does not solve conflicts between tools  2 „boxes“: separate directory for tools  solves conflicts between code libraries and tools  does not solve conflicts between tools
  17. None
  18. What could we do?  one „box“ per tool: one

    separate directory and one composer.json for each tool  solves all inter-tool dependency problems  Who would be willing to maintain this?  one „box“ per tool: one PHAR for each tool  solves all inter-tool dependency problems  easy to maintain and update with the right tool  does not (easily) allow extending tools with other Composer packages (e.g. PHPStan)
  19. PHIVE to the rescue!

  20. Installing a tool with PHIVE

  21. Installing a tool with PHIVE

  22. Installing a tool with PHIVE

  23. Installing a tool with PHIVE a bit like a combination

    of composer.json and composer.lock
  24. Installing a tool with PHIVE

  25. Updating all PHIVE-installed tools

  26. Downloading all installed tools

  27. Automating a PHIVE installation

  28. Automating a PHIVE installation

  29. Automating a PHIVE installation cache this folder in Docker and

    in the pipeline
  30. Photo by Daniel Tuttle on Unsplash https://unsplash.com/photos/BPGPk_n7rkc

  31.  How to get PHIVE?  download + cache, version-control,

    or have it in the image  plan automating update of PHARS/tools that are not (yet) PHIVE-controlled  Symfony security checker, Deployer, CacheTool  use Composer for tools that need extensions Things to plan for automation
  32. 1. Start with using Composer for everything. (This keeps things

    simple as long as possible.) 2. Then the first dependency conflict happens. 3. Move all tools to PHIVE. 4. Keep using Composer for tools that a) are not available via PHIVE b) need other Composer-installed libraries (e.g., PHPStan) Recommendation for an approach