Categories


Archives


Recent Posts


Categories


Composer Virtual Packages

astorm

Frustrated by Magento? Then you’ll love Commerce Bug, the must have debugging extension for anyone using Magento. Whether you’re just starting out or you’re a seasoned pro, Commerce Bug will save you and your team hours everyday. Grab a copy and start working with Magento instead of against it.

Updated for Magento 2! No Frills Magento Layout is the only Magento front end book you'll ever need. Get your copy today!

The KnpLabs/php-github-api project was invaluable to me during my recent composer/Magento research. GitHub offers both REST and GraphQL APIs that you interact with via HTTP, but it’s often easier to use these sorts of APIs with a package that gives you classes or functions that handle the HTTP POSTing and serializing of the data. That’s exactly what KnpLabs/php-github-api is.

There was, however, one hiccup. When I tried installing the packagist package, I got a pile of confusing errors.

$ composer require knplabs/github-api
Using version ^2.11 for knplabs/github-api
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for knplabs/github-api ^2.11 -> satisfiable by
      knplabs/github-api[2.11.0].
    - knplabs/github-api 2.11.0 requires php-http/client-implementation
      ^1.0 -> no matching package found.

Potential causes:
 - A typo in the package name
 - The package is not available in a stable-enough version according to
   your minimum-stability setting
   see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for
   more details.
 - It's a private package and you forgot to add a custom repository
   to find it

Ugh — composer’s great, but when there’s an un-installable set of dependencies it can be a nightmare to debug. Also — how the heck can I have dependency conflicts when this is the only package I want installed?

It looks like the package wants php-http/client-implementation — so I tried installing both, but got a new error message.

$ composer require knplabs/github-api php-http/client-implementation

[InvalidArgumentException]
Could not find package php-http/client-implementation.

Did you mean this?
  bower-asset/deprecated

What the heck again?! The knplabs/github-api package is dependent on php-http/client-implementation, but composer can’t find php-http/client-implementation? I was almost ready to quit at this point — but instead I popped over to the project’s README.md and got the magic string

$ composer require knplabs/github-api php-http/guzzle6-adapter "^1.1"

and the project installed without issue.

Too Much Software Engineering

I thought this might be worth reporting to the project maintainers — but it turns out this is a known issue, and the intended behavior. KnpLabs/php-github-api uses a little-known-to-me feature of composer — virtual packages and the provides key.

The php-http/client-implementation package is a virtual package. A virtual package is a lot like an Interface in traditional object oriented programming. The same way an a class implements an interface, a virtual package provides an implementation for some package functionality. According to it’s proponents, this is a good thing because it’s an example of the dependency inversion principle.

For myself — the general pattern of implementing a system or a feature in such a way that some piece of work can be implemented in many different ways makes a lot of sense. In practice though, a lot of object oriented programmers decide that anything they work on needs to be abstracted like this where I’d prefer an approach where the programmer uses their experience and expertise to decide which parts of the systems need this sort of abstraction.

That this sort of thinking has slipped into a package management system seems — a little bit bananas to me. That running composer require knplabs/github-api resulted in an opaque error message was severely discouraging me. Yes, the full installation instructions were just a google search away, but then we’re into encouraging folks to blindly copy/paste strings from the internet without understanding what they do, and that seems like a step in the wrong direction. Expecting folks who just want to have a nice experience for making API calls to also understand the ins and outs of a not well known composer feature seems unreasonable. (If you want to to know more Judas Thaddaeus and I have a newsletter you might be interested in).

That’s open source though — the folks who provide these packages aren’t under any obligation to build their software how I’d prefer it built.

Open Source Takes, and Open Source Gives

Fortunately, open source means I can take small-steps to make things work how I want.

$ composer require pulsestorm/php-github-api

The pulsestorm/php-github-api package is a composer “meta-package” I threw together and published to packagist. This package requires in both the knplabs/github-api package and a default HTTP adapter.

    #File: composer.json
    "require": {
        "knplabs/github-api": "^2.11",
        "php-http/guzzle6-adapter": "^1.1"
    }

I think anyone that’s worked and had success with PHP has no illusions about the platforms shortcoming’s — but in the past five to ten years the culture of java-style engineering has taken hold and — that’s cool I guess? — but it’s making the platform less accessible to the non-traditional programmer, and that makes it a much less interesting place.

Copyright © Alan Storm 1975 – 2019 All Rights Reserved

Originally Posted: 21st October 2019