Skip to content

Commit 09075e5

Browse files
Merge pull request #105 from gitlost/issue_4127
Shell:columns(): Better calc on Windows. Check TERM. Make testable.
2 parents 6d4f657 + 314caec commit 09075e5

File tree

2 files changed

+77
-10
lines changed

2 files changed

+77
-10
lines changed

lib/cli/Shell.php

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,35 @@ class Shell {
2727
static public function columns() {
2828
static $columns;
2929

30+
if ( getenv( 'PHP_CLI_TOOLS_TEST_SHELL_COLUMNS_RESET' ) ) {
31+
$columns = null;
32+
}
3033
if ( null === $columns ) {
31-
if (self::is_windows() ) {
32-
$output = array();
33-
exec('mode CON', $output);
34-
foreach ($output as $line) {
35-
if (preg_match('/Columns:( )*([0-9]+)/', $line, $matches)) {
36-
$columns = (int)$matches[2];
37-
break;
34+
if ( function_exists( 'exec' ) ) {
35+
if ( self::is_windows() ) {
36+
// Cater for shells such as Cygwin and Git bash where `mode CON` returns an incorrect value for columns.
37+
if ( ( $shell = getenv( 'SHELL' ) ) && preg_match( '/(?:bash|zsh)(?:\.exe)?$/', $shell ) && getenv( 'TERM' ) ) {
38+
$columns = (int) exec( 'tput cols' );
39+
}
40+
if ( ! $columns ) {
41+
$return_var = -1;
42+
$output = array();
43+
exec( 'mode CON', $output, $return_var );
44+
if ( 0 === $return_var && $output ) {
45+
// Look for second line ending in ": <number>" (searching for "Columns:" will fail on non-English locales).
46+
if ( preg_match( '/:\s*[0-9]+\n[^:]+:\s*([0-9]+)\n/', implode( "\n", $output ), $matches ) ) {
47+
$columns = (int) $matches[1];
48+
}
49+
}
50+
}
51+
} else {
52+
if ( getenv( 'TERM' ) ) {
53+
$columns = (int) exec( '/usr/bin/env tput cols' );
3854
}
3955
}
40-
} else if (!preg_match('/(^|,)(\s*)?exec(\s*)?(,|$)/', ini_get('disable_functions'))) {
41-
$columns = (int) exec('/usr/bin/env tput cols');
4256
}
4357

44-
if ( !$columns ) {
58+
if ( ! $columns ) {
4559
$columns = 80; // default width of cmd window on Windows OS
4660
}
4761
}

tests/test-shell.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
use cli\Shell;
4+
5+
/**
6+
* Class TestShell
7+
*/
8+
class TestShell extends PHPUnit_Framework_TestCase {
9+
10+
/**
11+
* Test getting TERM columns.
12+
*/
13+
function testColumns() {
14+
// Save.
15+
$env_term = getenv( 'TERM' );
16+
$env_columns = getenv( 'COLUMNS' );
17+
$env_is_windows = getenv( 'WP_CLI_TEST_IS_WINDOWS' );
18+
$env_shell_columns_reset = getenv( 'PHP_CLI_TOOLS_TEST_SHELL_COLUMNS_RESET' );
19+
20+
putenv( 'PHP_CLI_TOOLS_TEST_SHELL_COLUMNS_RESET=1' );
21+
22+
// No TERM should result in default 80.
23+
24+
putenv( 'TERM' );
25+
26+
putenv( 'WP_CLI_TEST_IS_WINDOWS=0' );
27+
$columns = cli\Shell::columns();
28+
$this->assertSame( 80, $columns );
29+
30+
putenv( 'WP_CLI_TEST_IS_WINDOWS=1' );
31+
$columns = cli\Shell::columns();
32+
$this->assertSame( 80, $columns );
33+
34+
// TERM and COLUMNS should result in whatever COLUMNS is.
35+
36+
putenv( 'TERM=vt100' );
37+
putenv( 'COLUMNS=100' );
38+
39+
putenv( 'WP_CLI_TEST_IS_WINDOWS=0' );
40+
$columns = cli\Shell::columns();
41+
$this->assertSame( 100, $columns );
42+
43+
putenv( 'WP_CLI_TEST_IS_WINDOWS=1' );
44+
$columns = cli\Shell::columns();
45+
$this->assertSame( 100, $columns );
46+
47+
// Restore.
48+
putenv( false === $env_term ? 'TERM' : "TERM=$env_term" );
49+
putenv( false === $env_columns ? 'COLUMNS' : "COLUMNS=$env_columns" );
50+
putenv( false === $env_is_windows ? 'WP_CLI_TEST_IS_WINDOWS' : "WP_CLI_TEST_IS_WINDOWS=$env_is_windows" );
51+
putenv( false === $env_shell_columns_reset ? 'PHP_CLI_TOOLS_TEST_SHELL_COLUMNS_RESET' : "PHP_CLI_TOOLS_TEST_SHELL_COLUMNS_RESET=$env_shell_columns_reset" );
52+
}
53+
}

0 commit comments

Comments
 (0)