bamarni / composer-bin-plugin Goto Github PK
View Code? Open in Web Editor NEWNo conflicts for your bin dependencies
License: MIT License
No conflicts for your bin dependencies
License: MIT License
What is wrong with just using org/project
as the namespace? This would simplify the command to be just composer bin require org/project
and could create the vendor-bin/org/project
directory. This way could also allow multiple projects to reside in the same vendor-bin/org
namespace.
Hello - and first of all: Thanks for this plugin!
Just a small kind of a bug: The forward-command does not work on the first installation. As the plugin is not installed yet, it does not react to the install-command. Thus, the install-command needs to be executed twice currently.
It would be nice, if forward-command could react to/after the first call of composer install.
Greets! π
Jonas
cf. #15
Currently it's not possible to pass options to the proxied command :
composer bin phpunit install --no-scripts
[Symfony\Component\Console\Exception\RuntimeException]
The "--no-scripts" option does not exist.
bin <namespace> <args> (<args>)...
Hello, is it possible to reliably detect from inside a library that it was installed in a special way through this plugin and not as a normal require-dev dependency? Thank you.
Command composer update --dry-run roave/security-advisories
fails if composer.json
config.allow-plugins contains "bamarni/composer-bin-plugin": true
With that allow-plugins
:
dev@php-fpm:/app$ composer update --dry-run roave/security-advisories
In Input.php line 193:
[TypeError]
Symfony\Component\Console\Input\Input::escapeToken(): Argument #1 ($token) must be of type string, array given
Exception trace:
at phar:///usr/bin/composer/vendor/symfony/console/Input/Input.php:193
Symfony\Component\Console\Input\Input->escapeToken() at n/a:n/a
array_map() at phar:///usr/bin/composer/vendor/symfony/console/Input/ArrayInput.php:120
Symfony\Component\Console\Input\ArrayInput->__toString() at /app/vendor/bamarni/composer-bin-plugin/src/BinCommand.php:52
Bamarni\Composer\Bin\BinCommand->execute() at phar:///usr/bin/composer/vendor/symfony/console/Command/Command.php:298
Symfony\Component\Console\Command\Command->run() at /app/vendor/bamarni/composer-bin-plugin/src/Plugin.php:123
Bamarni\Composer\Bin\Plugin->onCommandEventInstallUpdate() at /app/vendor/bamarni/composer-bin-plugin/src/Plugin.php:84
Bamarni\Composer\Bin\Plugin->onCommandEvent() at n/a:n/a
call_user_func() at phar:///usr/bin/composer/src/Composer/EventDispatcher/EventDispatcher.php:202
Composer\EventDispatcher\EventDispatcher->doDispatch() at phar:///usr/bin/composer/src/Composer/EventDispatcher/EventDispatcher.php:108
Composer\EventDispatcher\EventDispatcher->dispatch() at phar:///usr/bin/composer/src/Composer/Command/UpdateCommand.php:196
Composer\Command\UpdateCommand->execute() at phar:///usr/bin/composer/vendor/symfony/console/Command/Command.php:298
Symfony\Component\Console\Command\Command->run() at phar:///usr/bin/composer/vendor/symfony/console/Application.php:1015
Symfony\Component\Console\Application->doRunCommand() at phar:///usr/bin/composer/vendor/symfony/console/Application.php:299
Symfony\Component\Console\Application->doRun() at phar:///usr/bin/composer/src/Composer/Console/Application.php:334
Composer\Console\Application->doRun() at phar:///usr/bin/composer/vendor/symfony/console/Application.php:171
Symfony\Component\Console\Application->run() at phar:///usr/bin/composer/src/Composer/Console/Application.php:130
Composer\Console\Application->run() at phar:///usr/bin/composer/bin/composer:88
require() at /usr/bin/composer:29
update [--with WITH] [--prefer-source] [--prefer-dist] [--prefer-install PREFER-INSTALL] [--dry-run] [--dev] [--no-dev] [--lock] [--no-install] [--no-autoloader] [--no-suggest] [--no-progress] [-w|--with-dependencies] [-W|--with-all-dependencies] [-v|vv|vvv|--verbose] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--apcu-autoloader] [--apcu-autoloader-prefix APCU-AUTOLOADER-PREFIX] [--ignore-platform-req IGNORE-PLATFORM-REQ] [--ignore-platform-reqs] [--prefer-stable] [--prefer-lowest] [-i|--interactive] [--root-reqs] [--] [<packages>...]
dev@php-fpm:/app$
and without it (expected result):
dev@php-fpm:/app$ composer update --dry-run roave/security-advisories
bamarni/composer-bin-plugin contains a Composer plugin which is currently not in your allow-plugins config. See https://getcomposer.org/allow-plugins
Do you trust "bamarni/composer-bin-plugin" to execute code and wish to enable it now? (writes "allow-plugins" to composer.json) [y,n,d,?] n
Loading composer repositories with package information
Updating dependencies
Nothing to modify in lock file
Installing dependencies from lock file (including require-dev)
Nothing to install, update or remove
80 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
dev@php-fpm:/app$
also if I use --no-plugins
option, it works as expected;
dev@php-fpm:/app$ composer update --dry-run --no-plugins roave/security-advisories
Loading composer repositories with package information
Info from https://repo.packagist.org: #StandWithUkraine
Updating dependencies
Nothing to modify in lock file
Installing dependencies from lock file (including require-dev)
Nothing to install, update or remove
80 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
dev@php-fpm:/app$
First of all, great tool, thanks for making it!
So, I would like to suggest adding a way of versioning tools without the need to commit all composer.json
and composer.lock
files from ./vendor-bin
in order to insure reproducible CI. Also, committing them all feels like a lot of clutter.
It would be also useful to be able to specify all tools in the main composer.json
file.
Currently I'm struggling with this Makefile
:
# runs copy paste detection
phpcpd: bin/phpcpd
bin/phpcpd ./src --min-lines=1 --min-tokens=35
# install all bin tools
install-bin: bin/phpcpd bin/phpcbf bin/phpmd bin/phpstan bin/psalm
# install sebastian/phpcpd
bin/phpcpd: install
composer bin phpcpd require --dev sebastian/phpcpd @stable
However I can't stop it from installing over and over each time I run make phpcpd
.
While adding a bin requirement I got an error like this:
$ composer -V
Composer version 1.6.4 2018-04-13 12:04:24
$ composer show | grep "bamarni/composer-bin-plugin"
bamarni/composer-bin-plugin v1.2.0
$ composer bin phpmetrics require phpmetrics/phpmetrics
Changed current directory to vendor-bin/phpmetrics
Composer could not find a composer.json file in /Users/brzuchal/Workspace/data-dump/vendor-bin/phpmetrics
To initialize a project, please create a composer.json file as described in the https://getcomposer.org/ "Getting Started" section
Am I doing something wrong?
Documentation doesn't say anything I need to do except require composer plugin.
Is there any chance you could tag a 1.4.1 release please, so there is a stable version compatible with composer 2 and php 5.5.9.
In my composer.json
I have:
"config": {
"bin-dir": "bin",
"sort-packages": true
}
In my other projects with the same config, I properly have my executables under bin
instead of the default vendor/bin
. However this plugin does not seem to take that into account and put executables in vendor/bin
still.
If all developer wants is to install one bin dependency per namespace, creating the separate package.json
file for each of them feels like an overkill.
How do you feel about adding the following sugar?
{
"extra": {
"bamarni-bin": {
"packages": {
"cs": {
"friendsofphp/php-cs-fixer": "^2.3"
},
"lint": {
"jakub-onderka/php-parallel-lint": "^0.9.2"
},
"phpstan": {
"phpstan/phpstan": "^0.7.0",
"phpstan/phpstan-nette": "^0.7.0"
}
}
}
}
}
Hello,
thanks for great plugin!
Sometimes we would like to have "bins" in production, for example https://github.com/cakephp/phinx or https://github.com/lavary/crunz, also we would like to have some "bins" for development, for example https://github.com/FriendsOfPHP/PHP-CS-Fixer and/or https://github.com/sebastianbergmann/phpunit.
Currently there is no way "mark" bin-package as dev only, this can be a problem in production env, because there are no sense to install phpunit and/or php-cs-fixer on prod.
I suggest two changes:
no-bin-dev
option to bin all
command or add bin all-no-dev
commandvendor-bin-dev
directoryWDYT?
Is there a way to add support for composer plugins that are defined in namespaces? e.g. something like composer bin namespace-foo plugin-bar options
?
I guess one solution would be to add the namespaced version as plugin to the root composer.json?
I am especially talking about plugins that provide composer commands
It is related to #122
However, the issue does not happen always, it just happens during the update.
Using PHP 8.1 and composer 2.3.7
So it works fine in these scnearios:
composer bin
plugin commands and composer commands work fine.What fails:
In PluginManager.php : eval()'d code line:
[Error]
Call to undefined method Bamarni\Composer\Bin\Config::fromComposer()
```
(removed code lines as I am currently on a different system, just copied the general message from the referenced bug as it was the same).
As everything works fine after the update, it isn't that huge an issue but should probably still be looked into.
We have configured a special cache directory using the environment variable COMPOSER_CACHE_DIR
.
When running composer install
, the cache dir is used by composer.
But all packages installed by the composer-bin-plugin are always downloaded from their origin.
Why is the configured cache dir ignored?
$ composer install --no-interaction
Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Package operations: 96 installs, 0 updates, 0 removals
- Installing bamarni/composer-bin-plugin (1.4.1): Extracting archive
- Installing composer/package-versions-deprecated (1.11.99.1): Extracting archive
- Installing azuyalabs/yasumi (2.3.0): Extracting archive
- Installing ckeditor/ckeditor (4.4.8): Extracting archive
- Installing clue/stream-filter (v1.5.0): Extracting archive
- Installing developerforce/force.com-toolkit-for-php (dev-master a131708): Extracting archive
- Installing doctrine/cache (1.11.0): Extracting archive
- Installing doctrine/deprecations (v0.5.3): Extracting archive
- Installing doctrine/event-manager (1.1.1): Extracting archive
- Installing psr/container (1.1.1): Extracting archive
- Installing symfony/service-contracts (v2.4.0): Extracting archive
- Installing symfony/stopwatch (v5.2.7): Extracting archive
- Installing symfony/polyfill-php80 (v1.23.1): Extracting archive
- Installing symfony/polyfill-mbstring (v1.23.1): Extracting archive
- Installing symfony/polyfill-intl-normalizer (v1.23.0): Extracting archive
- Installing symfony/polyfill-intl-grapheme (v1.23.1): Extracting archive
- Installing symfony/polyfill-ctype (v1.23.0): Extracting archive
- Installing symfony/string (v5.3.10): Extracting archive
- Installing symfony/polyfill-php73 (v1.23.0): Extracting archive
- Installing symfony/deprecation-contracts (v2.5.0): Extracting archive
- Installing symfony/console (v5.3.7): Extracting archive
- Installing symfony/filesystem (v5.2.7): Extracting archive
- Installing laminas/laminas-zendframework-bridge (1.1.1): Extracting archive
- Installing laminas/laminas-eventmanager (3.2.1): Extracting archive
- Installing laminas/laminas-code (3.4.1): Extracting archive
- Installing friendsofphp/proxy-manager-lts (v1.0.3): Extracting archive
- Installing doctrine/dbal (2.13.1): Extracting archive
- Installing doctrine/migrations (2.3.3): Extracting archive
- Installing symfony/property-info (v5.3.8): Extracting archive
- Installing symfony/property-access (v5.2.4): Extracting archive
- Installing symfony/options-resolver (v5.2.4): Extracting archive
- Installing psr/log (1.1.3): Extracting archive
- Installing symfony/polyfill-php72 (v1.22.1): Extracting archive
- Installing symfony/polyfill-intl-idn (v1.22.1): Extracting archive
- Installing ralouphie/getallheaders (3.0.3): Extracting archive
- Installing psr/http-message (1.0.1): Extracting archive
- Installing guzzlehttp/psr7 (1.8.2): Extracting archive
- Installing guzzlehttp/promises (1.4.1): Extracting archive
- Installing guzzlehttp/guzzle (6.5.5): Extracting archive
- Installing dsvgruppe/zebra-adapter (1.2.0): Extracting archive
- Installing react/promise (v2.8.0): Extracting archive
- Installing ezimuel/guzzlestreams (3.0.1): Extracting archive
- Installing ezimuel/ringphp (1.1.2): Extracting archive
- Installing elasticsearch/elasticsearch (v7.11.0): Extracting archive
- Installing facebook/graph-sdk (5.6.3): Extracting archive
- Installing jdorn/sql-formatter (v1.2.17): Extracting archive
- Installing phpseclib/phpseclib (2.0.31): Extracting archive
- Installing paragonie/random_compat (v9.99.99): Extracting archive
- Installing jumbojett/openid-connect-php (v0.9.2): Extracting archive
- Installing kairos/phpqrcode (v1.0.0): Extracting archive
- Installing laminas/laminas-loader (2.6.1): Extracting archive
- Installing laminas/laminas-stdlib (3.2.1): Extracting archive
- Installing container-interop/container-interop (1.2.0): Extracting archive
- Installing laminas/laminas-validator (2.13.5): Extracting archive
- Installing laminas/laminas-escaper (2.6.1): Extracting archive
- Installing laminas/laminas-uri (2.7.1): Extracting archive
- Installing laminas/laminas-server (2.8.1): Extracting archive
- Installing laminas/laminas-soap (2.8.0): Extracting archive
- Installing laminas/laminas-xml (1.2.0): Extracting archive
- Installing laminas/laminas-math (3.2.0): Extracting archive
- Installing laminas/laminas-http (2.13.0): Extracting archive
- Installing laminas/laminas-xmlrpc (2.9.0): Extracting archive
- Installing league/mime-type-detection (1.7.0): Extracting archive
- Installing league/flysystem (2.3.1): Extracting archive
- Installing league/flysystem-memory (2.0.6): Extracting archive
- Installing php-http/message-factory (v1.0.2): Extracting archive
- Installing php-http/message (1.11.0): Extracting archive
- Installing psr/http-client (1.0.1): Extracting archive
- Installing php-http/promise (1.1.0): Extracting archive
- Installing php-http/httplug (2.2.0): Extracting archive
- Installing php-http/discovery (1.13.0): Extracting archive
- Installing php-http/guzzle6-adapter (v2.0.2): Extracting archive
- Installing thecodingmachine/gotenberg-php-client (6.3.0): Extracting archive
- Installing league/flysystem-sftp (2.2.1): Extracting archive
- Installing league/flysystem-ftp (2.3.1): Extracting archive
- Installing dg/bypass-finals (v1.3.1): Extracting archive
- Installing mikey179/vfsstream (v1.6.8): Extracting archive
- Installing mustache/mustache (v2.13.0): Extracting archive
- Installing nikic/fast-route (v1.3.0): Extracting archive
- Installing php-amqplib/php-amqplib (v2.7.3): Extracting archive
- Installing roave/security-advisories (dev-master db47aac)
- Installing sentry/sentry (1.11.0): Extracting archive
- Installing squizlabs/php_codesniffer (3.6.0): Extracting archive
- Installing symfony/var-exporter (v5.2.7): Extracting archive
- Installing psr/cache (1.0.1): Extracting archive
- Installing symfony/cache-contracts (v2.4.0): Extracting archive
- Installing symfony/cache (v5.2.7): Extracting archive
- Installing symfony/finder (v5.2.4): Extracting archive
- Installing symfony/http-foundation (v5.2.7): Extracting archive
- Installing symfony/lock (v5.2.6): Extracting archive
- Installing symfony/process (v5.4.0): Extracting archive
- Installing symfony/serializer (v5.3.12): Extracting archive
- Installing tedivm/jshrink (v1.3.3): Extracting archive
- Installing symfony/css-selector (v5.2.7): Extracting archive
- Installing tijsverkoyen/css-to-inline-styles (2.2.3): Extracting archive
- Installing webmozart/assert (1.10.0): Extracting archive
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.
Generating autoload files
composer/package-versions-deprecated: Generating version class...
composer/package-versions-deprecated: ...done generating version class
43 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Package operations: 3 installs, 0 updates, 0 removals
- Downloading php-parallel-lint/php-console-color (v0.3)
- Downloading php-parallel-lint/php-console-highlighter (v0.5)
- Downloading php-parallel-lint/php-parallel-lint (v1.3.1)
- Installing php-parallel-lint/php-console-color (v0.3): Extracting archive
- Installing php-parallel-lint/php-console-highlighter (v0.5): Extracting archive
- Installing php-parallel-lint/php-parallel-lint (v1.3.1): Extracting archive
Generating autoload files
Have a system with 1.6.0 already in composer.lock
$ composer update
Loading composer repositories with package information
Updating dependencies
Lock file operations: 0 installs, 1 update, 0 removals
- Upgrading bamarni/composer-bin-plugin (1.6.0 => 1.7.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 0 installs, 1 update, 0 removals
- Upgrading bamarni/composer-bin-plugin (1.6.0 => 1.7.0): Extracting archive
Generating optimized autoload files
In PluginManager.php(273) : eval()'d code line 119:
[Error]
Call to undefined method Bamarni\Composer\Bin\Config::fromComposer()
Exception trace:
at phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(273) : eval()'d code:119
Bamarni\Composer\Bin\Plugin_composer_tmp0->onEvent() at phar:///usr/local/bin/composer/src/Composer/Plugin/PluginManager.php(273) : eval()'d code:99
Bamarni\Composer\Bin\Plugin_composer_tmp0->onPostAutoloadDump() at n/a:n/a
call_user_func() at phar:///usr/local/bin/composer/src/Composer/EventDispatcher/EventDispatcher.php:202
Composer\EventDispatcher\EventDispatcher->doDispatch() at phar:///usr/local/bin/composer/src/Composer/EventDispatcher/EventDispatcher.php:125
Composer\EventDispatcher\EventDispatcher->dispatchScript() at phar:///usr/local/bin/composer/src/Composer/Autoload/AutoloadGenerator.php:432
Composer\Autoload\AutoloadGenerator->dump() at phar:///usr/local/bin/composer/src/Composer/Installer.php:341
Composer\Installer->run() at phar:///usr/local/bin/composer/src/Composer/Command/UpdateCommand.php:241
Composer\Command\UpdateCommand->execute() at phar:///usr/local/bin/composer/vendor/symfony/console/Command/Command.php:298
Symfony\Component\Console\Command\Command->run() at phar:///usr/local/bin/composer/vendor/symfony/console/Application.php:1015
Symfony\Component\Console\Application->doRunCommand() at phar:///usr/local/bin/composer/vendor/symfony/console/Application.php:299
Symfony\Component\Console\Application->doRun() at phar:///usr/local/bin/composer/src/Composer/Console/Application.php:334
Composer\Console\Application->doRun() at phar:///usr/local/bin/composer/vendor/symfony/console/Application.php:171
Symfony\Component\Console\Application->run() at phar:///usr/local/bin/composer/src/Composer/Console/Application.php:130
Composer\Console\Application->run() at phar:///usr/local/bin/composer/bin/composer:88
require() at /usr/local/bin/composer:29
update [--with WITH] [--prefer-source] [--prefer-dist] [--prefer-install PREFER-INSTALL] [--dry-run] [--dev] [--no-dev] [--lock] [--no-install] [--no-autoloader] [--no-suggest] [--no-progress] [-w|--with-dependencies] [-W|--with-all-dependencies] [-v|vv|vvv|--verbose] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--apcu-autoloader] [--apcu-autoloader-prefix APCU-AUTOLOADER-PREFIX] [--ignore-platform-req IGNORE-PLATFORM-REQ] [--ignore-platform-reqs] [--prefer-stable] [--prefer-lowest] [-i|--interactive] [--root-reqs] [--] [<packages>...]
IMO the existing 1.6.0 does not have fromComposer
available - that was added in #90 for 1.7.0
The workaround is to run composer update
again, and this time it does not get any error.
I noticed the problem in automated CI stuff, in repos where there is already a committed composer.lock
that has 1.6.0 (and other pinned dependencies), and the CI does composer update
at some point. That falls over. I can manually make PRs for those to update to 1.7.0.
I wonder if there is a cleaner way to avoid this transition issue?
When I run just composer update --lock
to update my root composer.lock
's content-hash
, the post-update-cmd
is invoked and basically updates all vendor-bin
dependencies, not just their lock files.
// composer.json (extract)
"scripts": {
"bin": "echo 'bin not installed'",
"post-install-cmd": [
"@composer bin all install --ansi"
],
"post-update-cmd": [
"@composer bin all update --ansi"
]
}
This doesn't seem right, so either (a) Composer shouldn't run the post-update-cmd
on update --lock
, or (b) the Composer-bin-plugin should/could detect this somehow and only run update --lock
as well (maybe Composer passes the parameter in an ENV variable or so?).
Obviously, a workaround for us would be to remove the post-update-cmd
, because we can call bin all update
manually if we need to.
Right now Composer-Bin does resolve every single package namespace and installs its dependencies.
Unfortunately this leads to lots of duplicate classes and even different interfaces when the packages are installed in different versions, which really affects the UX within the IDE.
Yes, this can be solved by making the IDE ignoring some specific directories.
But using symlinks would be nice too.
In my opinion Composer-Bin could prevent duplicates by symlinking in a "special way":
Now it is up to the IDE to see the symlink and offer just one "thing" in the auto-completion.
Also it is up to the dev to add something like roave security helper,
so that insecure versions wont be used.
Remaining problem: What if the symlink target gets deleted?
PHP 5.x isn't supported anymore, so I think that this library should also drop that support.
With that we could use proper return types on methods and so on - WDYT?
@bamarni thanks for that great composer plugin. I'm using it for a while now. It saved me from a lot of headaches.
But when working with the command, in some cases I missed some functionality. Therefore I'd propose to add two new commands:
Provides an overview of "installed" bin directories/containers/scopes (or how you would name it). Maybe an additional option --with-require
could also list the root dependencies of that scope.
Will remove the directory for {scope}
and remove all bin symlinks for that scope.
Hi Bilal,
Thanks for this awesome plugin. I use it in all my computers and helped immensely to organize my global composer packages.
When we run composer bin example
, composer changes the directory to vendor-bin/example
, and executes the command specified next. Composer 1.5.1 came with a new feature that it checks scans the directories upwards until it finds a composer.json
file if the current directory does not contain a composer.json
file.
User is prompted of course, and the default value is set so that composer is allowed to use the root level composer.json
file. Can we update the README.txt
of this project to indicate that users wishing to install something in a new vendor-bin namespace should answer No?
Thanks.
This plugin can no longer be used with Composer 2.2 even though the composer.json
says it's compatible, due to #86
PHP Fatal error: Uncaught Error: Call to undefined method Bamarni\Composer\Bin\BinCommand::requireComposer() in /tmp/tmp.Kzy6XI6bnx/vendor/bamarni/composer-bin-plugin/src/BinCommand.php:91
Stack trace:
#0 phar:///usr/local/lib/composer-2.2.14/vendor/symfony/console/Command/Command.php(245): Bamarni\Composer\Bin\BinCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#1 phar:///usr/local/lib/composer-2.2.14/vendor/symfony/console/Application.php(835): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#2 phar:///usr/local/lib/composer-2.2.14/vendor/symfony/console/Application.php(185): Symfony\Component\Console\Application->doRunCommand(Object(Bamarni\Composer\Bin\BinCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#3 phar:///usr/local/lib/composer-2.2.14/src/Composer/Console/Application.p in /tmp/tmp.Kzy6XI6bnx/vendor/bamarni/composer-bin-plugin/src/BinCommand.php on line 91
So, having composer bin install phpcs with Wordpress standards works just fine:
$ composer global bin wordpress require squizlabs/php_codesniffer wp-coding-standards/wpcs dealerdirect/phpcodesniffer-composer-installer
$ phpcs -i
## The installed coding standards are Squiz, PSR1, PEAR, PSR12, Zend, PSR2, MySource, WordPress-Core, WordPress-Extra, WordPress and WordPress-Docs
However, once phpcs and Drupal standards are installed to a different bin, phpcs stops seeing all custom standards
$ composer global bin drupal require squizlabs/php_codesniffer drupal/coder dealerdirect/phpcodesniffer-composer-installer
$ phpcs -i
## The installed coding standards are Squiz, PSR1, PEAR, PSR12, Zend, PSR2 and MySource
Not sure whether it's an issue with composer-bin-plugin or dealerdirect/phpcodesniffer-composer-installer or both.
This bin package doesn't seem to work with https://github.com/ergebnis/composer-normalize, I believe this is because it registers as a Composer plugin rather than an actual binary file.
Maybe a bit of branding at some point could make the project a bit more attractive, dunno :)
I've come across https://github.com/lerna/lerna, it's very similar, might be worth trying to mention them at some point to show that this approach is not unique to PHP/Composer.
Composer-Bin-Plugin helps lowering the chance of version conflicts by separating tools into different directories.
Unfortunately none of these tools or "sub-composer" setups respect the options made on the top-level.
The composer-bin-plugin should forward some of the important or useful options (e.g. --no-dev).
Example of an "vendor-bin/foo/composer.json":
{
"autoload-dev": { "... stuff here ..." }
"require-dev": {
"only-for-deveolpment-here/some-package": "~1"
}
}
Running composer install --no-dev
(with lockfiles) present would ignore the "no-dev Option" and install the dev package. It also adds an autoloader that is never used in production mode. Forwarding the "no-dev Option" would solve this already.
Executing composer bin all install
with Composer 2.2 fails as due to f0b48b5 and other changes.
PHP Fatal error: Uncaught Error: Undefined class constant 'SUCCESS' in /tmp/tmp.iXBtOtyjej/vendor/bamarni/composer-bin-plugin/src/Command/BinCommand.php:161
Stack trace:
#0 /tmp/tmp.iXBtOtyjej/vendor/bamarni/composer-bin-plugin/src/Command/BinCommand.php(133): Bamarni\Composer\Bin\Command\BinCommand->executeAllNamespaces('/tmp/tmp.iXBtOt...', 'vendor-bin', Object(Symfony\Component\Console\Input\StringInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#1 phar:///usr/local/lib/composer-2.2.14/vendor/symfony/console/Command/Command.php(245): Bamarni\Composer\Bin\Command\BinCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#2 phar:///usr/local/lib/composer-2.2.14/vendor/symfony/console/Application.php(835): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#3 phar:///usr/local/lib/composer-2.2.14/vendor/symfony/console/Application.php(185): S in /tmp/tmp.iXBtOtyjej/vendor/bamarni/composer-bin-plugin/src/Command/BinCommand.php on line 161
If multiple namespaces contain a custom Composer script in their composer.json which have the same name, the following warning is triggered while executing composer bin all install
: A script named <script name> would override a Composer command and has been skipped
Steps to reproduce:
Add two tools in different namespaces:
composer bin phpcs require squizlabs/php_codesniffer
composer bin phpunit require phpunit/phpunit
Take this script
"scripts": {
"foo": ""
}
and append it to both composer.json:
vi vendor-bin/phpcs/composer.json
vi vendor-bin/phpunit/composer.json
Finally run the command to install the dependencies of all namespaces:
composer bin all install
Output:
root@a59f18950fef:/app# composer bin all install
Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Nothing to install, update or remove
Generating autoload files
A script named foo would override a Composer command and has been skipped
Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Nothing to install, update or remove
Generating autoload files
26 packages you are using are looking for funding.
Use thecomposer fund
command to find out more!
Is there anything left before having a stable release (or beta/rc)?
Also is there any point in keeping all the classes as extendable i.e. not making them final? (that is actually the only last change I would like to submit)
I think we already mentioned that once in a discussion somewhere, would there be a way to manage binaries conflicts?
For example say I if require PHPUnit in two namespaces (each with a different version), could this be handled? A way would be to add extra config to composer.json
to tell which one to pick, another one could be to change the link and prefix it by the namespace. For example if you have the namespaces symfony
and laravel
, you would end-up with:
vendor/bin/
- symfony-phpunit
- laravel-phpunit
Instead of just phpunit
.
WDYT?
Hi there
Thank you very much for this wonderful composer plugin, very happy with it so far!
I've noticed with the forward-command
config, that only composer install
and composer update
are being forwarded to the bin directories.
But I sometimes like to run composer outdated
as well against everything, and right now I need to do this one by one, which is a bit annoying.
Would be nice if this command can also be forwarded.
Thanks for considering this! π
It would be great if we have inherit config-partially from main composer.json
Example: github-oauth
Hey, so I am trying to install the package and it seems to just die. I have been unable to figure out why, the -v doesn't seem to work with require. Any ideas?
This is in a empty directory with no composer.json file and I cleared the composer cache.
$ composer require --dev bamarni/composer-bin-plugin
1/1: http://repo.packagist.org/p/provider-latest$e5c4b4043ebd06dedebcf930d12b00d0f3ab2a363d48bd37c4dc88b74585405f.json
Finished: success: 1, skipped: 0, failure: 0, total: 1
1/1: http://repo.packagist.org/p/provider-latest$e5c4b4043ebd06dedebcf930d12b00d0f3ab2a363d48bd37c4dc88b74585405f.json
Finished: success: 1, skipped: 0, failure: 0, total: 1
1/1: http://repo.packagist.org/p/provider-latest$e5c4b4043ebd06dedebcf930d12b00d0f3ab2a363d48bd37c4dc88b74585405f.json
Finished: success: 1, skipped: 0, failure: 0, total: 1
Using version ^1.3 for bamarni/composer-bin-plugin
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Installing bamarni/composer-bin-plugin (v1.3.0): Loading from cache
Plugin installation failed, rolling back
- Removing bamarni/composer-bin-plugin (v1.3.0)
Installation failed, deleting ./composer.json.
[ErrorException]
include(/home/vagrant/Code/_play/ttttmp/vendor/bamarni/composer-bin-plugin/src/Plugin.php): failed to open stream: No such file or directory
require [--dev] [--prefer-source] [--prefer-dist] [--no-progress] [--no-suggest] [--no-update] [--no-scripts] [--update-no-dev] [--update-with-dependencies] [--update-with-all-dependencies] [--ignore-platform-reqs] [--prefer-stable] [--prefer-lowest] [--sort-packages] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--apcu-autoloader] [--] [<packages>]...
(I hope someone has a better title)
The plugin is installed as a dev dependency (in "require-dev") and has "@composer bin all install" as a "post-install-cmd" setup.
Installing no-dev ("composer install --no-dev") makes the installation fail with the error "Command 'bin' is not defined.".
It would be great if the plugin would offer a solution to this e.g. by handling the post-install and post-update command itself.
As a developer I want to define several dev tools in multiple sub-directories so that I bypass possible version conflicts.
With this the composer-bin-plugin has nothing to do with the production environment, so it is a dev dependency.
Unfortunately the needed composer hooks makes it fail in such scenario.
Wrapping a custom bash script around this may help but that is not really a good solution.
Example:
{
"require-dev": {
"bamarni/composer-bin-plugin": "1.4.1"
},
"scripts": {
"post-install-cmd": [
"@composer bin all install --ansi"
]
}
}
# Composer version 2.2.4
composer install --no-dev
Notes:
Right now every package namespace creates its own autoloader:
From my own experience and lately discussed in composer/composer#9636
a custom autoloader could be a thing:
Right now developer can do this on their own:
<?php
require_once 'vendor-bin/test/vendor/autoload.php';
require_once 'vendor/autoload.php';
But this needs some hands on when adding another section
composer bin require new-section bar/baz
Having this more dynamically would be a little helper.
The common/central "vendor/autoload.php" should be changed to:
require_once 'vendor/composer/autoload_real.php';
$loader = ComposerAutoloaderInit1234::getLoader();
require_once 'vendor-bin/tools/dev/autoload.php';
require_once 'vendor-bin/tools/tool-a/autoload.php';
require_once 'vendor-bin/tools/tool-b/autoload.php';
return $loader;
In the same order as given in the JSON, to give users control about the autoloading order.
While the single tools put their own autoloader on top ("vendor-bin/tools/dev/autoload.php"):
require_once '/vendor/tools/composer/autoload_real.php';
$loader = ComposerAutoloaderInit6789::getLoader();
require_once 'vendor/autoload.php';
return $loader;
Something like this (just a quick fuzzy example).
Note: Including each another file does not lead to endless recursive includes.
The require_once
returns the object on the first include and just TRUE
for any further call.
For example, we want to use some bin in our project, like scss made with Ruby or https://github.com/phrase/phraseapp-client/releases/download/1.6.0/phraseapp_linux_amd64 made with Go. And these bins obviously are not composer packages and we want to include just compiled bin.
Could it be achieved with a composer or with this plugin? Or support could be added?
For: composer bin bdd require behat/behat:^3.0 phpspec/phpspec:^2.0
Why is the namespace bdd
required? Wouldn't be possible to generate one from the required package? Also why grouping dependencies together? Wouldn't it be better to just have 1 package per namespace?
global composer.json
:
$ cat ~/.composer/composer.json
{
"require": {
"bamarni/composer-bin-plugin": "^1.2"
}
}
current installed version:
$ composer global show | grep bamarni
Changed current directory to ~/.composer
bamarni/composer-bin-plugin v1.2.0
try to update:
$ composer global update
Changed current directory to ~/.composer
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Generating autoload files
github current version 1.3
: https://github.com/bamarni/composer-bin-plugin/releases
packagist current version 1.2
: https://packagist.org/packages/bamarni/composer-bin-plugin
Having global binaries isolated is cool, but would it be possible to do it on a project basis as well?
In some cases, having the binaries linked to the original may not be a desirable behaviour, would it be possible to add a way to disable it (via an extra
conf?)
After playing with it for a couple of month, I realise that installing some binaries to avoid any dependency conflict is, indeed a use case, but it is much more interesting to use to install optional dependencies. For example if I have a library acme/lib
, I may have frameworks bridges in it, in which case it is interesting to install them in sub-directories via this plugin to avoid any conflict between those dependencies and be able to install in parallel both Symfony and Laravel, and be able to run the tests for my lib, the Laravel and Symfony bridge at once.
There is certainly some subtleties when doing that, https://github.com/wikimedia/composer-merge-plugin that you pointed me at one point does help to solve them and I'm working to simplify a bit the set up.
So this other use case made me realise that linking the binaries is indeed a nice feature (and was the original goal of this plugin?), but ultimately the other usage is as interesting, requires no change in this plugin and describe more what this plugin is really about: managing sub-packages. So maybe another name would be more suited for this plugin? composer-subpackages-plugin
?
when using this plugin, composer installs the vendors into additional folders.
would be great to have a copy & paste'table example on how to cache this dependencies within a Github Action run.
something along the lines of https://github.com/shivammathur/setup-php#cache-composer-dependencies but adjusted for the composer-bin-plugin use-case
In ExtraPlugin::mergeOrDefer()
, I think we should skip itself IMO. The issue occurs with https://github.com/theofidry/composer-inheritance-plugin where when I do composer bin X
, it will be executed recursively...
I'm however not sure if this should be fixed here or in my plugin.
When following the docs to install locally rather than globally it says to do:
composer require --dev bamarni/composer-bin-plugin
composer bin php-scoper require --dev humbug/php-scoper
but since humbug/php-scoper
has a dev-master
requirement the scopes composer.json
needs to be updated or it will error out on the second command. The below will is what it should be.
composer require --dev bamarni/composer-bin-plugin
composer bin php-scoper config minimum-stability dev
composer bin php-scoper config prefer-stable true
composer bin php-scoper require --dev humbug/php-scoper
Currently if you run a binary from a "bin", and it uses Composer's InstalledVersions
API, it will report packages from the main project's directory composer.json
, instead of bin's.
This behavior breaks, for example, roave/infection-static-analysis-plugin
, which relies on such checks (which are wrapped in ocramius/package-versions
lib, see here).
I'm not sure this plugin itself can do something about it -- maybe it requires changes to the Composer plugin system itself, but it is a problem nevertheless.
Also see Ocramius/PackageVersions#220
Scenario: you have a package symfony/yaml
in your package.json
, which will be resolved in the version 3.1.2
. Now you have phpunit/phpunit
installed in a phpunit
namespace. To that point everything works fine. Somehow, you must use random/phpunit-plugin
with your phpunit which requires symfony/yaml
as well. In the phpunit
namespace, this symfony/yaml
is resolved in the version 2.8.3
. Now let's assume random/phpunit-plugin
cannot work with symfony/yaml 3.1.2
and your project cannot work with the 2.8.3
version.
What will happen? You will you get an error somewhere or will it silently fail or result in some weird bugs?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.