使用Composer运行交互式脚本

问题描述 投票:0回答:1

我使用 Symfony Process 编写了一个要求密码的命令:

$validPassword = false;
do {
    $question = new Question('Enter password: ');
    $question->setHidden(true);
    $question->setHiddenFallback(false);
    $password = $questionHelper->ask($input, $output, $question);
    if ($password === null || trim($password) === '') {
        continue;
    }

    try {
        doSomeTaskThatRequiresThePassword($password);
        $validPassword = true;
    } catch (\RuntimeException $e) {
        $output->writeln(
            sprintf(
                '<error>Error: %s</error>',
                $e->getMessage()
            )
        );
    }
} while (!$validPassword);

命令是从独立文件调用的:

#!/usr/bin/env php
<?php
require __DIR__ . '/vendor/autoload.php';

use App\MyCommand;

(new MyCommand())->run();

此外,由于我使用的是 Windows,所以我有一个小包装:

@ECHO OFF
setlocal DISABLEDELAYEDEXPANSION
SET BIN_TARGET=%~dp0my-command
php "%BIN_TARGET%" %*

以上所有内容都非常有魅力。

我使用 Composer 来运行所有项目实用程序和自定义命令,因此我对此尝试了相同的操作:

{
    "scripts": {
        "lint": [
            "@phpcs"
        ],
        "phpcs": "phpcs",
        "phpcbf": "phpcbf",
        "my-command": "my-command with some parameters --verbose --blah blah"
    }
}

问题是执行并没有在

$questionHelper->ask()
处停止。当 do/while 使用空密码进行时,我只是进入无限循环。使用 PowerShell 或命令提示符,或者跳过 *.bat 包装并将命令定义为
"php my-command"
,都没有任何区别。

C:\Projects\Foo>composer my-command
> php my-command with some parameters --verbose --blah blah
Enter password:
Enter password:
Enter password:
Enter password:
Enter password:
[…]

这是 Composer 的固有限制还是我需要调整一些内容才能运行交互式命令?

php windows composer-php symfony-process
1个回答
0
投票

Composer 似乎仅在 Linux 上支持交互式脚本(自 Composer/2.7.9),因为它需要 TTY 模式,而 PHP 实现的 Win32 API 不支持该模式。

但是,它为 Symfony 进程提供了 一流的支持

从 Composer 2.5 开始,脚本也可以是 Symfony 控制台命令 类,它允许您轻松运行它们,包括传递 选项。但是,不建议在处理事件时这样做。

因此您可以完全删除包装器脚本并直接调用命令类:

{
    "scripts": {
        "my-command": "\\App\\MyCommand"
    }
}

不幸的是,这不允许额外的参数,除非每次都手动提供:

PS C:\> composer my-command with some parameters --verbose --blah blah

令人惊讶的是,如果间接调用该类,您可以预定义其他参数,因此并不是真的不支持定义参数,只是没有人想到这种特定的语法:

{
    "scripts": {
        "my-command-class": "\\App\\MyCommand",
        "my-command": "@my-command-class with some parameters --verbose --blah blah"
    }
}
PS C:\> composer my-command
© www.soinside.com 2019 - 2024. All rights reserved.