【问题标题】:How do I make Composer automatically install all dependencies of a package from my local repository?如何让 Composer 自动从我的本地存储库安装包的所有依赖项?
【发布时间】:2021-06-07 04:17:20
【问题描述】:

我在 Ubuntu 上使用 Composer 1.6.3 并拥有以下全局 ~/.config/composer/config.json 文件:

{
    "config": {},
    "repositories": {
        "packagist": false,
        "codifier": {
          "type": "composer",
          "url": "file:///usr/local/codifier/library/PHP/Codifier"
        }
    }
}

换句话说,我禁用了 Packagist 并指向我自己本地机器上的存储库。这个本地存储库有一个 packages.json 定义所有可用的本地包:

{
  "packages": {
    "codifier/cache": {
      "dev-master": {
        "name": "codifier/cache",
        "version": "dev-master",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Cache",
          "type": "git",
          "reference": "master"
        }
      },
      "1.0.0": {
        "name": "codifier/cache",
        "version": "1.0.0",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Cache",
          "type": "git",
          "reference": "v1.0.0"
        }
      }
    },
    "codifier/environment": {
      "dev-master": {
        "name": "codifier/environment",
        "version": "dev-master",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Environment",
          "type": "git",
          "reference": "master"
        }
      },
      "1.0.0": {
        "name": "codifier/environment",
        "version": "1.0.0",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Environment",
          "type": "git",
          "reference": "v1.0.0"
        }
      }
    },
    "codifier/event": {
      "dev-master": {
        "name": "codifier/event",
        "version": "dev-master",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Event",
          "type": "git",
          "reference": "master"
        }
      },
      "1.0.0": {
        "name": "codifier/event",
        "version": "1.0.0",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Event",
          "type": "git",
          "reference": "v1.0.0"
        }
      }
    },
    "codifier/mime": {
      "dev-master": {
        "name": "codifier/mime",
        "version": "dev-master",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Mime",
          "type": "git",
          "reference": "master"
        }
      },
      "1.0.0": {
        "name": "codifier/mime",
        "version": "1.0.0",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Mime",
          "type": "git",
          "reference": "v1.0.0"
        }
      }
    },
    "codifier/net": {
      "dev-master": {
        "name": "codifier/net",
        "version": "dev-master",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Net",
          "type": "git",
          "reference": "master"
        }
      },
      "1.0.0": {
        "name": "codifier/net",
        "version": "1.0.0",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Net",
          "type": "git",
          "reference": "v1.0.0"
        }
      }
    },
    "codifier/number": {
      "dev-master": {
        "name": "codifier/number",
        "version": "dev-master",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Number",
          "type": "git",
          "reference": "master"
        }
      },
      "1.0.0": {
        "name": "codifier/number",
        "version": "1.0.0",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Number",
          "type": "git",
          "reference": "v1.0.0"
        }
      }
    },
    "codifier/persistence": {
      "dev-master": {
        "name": "codifier/persistence",
        "version": "dev-master",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Persistence",
          "type": "git",
          "reference": "master"
        }
      },
      "0.1.0": {
        "name": "codifier/persistence",
        "version": "0.1.0",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Persistence",
          "type": "git",
          "reference": "v0.1.0"
        }
      }
    },
    "codifier/process": {
      "dev-master": {
        "name": "codifier/process",
        "version": "dev-master",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Process",
          "type": "git",
          "reference": "master"
        }
      },
      "1.0.0": {
        "name": "codifier/process",
        "version": "1.0.0",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Process",
          "type": "git",
          "reference": "v1.0.0"
        }
      }
    },
    "codifier/socket": {
      "dev-master": {
        "name": "codifier/socket",
        "version": "dev-master",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Socket",
          "type": "git",
          "reference": "master"
        }
      },
      "1.0.0": {
        "name": "codifier/socket",
        "version": "1.0.0",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Socket",
          "type": "git",
          "reference": "v1.0.0"
        }
      }
    },
    "codifier/stdlib": {
      "dev-master": {
        "name": "codifier/stdlib",
        "version": "dev-master",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/StdLib",
          "type": "git",
          "reference": "master"
        }
      },
      "0.1.0": {
        "name": "codifier/stdlib",
        "version": "0.1.0",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/StdLib",
          "type": "git",
          "reference": "v0.1.0"
        }
      }
    },
    "codifier/text": {
      "dev-master": {
        "name": "codifier/text",
        "version": "dev-master",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Text",
          "type": "git",
          "reference": "master"
        }
      },
      "1.0.0": {
        "name": "codifier/text",
        "version": "1.0.0",
        "source": {
          "url": "file:///usr/local/codifier/library/PHP/Codifier/Text",
          "type": "git",
          "reference": "v1.0.0"
        }
      }
    }
  }
}

到目前为止,这部分按预期工作。当我在随机文件夹中执行 $ composer show -a 时,我得到以下输出:

No composer.json found in the current directory, showing available packages from codifier
codifier/cache      
codifier/environment
codifier/event      
codifier/mime       
codifier/net        
codifier/number     
codifier/persistence
codifier/process    
codifier/socket     
codifier/stdlib     
codifier/text

所有这些包都定义了它们自己的依赖项。例如,codifier/socket 包的根目录中有以下composer.json 文件:

{
  "name": "codifier/socket",
  "authors": [ ##REDACTED## ],
  "require": {
    "php": ">=7.3.0",
    "codifier/event": "^1.0",
    "codifier/net": "^1.0",
    "codifier/process": "^1.0"
  },
  "autoload": {
    "psr-4": {
      "Codifier\\Socket\\": "src"
    }
  }
}

现在,我认为 Composer 的全部意义在于它会自动并递归地安装所有必需的依赖项,而不是我不得不再次手动 require 所有依赖项,但事实并非如此。

当我创建一个新的干净应用程序目录$ mkdir Test && cd Test 然后执行$ composer require codifier/socket 时,我得到这个输出:

Using version ^1.0 for codifier/socket
./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 codifier/socket (1.0.0): Cloning v1.0.0 from cache
Writing lock file
Generating autoload files

...然后当我执行$ composer install 时,我得到以下输出:

Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Nothing to install or update
Generating autoload files

换句话说,只安装了codifier/socket,但没有安装它的依赖项。因此,Test/vendor 的内容现在是:

- codifier/
  - socket/

...当我期望的内容是:

- codifier/
  - socket/
  - event/
  - net/
  - process/
  etc.

...因为我希望 Composer 以递归方式获取所有必需的依赖项。

我也试过$ composer clear-cache,但这并没有什么不同,我想我还看到一些帖子建议我需要在composer.json 中为这个应用程序定义"repositories",但这只是没有对我来说没有任何意义,因为我已经在我的全局 config.json 文件中指出了这些内容。

我在这里缺少什么?我是否错过了 Composer 的要点,因为我认为它会自动解析并自动安装所有必需的依赖项?

--- 更新 ---

我现在还尝试通过我的本地 Web 服务器提供这些包(当然,相应地更改了 json 文件中的所有 "url" 字段),因为我认为 Composer 可能无法处理 file://协议正确,但无济于事:它给出了完全相同的结果:它只安装 codifier/socket 并忽略它的依赖关系。

我不知道我还需要做什么才能使这个本地 packages.json 存储库正常工作。

【问题讨论】:

    标签: php composer-php dependency-management


    【解决方案1】:

    我刚刚顿悟,终于想出了如何让它发挥作用,但感觉非常多余。我让它工作的方法是简单地将包的composer.json 文件中的"require" 信息复制到我的存储库的packages.json 文件中。

    再次以codifier/socket包中的composer.json文件为例:

    {
      "name": "codifier/socket",
      "authors": [ ##REDACTED## ],
      "require": {
        "php": ">=7.3.0",
        "codifier/event": "^1.0",
        "codifier/net": "^1.0",
        "codifier/process": "^1.0"
      },
      "autoload": {
        "psr-4": {
          "Codifier\\Socket\\": "src"
        }
      }
    }
    

    ...packages.json 中的相关信息将变为:

    {
      "packages": {
    
        ...
    
        "codifier/socket": {
          "dev-master": {
            "name": "codifier/socket",
            "version": "dev-master",
            "source": {
              "url": "file:///usr/local/codifier/library/PHP/Codifier/Socket",
              "type": "git",
              "reference": "master"
            },
            "require": {
              "php": ">=7.3.0",
              "codifier/event": "^1.0",
              "codifier/net": "^1.0",
              "codifier/process": "^1.0"
            }
          },
          "1.0.0": {
            "name": "codifier/socket",
            "version": "1.0.0",
            "source": {
              "url": "file:///usr/local/codifier/library/PHP/Codifier/Socket",
              "type": "git",
              "reference": "v1.0.0"
            },
            "require": {
              "php": ">=7.3.0",
              "codifier/event": "^1.0",
              "codifier/net": "^1.0",
              "codifier/process": "^1.0"
            }
          }
        },
        
        ...
    
      }
    }
    

    当我将它应用于所有包时,一切正常。

    不过,我仍然不明白的是,为什么 Composer 没有从包本身的实际 composer.json 中提取此 "require" 信息。我知道文档状态Composer doesn't recursively follow repositories,但它肯定必须递归地遵循依赖关系,不是吗?不过,也许它根本就没有,这就是它的预期工作方式。

    这一切都意味着我必须做更多的 git 解析才能为每个单独的包版本获取正确的数据,但就这样吧。1)

    这个解决方案也可能会引导我解决我遇到的自动加载问题,其中composer.json 中定义的"autoload" 命名空间也没有被选中。接下来我会尝试一下,如果也能解决这个问题,我会修改这个答案。

    --- 更新 ---

    正如预期的那样:当我将"autoload" 信息也合并到packages.json 中时,自动加载也开始工作了。


    1) 我已经知道Satis,但我不想安装和学习另一个软件。

    【讨论】:

    • 这就是packages.json 的重点——它提供了所有包的元数据,因此 Composer 不需要读取数十个外部 git 存储库来完成可用包的列表.
    • @rob006 是的,我想得越多,它实际上就越有意义,这正是你刚才所说的原因。干杯!
    猜你喜欢
    • 2014-06-28
    • 2018-02-02
    • 2016-07-29
    • 2017-06-28
    • 1970-01-01
    • 1970-01-01
    • 2018-02-03
    • 2012-04-21
    • 2011-06-11
    相关资源
    最近更新 更多