如何配置要全局安装的composer包?

时间:2022-05-23 07:14:56

Update:

更新:

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

我实际上发布了这个包,这样你就可以自己看到问题了。

Check it out here naomik/yamldump

看看naomik/yamldump吧


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

我正在尝试制作一个CLI工具,并将它与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

composer.json

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

bin/yamldump

bin / yamldump

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

// use Yaml namespace
use Symfony\Component\Yaml as Yaml;

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

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

// create parser
$parser = new Yaml\Parser();

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

So when I install it globally, I get this

全局安装时,我得到这个

$ composer global require naomik/yamldump=dev-master

Files are installed to

文件安装

  • ~/.composer/vendor/bin/yamldump -> ../naomik/yamldump/bin/yamldump
  • ~ / .composer /供应商/ bin / yamldump - > . . / naomik / yamldump / bin / yamldump
  • ~/.composer/vendor/naomik/yamldump/
  • ~ / .composer /供应商/ naomik / yamldump /
  • ~/.composer/vendor/symfony/yaml/
  • ~ / .composer /供应商/ symfony / 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和我的包的供应商/autoload。php不能在适当的位置找到Yaml包。

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:

我不介意symfony/yaml是全球安装的,但我认为composer global require会像这样安装包:

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

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?

毕竟,如果我有依赖于symfony/yaml=2.5.3的软件包A和需要symfony/yaml=2.6.x的软件包B怎么办?

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...

如果composer global需要安装依赖关系到~/.composer/vendor/*,那么每个全球所需的包都不能维护它的依赖项的版本需求……

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

我知道这是一个复杂的问题,但我真的不知道如何开始修复它。


The goal

我们的目标

A user should be able to

用户应该能够。

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

The error

这个错误

$ 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

The question

这个问题

Here it is in black & white:

这是黑白的:

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?

我打算如何写要求“供应商/自动记录”。php“行,是否可以同时适用于本地安装包和全局安装包?

1 个解决方案

#1


4  

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:

针对供应商/自动装载。php通常不是一个好主意,只有在您从正确的目录运行脚本时才会运行。以下内容更适合您:

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.

如果直接在应用程序上工作,第一步是在您期望的位置查找自动加载器。如果不存在,那么如果应用程序是作为依赖项安装的,它将查找自动加载器的位置。

#1


4  

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:

针对供应商/自动装载。php通常不是一个好主意,只有在您从正确的目录运行脚本时才会运行。以下内容更适合您:

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.

如果直接在应用程序上工作,第一步是在您期望的位置查找自动加载器。如果不存在,那么如果应用程序是作为依赖项安装的,它将查找自动加载器的位置。