Skip to content

Commit

Permalink
Merge pull request #15431 from craftcms/feature/env
Browse files Browse the repository at this point in the history
`env` commands
  • Loading branch information
brandonkelly authored Jul 27, 2024
2 parents 11c23bc + b1348ee commit d4a48f8
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 18 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG-WIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- Double-clicking on folders within asset indexes and folder selection modals now navigates the index/modal into the folder. ([#15238](https://github.com/craftcms/cms/discussions/15238))

### Administration
- Added the `env`, `env/set`, and `env/remove` commands. ([#15431](https://github.com/craftcms/cms/pull/15431))
- New sites’ Base URL settings now default to an environment variable name based on the site name. ([#15347](https://github.com/craftcms/cms/pull/15347))
- Craft now warns against using the `@web` alias for URL settings, regardless of whether it was explicitly defined. ([#15347](https://github.com/craftcms/cms/pull/15347))

Expand All @@ -22,6 +23,7 @@
- Added `craft\filters\Headers`. ([#15397](https://github.com/craftcms/cms/pull/15397))
- Added `Craft.EnvVarGenerator`.
- `craft\helpers\UrlHelper::cpUrl()` now returns URLs based on the primary site’s base URL (if it has one), for console requests if the `baseCpUrl` config setting isn’t set, and the `@web` alias wasn’t explicitly defined. ([#15374](https://github.com/craftcms/cms/issues/15374))
- `craft\services\Config::setDotEnvVar()` now accepts `false` for its `value` argument, which removes the environment variable from the `.env` file.
- Deprecated `craft\web\assets\elementresizedetector\ElementResizeDetectorAsset`.

### System
Expand Down
99 changes: 99 additions & 0 deletions src/console/controllers/EnvController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php
/**
* @link https://craftcms.com/
* @copyright Copyright (c) Pixel & Tonic, Inc.
* @license https://craftcms.github.io/license/
*/

namespace craft\console\controllers;

use Craft;
use craft\console\Controller;
use craft\helpers\App;
use craft\helpers\Console;
use yii\base\Exception;
use yii\console\ExitCode;

/**
* Sets or removes environment variables in the `.env` file.
*
* @author Pixel & Tonic, Inc. <[email protected]>
* @since 4.11.0
*/
class EnvController extends Controller
{
/**
* @inheritdoc
*/
public $defaultAction = 'show';

/**
* Displays the value of an environment variable, or sets its value if $name contains `=`.
*
* php craft env CRAFT_DEV_MODE
* php craft env CRAFT_DEV_MODE=true
*
* @param string $name
* @return int
*/
public function actionShow(string $name): int
{
if (str_contains($name, '=')) {
[$name, $value] = explode('=', $name, 2);
return $this->runAction('set', [$name, $value]);
}

$value = App::env($name);
$dump = Craft::dump($value, return: true);
$this->stdout(trim($dump) . "\n");
return ExitCode::OK;
}

/**
* Sets an environment variable in the `.env` file.
*
* php craft env/set CRAFT_DEV_MODE true
*
* @param string $name
* @param string $value
* @return int
*/
public function actionSet(string $name, string $value = ''): int
{
if (str_contains($name, '=')) {
[$name, $value] = explode('=', $name, 2);
}

try {
Craft::$app->getConfig()->setDotEnvVar(trim($name), trim($value));
} catch (Exception $e) {
$this->stderr($e->getMessage() . "\n", Console::FG_RED);
return ExitCode::UNSPECIFIED_ERROR;
}

$dump = Craft::dump(App::env($name), return: true);
$this->stdout(sprintf("%s %s.\n", $this->markdownToAnsi("`$name` is now"), trim($dump)));
return ExitCode::OK;
}

/**
* Removes an environment variable from the `.env` file.
*
* php craft env/remove CRAFT_DEV_MODE
*
* @param string $name
* @return int
*/
public function actionRemove(string $name): int
{
try {
Craft::$app->getConfig()->setDotEnvVar($name, false);
} catch (Exception $e) {
$this->stderr($e->getMessage() . "\n", Console::FG_RED);
return ExitCode::UNSPECIFIED_ERROR;
}

$this->stdout($this->markdownToAnsi("`$name` has been removed.") . "\n");
return ExitCode::OK;
}
}
42 changes: 25 additions & 17 deletions src/services/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -338,13 +338,13 @@ public function getDotEnvPath(): string
}

/**
* Sets an environment variable value in the project's .env file.
* Sets an environment variable value in the project's `.env` file.
*
* @param string $name The environment variable name
* @param string $value The environment variable value
* @param string|false $value The environment variable value, or `false` if it should be removed.
* @throws Exception if the .env file doesn't exist
*/
public function setDotEnvVar(string $name, string $value): void
public function setDotEnvVar(string $name, string|false $value): void
{
$path = $this->getDotEnvPath();

Expand All @@ -354,28 +354,36 @@ public function setDotEnvVar(string $name, string $value): void

$contents = file_get_contents($path);
$qName = preg_quote($name, '/');
$slashedValue = addslashes($value);

// Only surround with quotes if the value contains a space
if (str_contains($slashedValue, ' ') || str_contains($slashedValue, '#')) {
$slashedValue = "\"$slashedValue\"";
}
if ($value === false) {
$contents = preg_replace("/\s*^\s*$qName=.*/m", '', $contents);
} else {
$slashedValue = addslashes($value);
// Only surround with quotes if the value contains a space
if (str_contains($slashedValue, ' ') || str_contains($slashedValue, '#')) {
$slashedValue = "\"$slashedValue\"";
}
$def = "$name=$slashedValue";

$def = "$name=$slashedValue";
$token = StringHelper::randomString();
$contents = preg_replace("/^(\s*)$qName=.*/m", $token, $contents, -1, $count);
$token = StringHelper::randomString();
$contents = preg_replace("/^\s*$qName=.*/m", $token, $contents, -1, $count);

if ($count !== 0) {
$contents = str_replace($token, $def, $contents);
} else {
$contents = rtrim($contents);
$contents = ($contents ? $contents . PHP_EOL . PHP_EOL : '') . $def . PHP_EOL;
if ($count !== 0) {
$contents = str_replace($token, $def, $contents);
} else {
$contents = rtrim($contents);
$contents = ($contents ? $contents . PHP_EOL . PHP_EOL : '') . $def . PHP_EOL;
}
}

FileHelper::writeToFile($path, $contents);

// Now actually set the environment variable
$_SERVER[$name] = $value;
if ($value === false) {
unset($_SERVER[$name]);
} else {
$_SERVER[$name] = $value;
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/services/Gql.php
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ public function executeQuery(
$event->result = $cachedResult;
} else {
$isIntrospectionQuery = GqlHelper::isIntrospectionQuery($event->query);
$schemaDef = $this->getSchemaDef($schema, true);
$schemaDef = $this->getSchemaDef($schema, $debugMode || $isIntrospectionQuery);
$elementsService = Craft::$app->getElements();
$elementsService->startCollectingCacheInfo();

Expand Down

0 comments on commit d4a48f8

Please sign in to comment.