bamarni / composer-bin-plugin
您的 bin 依赖没有冲突
Requires
- php: ^7.2.5 || ^8.0
- composer-plugin-api: ^2.0
Requires (Dev)
- ext-json: *
- composer/composer: ^2.0
- phpstan/extension-installer: ^1.1
- phpstan/phpstan: ^1.8
- phpstan/phpstan-phpunit: ^1.1
- phpunit/phpunit: ^8.5 || ^9.5
- symfony/console: ^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0
- symfony/finder: ^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0
- symfony/process: ^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0
README
目录
为什么?一个难题的简单解决方案。
当使用 Composer 管理您的依赖项时,您的依赖项会以兼容的版本进行扁平化处理,或者在不可能的情况下,会导致冲突错误。
然而,在将工具作为依赖项添加的情况下,例如 PHPStan* 或 Rector 可能会因为它们带来的依赖而产生不良影响。例如,如果 phpstan 依赖于 nikic/php-parser
4.x 和 rector 3.x,您无法同时安装这两个工具(尽管从使用角度来看,它们不需要兼容)。另一个例子,可能您不能再添加一个非开发依赖项,因为 PHPStan 带来的依赖与它不兼容。
这个问题并没有什么特殊之处:这是 PHP 中 Composer 处理依赖的方式。然而,在上面的情况下,这种冲突是令人烦恼的,因为冲突不应该存在:这是 Composer 的局限性,因为它无法推断您如何使用每个依赖项。
解决上述问题的方法之一是将这些依赖项安装在不同的 composer.json
文件中。这有其缺点,例如,如果您使用 PHPUnit 进行此操作,您可能会发现自己处于一个场景,其中 PHPUnit 将无法执行您的测试,因为您的代码与它不兼容,而 Composer 无法告知,因为 PHPUnit 依赖项独自存在于其自己的 composer.json
中。这正是 Composer 旨在解决的问题。一般来说,您应该仅将此方法限制在不需要自动加载代码的工具上。
然而,管理多个 composer.json
可能会有些麻烦。此插件旨在帮助您完成这项工作。
*: 实际上,您将不会遇到 PHPStan 的问题,因为 Composer 包 phpstan/phpstan
随附一个带有作用域的 PHAR(通过 PHP-Scoper 进行作用域),这不仅提供了一个没有依赖项的包,而且在自动加载代码时没有冲突/崩溃的风险。
用法;这个插件是如何工作的?
此插件注册了一个 bin <bin-namespace-name>
命令,允许您与 vendor-bin/<bin-namespace-name>/composer.json
* 文件交互。
例如
$ composer bin php-cs-fixer require --dev friendsofphp/php-cs-fixer # Equivalent to manually doing: $ mkdir vendor-bin/php-cs-fixer $ cd vendor-bin/php-cs-fixer && composer require --dev friendsofphp/php-cs-fixer
您还有一个特殊的 all
命名空间来与所有 bin 命名空间交互
# Runs "composer update" for each bin namespace
$ composer bin all update
安装
$ composer require --dev bamarni/composer-bin-plugin
配置
{ ... "extra": { "bamarni-bin": { "bin-links": false, "target-directory": "vendor-bin", "forward-command": true } } }
bin 链接 (bin-links
)
In 1.x: 默认启用。In 2.x: 默认禁用。
在安装 Composer 包时,Composer 可能会将 "bin 链接" 添加到 bin 目录。例如,默认情况下安装 phpunit/phpunit
时,它将添加一个指向位于 vendor/phpunit/phpunit
的 PHPUnit 脚本的符号链接 vendor/bin/phpunit
。
在1.x版本中,BamarniBinPlugin对“bin依赖项”的处理方式相同,也就是说,当执行composer bin php-cs-fixer require --dev friendsofphp/php-cs-fixer
时,它将添加一个bin链接vendor/bin/php-cs-fixer -> vendor-bin/php-cs-fixer/vendor/friendsofphp/php-cs-fixer
。
然而,这有点棘手,无法提供一致的行为。例如,当安装具有相同bin的多个包时(例如,在上述情况下安装另一个作为依赖项使用PHP-CS-Fixer的其他工具的bin命名空间),符号链接可能会被覆盖或根本不创建。由于无法控制这种行为,也无法提供直观或确定性的方法,建议将此设置设置为false
,这将是在2.x中的默认设置。
这意味着,您将不得不使用vendor-bin/php-cs-fixer/vendor/friendsofphp/php-cs-fixer/path/tophp-cs-fixer
(在这种情况下,建议通过Composer脚本来设置别名)而不是使用vendor/bin/php-cs-fixer
。
目标目录 (target-directory
)
默认为vendor-bin
,可以被覆盖为任何您想要的值。
转发命令 (forward-command
)
默认在1.x中禁用,将在2.x中默认启用。如果启用此模式,所有composer install
和composer update
命令都将转发到所有bin目录。
这是自动安装部分中显示的任务的替代方案。
技巧 & 小窍门
自动安装
您可以通过将命令转发到composer install
来轻松地将安装转发到所有(在这种情况下,具有extra.bamarni-bin.forward_command = true
更合适)或特定的bin命名空间。
{ "scripts": { "bin": "echo 'bin not installed'", "post-install-cmd": ["@composer bin php-cs-fixer install --ansi"] } }
您可以通过利用Composer脚本事件来自定义此设置。
减少杂乱
您可以将以下行添加到您的.gitignore
文件中,以避免提交工具的依赖项。
# .gitignore /vendor-bin/**/vendor/
更新每个工具可能会在composer.lock
文件中创建许多难以识别的更改。您可以使用.gitattributes
文件来通知git不要显示composer.lock
文件的差异。
# .gitattributes
/vendor-bin/**/composer.lock binary
GitHub Actions 集成
目前没有方法可以利用ramsey/composer-install
来安装所有命名空间的bin。然而,您可能不需要在CI中本地安装此功能,在这种情况下,转发命令应该足够好。
如果您仍然需要安装特定的bin命名空间,可以通过设置working-directory
来完成。
#... - name: "Install PHP-CS-Fixer Composer dependencies" uses: "ramsey/composer-install@v2" with: working-directory: "vendor-bin/php-cs-fixer"
相关插件
- theofidry/composer-inheritance-plugin:与该插件配合使用的Wikimedia composer-merge-plugin的具有观点的版本。
向后兼容承诺
向后兼容的承诺仅适用于以下API
- 插件注册的命令
- 命令的行为(但不是它们的日志/输出)
- Composer配置
插件实现被认为是严格内部,其代码可能随时以非向后兼容的方式更改。
贡献
有一个makefile可以帮助
$ make # Runs all checks $ make help # List all available commands
注意:您需要先安装phive。