Composer bin plugin — Isolate your bin dependencies

Overview

Composer bin plugin — Isolate your bin dependencies

Package version Build Status License

Table of Contents

  1. Why?
  2. How does this plugin work?
  3. Installation
  4. Usage
    1. Example
    2. The all bin namespace
    3. What happens when symlink conflicts?
  5. Tips
    1. Auto-installation
    2. Disable links
    3. Change directory
    4. Forward mode
    5. Reduce clutter
  6. Related plugins

Why?

In PHP, with Composer, your dependencies are flattened, which might result in conflicts. Most of the time those conflicts are legitimate and should be properly resolved. However you may have dev tools that you want to manage via Composer for convenience, but should not influence your project dependencies or for which conflicts don't make sense. For example: EtsyPhan and PhpMetrics. Installing one of those static analysis tools should not change your application dependencies, neither should it be a problem to install both of them at the same time.

How does this plugin work?

It allows you to install your bin vendors in isolated locations, and still link them to your bin-dir (if you want to).

This is done by registering a bin command, which can be used to run Composer commands inside a namespace.

Installation

# Globally
$ composer global require bamarni/composer-bin-plugin

# In your project
$ composer require --dev bamarni/composer-bin-plugin

Usage

$ composer bin [namespace] [composer_command]
$ composer global bin [namespace] [composer_command]

Example

Let's install Behat and PhpSpec inside a bdd bin namespace, EtsyPhan in etsy-phan and PhpMetrics in phpmetrics:

$ composer bin bdd require behat/behat phpspec/phpspec
$ composer bin etsy-phan require etsy/phan
$ composer bin phpmetrics require phpmetrics/phpmetrics

This command creates the following directory structure :

.
├── composer.json
├── composer.lock
├── vendor/
│   └── bin
│       ├── behat -> ../../vendor-bin/bdd/vendor/behat/behat/bin/behat
│       ├── phpspec -> ../../vendor-bin/bdd/vendor/phpspec/phpspec/bin/phpspec
│       ├── phan -> ../../vendor-bin/etsy-phan/vendor/etsy/phan/phan
│       └── phpmetrics -> ../../vendor-bin/phpmetrics/vendor/phpmetrics/phpmetrics/bin/phpmetrics
└── vendor-bin/
    └── bdd
    │   ├── composer.json
    │   ├── composer.lock
    │   └── vendor/
    │       ├── behat/
    │       ├── phpspec/
    │       └── ...
    └── etsy-phan
    │   ├── composer.json
    │   ├── composer.lock
    │   └── vendor/
    │       ├── etsy/
    │       └── ...
    └── phpmetrics
        ├── composer.json
        ├── composer.lock
        └── vendor/
            ├── phpmetrics/
            └── ...

You can continue to run vendor/bin/behat, vendor/bin/phpspec and co. as before but they will be properly isolated. Also, composer.json and composer.lock files in each namespace will allow you to take advantage of automated dependency management as normally provided by Composer.

The all bin namespace

The all bin namespace has a special meaning. It runs a command for all existing bin namespaces. For instance, the following command would update all your bins :

$ composer bin all update
Changed current directory to vendor-bin/phpspec
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Generating autoload files
Changed current directory to vendor-bin/phpunit
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Generating autoload files

What happens when symlink conflicts?

If we take the case described in the example section, there might be more binaries linked due to the dependencies. For example PhpMetrics depends on Nikic PHP-Parser and as such you will also have php-parse in .vendor/bin/:

.
├── composer.json
├── composer.lock
├── vendor/
│   └── bin
│       ├── phpmetrics -> ../../vendor-bin/phpmetrics/vendor/phpmetrics/phpmetrics/bin/phpmetrics
│       └── php-parse -> ../../vendor-bin/phpmetrics/vendor/nikic/PHP-Parser/bin/php-parsee
└── vendor-bin/
    └── phpmetrics
        ├── composer.json
        ├── composer.lock
        └── vendor/
            ├── phpmetrics/
            ├── nikic/
            └── ...

