Fixes #14188: Add constants and function for sysexits(3) to ConsoleHelper

This commit is contained in:
Carsten Brandt
2017-07-15 22:26:15 +02:00
committed by Alexander Makarov
parent 0adae899ce
commit 2f9f15bf92
9 changed files with 218 additions and 38 deletions

View File

@ -267,12 +267,21 @@ public function actionIndex()
}
```
There are some predefined constants you can use:
There are some predefined constants you can use. These are defined in the [[yii\console\ExitCode]] class:
- [[yii\console\Controller::EXIT_CODE_NORMAL|Controller::EXIT_CODE_NORMAL]] with value of `0`;
- [[yii\console\Controller::EXIT_CODE_ERROR|Controller::EXIT_CODE_ERROR]] with value of `1`.
```php
public function actionIndex()
{
if (/* some problem */) {
echo "A problem occurred!\n";
return ExitCode::UNSPECIFIED_ERROR;
}
// do something
return ExitCode::OK;
}
```
It's a good practice to define meaningful constants for your controller in case you have more error code types.
It's a good practice to define meaningful constants for your controller in case you have more specific error code types.
### Formatting and colors

View File

@ -33,6 +33,7 @@ Yii Framework 2 Change Log
- Enh #14105: Implemented a solution for retrieving DBMS constraints in `yii\db\Schema` (sergeymakinen)
- Enh #14417: Added configuration for headers in PHP files generated by `message/extract` command (rob006)
- Enh #13835: Added `yii\web\Request::getOrigin()` method that returns HTTP_ORIGIN of current CORS request (yyxx9988)
- Enh #14188: Add constants and function for sysexits(3) to `ConsoleHelper` (tom--, samdark, cebe)
- Bug #14165: Set `_slave` of `Connection` to `false` instead of `null` in `close` method (rossoneri)
- Bug #14423: Fixed `ArrayHelper::merge` behavior with null values for integer-keyed elements (dmirogin)

View File

@ -39,7 +39,13 @@ use yii\helpers\Console;
*/
class Controller extends \yii\base\Controller
{
/**
* @deprecated since 2.0.13. Use [[ExitCode::OK]] instead.
*/
const EXIT_CODE_NORMAL = 0;
/**
* @deprecated since 2.0.13. Use [[ExitCode::UNSPECIFIED_ERROR]] instead.
*/
const EXIT_CODE_ERROR = 1;
/**

View File

@ -0,0 +1,159 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\console;
/**
* This class provides constants for defining console command exit codes.
*
* The exit codes follow the codes defined in the [FreeBSD sysexits(3)](http://man.openbsd.org/sysexits) manual page.
*
* These constants can be used in console controllers for example like this:
*
* ```php
* public function actionIndex()
* {
* if (!$this->isAllowedToPerformAction()) {
* $this->stderr('Error: ' . ExitCode::getReason(ExitCode::NOPERM));
* return ExitCode::NOPERM;
* }
*
* // do something
*
* return ExitCode::OK;
* }
* ```
*
* @author Tom Worster <fsb@thefsb.org>
* @author Alexander Makarov <sam@rmcreative.ru>
* @see http://man.openbsd.org/sysexits
* @since 2.0.13
*/
class ExitCode
{
/**
* The command completed successfully.
*/
const OK = 0;
/**
* The command exited with an error code that says nothing about the error.
*/
const UNSPECIFIED_ERROR = 1;
/**
* The command was used incorrectly, e.g., with the wrong number of
* arguments, a bad flag, a bad syntax in a parameter, or whatever.
*/
const USAGE = 64;
/**
* The input data was incorrect in some way. This should only be used for
* user's data and not system files.
*/
const DATAERR = 65;
/**
* An input file (not a system file) did not exist or was not readable.
* This could also include errors like ``No message'' to a mailer (if it
* cared to catch it).
*/
const NOINPUT = 66;
/**
* The user specified did not exist. This might be used for mail addresses
* or remote logins.
*/
const NOUSER = 67;
/**
* The host specified did not exist. This is used in mail addresses or
* network requests.
*/
const NOHOST = 68;
/**
* A service is unavailable. This can occur if a support program or file
* does not exist. This can also be used as a catchall message when
* something you wanted to do does not work, but you do not know why.
*/
const UNAVAILABLE = 69;
/**
* An internal software error has been detected. This should be limited to
* non-operating system related errors as possible.
*/
const SOFTWARE = 70;
/**
* An operating system error has been detected. This is intended to be
* used for such things as ``cannot fork'', ``cannot create pipe'', or the
* like. It includes things like getuid returning a user that does not
* exist in the passwd file.
*/
const OSERR = 71;
/**
* Some system file (e.g., /etc/passwd, /var/run/utx.active, etc.) does not
* exist, cannot be opened, or has some sort of error (e.g., syntax error).
*/
const OSFILE = 72;
/**
* A (user specified) output file cannot be created.
*/
const CANTCREAT = 73;
/**
* An error occurred while doing I/O on some file.
*/
const IOERR = 74;
/**
* Temporary failure, indicating something that is not really an error. In
* sendmail, this means that a mailer (e.g.) could not create a connection,
* and the request should be reattempted later.
*/
const TEMPFAIL = 75;
/**
* The remote system returned something that was ``not possible'' during a
* protocol exchange.
*/
const PROTOCOL = 76;
/**
* You did not have sufficient permission to perform the operation. This
* is not intended for file system problems, which should use NOINPUT or
* CANTCREAT, but rather for higher level permissions.
*/
const NOPERM = 77;
/**
* Something was found in an unconfigured or misconfigured state.
*/
const CONFIG = 78;
/**
* @var array a map of reason descriptions for exit codes.
*/
public static $reasons = [
self::OK => 'Success',
self::UNSPECIFIED_ERROR => "Unspecified error",
self::USAGE => 'Incorrect usage, argument or option error',
self::DATAERR => 'Error in input data',
self::NOINPUT => 'Input file not found or unreadable',
self::NOUSER => 'User not found',
self::NOHOST => 'Host not found',
self::UNAVAILABLE => 'A requied service is unavailable',
self::SOFTWARE => 'Internal error',
self::OSERR => 'Error making system call or using OS service',
self::OSFILE => 'Error accessing system file',
self::CANTCREAT => 'Cannot create output file',
self::IOERR => 'I/O error',
self::TEMPFAIL => 'Temporary failure',
self::PROTOCOL => 'Unexpected remote service behavior',
self::NOPERM => 'Insufficient permissions',
self::CONFIG => 'Configuration error',
];
/**
* Returns a short reason text for the given exit code.
*
* This method uses [[$reasons]] to determine the reason for an exit code.
* @param int $exitCode one of the constants defined in this class.
* @return string the reason text, or `"Unknown exit code"` if the code is not listed in [[$reasons]].
*/
public static function getReason($exitCode)
{
return isset($exReasons[$exitCode]) ? $exReasons[$exitCode] : "Unknown exit code";
}
}

View File

@ -10,6 +10,7 @@ namespace yii\console\controllers;
use Yii;
use yii\console\Controller;
use yii\console\Exception;
use yii\console\ExitCode;
use yii\helpers\Console;
use yii\helpers\FileHelper;
use yii\helpers\VarDumper;
@ -728,7 +729,7 @@ return [
EOD;
if (file_exists($configFile)) {
if (!$this->confirm("File '{$configFile}' already exists. Do you wish to overwrite it?")) {
return self::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
}
if (!file_put_contents($configFile, $template)) {
@ -736,7 +737,7 @@ EOD;
}
$this->stdout("Configuration file template created at '{$configFile}'.\n\n", Console::FG_GREEN);
return self::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
/**

View File

@ -11,6 +11,7 @@ use Yii;
use yii\base\InvalidConfigException;
use yii\console\Controller;
use yii\console\Exception;
use yii\console\ExitCode;
use yii\helpers\Console;
use yii\helpers\FileHelper;
@ -155,7 +156,7 @@ abstract class BaseMigrateController extends Controller
if (empty($migrations)) {
$this->stdout("No new migrations found. Your system is up-to-date.\n", Console::FG_GREEN);
return self::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
$total = count($migrations);
@ -183,7 +184,7 @@ abstract class BaseMigrateController extends Controller
$this->stdout("\n$applied from $n " . ($applied === 1 ? 'migration was' : 'migrations were') . " applied.\n", Console::FG_RED);
$this->stdout("\nMigration failed. The rest of the migrations are canceled.\n", Console::FG_RED);
return self::EXIT_CODE_ERROR;
return ExitCode::UNSPECIFIED_ERROR;
}
$applied++;
}
@ -225,7 +226,7 @@ abstract class BaseMigrateController extends Controller
if (empty($migrations)) {
$this->stdout("No migration has been done before.\n", Console::FG_YELLOW);
return self::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
$migrations = array_keys($migrations);
@ -244,7 +245,7 @@ abstract class BaseMigrateController extends Controller
$this->stdout("\n$reverted from $n " . ($reverted === 1 ? 'migration was' : 'migrations were') . " reverted.\n", Console::FG_RED);
$this->stdout("\nMigration failed. The rest of the migrations are canceled.\n", Console::FG_RED);
return self::EXIT_CODE_ERROR;
return ExitCode::UNSPECIFIED_ERROR;
}
$reverted++;
}
@ -287,7 +288,7 @@ abstract class BaseMigrateController extends Controller
if (empty($migrations)) {
$this->stdout("No migration has been done before.\n", Console::FG_YELLOW);
return self::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
$migrations = array_keys($migrations);
@ -304,14 +305,14 @@ abstract class BaseMigrateController extends Controller
if (!$this->migrateDown($migration)) {
$this->stdout("\nMigration failed. The rest of the migrations are canceled.\n", Console::FG_RED);
return self::EXIT_CODE_ERROR;
return ExitCode::UNSPECIFIED_ERROR;
}
}
foreach (array_reverse($migrations) as $migration) {
if (!$this->migrateUp($migration)) {
$this->stdout("\nMigration failed. The rest of the migrations are canceled.\n", Console::FG_RED);
return self::EXIT_CODE_ERROR;
return ExitCode::UNSPECIFIED_ERROR;
}
}
$this->stdout("\n$n " . ($n === 1 ? 'migration was' : 'migrations were') . " redone.\n", Console::FG_GREEN);
@ -399,7 +400,7 @@ abstract class BaseMigrateController extends Controller
$this->stdout("The migration history is set at $originalVersion.\nNo actual migration was performed.\n", Console::FG_GREEN);
}
return self::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
}
@ -419,7 +420,7 @@ abstract class BaseMigrateController extends Controller
}
}
return self::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
}
@ -786,7 +787,7 @@ abstract class BaseMigrateController extends Controller
if (strpos($migration, $version) === 0) {
$this->actionUp($i + 1);
return self::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
}
@ -800,7 +801,7 @@ abstract class BaseMigrateController extends Controller
$this->actionDown($i);
}
return self::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
}

View File

@ -12,6 +12,7 @@ use yii\caching\ApcCache;
use yii\caching\CacheInterface;
use yii\console\Controller;
use yii\console\Exception;
use yii\console\ExitCode;
use yii\helpers\Console;
/**
@ -88,11 +89,11 @@ class CacheController extends Controller
if (!$foundCaches) {
$this->notifyNoCachesFound();
return static::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
if (!$this->confirmFlush($foundCaches)) {
return static::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
foreach ($caches as $name => $class) {
@ -116,7 +117,7 @@ class CacheController extends Controller
if (empty($caches)) {
$this->notifyNoCachesFound();
return static::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
foreach ($caches as $name => $class) {
@ -150,14 +151,14 @@ class CacheController extends Controller
$connection = Yii::$app->get($db, false);
if ($connection === null) {
$this->stdout("Unknown component \"$db\".\n", Console::FG_RED);
return self::EXIT_CODE_ERROR;
return ExitCode::UNSPECIFIED_ERROR;
}
if (!$connection instanceof \yii\db\Connection) {
$this->stdout("\"$db\" component doesn't inherit \\yii\\db\\Connection.\n", Console::FG_RED);
return self::EXIT_CODE_ERROR;
return ExitCode::UNSPECIFIED_ERROR;
} elseif (!$this->confirm("Flush cache schema for \"$db\" connection?")) {
return static::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
try {

View File

@ -12,6 +12,7 @@ use yii\base\InvalidConfigException;
use yii\base\InvalidParamException;
use yii\console\Controller;
use yii\console\Exception;
use yii\console\ExitCode;
use yii\helpers\Console;
use yii\helpers\FileHelper;
use yii\test\FixtureTrait;
@ -112,7 +113,7 @@ class FixtureController extends Controller
$helpCommand = Console::ansiFormat('yii help fixture', [Console::FG_CYAN]);
$this->stdout("Use $helpCommand to get usage info.\n");
return self::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
$filtered = $this->filterFixtures($fixturesInput);
@ -142,11 +143,11 @@ class FixtureController extends Controller
if (!$fixturesToLoad) {
$this->notifyNothingToLoad($foundFixtures, $except);
return static::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
if (!$this->confirmLoad($fixturesToLoad, $except)) {
return static::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
$fixtures = $this->getFixturesConfig(array_merge($this->globalFixtures, $fixturesToLoad));
@ -161,7 +162,7 @@ class FixtureController extends Controller
$this->loadFixtures($fixturesObjects);
$this->notifyLoaded($fixtures);
return static::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
/**
@ -212,11 +213,11 @@ class FixtureController extends Controller
if (!$fixturesToUnload) {
$this->notifyNothingToUnload($foundFixtures, $except);
return static::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
if (!$this->confirmUnload($fixturesToUnload, $except)) {
return static::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
$fixtures = $this->getFixturesConfig(array_merge($this->globalFixtures, $fixturesToUnload));

View File

@ -9,6 +9,7 @@ namespace yii\console\controllers;
use Yii;
use yii\console\Exception;
use yii\console\ExitCode;
use yii\db\Connection;
use yii\db\Query;
use yii\di\Instance;
@ -219,7 +220,7 @@ class MessageController extends \yii\console\Controller
$filePath = Yii::getAlias($filePath);
if (file_exists($filePath)) {
if (!$this->confirm("File '{$filePath}' already exists. Do you wish to overwrite it?")) {
return self::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
}
@ -242,11 +243,11 @@ EOD;
if (file_put_contents($filePath, $content) === false) {
$this->stdout("Configuration file was NOT created: '{$filePath}'.\n\n", Console::FG_RED);
return self::EXIT_CODE_ERROR;
return ExitCode::UNSPECIFIED_ERROR;
}
$this->stdout("Configuration file created: '{$filePath}'.\n\n", Console::FG_GREEN);
return self::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
/**
@ -266,17 +267,17 @@ EOD;
if (file_exists($filePath)) {
if (!$this->confirm("File '{$filePath}' already exists. Do you wish to overwrite it?")) {
return self::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
}
if (!copy(Yii::getAlias('@yii/views/messageConfig.php'), $filePath)) {
$this->stdout("Configuration file template was NOT created at '{$filePath}'.\n\n", Console::FG_RED);
return self::EXIT_CODE_ERROR;
return ExitCode::UNSPECIFIED_ERROR;
}
$this->stdout("Configuration file template created at '{$filePath}'.\n\n", Console::FG_GREEN);
return self::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
/**
@ -677,7 +678,7 @@ EOD;
ksort($existingMessages);
if (array_keys($existingMessages) === $messages && (!$sort || array_keys($rawExistingMessages) === $messages)) {
$this->stdout("Nothing new in \"$category\" category... Nothing to save.\n\n", Console::FG_GREEN);
return self::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
unset($rawExistingMessages);
$merged = [];
@ -731,11 +732,11 @@ EOD;
if (file_put_contents($fileName, $content) === false) {
$this->stdout("Translation was NOT saved.\n\n", Console::FG_RED);
return self::EXIT_CODE_ERROR;
return ExitCode::UNSPECIFIED_ERROR;
}
$this->stdout("Translation saved.\n\n", Console::FG_GREEN);
return self::EXIT_CODE_NORMAL;
return ExitCode::OK;
}
/**