diff --git a/README.txt b/README.txt index c6009e59083cb2710fdf92e3252706846a58fab8..a58e78f79c847d0725435ba74eb71efb387236c2 100644 --- a/README.txt +++ b/README.txt @@ -190,6 +190,21 @@ Alternately, if you only want to override a few values, copy example.drush.ini from the "examples" folder into $HOME/.drush or the folder /etc/drush and edit to suit. See comments in example.drush.ini for more details. +You may also use environment variables to control the php settings that Drush +will use. There are three options: + + export PHP_INI='/path/to/php.ini' + + export DRUSH_INI='/path/to/drush.ini' + + export PHP_OPTIONS='-d memory_limit="128M"' + +In the case of PHP_INI and DRUSH_INI, these environment variables specify the +full path to a php.ini or drush.ini file, should you wish to use one that is +not in one of the standard locations described above. The PHP_OPTIONS +environment variable can be used to specify individual options that should +be passed to php on the command line when Drush is executed. + Drush requires a fairly unrestricted php environment to run in. In particular, you should insure that safe_mode, open_basedir, disable_functions and disable_classes are empty. diff --git a/drush b/drush index aa3805abb5c861d255a5c6d56598c6edd92cb6eb..594dbbac5784b42556532da53b76873ddf872a15 100755 --- a/drush +++ b/drush @@ -33,7 +33,7 @@ done # Build the path to drush.php. SCRIPT_PATH="`dirname "$SELF_PATH"`/drush.php" -if [ ! -z "$CYGWIN" ] ; then +if [ -n "$CYGWIN" ] ; then SCRIPT_PATH="`cygpath -w -a -- "$SCRIPT_PATH"`" fi @@ -43,7 +43,7 @@ fi # we redirect stderr in any way, e.g. `tput cols 2>/dev/null`, then the # error message is suppressed, but tput cols becomes confused about the # terminal and prints out the default value (80). -if [ -z $COLUMNS ] && [ -n "$TERM" ] && [ "$TERM" != dumb ] && [ ! -z "`which tput`" ] ; then +if [ -z $COLUMNS ] && [ -n "$TERM" ] && [ "$TERM" != dumb ] && [ -n "`which tput`" ] ; then # Note to cygwin/mingw/msys users: install the ncurses package to get tput command. # Note to mingw/msys users: there is no precompiled ncurses package. if COLUMNS="`tput cols`"; then @@ -51,7 +51,7 @@ if [ -z $COLUMNS ] && [ -n "$TERM" ] && [ "$TERM" != dumb ] && [ ! -z "`which tp fi fi -if [ ! -z "$DRUSH_PHP" ] ; then +if [ -n "$DRUSH_PHP" ] ; then # Use the DRUSH_PHP environment variable if it is available. php="$DRUSH_PHP" else @@ -66,7 +66,7 @@ else fi # On MSYSGIT, we need to use "php", not the full path to php - if [ ! -z "$MINGW" ] ; then + if [ -n "$MINGW" ] ; then php="php" fi fi @@ -78,24 +78,42 @@ for conf_dir in "`dirname "$SELF_PATH"`" /etc/drush $HOME/.drush ; do continue fi # Handle paths that don't start with a drive letter on MinGW shell. Equivalent to cygpath on Cygwin. - if [ ! -z "$MINGW" ] ; then + if [ -n "$MINGW" ] ; then conf_dir=`sh -c "cd $conf_dir; pwd -W"` fi if [ -f "$conf_dir/php.ini" ] ; then - drush_php_ini=$conf_dir/php.ini + drush_php_ini="$conf_dir/php.ini" fi if [ -f "$conf_dir/drush.ini" ] ; then - drush_php_override=$conf_dir/drush.ini + drush_php_override="$conf_dir/drush.ini" fi done +# If the PHP_INI environment variable is specified, then tell +# php to use the php.ini file that it specifies. +if [ -n "$PHP_INI" ] ; then + drush_php_ini="$PHP_INI" +fi +# If the DRUSH_INI environment variable is specified, then +# extract all ini variable assignments from it and convert +# them into php '-d' options. These will override similarly-named +# options in the php.ini file +if [ -n "$DRUSH_INI" ] ; then + drush_php_override="$DRUSH_INI" +fi # Add in the php file location and/or the php override variables as appropriate -if [ "x$drush_php_ini" != "x" ] ; then +if [ -n "$drush_php_ini" ] ; then php_options="--php-ini $drush_php_ini" fi -if [ "x$drush_php_override" != "x" ] ; then +if [ -n "$drush_php_override" ] ; then php_options=`grep '^[a-z_A-Z0-9.]\+ *=' $drush_php_override | sed -e 's|\([^ =]*\) *= *\(.*\)|\1="\2"|' -e 's| ||g' -e 's|^|-d |' | tr '\n\r' ' '` fi +# If the PHP_OPTIONS environment variable is specified, then +# its contents will be passed to php on the command line as +# additional options to use. +if [ -n "$PHP_OPTIONS" ] ; then + php_options="$php_options $PHP_OPTIONS" +fi # Pass in the path to php so that drush knows which one # to use if it re-launches itself to run subcommands. We diff --git a/examples/example.drush.ini b/examples/example.drush.ini index eaf20972d87eb3b15574e458031a3497a38b8b74..6166bb4ca5f4b73c5007c603299645a4563ce608 100644 --- a/examples/example.drush.ini +++ b/examples/example.drush.ini @@ -12,13 +12,18 @@ ; php.ini file drush is using by running "drush status". ; If the php.ini file shown is your webserver ini ; file, then rename this file, example.drush.ini, -; to drush.ini and copy it to one of the following +; to drush.ini and copy it to one of the following ; locations: ; ; 1. Drush installation folder ; 2. User's .drush folder (i.e. ~/.drush/drush.ini) ; 3. System wide configuration folder (i.e. /etc/drush/drush.ini) ; +; If the environment variable DRUSH_INI is defined, +; then the file it specified will be used as drush.ini. +; +; export DRUSH_INI='/path/to/drush.ini' +; ; When in use, the variables defined in this file ; will override the setting values that appear in ; your php.ini file. See the examples below for @@ -32,14 +37,18 @@ ; has the same value as the webserver php.ini ; to keep the size of the override list small. ; -; To fully specify the value of all php.ini variables, -; copy your webserver php.ini file to one of the +; To fully specify the value of all php.ini variables, +; copy your webserver php.ini file to one of the ; locations mentioned above (e.g. /etc/drush/php.ini) -; and edit it to suit. +; and edit it to suit. Alternately, you may use +; the environment variable PHP_INI to point at +; the file that Drush should use. +; +; export PHP_INI='/path/to/php.ini' ; ; The options listed below are particularly relevant ; to drush. -; +; ; ; drush needs as much memory as Drupal in order @@ -64,7 +73,7 @@ display_errors = stderr ; sometimes set to restrictive values in a ; webserver's php.ini: ; -;safe_mode = -;open_basedir = +;safe_mode = +;open_basedir = ;disable_functions = ;disable_classes = diff --git a/tests/drushScriptTest.php b/tests/drushScriptTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c07d34762d443d05bb7deb71d437dd48c1553753 --- /dev/null +++ b/tests/drushScriptTest.php @@ -0,0 +1,27 @@ +is_windows()) { + $this->markTestSkipped('environment variable tests not currently functional on Windows.'); + } + + $options = array( + ); + $env = array( + 'PHP_OPTIONS' => '-d default_mimetype="text/drush"', + ); + $this->drush('ev', array('print ini_get("default_mimetype");'), $options, NULL, NULL, self::EXIT_SUCCESS, NULL, $env); + $output = $this->getOutput(); + $this->assertEquals('text/drush', $output); + } +} diff --git a/tests/drush_testcase.inc b/tests/drush_testcase.inc index 7127e33a1edc6a3ccc28cd91d90222727b5adffc..48bb3da67e5224e8e9e18d89f1a1e5db0a770c6b 100644 --- a/tests/drush_testcase.inc +++ b/tests/drush_testcase.inc @@ -316,10 +316,29 @@ abstract class Drush_CommandTestCase extends Drush_TestCase { * @return integer * Exit code. Usually self::EXIT_ERROR or self::EXIT_SUCCESS. */ - function execute($command, $expected_return = self::EXIT_SUCCESS) { + function execute($command, $expected_return = self::EXIT_SUCCESS, $env = NULL) { $this->_output = FALSE; + $return = 1; $this->log("Executing: $command", 'notice'); - exec($command, $this->_output, $return); + // If the test passed in an environment to use, then run the test + // with proc_open + if (isset($env)) { + $descriptorspec = array( + 0 => array("pipe", "r"), + 1 => array("pipe", "w") ); + $process = proc_open($command, $descriptorspec, $pipes, NULL, $env); + if (is_resource($process)) { + fclose($pipes[0]); + $output = stream_get_contents($pipes[1]); + $this->_output = explode("\n", rtrim($output)); // one more /n than with exec + fclose($pipes[1]); + $return = proc_close($process); + } + } + // Tests that do not provide their own environment run with exec + else { + exec($command, $this->_output, $return); + } $this->assertEquals($expected_return, $return, 'Unexpected exit code: ' . $command); return $return; } @@ -344,7 +363,7 @@ abstract class Drush_CommandTestCase extends Drush_TestCase { * @return integer * An exit code. */ - function drush($command, array $args = array(), array $options = array(), $site_specification = NULL, $cd = NULL, $expected_return = self::EXIT_SUCCESS, $suffix = NULL) { + function drush($command, array $args = array(), array $options = array(), $site_specification = NULL, $cd = NULL, $expected_return = self::EXIT_SUCCESS, $suffix = NULL, $env = NULL) { $global_option_list = array('simulate', 'root', 'uri', 'include', 'config', 'alias-path', 'ssh-options'); // insert "cd ... ; drush" $cmd[] = $cd ? sprintf('cd %s &&', self::escapeshellarg($cd)) : NULL; @@ -387,7 +406,7 @@ abstract class Drush_CommandTestCase extends Drush_TestCase { } $cmd[] = $suffix; $exec = array_filter($cmd, 'strlen'); // Remove NULLs - return $this->execute(implode(' ', $exec), $expected_return); + return $this->execute(implode(' ', $exec), $expected_return, $env); } function drush_major_version() {