How to require vendor/autoload.php with behat.yml - composer-php

In my project I have an autoload.php file which is responsible for requiring context classes. This is the file auto-generated by Composer. How can I include that file using behat.yml?
In PHPUnit's phpunit.xml.dist I can do this simply with bootstrap attribute like this:
<phpunit bootstrap="vendor/autoload.php">
Is there a similar setting in Behat?
Note: I'm not asking about running Behat from vendor directory, because when I do it works as expected. That's because the file vendor/bin/behat contains the
include __DIR__.'/../vendor/autoload.php';
expression. But I also have behat installed globally and when I run global behat command it fails to autoload my context classes. And this is the use case that I'm interested in.

Composer's autoloader is used by default.
However, depending on where you've installed Behat a different autoloader will be used. Project's autoloader is used if you installed Behat in your project, while the global autoloader is used if you installed Behat globally.
There's no way of changing this behaviour with configuration alone. Note that this is an expected behaviour. See https://github.com/Behat/Behat/issues/490#issuecomment-40928786
Furthermore, installing Behat in your project is the recommended way.
You could probably write a Behat extension to include project's autoloader even if a global behat version is used, but I don't think it's worth it. It could also lead to odd autoloading issues with duplicate or wrong versions of classes etc.
Finally, you can also configure the autoloader manually: http://docs.behat.org/en/latest/guides/6.profiles.html#custom-autoloading

You could use the following new BehatExtension:
https://github.com/Postcon/BehatBootstrapExtension

Related

Why are there naming collisions in Composer's vendor folder? (between bin and hhvm)

I have been learning to use hacklang and hhvm and I have went about using composer and installing all the needed packages as
composer require hhvm/hsl hhvm/hhvm-autoload
composer require --dev hhvm/hhast hhvm/hacktest facebook/fbexpect
I have also setup the .hhconfig aswell as the hh_autoload.json and hhast-lint.json
However there is a naming collision between the Vendor/bin and Vendor/HHVM
Can anyone explain why this is happening or how to fix it?
This happens because composer copies vendor/vendor/package/bin/file to vendor/bin/file, causing symbols in vendor/vendor/package/bin/file to be defined twice. IT IS EXPECTED.
to avoid naming issues, add the following to your .hhconfig :
ignored_paths = [ "vendor/.+/tests/.+", "vendor/.+/bin/.+" ]

Refactoring Composer executable file for portability

Installing Composer locally puts a file named composer in your directory. I have taken to copying this file into each of my projects that uses Composer, so that I can run php composer in each folder.
Since this results in a lot of needlessly-repeated code, I want to refactor the composer file into something minimal. The most logical solution would be to refer to a class that resides in the vendor folder. Why is there so much code in the composer file anyway? I'd prefer not to put the code into my own libraries if I don't have to.
For comparison, here's a sample of code in a typical phpunit file:
require_once 'my_bootstrap.php';
spl_autoload_register(array(MyBootstrap::class,'autoload'));
// Do some other stuff here.
\PHPUnit_TextUI_Command::main();
I want to reduce the composer file in each project to something like this.
I do not want to install Composer globally. I want each project to be an environment unto itself and not have to instruct another developer to install anything other than PHP.

How can I recreate composer.json from the content of the vendor directory?

I have a project where I am using composer.
However, I have lost my composer.json.
Is there a way to recreate composer.json from the content of the vendor directory?
Identifying the installed dependencies can be easily achieved by inspecting
vendor
└── composer
   └── installed.json
However, you will be faced with the following problems:
Direct and indirect dependencies
installed.json lists all installed dependencies, that is, both
direct and
indirect
dependencies.
Direct dependencies are dependencies that are explicitly listed in the
require and require-dev sections.
Indirect dependencies are dependencies of your direct dependencies.
That is, while you could programmatically parse installed.json and
collect the dependencies listed therein, you will need to decide for
yourself whether these are direct or indirect dependencies, or in other
words, whether you want to explicitly require these dependencies in
composer.json.
Production and development dependencies
installed.json lists all installed dependencies, that is, depending
on whether you ran
$ composer install
or
$composer install --no-dev
before you lost your composer.json, installed.json will contain
direct and indirect dependencies listed in
require and require-dev or
require
sections, respectively.
That is, you will need to decide for yourself whether these are
dependencies which should be listed in the
require or
require-dev
sections.
See
https://getcomposer.org/doc/04-schema.md#require
https://getcomposer.org/doc/04-schema.md#require-dev
https://getcomposer.org/doc/03-cli.md#install
Using "require-dev" to install packages in composer
to find out more about the purpose and the differences between these
sections.
Version Constraints
installed.json lists all installed dependencies with the exact
versions installed.
However, the composer.json you lost in all likelihood did not list
dependencies with exact versions, but using one of the many possibilities
for specifying version constraints.
That is, you will need to decide for yourself whether you want to use exact versions, or relax the constraints, for example, by using
the ~ operator
the ^ operator
etc.
See
https://getcomposer.org/doc/articles/versions.md#writing-version-constraints
to find out more about version constraints.
Hoppe!!
I had a similar problem with a Laravel project
In order to solve it:
Create a separate base project, with the same version of Laravel to work with, in case you don't work with Laravel, you can skip to step 3.
Copy the contents of the file to have a stable working base
Run the a python script gist , giving it the installed.json path, this will return the require and require-dev of the project
Copy and paste the requirements inside composer.json. In case of working with Laravel, be careful not to affect the require brought from the base app.

How to use composer included items?

In my composer.json file I added "kigkonsult/icalcreator": "v2.23.7" to the required list, and after doing the install I see that directory in existence under the vendor dir. I can't figure out how to "use" it though in my PHP files in this project.
If I weren't using composer I'd just require the icalcreator.php file in that area. What's the right syntax when I include it via composer?
Once the package is installed you need to add the composer autoloader somewhere in your project.
require_once('/path/to/vendor/autoload.php');
Normally Composer uses PSR-4 autoloading, but it looks like this package doesn't. It just adds it's own autoloader to composer so just including the Composer loader should be sufficient.
Once the autoloader is added you can just use the package however you need. Composer will automatically register the packages custom autoloader and PHP will use that to load the appropriate file.

Let Composer to install plugins to another directory

I have framework wich uses plugins as subdirectories in plugin/ directory. Plugins are git submodules and it works just fine. But some plugins require 3rd party libraries and I want to use Composer ti install them. Also there are dependencies between plugins which could be handled by Composer too.
I tried to use composer, but it will install everything into vendor/ directory, which is wrong because plugins must go into plugin/ directory. There is also core of the framework in core/ and application specific files in app/ directory.
What is the best way to use Composer in this scenario?
There should be a way for Composer to decide which package is a plugin and should be placed in the plugins directory. In composer, there is a special type setting which you should use in that case.
Then you can use a custom installer to install the special plugin types in the plugin directory.

Resources