Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Composer run-script does not propagate Windows console handle #11709

Open
demurgos opened this issue Nov 7, 2023 · 3 comments
Open

Composer run-script does not propagate Windows console handle #11709

demurgos opened this issue Nov 7, 2023 · 3 comments
Labels
Milestone

Comments

@demurgos
Copy link

demurgos commented Nov 7, 2023

If I have a program providing an interactive command line interface, calling it through composer run-script breaks on Windows as the Console handle is not passed to the sub-process. The issue happens when using PowerShell on Windows.

Full repro at https://github.com/demurgos/composer-windows-console

In the repro, I have a test program with an interactive select, where you can use arrows to select a value and Enter to confirm.
The test program is located at ./target/debug/dia.exe (it's a small Rust program). If I call it directly with ./target/debug/dia.exe, I get the proper interaction. If I place it inside a scripts entry in composer.json and call it through composer run-script, the console handle is missing and it breaks.

My composer.json:

{
    "type": "project",
    "license": "MIT",
    "require": {
        "php": ">=8.1.0"
    },
    "scripts": {
        "build": "cargo build",
        "dia": "./target/debug/dia.exe"
	}
}

Output of composer diagnose:

PS C:\data\dia> composer diagnose
Checking composer.json: OK
Checking platform settings: OK
Checking git settings: OK git version 2.42.0
Checking http connectivity to packagist: OK
Checking https connectivity to packagist: OK
Checking github.com rate limit: OK
Checking disk free space: OK
Checking pubkeys:
Tags Public Key Fingerprint: 57815BA2 7E54DC31 7ECC7CC5 573090D0  87719BA6 8F3BB723 4E5D42D0 84A14642
Dev Public Key Fingerprint: 4AC45767 E5EC2265 2F0C1167 CBBB8A2B  0C708369 153E328C AD90147D AFE50952
OK
Checking composer version: OK
Composer version: 2.6.5
PHP version: 8.2.12
PHP binary path: C:\tools\php82\php.exe
OpenSSL version: OpenSSL 3.0.11 19 Sep 2023
cURL version: 8.4.0 libz 1.2.12 ssl OpenSSL/3.0.11
zip: extension not loaded, unzip not available, 7-Zip present (7z)

When I run this command: composer -vvv run-script dia

I get the following output:

PS C:\data\dia> composer -vvv run-script dia
Running 2.6.5 (2023-10-06 10:11:52) with PHP 8.2.12 on Windows NT / 10.0
Reading ./composer.json (C:\data\dia\composer.json)
Loading config file ./composer.json (C:\data\dia\composer.json)
Checked CA file /etc/pki/tls/certs/ca-bundle.crt does not exist or it is not a file.
Checked directory /etc/pki/tls/certs/ca-bundle.crt does not exist or it is not a directory.
Checked CA file /etc/ssl/certs/ca-certificates.crt does not exist or it is not a file.
Checked directory /etc/ssl/certs/ca-certificates.crt does not exist or it is not a directory.
Checked CA file /etc/ssl/ca-bundle.pem does not exist or it is not a file.
Checked directory /etc/ssl/ca-bundle.pem does not exist or it is not a directory.
Checked CA file /usr/local/share/certs/ca-root-nss.crt does not exist or it is not a file.
Checked directory /usr/local/share/certs/ca-root-nss.crt does not exist or it is not a directory.
Checked CA file /usr/ssl/certs/ca-bundle.crt does not exist or it is not a file.
Checked directory /usr/ssl/certs/ca-bundle.crt does not exist or it is not a directory.
Checked CA file /opt/local/share/curl/curl-ca-bundle.crt does not exist or it is not a file.
Checked directory /opt/local/share/curl/curl-ca-bundle.crt does not exist or it is not a directory.
Checked CA file /usr/local/share/curl/curl-ca-bundle.crt does not exist or it is not a file.
Checked directory /usr/local/share/curl/curl-ca-bundle.crt does not exist or it is not a directory.
Checked CA file /usr/share/ssl/certs/ca-bundle.crt does not exist or it is not a file.
Checked directory /usr/share/ssl/certs/ca-bundle.crt does not exist or it is not a directory.
Checked CA file /etc/ssl/cert.pem does not exist or it is not a file.
Checked directory /etc/ssl/cert.pem does not exist or it is not a directory.
Checked CA file /usr/local/etc/ssl/cert.pem does not exist or it is not a file.
Checked directory /usr/local/etc/ssl/cert.pem does not exist or it is not a directory.
Checked CA file /usr/local/etc/openssl/cert.pem does not exist or it is not a file.
Checked directory /usr/local/etc/openssl/cert.pem does not exist or it is not a directory.
Checked CA file /usr/local/etc/openssl@1.1/cert.pem does not exist or it is not a file.
Checked directory /usr/local/etc/openssl@1.1/cert.pem does not exist or it is not a directory.
Checked CA file /etc/pki/tls/certs does not exist or it is not a file.
Checked directory /etc/pki/tls/certs does not exist or it is not a directory.
Checked CA file /etc/ssl/certs does not exist or it is not a file.
Checked directory /etc/ssl/certs does not exist or it is not a directory.
Checked CA file /etc/ssl does not exist or it is not a file.
Checked directory /etc/ssl does not exist or it is not a directory.
Checked CA file /usr/local/share/certs does not exist or it is not a file.
Checked directory /usr/local/share/certs does not exist or it is not a directory.
Checked CA file /usr/ssl/certs does not exist or it is not a file.
Checked directory /usr/ssl/certs does not exist or it is not a directory.
Checked CA file /opt/local/share/curl does not exist or it is not a file.
Checked directory /opt/local/share/curl does not exist or it is not a directory.
Checked CA file /usr/local/share/curl does not exist or it is not a file.
Checked directory /usr/local/share/curl does not exist or it is not a directory.
Checked CA file /usr/share/ssl/certs does not exist or it is not a file.
Checked directory /usr/share/ssl/certs does not exist or it is not a directory.
Checked CA file /etc/ssl does not exist or it is not a file.
Checked directory /etc/ssl does not exist or it is not a directory.
Checked CA file /usr/local/etc/ssl does not exist or it is not a file.
Checked directory /usr/local/etc/ssl does not exist or it is not a directory.
Checked CA file /usr/local/etc/openssl does not exist or it is not a file.
Checked directory /usr/local/etc/openssl does not exist or it is not a directory.
Checked CA file /usr/local/etc/openssl@1.1 does not exist or it is not a file.
Checked directory /usr/local/etc/openssl@1.1 does not exist or it is not a directory.
Checked CA file C:\Users\demurgos\AppData\Local\Temp\ope2B3D.tmp: valid
Executing command (C:\data\dia): git branch -a --no-color --no-abbrev -v
Failed to initialize global composer: Composer could not find the config file: C:/Users/demurgos/AppData/Roaming/Composer/composer.json

Reading ./composer.lock (C:\data\dia\composer.lock)
Reading C:\data\dia/vendor/composer/installed.json (C:\data\dia\vendor\composer\installed.json)
> dia: ./target/debug/dia.exe
Executing command (CWD): .\target\debug\dia.exe
thread 'main' panicked at src\main.rs:10:10:
called `Result::unwrap()` on an `Err` value: IO(Custom { kind: NotConnected, error: "not a terminal" })
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Script ./target/debug/dia.exe handling the dia event returned with error code 101

And I expected this to happen:

PS C:\data\dia> ./target/debug/dia.exe
What do you choose?:
> foo
  bar
  baz

Note that it works on Linux, because the tty/pty file descriptors are passed properly. But Windows does not use tty/pty fds.

@Seldaek
Copy link
Member

Seldaek commented Nov 8, 2023

Right, AFAIK this isn't currently doable on windows, but if you find a way to fix this please let me know. I have nothing against it in theory but symfony/process does not support it as far as I remember.

@Seldaek Seldaek added the Bug label Nov 8, 2023
@Seldaek Seldaek added this to the Bugs milestone Nov 8, 2023
@demurgos
Copy link
Author

demurgos commented Nov 8, 2023

I started looking into the issue a bit, but I have to use a VM to test on Windows so it's not very convenient. I found that PHP's proc_open supports the right flags to share the handle, but I don't know what Symfony's process package is using. I'll check

@dee22
Copy link

dee22 commented Jan 20, 2024

I have the same problem.
Running .\bin\console play or .\bin\vendor\console play works with interactive input and ANSI colors.
When using the same commands in composer.json as "scripts",
it just skips interactivity or returns an error and also no ANSI colors are displayed.
I got down my error trace, when i used:

$io = new SymfonyStyle($input, $output);
$answer = $io->ask('Set a name:', 'UnnamedLib');

ending in this file:
vendor\symfony\console\Helper\QuestionHelper.php

Line Code Comment
107 $inputStream = $this->inputStream ?: \STDIN; // $this->inputStream is NULL here.
523 $ret = fgets($inputStream, 4096); // instant returns with EOF changed to TRUE

But i also realized that the same happens when i just start an interactive php shell from the composer script section like this:
"php-test": "php -a",
and then running composer php-test
I'm using PHP 8.2.10 with composer 2.6.6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants