Composer - 仅在开发环境中运行脚本

Composer - run scripts only in dev environment

提问人:Richard Knop 提问时间:10/26/2012 更新时间:1/21/2023 访问量:52993

问:

这是我composer.json文件:

"require": {
    "php": ">=5.4",
    "zendframework/zendframework": "2.*",
    "doctrine/doctrine-module": "dev-master",
    "doctrine/doctrine-orm-module": "0.*",
    "gedmo/doctrine-extensions": "dev-master"
},
"require-dev": {
    "phpunit/phpunit": "3.7.*"
},
"scripts": {
    "post-update-cmd": [
        "rm -rf vendor/Behat",
        "git clone git://github.com/Behat/Behat.git",
        "cp composer.phar Behat/composer.phar",
        "cd Behat && git submodule update --init",
        "cd Behat && php composer.phar install",
        "cd Behat && php composer.phar require guzzle/guzzle:3.0.*",
        "mv Behat vendor/Behat",
        "ln -sf ../Behat/bin/behat vendor/bin/"
    ]
}

我怎样才能使脚本只在开发环境中运行?

基本上,我希望脚本仅在调用时运行:

php composer.phar update --dev
PHP Jenkins 作曲家-PHP

评论


答:

64赞 hakre 10/26/2012 #1

要在不触发任何脚本的情况下执行非开发环境更新,请使用 --no-scripts 命令行开关作为 update 命令

php composer.phar update --no-scripts
                         ^^^^^^^^^^^^

默认情况下,Composer 脚本仅在基础包2 中执行1。因此,您可以有一个用于开发的包,并在实时环境中使其成为实时系统的依赖项。

除此之外,我看不出有任何方法可以自动区分脚本。


这个答案是从 2012 年开始的,现在可以安全地列出按外观顺序排列的其他选项。由于该列表仅供作曲家使用,并且原始问题闻起来属于 x/y,因此一般答案是使用构建管理器。

但事实证明,这可以在询问的那天完成,就像这个 composer-json 示例一样:

{
  "scripts": {
    "post-update-cmd": "composer::dev-post-update-cmd",
    "dev-post-update-cmd": [
      "rm -rf vendor/Behat",
      ": ... ",
      "ln -sf ../Behat/bin/behat vendor/bin/"
    ]
  }
}
  • 1.0.0-alpha6 (2012-10-23): 使用 PHP 脚本类和 ,例如 .如果那样.__callStaticcomposer::dev-post-update-cmdin_array('--dev', $_SERVER['argv'])$eventDispatcher->dispatchCommandEvent($name)
  • 1.0.0-alpha7 (2013-05-04):现在是默认的,此后是可选的,对于非脚本调度是必需的。这有效地将相关命令行从:仅运行更改为:不运行。 现在可用,在事件调度器上调度脚本时,新的第二个参数也是必需的。与克里斯蒂安·科赫(Christian Koch)的回答进行比较。--dev--no-dev--devcomposer update --devcomposer update --no-dev$event->isDevMode()
  • 1.0.0-alpha9 (2014-12-07):现在允许通过从 .这适用于 b/c 不存在的类,无需出现错误。autoload-dev--no-devautoload
  • 1.3.0-RC (2016-12-11):已弃用。 environment 参数现在在 update/install/dumpautoload 脚本中可用。PHP 脚本类不再需要继承,除非环境参数在您的设置中不起作用,然后使用 PHP 类脚本进行解决方法。与吠陀的回答比较。--devCOMPOSER_DEV_MODE
  • 3(未来):将不必要地使作曲家致命,至少这是宣布的。这将圆圈关闭到 1.0.0-alpha7 之前,而 1.0.0-alpha7 在相反的情况下也失败了。当时和将来使用的命令行库无法对称地处理,如果一对被分割并且必须离开,那么它只能抛出。--dev--no-dev-[-not]-args

引用

  1. 请参阅什么是脚本中的“注意:”?- 脚本 - Composer Docs
  2. 基础包在 Composer 文档中通常称为根包

评论

1赞 Tobias Gaertner 8/29/2018
“默认情况下,Composer 脚本仅在基础包中执行。” - 是这样吗?添加 --no-script 破坏了我的部署,因为它没有在底层依赖项中执行脚本......
4赞 hakre 8/30/2018
@TobiasGaertner: 引用: “注意:只执行根包composer.json中定义的脚本。如果根包的依赖项指定了自己的脚本,则 Composer 不会执行这些附加脚本。发件人: getcomposer.org/doc/articles/scripts.md#what-is-a-script-
14赞 Christian Koch 2/26/2013 #2

无法为默认安装和 --dev 选项选择不同的脚本,但您可以使用 Composer\Script\Event 中的 isDevMode() 方法仅在开发环境中运行命令。http://getcomposer.org/apidoc/master/Composer/Script/Event.html

7赞 Ali Gangji 7/18/2016 #3

您可以通过为 dev 路径设置自定义脚本来获得相同的效果,而不是使用钩子。post-update-cmd

"scripts": {
    "update-behat": [
        "rm -rf vendor/Behat",
        "git clone git://github.com/Behat/Behat.git",
        "cp composer.phar Behat/composer.phar",
        "cd Behat && git submodule update --init",
        "cd Behat && php composer.phar install",
        "cd Behat && php composer.phar require guzzle/guzzle:3.0.*",
        "mv Behat vendor/Behat",
        "ln -sf ../Behat/bin/behat vendor/bin/"
    ],
    "dev-update": [
        "@composer update --dev",
        "@update-behat"
    ]
}