But what happens if another bin-namespace has a dependency using Nikic PHP-Parser? In that situation symlinks would collides and are not created (only the colliding ones).

Tips

Auto-installation

For convenience, you can add the following script in your composer.json :

{
    "scripts": {
        "bin": "echo 'bin not installed'",
        "post-install-cmd": ["@composer bin all install --ansi"],
        "post-update-cmd": ["@composer bin all update --ansi"]
    }
}

This makes sure all your bins are installed during composer install and updated during composer update.

Disable links

By default, binaries of the sub namespaces are linked to the root one like described in example. If you wish to disable that behaviour, you can do so by adding a little setting in the extra config:

{
    "extra": {
        "bamarni-bin": {
            "bin-links": false
        }
    }
}

Change directory

By default, the packages are looked for in the vendor-bin directory. The location can be changed using target-directory value in the extra config:

{
    "extra": {
        "bamarni-bin": {
            "target-directory": "ci/vendor"
        }
    }
}

Forward mode

There is a forward mode which is disabled by default. This can be activated by using the forward-command value in the extra config.

{
    "extra": {
        "bamarni-bin": {
            "forward-command": true
        }
    }
}

If this mode is activated, all your composer install and composer update commands are forwared to all bin directories. This is an replacement for the tasks shown in section Auto-installation.

Reduce clutter

You can add following line to your .gitignore file in order to avoid committing dependencies of your tools.

/vendor-bin/**/vendor

Updating each tool can create many not legible changes in composer.lock files. You can use .gitattributes file in order to inform git that it shouldn't show diffs of composer.lock files.

vendor-bin/**/composer.lock binary

Related plugins

Comments
  • Error during bin require with Symfony Flex

    Error during bin require with Symfony Flex

    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.

    opened by brzuchal 16
  • added docs on how to cache dependencies within a github action

    added docs on how to cache dependencies within a github action

    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

    opened by staabm 14
  • Is the namespace parameter necessary?

    Is the namespace parameter necessary?

    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.

    opened by uberhacker 14
  • Make sure that composer file exists before running

    Make sure that composer file exists before running

    The source of issue in #39 appears to be custom RequireCommand in Symfony Flex.

    More specifically:

    $this->getComposer();
    

    Making sure that composer file exists fixes the issue.

    Should I add tests and document it or do you see some better solution?

    I have tried disabling plugins in command that BinCommand is running, but I think plugins are already loaded at that time, so it has no effect.

    opened by Isinlor 12
  • Remove namespaces?

    Remove namespaces?

    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?

    opened by theofidry 11
  • Detect installation via this plugin

    Detect installation via this plugin

    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.

    enhancement help wanted 
    opened by ondrejmirtes 10
  • Fix the parsing of the input

    Fix the parsing of the input

    Closes #22.

    For some reason, I can see that when I do composer bin all install, the actual input of the plugin is composer bin --ansi all install which breaks the regex.

    opened by theofidry 7
  • Doesn't work with ergebnis/composer-normalize

    Doesn't work with ergebnis/composer-normalize

    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.

    opened by Jamesking56 6
  • Composer plugin support in namespaces?

    Composer plugin support in namespaces?

    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

    opened by AndreasA 6
  • Add support for composer-plugin-api ^2 and implement PlginInterface methods from ^2

    Add support for composer-plugin-api ^2 and implement PlginInterface methods from ^2

    Hi Bilal,

    This PR adds support for Composer v2 for this plugin! composer/composer#8726 and has more information on changes.

    Composer version 2 has composer-plugin-api version 2. This commit updates the version constraint to ^1 || ^2 so we can support both composer versions.

    See What's new in Composer 2 and UPGRADE-2.0 for more changes in API. Empty methods \Bamarni\Composer\Bin\Plugin::deactivate() and \Bamarni\Composer\Bin\Plugin::uninstall() are added to make it compatible both versions.

    Travis will report that this builds fails. It is because the composer/composer package is not pinned to a version constraint. Even without these changes, builds fail.

    Thank you.

    opened by Ayesh 6
  • Installation fails

    Installation fails

    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>]...
    
    
    opened by TerrePorter 6
