如何将作曲家包配置为全局安装?

2022-01-21 00:00:00 package php composer-php packagist

更新:

我实际上发布了这个包,以便您自己查看问题.

I actually published this package so you can see the problem for yourself.

在这里查看 naomik/yamldump

我正在尝试制作一个小 CLI 工具并用 composer 打包它.

I'm trying to make a little CLI tool and package it up with composer.

下面是一个极其简化的程序版本,但足以说明我遇到的问题.

Below is an extremely simplified version of the program, but it's enough to demonstrate the problem I'm encountering.

项目有一个依赖,一个二进制"文件

The project has one dependency, and one "binary" file

composer.json

{
  "name": "naomik/yamldump",
  "version": "0.2.0",
  "bin": [
    "bin/yamldump"
  ],
  "require": {
    "symfony/yaml": "2.5.3"
  }
}

bin/yamldump

#!/usr/bin/env php
<?php

// use Yaml namespace
use SymfonyComponentYaml as Yaml;

// autoload
require_once "vendor/autoload.php";

// read yaml
$yaml = file_get_contents(sprintf("%s/%s", getcwd(), $argv[1]));

// create parser
$parser = new YamlParser();

// parse the yaml
var_dump($parser->parse($yaml));

<小时>

所以当我在全局安装它时,我得到了这个


So when I install it globally, I get this

$ composer global require naomik/yamldump=dev-master

文件被安装到

  • ~/.composer/vendor/bin/yamldump ->../naomik/yamldump/bin/yamldump
  • ~/.composer/vendor/naomik/yamldump/
  • ~/.composer/vendor/symfony/yaml/

这是个问题,因为我不打算全局安装symfony/yaml 并且我的包的vendor/autoload.php不能再在合适的位置找到 Yaml 包.

This is a problem, because I did not intend to globally install symfony/yaml and my package's vendor/autoload.php can no longer find the Yaml package in the proper location.

我不介意 symfony/yaml 是全局安装的,但对我来说 composer global require 会安装像这样的包:

I don't mind that symfony/yaml was installed globally, but it would make sense to me that composer global require would install the package like this:

  • ~/.composer/vendor/bin/yamldump ->../naomik/yamldump/bin/yamldump
  • ~/.composer/vendor/naomik/yamldump/
  • ~/.composer/vendor/naomik/yamldump/vendor/symfony/yaml/

毕竟,如果我有 Package A 依赖于 symfony/yaml=2.5.3Package B 需要 >symfony/yaml=2.6.x?

After all, what if I have Package A that depends on symfony/yaml=2.5.3 and Package B that requires symfony/yaml=2.6.x?

如果 composer global require 将依赖项安装到 ~/.composer/vendor/*,则每个全局必需的包都无法维护其自身依赖项的版本要求...

If the composer global require installs dependencies to ~/.composer/vendor/*, each globally required package can't maintain it's own version requirement of its dependency...

我知道这是一个令人费解的问题,但我真的不知道如何着手解决它.

I know this is sort of a convoluted problem, but I really don't know how to begin fixing it.

目标

用户应该能够

$ composer global require naomik/yamldump=dev-master
$ yamldump sample.yml

错误

$ yamldump sample.yml
Warning: require_once(vendor/autoload.php): failed to open stream: No such file or directory in /Users/naomik/.composer/vendor/naomik/yamldump/bin/yamldump on line 8

Fatal error: require_once(): Failed opening required 'vendor/autoload.php' (include_path='.:') in /Users/naomik/.composer/vendor/naomik/yamldump/bin/yamldump on line 8

问题

这里是黑色的&白:

Here it is in black & white:

我打算如何编写 require "vendor/autoload.php" 行并让它同时适用于本地安装的包和全局安装的包?

How am I intended to write the require "vendor/autoload.php" line and have it work for both locally installed packages and globally installed packages?

推荐答案

定位 vendor/autoload.php 通常不是一个好主意,只有从正确的目录运行脚本才有效.以下内容应该更好地为您服务:

Targeting vendor/autoload.php is generally not a good idea and only works if you run the script from the correct directory. The following should serve you better:

require_once __DIR__.'/../vendor/autoload.php';

但是,如果您的应用程序作为依赖项安装,这仍然可能是一个问题.在这种情况下,您可能需要更实质性的东西:

However, this still might be an issue if your application is installed as a dependency. In that case, you might need something more substantial:

if (
    (!$classLoader = includeIfExists(__DIR__.'/../vendor/autoload.php')) &&
    (!$classLoader = includeIfExists(__DIR__.'/../../../autoload.php'))
) {
    echo 'You must set up the project dependencies, run the following commands:'.PHP_EOL.
        'curl -sS https://getcomposer.org/installer | php'.PHP_EOL.
        'php composer.phar install'.PHP_EOL;
    exit(1);
}

如果您直接在应用程序上工作,这首先会在您期望的位置查找自动加载器.如果不存在,它会查看自动加载器在您的应用程序作为依赖项安装时的位置.

This first looks for the autoloader in the location you would expect it to be if you are working directly on your application. If that does not exist, it looks where the autoloader would be if your application is installed as a dependency.

相关文章