Browse Source

Merge branch '3.2' of github.com:cakephp/cakephp into 3.2

Mark Story 10 years ago
parent
commit
a3fdebe3e1

+ 26 - 0
src/Console/Exception/StopException.php

@@ -0,0 +1,26 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://book.cakephp.org/3.0/en/development/errors.html#error-exception-configuration
+ * @since         3.2.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Console\Exception;
+
+use Cake\Core\Exception\Exception;
+
+/**
+ * Exception class for halting errors in console tasks
+ *
+ * @see Cake\Console\Shell::_stop()
+ * @see Cake\Console\Shell::error()
+ */
+class StopException extends Exception
+{
+}

+ 27 - 6
src/Console/Shell.php

@@ -15,6 +15,7 @@
 namespace Cake\Console;
 
 use Cake\Console\Exception\ConsoleException;
+use Cake\Console\Exception\StopException;
 use Cake\Core\Configure;
 use Cake\Core\Plugin;
 use Cake\Datasource\ModelAwareTrait;
@@ -716,21 +717,40 @@ class Shell
      * Displays a formatted error message
      * and exits the application with status code 1
      *
+     * @param string $message The error message
+     * @param int $exitCode The exit code for the shell task.
+     * @throws \Cake\Console\Exception\StopException
+     * @return void
+     * @link http://book.cakephp.org/3.0/en/console-and-shells.html#styling-output
+     */
+    public function abort($message, $exitCode = self::CODE_ERROR)
+    {
+        $this->_io->err('<error>' . $message . '</error>');
+        throw new StopException($message, $exitCode);
+    }
+
+    /**
+     * Displays a formatted error message
+     * and exits the application with status code 1
+     *
      * @param string $title Title of the error
      * @param string|null $message An optional error message
+     * @param int $exitCode The exit code for the shell task.
+     * @throws \Cake\Console\Exception\StopException
      * @return int Error code
      * @link http://book.cakephp.org/3.0/en/console-and-shells.html#styling-output
+     * @deprecated Since 3.2.0. Use Shell::abort() instead.
      */
-    public function error($title, $message = null)
+    public function error($title, $message = null, $exitCode = self::CODE_ERROR)
     {
         $this->_io->err(sprintf('<error>Error:</error> %s', $title));
 
         if (!empty($message)) {
             $this->_io->err($message);
         }
-        $this->_stop(self::CODE_ERROR);
 
-        return self::CODE_ERROR;
+        $this->_stop($exitCode);
+        return $exitCode;
     }
 
     /**
@@ -827,15 +847,16 @@ class Shell
     }
 
     /**
-     * Stop execution of the current script. Wraps exit() making
-     * testing easier.
+     * Stop execution of the current script.
+     * Raises a StopException to try and halt the execution.
      *
      * @param int|string $status see http://php.net/exit for values
+     * @throws \Cake\Console\Exception\StopException
      * @return void
      */
     protected function _stop($status = 0)
     {
-        exit($status);
+        throw new StopException('Halting error reached', $status);
     }
 
     /**

+ 6 - 1
src/Console/ShellDispatcher.php

@@ -15,6 +15,7 @@
 namespace Cake\Console;
 
 use Cake\Console\Exception\MissingShellException;
+use Cake\Console\Exception\StopException;
 use Cake\Core\App;
 use Cake\Core\Configure;
 use Cake\Core\Exception\Exception;
@@ -176,7 +177,11 @@ class ShellDispatcher
      */
     public function dispatch($extra = [])
     {
-        $result = $this->_dispatch($extra);
+        try {
+            $result = $this->_dispatch($extra);
+        } catch (StopException $e) {
+            return $e->getCode();
+        }
         if ($result === null || $result === true) {
             return 0;
         }

+ 26 - 0
tests/TestCase/Console/ShellDispatcherTest.php

@@ -149,6 +149,32 @@ class ShellDispatcherTest extends TestCase
     }
 
     /**
+     * Verify dispatch handling stop errors
+     *
+     * @return void
+     */
+    public function testDispatchShellWithAbort()
+    {
+        $io = $this->getMock('Cake\Console\ConsoleIo');
+        $shell = $this->getMock('Cake\Console\Shell', ['main'], [$io]);
+        $shell->expects($this->once())
+            ->method('main')
+            ->will($this->returnCallback(function () use ($shell) {
+                $shell->abort('Bad things', 99);
+            }));
+
+        $dispatcher = $this->getMock('Cake\Console\ShellDispatcher', ['findShell']);
+        $dispatcher->expects($this->any())
+            ->method('findShell')
+            ->with('aborter')
+            ->will($this->returnValue($shell));
+
+        $dispatcher->args = ['aborter'];
+        $result = $dispatcher->dispatch();
+        $this->assertSame(99, $result, 'Should return the exception error code.');
+    }
+
+    /**
      * Verify correct dispatch of Shell subclasses with a main method
      *
      * @return void