Releases(1.8.2)
  • 1.8.2(Oct 31, 2022)

    Bugfixes

    • Make the name more explicit (#146)

    Misc

    • Rework doc (#139)
    • Add GA integration docs (#140)
    • Remove TravisCI badge (#142)
    • Fix end-to-end tests (#143)
    • Check behaviour of Composer\Versions (#141)
    • Fix file comment (#144)
    • Fix the pipeline (#147)
    Source code(tar.gz)
    Source code(zip)
  • 1.8.1(Aug 3, 2022)

    Bugfixes

    • Fix exit code returned when executing all bin namespaces (#136)
    • Correct the Symfony constraints (#137)

    Misc

    • Fix minor typos and grammar (#133)
    • Use requireComposer() when possible (#135)
    Source code(tar.gz)
    Source code(zip)
  • 1.8.0(Jul 14, 2022)

    Features

    • Add a Backward Compatibility Promise section in https://github.com/bamarni/composer-bin-plugin/pull/126
    • Validate the config in https://github.com/bamarni/composer-bin-plugin/pull/130
    • Introduce config deprecations in https://github.com/bamarni/composer-bin-plugin/pull/123

    Bugfixes

    • Fix usage with Composer <2.3 in https://github.com/bamarni/composer-bin-plugin/pull/132

    Misc

    • Add PHPStan to CI in https://github.com/bamarni/composer-bin-plugin/pull/117
    • Fix array shape in MyTestCommand in https://github.com/bamarni/composer-bin-plugin/pull/119
    • Remove extra parameter of assertDataSetRecordedIs in https://github.com/bamarni/composer-bin-plugin/pull/118
    • Raise PHPStan level in https://github.com/bamarni/composer-bin-plugin/pull/120
    • Add tests for the config in https://github.com/bamarni/composer-bin-plugin/pull/127
    • Fix PHPStan issues in https://github.com/bamarni/composer-bin-plugin/pull/128
    • Make the e2e tests more resilient in https://github.com/bamarni/composer-bin-plugin/pull/129
    • Re-organise the code in https://github.com/bamarni/composer-bin-plugin/pull/131

    Full Changelog: https://github.com/bamarni/composer-bin-plugin/compare/1.7.0...1.8.0

    Source code(tar.gz)
    Source code(zip)
  • 1.7.0(Jul 10, 2022)

    Features

    • Improve the logging experience in https://github.com/bamarni/composer-bin-plugin/pull/92
    • Mark classes as @final in https://github.com/bamarni/composer-bin-plugin/pull/98
    • Add extra logging on normal verbosity in https://github.com/bamarni/composer-bin-plugin/pull/112

    Bugfixes

    • Add missing ext-json requirement in https://github.com/bamarni/composer-bin-plugin/pull/82
    • Ensure we clean up the state even when executing only one namespace in https://github.com/bamarni/composer-bin-plugin/pull/94
    • Cleanup application commands between each executions in https://github.com/bamarni/composer-bin-plugin/pull/96
    • Ensure additional flags & options are forwarded in https://github.com/bamarni/composer-bin-plugin/pull/106
    • Fix executing plugin in a namespace in https://github.com/bamarni/composer-bin-plugin/pull/115

    Misc

    • Leverage PHP types in https://github.com/bamarni/composer-bin-plugin/pull/78
    • Fix GitHubActions for master in https://github.com/bamarni/composer-bin-plugin/pull/80
    • Enable PHP strict types in https://github.com/bamarni/composer-bin-plugin/pull/81
    • Extract the input creation into a dedicated utility class in https://github.com/bamarni/composer-bin-plugin/pull/83
    • Leverage constants in https://github.com/bamarni/composer-bin-plugin/pull/84
    • Introduce PHP-CS-Fixer in https://github.com/bamarni/composer-bin-plugin/pull/85
    • Use the new requireComposer() instead of the deprecated getComposer() in https://github.com/bamarni/composer-bin-plugin/pull/86
    • Fail the command if mkdir fails in https://github.com/bamarni/composer-bin-plugin/pull/87 and https://github.com/bamarni/composer-bin-plugin/pull/88
    • Extract config creation into a dedicated class in https://github.com/bamarni/composer-bin-plugin/pull/89
    • Tweak the Config in https://github.com/bamarni/composer-bin-plugin/pull/90
    • Various minor refactoring in https://github.com/bamarni/composer-bin-plugin/pull/79
    • Use getApplication() instead of passing the instance around in https://github.com/bamarni/composer-bin-plugin/pull/93
    • Code readability improvements in https://github.com/bamarni/composer-bin-plugin/pull/91
    • Add end-to-end tests in https://github.com/bamarni/composer-bin-plugin/pull/95
    • Add test in https://github.com/bamarni/composer-bin-plugin/pull/97
    • Add a Logger class in https://github.com/bamarni/composer-bin-plugin/pull/99
    • Rename plugin log prefix in https://github.com/bamarni/composer-bin-plugin/pull/100
    • Simplify workflow in https://github.com/bamarni/composer-bin-plugin/pull/101
    • Add tests for the forward command setting in https://github.com/bamarni/composer-bin-plugin/pull/102
    • Fix logging when forwarding the command in https://github.com/bamarni/composer-bin-plugin/pull/104
    • Fix forwarded command does not work on first install in https://github.com/bamarni/composer-bin-plugin/pull/103
    • Clarify behaviour when there is conflicting symlinks in https://github.com/bamarni/composer-bin-plugin/pull/105
    • Normalize composer.json in https://github.com/bamarni/composer-bin-plugin/pull/108
    • Add PHPStan in https://github.com/bamarni/composer-bin-plugin/pull/109
    • Add infection in https://github.com/bamarni/composer-bin-plugin/pull/110
    • Introduce Makefile in https://github.com/bamarni/composer-bin-plugin/pull/107
    • Move PHP-CS-Fixer to phive in https://github.com/bamarni/composer-bin-plugin/pull/111
    • Capture buggy behaviour with forwarded command in https://github.com/bamarni/composer-bin-plugin/pull/113
    • Add env variables to e2e tests to make the tests more portable in https://github.com/bamarni/composer-bin-plugin/pull/114
    • Add tests to ensure environment variables are correctly forwarded in https://github.com/bamarni/composer-bin-plugin/pull/116

    Full Changelog: https://github.com/bamarni/composer-bin-plugin/compare/1.6.0...1.7.0

    Source code(tar.gz)
    Source code(zip)
  • 1.6.0(Jul 6, 2022)

  • v1.5.0(Feb 22, 2022)

  • 1.4.2(Feb 16, 2022)

  • 1.4.1(Jun 2, 2020)

  • 1.4.0(Apr 17, 2020)

  • v1.3.0(Mar 17, 2019)

    Features

    • Add debug logs (#32)

    Bugfixes

    • Make sure that composer file exists before running (#42)
    • Do not fail hard when installing no dev deps (#45)

    Misc

    • Add PHP 7.2 & 7.3 to Travis (#43)
    • Drop PHP 5.3
    • Allow Symfony v4
    • Remove unnecessary files for production (#44)
    Source code(tar.gz)
    Source code(zip)
Owner
Bilal Amarni
Bilal Amarni
🔨 Prefixes all PHP namespaces in a file/directory to isolate the code bundled in PHARs.

PHP-Scoper PHP-Scoper is a tool which essentially moves any body of code, including all dependencies such as vendor directories, to a new and distinct

Humbug 590 Jan 2, 2023
A composer plugin, to install differenty types of composer packages in custom directories outside the default composer default installation path which is in the vendor folder.

composer-custom-directory-installer A composer plugin, to install differenty types of composer packages in custom directories outside the default comp

Mina Nabil Sami 136 Dec 30, 2022
A Composer Package which installs the PhantomJS binary (Linux, Windows, Mac) into /bin of your project.

phantomjs-installer A Composer package which installs the PhantomJS binary (Linux, Windows, Mac) into /bin of your project. Table of Contents Installa

Jens A. Koch 149 Nov 8, 2022
This composer plugin is a temporary implementation of using symbolic links to local packages as dependencies to allow a parallel work process

Composer symlinker A Composer plugin to install packages as local symbolic links. This plugin is a temporary implementation of using symbolic links to

Pierre Cassat 18 Nov 9, 2021
Plugin for composer to apply patches onto dependencies.

composer-patches-plugin This plugin allows you to provide patches for any package from any package. If you don't want a patch package outside the root

Netresearch 75 Aug 7, 2022
Ied plugin composer - Inspired Plugin Composer: Create, publish and edit plugins from within Textpattern CMS.

ied_plugin_composer Create, publish and edit plugins from within Textpattern CMS. Creates a new page under the Extensions tab where you can edit and e

Stef Dawson 8 Oct 3, 2020
Composer plugin that wraps all composer vendor packages inside your own namespace. Intended for WordPress plugins.

Imposter Plugin Composer plugin that wraps all composer vendor packages inside your own namespace. Intended for WordPress plugins. Built with ♥ by Typ

Typist Tech 127 Dec 17, 2022
Composer Registrar Composer Plugin for Magento 2

This module add a global registration.php that replace the default glob search performed for each request to discover the components not installed from composer.

OpenGento 3 Mar 22, 2022
WordPress Feature Project: Plugin Dependencies

WordPress Feature Project: Plugin Dependencies Contributors: afragen, costdev Description: Parses 'Requires Plugins' header, add plugin install depend

WordPress 41 Dec 17, 2022
This package contains a PHP implementation to solve 3D bin packing problems.

3D Bin Packager This package contains a PHP implementation to solve 3d bin packing problems based on gedex implementation on Go and enzoruiz implement

Farista Latuconsina 7 Nov 21, 2022
Set a customer password with bin/magento.

Set a customer password Since Magento 2 no longer provides facilities to set a customers password, this command can come in handy during development w

Vinai Kopp 25 Mar 8, 2022
bin/magento command to display configured preferences for classes or interfaces

bin/magento command to display configured preferences for classes or interfaces A bin/magento command that will show you the configured preferences fo

David Manners 14 Jul 18, 2022
A faster drop in replacement for bin/magento cache:clean with file watcher

"You know, hope is a mistake. If you can't fix what's broken, you'll, uh... you'll go insane." - Max Rockatansky Magento 2 Cache Clean A faster drop i

mage2tv 460 Dec 26, 2022
Magento-composer-installer - Composer installer for Magento modules

!!! support the maintainer of this project via Patreon: https://www.patreon.com/Flyingmana Magento Composer Installer The purpose of this project is t

null 213 Sep 24, 2022
Composer Repository Manager for selling Magento 2 extension and offering composer installation for ordered packages.

Magento 2 Composer Repository Credits We got inspired by https://github.com/Genmato. Composer Repository for Magento 2 This extension works as a Magen

EAdesign 18 Dec 16, 2021
Composer registry manager that help to easily switch to the composer repository you want

CRM - Composer Registry Manager Composer Registry Manager can help you easily and quickly switch between different composer repositories. 简体中文 Install

Tao 500 Dec 29, 2022
Dependency graph visualization for composer.json (PHP + Composer)

clue/graph-composer Graph visualization for your project's composer.json and its dependencies: Table of contents Usage graph-composer show graph-compo

Christian Lück 797 Jan 5, 2023
Drupal Composer Scaffold - A flexible Composer project scaffold builder

This project provides a composer plugin for placing scaffold files (like index.php, update.php, …) from the drupal/core project into their desired location inside the web root. Only individual files may be scaffolded with this plugin.

Drupal 44 Sep 22, 2022
Victor The Cleaner for Composer - This tool removes unnecessary files and directories from Composer vendor directory.

Victor The Cleaner for Composer This tool removes unnecessary files and directories from Composer vendor directory. The Cleaner leaves only directorie

David Grudl 133 Oct 26, 2022