Skip to content

Commit 65b93d0

Browse files
committed
Cater for Windows bash. Use function_exists. Check TERM. Test arg.
1 parent 6d4f657 commit 65b93d0

2 files changed

Lines changed: 66 additions & 11 deletions

File tree

lib/cli/Shell.php

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,43 @@ class Shell {
2121
/**
2222
* Returns the number of columns the current shell has for display.
2323
*
24+
* @param mixed $test For testing only.
25+
*
2426
* @return int The number of columns.
2527
* @todo Test on more systems.
2628
*/
27-
static public function columns() {
29+
static public function columns( $test = null ) {
2830
static $columns;
2931

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

44-
if ( !$columns ) {
60+
if ( ! $columns ) {
4561
$columns = 80; // default width of cmd window on Windows OS
4662
}
4763
}

tests/test-shell.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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+
18+
// No TERM should result in default 80.
19+
20+
putenv( 'TERM' );
21+
$columns = cli\Shell::columns( true /*test*/ );
22+
$this->assertSame( 80, $columns );
23+
$columns = cli\Shell::columns( 'WIN' /*test*/ );
24+
$this->assertSame( 80, $columns );
25+
26+
// TERM and COLUMNS should result in whatever COLUMNS is.
27+
28+
putenv( 'TERM=vt100' );
29+
putenv( 'COLUMNS=100' );
30+
$columns = cli\Shell::columns( true /*test*/ );
31+
$this->assertSame( 100, $columns );
32+
$columns = cli\Shell::columns( 'WIN' /*test*/ );
33+
$this->assertSame( 100, $columns );
34+
35+
// Restore.
36+
putenv( false === $env_term ? 'TERM' : "TERM=$env_term" );
37+
putenv( false === $env_columns ? 'COLUMNS' : "COLUMNS=$env_columns" );
38+
}
39+
}

0 commit comments

Comments
 (0)