然后简单地运行php composer.phar dev-update

3赞 Krasnoperov Viltaly 12/20/2017 #4

下面是一个小包,你可以用它来执行此操作 https://github.com/neronmoon/scriptsdev 它增加了定义 only-dev 脚本的功能。 用法

...
"extra": {
    "scripts-dev": {
    "post-install-cmd": [
        "npm install --dev"
    ],
    "post-update-cmd": "php ./someCoolCommand.php"
    },
}
...
4赞 Majbah Habib 2/13/2018 #5

运行以下命令。

 composer update --no-scripts
14赞 Veda 9/5/2018 #6

您可以使用 COMPOSER_DEV_MODE 环境变量(版本 1.3.0-RC 中的新功能 - 2016-12-11):

"scripts": {
    "post-install-cmd": [
        "[ $COMPOSER_DEV_MODE -eq 0 ] || echo devmode only"
    ]
},

评论

0赞 Fabiano 2/5/2019
我曾经运行过这个,但由于某种原因它开始显示:.有什么想法吗?sh: 1: [: -eq: unexpected operator
0赞 Veda 2/6/2019
@Fabiano我认为错误均值未设置。可能是您使用的是早于 1.3.0-RC 版本的作曲家吗?$COMPOSER_DEV_MODE
0赞 Fabiano 2/7/2019
使用 composer 版本 .我将 sh 命令替换为 PHP 类静态方法调用。它确实添加了另一个目录,并且需要使用 PSR-0 自动加载,但最终添加条件行为更干净。Composer 1.8.3 2019-01-30 08:31:33
0赞 midlan 4/13/2020
对我来说@Veda同样的问题,我添加了查看所有变量并且不存在变量。我有 composer 版本 1.8.4"post-install-cmd": [ "export"]COMPOSER_DEV_MODE
0赞 Veda 4/13/2020
@midlan,我不知道。使用set怎么样?也许变量没有被导出?
38赞 Webber 10/27/2018 #7

介绍

有些答案有点简短,没有详细说明完成此操作的背景。我想与那些在阅读之前的答案后仍然感到困惑的人分享一些知识。

确定适合您的选项

首先,花点时间意识到你正在有效地创建一个不同的流,特定于特定环境(即你的开发服务器/容器)。这与任何最佳实践都背道而驰,因为它通常容易出错。话虽如此,您可以通过多种方式实现您想要的;

不触发任何脚本文档)

如果在某些环境中您不想触发任何脚本,则可以使用标志来阻止这种情况。--no-scripts

文档内容如下: :跳过 composer.json 中定义的脚本的执行。--no-scripts

composer upgrade --no-scripts

这在代码当前无法正常工作时升级包时特别有用。如果您唯一的脚本与开发和测试相关,它也可以工作。

单独运行一个脚本文档)

只需根据需要运行特定命令:

composer run-script [--dev] [--no-dev] script

当您只想在特定场合运行脚本时,这很有用。

例如,在运行任何测试之前必须执行特定脚本的构建系统上;构建系统提供配置选项来调用自定义脚本,如上所述。

在命令中定义条件docs)

文档内容如下:在 composer 安装或更新过程中,一个名为 COMPOSER_DEV_MODE 的变量将被添加到环境中。如果该命令是使用 --no-dev 标志运行的,则此变量将设置为 0,否则将设置为 1。

示例如下所示

"scripts": {
    "post-install-cmd": [
         "[ $COMPOSER_DEV_MODE -eq 0 ] || <your command>"
    ]
}

就我个人而言,如果您使用容器,我会说这是推荐的方式。

注意:这在 Windows 上不起作用,因为它需要 %COMPOSER_DEV_MODE%。

还有一些软件包(如 neronmoon 的 scriptsdev)可以帮助您实现相同的目标,而无需在所有命令中键入上述内容,使用 composer.json 中该部分中的某个部分dev-scriptsextra

在 PHP 脚本中定义条件文档)

调用 PHP 方法,该方法根据应用程序执行此操作的方式检查环境。您甚至可以通过将其与上述方法结合使用来重用此条件;“在命令中定义条件”。

"scripts": {
    "post-update-cmd": [
        "AppNameSpaceName\\YourClassName::methodName"
    ]
}

然后,您可以继续创建类,如下所示:

<?php

namespace AppNameSpaceName;

class YourClassName 
{
    methodName() {
         // do stuff
    }
}

在许多现代框架中,已经存在一种机制来确定应用程序的运行时环境(Symfony方式Laravel方式)。

Yarn run文档)

由于现在大多数 PHP 应用程序也转译它们的 javascript 文件,因此将安装 NPM 或 Yarn。您可以使用脚本部分仅在开发计算机/容器上运行此部分。例如:

yarn run dev-only-script

在 package.json 中有一个部分

"scripts": {
    "dev-only-script": "rm some/folder && ln -s path/to/your/folder some/"
}

这样做的重点是让你composer.json干净。在 yarn 中,您可以有 和 的脚本。dev-servertestbuild

-1赞 munazzil 3/23/2022 #8

您可以运行其中任何一个并检查,

composer update --no-scripts

 composer dump-autoload

评论

2赞 Nico Haase 3/23/2022
请分享更多细节。这如何解决给定的问题?该部分是许多其他答案的一部分 - 请不要重复它们,除非您想添加一些新的见解。如果是这种情况,请在您的答案中分享它们--no-scripts