Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Script in dependency needs path to Composer autoloader

I am developing a package - myvendor/mylib - that I plan to distribute using Composer, probably via Packagist. This package contains - among other things - a commandline PHP script bin/console.php that I would like to make available to projects - say myvendor/mymain - that import the mylib package.

I am aware that I can specify in the mylib package a config setting in composer.json with an array of bins to import:

{
    "name": "myvendor/mylib",
    "config" : {
        "bin" : ["bin/console.php"]
    }
}

When the mymain project does a composer install/update, then this mylib/bin/console.php is symlinked as mymain/bin/console.php Further, I am aware that the mymain project can specify - in his own composer.json - where he wants dependency bins to be symlinked:

{
    "name": "myvendor/mymain",
    "config": {
        "bin-dir": "scripts"
    }   
}

In this case, the console script is then symlinked as scripts/console.php.

This works fine - and is cool as as all get out, by the way. ;-)

However, the script bin/console.php itself needs to include the Composer-generated vendor/autoloader.php. When developing mylib in isolation, the script bin/console.php knows his own location relative to vendor/autoloader.php, so he can include it easily. But once it is imported as a dependency into another project - myvendor/mymain, in this case - then there is only the mymain/vendor/autoloader.php script. In principle, the console script cannot know where he resides relative to that autoloader script.

Does Composer provide some environment variable - accessible to the console script - that allows the script to locate the right vendor/autoloader.php script?

BTW: I am aware of the Composer CLI environment variable, so I imagine I could make it a requirement that the importing project - mymain - define (and export!) the var COMPOSER_VENDOR_DIR. Then my console script can use that to find the project's autoloader. But that seems potentially problematic in that:

  1. We want the setting to apply only to this project, but a shell var (and an export) would apply to all projects accessed from that shell session. Seems presumptuous of my little dependency - myvendor/mylib - to impose that on an importing project.

  2. In principle, the dependency itself - myvendor/mylib - should be able to find what he needs. Doesn't seem right to put the onus on the importer.

WDYT? Thanks in advance. Ideas welcome.

like image 275
David Weinraub Avatar asked Sep 03 '12 04:09

David Weinraub


People also ask

What is composer autoload files?

Composer is an application-level dependency manager for PHP. Dependency simply means libraries/packages your application depends upon. Apart from managing the dependencies, composer will also autoload the files needed for the application.

How do I update dependency in composer?

To update dependencies two commands can be used: composer update and composer require . The difference between these two commands is that composer update will try to update a dependency based on the current constraints in composer. json and will only update composer. lock .

Where is the composer JSON file?

composer. json is a JSON file placed in the root folder of PHP project. Its purpose is to specify a common project properties, meta data and dependencies, and it is a part of vast array of existing projects.

Where are composer dependencies defined?

To start using Composer in your project, all you need is a composer. json file. This file describes the dependencies of your project and may contain other metadata as well. It typically should go in the top-most directory of your project/VCS repository.


1 Answers

One approach (that came out of discussions with @igorw on IRC freenode #composer that I am paraphrasing and on which I am somewhat expanding) is to let the bin script console.php iterate up the filesystem, starting from __DIR__, looking for the presence of autoload.php.

like image 160
David Weinraub Avatar answered Sep 21 '22 15:09

David Weinraub