14

小さな CLI ツールを作成し、composer でパッケージ化しようとしています。

以下はプログラムの非常に簡略化されたバージョンですが、私が直面している問題を示すには十分です。

プロジェクトには 1 つの依存関係と 1 つの「バイナリ」ファイルがあります

composer.json

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

ビン/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));

したがって、グローバルにインストールすると、これが得られます

$ composer global require alice/yamldump=dev-master

ファイルのインストール先

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

これは問題です。グローバルにインストールするつもりはなくsymfony/yaml 私のパッケージvendor/autoload.phpは Yaml パッケージを適切な場所に見つけることができなくなったからです。

グローバルにインストールされてもかまいませんが、次のようにパッケージをインストールすることは理にかなってます。symfony/yamlcomposer global require

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

結局のところ、Package A依存するものsymfony/yaml=2.5.3Package B要求するものがある場合はどうなりsymfony/yaml=2.6.xますか?

composer global requireに依存関係をインストールする場合、~/.composer/vendor/*グローバルに必要な各パッケージは、依存関係の独自のバージョン要件を維持できません...

これが一種の複雑な問題であることはわかっていますが、修正を開始する方法が本当にわかりません。


目標

ユーザーは、次のことができる必要があります。

$ composer global require alice/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/alice/.composer/vendor/alice/yamldump/bin/yamldump on line 8

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

質問

ここに白黒があります:

require "vendor/autoload.php"行を記述して、ローカルにインストールされたパッケージとグローバルにインストールされたパッケージの両方で機能するようにするにはどうすればよいですか?

4

1 に答える 1

3

通常、ターゲティングvendor/autoload.phpはお勧めできません。適切なディレクトリからスクリプトを実行した場合にのみ機能します。以下はあなたに役立つはずです:

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

ただし、アプリケーションが依存関係としてインストールされている場合、これは依然として問題になる可能性があります。その場合、もっと実質的なものが必要になるかもしれません:

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);
}

これは、最初に、アプリケーションで直接作業している場合に予想される場所でオートローダーを探します。それが存在しない場合は、アプリケーションが依存関係としてインストールされている場合にオートローダーがどこにあるのかを調べます。

于 2014-08-22T02:19:04.660 に答える