├── .gitignore ├── LICENSE.md ├── README.md ├── composer.json └── src ├── EnvironmentBackupCommand.php ├── EnvironmentCommandsServiceProvider.php ├── EnvironmentReadCommand.php ├── EnvironmentRestoreCommand.php └── EnvironmentSetCommand.php /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | build 3 | composer.lock 4 | vendor 5 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Tamer Yousry 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Commands for .env file 2 | 3 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/tamer-dev/laravel-env-cli.svg)](https://packagist.org/packages/tamer-dev/laravel-env-cli) 4 | [![Total Downloads](https://img.shields.io/packagist/dt/tamer-dev/laravel-env-cli.svg)](https://packagist.org/packages/tamer-dev/laravel-env-cli) 5 | [![License](https://img.shields.io/github/license/tamer-dev/laravel-env-cli.svg)](LICENSE.md) 6 | 7 | This Laravel package offers to you some commands to work with your env file from the command line. 8 | if you are making changes frequently to your env file this package will help you to do this fast and in an effective way. 9 | 10 | This package supports the Laravel version from 5.7 to 10 . 11 | 12 | 13 | 14 | - [Installation](#installation) 15 | - [Usage:-](#usage) 16 | - [Set Environment Variable Command](#1-set-environment-variable-command) 17 | - [Read Environment Variable Command](#2-read-environment-variable-command) 18 | - [Backup Environment File Command](#3-backup-environment-file-command) 19 | - [Restore Environment File Command](#4-restore-environment-file-command) 20 | - [Contribution](#contribution) 21 | - [Notes](#notes) 22 | - [License](#license) 23 | 24 | 25 | 26 | ## Installation 27 | 28 | You can install this package with [Composer](https://getcomposer.org/) using the following command: 29 | 30 | ```bash 31 | composer require tamer-dev/laravel-env-cli 32 | ``` 33 | 34 | ## Usage 35 | 36 | #### 1- Set Environment Variable Command 37 | command definition :- 38 | `env:set {key} {value}` 39 | 40 | this command by default will use .env file 41 | 42 | optional command options:- 43 | `{--file=your-custom-env-name}` if you want to set a key in custom env file 44 | 45 | `{--b|backup}` take a backup from env file before set the key 46 | 47 | you must provide both a key and value . 48 | 49 | ```bash 50 | $ php artisan env:set app_name Example 51 | # Environment variable with key 'APP_NAME' has been changed from 'Laravel' to 'Example' 52 | ``` 53 | you can provide them as two arguments as commnd before or one argument like follwoing:- . 54 | ```bash 55 | $ php artisan env:set app_name=Example 56 | # Environment variable with key 'APP_NAME' has been changed from 'Laravel' to 'Example' 57 | ``` 58 | 59 | if you value have spaces you can wrapping them in quotes like follwoing:-. 60 | ```bash 61 | $ php artisan env:set app_name "Example App" 62 | # Environment variable with key 'APP_NAME' has been changed from 'Laravel' to '"Example App"' 63 | ``` 64 | 65 | you can create new environment variables if this key dose not exist. 66 | 67 | ```bash 68 | $ php artisan env:set editor=vscode 69 | # Environment variable with key 'EDITOR' has been set to 'vscode' 70 | ``` 71 | 72 | you can create or update environment variables in another file not in the default one by passing --file option like following:- 73 | 74 | ```bash 75 | $ php artisan env:set app_name Example --file=.env.example 76 | # Environment variable with key 'EDITOR' has been set to 'vscode' 77 | ``` 78 | 79 | also you can take a backup file from your env file before make any changes in same command by passing -b option (a new file backup with the name '.env.backup_' will be created) like following:- 80 | ```bash 81 | $ php artisan env:set app_name Example -b 82 | # Environment variable with key 'APP_NAME' has been changed from 'Laravel' to 'Example' 83 | ``` 84 | another features :- 85 | - update an empty value 86 | - stop invalid inputs 87 | - stop updateing in APP_KEY 88 | 89 | 90 | #### 2- Read Environment Variable Command 91 | 92 | command definition :- 93 | `env:read {key}` 94 | this command by default will use .env file 95 | 96 | ```bash 97 | $ php artisan env:read app_name 98 | # Environment variable with key [APP_NAME] have value [Laravel] file used is .env 99 | ``` 100 | optional command options:- 101 | `{--file=your-custom-env-name}` if you want to read a key from a custom env file 102 | 103 | ```bash 104 | $ php artisan env:read app_name --file=.env.example 105 | #Environment variable with key [APP_NAME] have value [tamertest3] file used is .env.example 106 | ``` 107 | 108 | #### 3- Backup Environment File Command 109 | 110 | this command will make a backup from env file (a new file backup with the name '.env.backup_' will be created) 111 | 112 | command definition :- 113 | `env:backup` 114 | this command by default will use .env file 115 | 116 | ```bash 117 | $ php artisan env:backup 118 | #new environment backup file has been created in this path '/var/www/html/laravel-env-cli/.env.backup_20200517204848' 119 | ``` 120 | optional command options:- 121 | `{--file=your-custom-env-name}` if you want to backup a custom env file 122 | 123 | ```bash 124 | $ php artisan env:backup --file=.env.example 125 | #new environment backup file has been created in this path '/var/www/html/laravel-env-cli/.env.example.backup_20200517205000' 126 | ``` 127 | 128 | #### 4- Restore Environment File Command 129 | restore your .env file from a backup file 130 | 131 | command definition :- 132 | `env:restore {backupedFileName}` 133 | this command by default will use .env file 134 | 135 | ```bash 136 | $ php artisan env:restore .env.backup_20200517204848 137 | #the env file '/var/www/html/laravel-env-cli/.env' 138 | #has been restored from this file path '/var/www/html/laravel-env-cli/.env.backup_20200517204848' 139 | ``` 140 | 141 | optional command options:- 142 | `{--file=your-custom-env-name}` if you want to restore a custom env file 143 | 144 | ```bash 145 | $ php artisan env:restore .env.backup_20200517204848 --file=.env.example 146 | #the env file '/var/www/html/laravel-env-cli/.env.example' 147 | #has been restored from this file path '/var/www/html/laravel-env-cli/.env.backup_20200517204848' 148 | ``` 149 | 150 | 151 | 152 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 153 | 154 | ## Contribution 155 | contribution are welcome ,if any one want to contribute in this package you can start by picking from this list : - 156 | 157 | - add tests 158 | - add more commands and important features 159 | - fix any issues 160 | 161 | ## Notes 162 | this package inspired by this package [imliam/laravel-env-set-command](https://github.com/imliam/laravel-env-set-command),for that all thanks to [imliam](https://github.com/imliam) 163 | 164 | ## License 165 | 166 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 167 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tamer-dev/laravel-env-cli", 3 | "description": "laravel commands to work with .env file in cli", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "tamer yousre", 8 | "email": "tamer.dev.alex@gmail.com" 9 | } 10 | ], 11 | "keywords": [ 12 | "tamer-dev", 13 | "laravel", 14 | "laravel-env", 15 | "laravel-env-commands", 16 | "laravel-env-set", 17 | "laravel-env-read", 18 | "environment", 19 | "variables", 20 | "env", 21 | "artisan" 22 | ], 23 | "homepage": "https://github.com/tamer-dev/laravel-env-cli", 24 | "minimum-stability": "dev", 25 | "autoload": { 26 | "psr-4": { 27 | "TamerDev\\EnvironmentCommands\\": "src/" 28 | } 29 | }, 30 | "require": { 31 | "php" : "^7.1|^8.0|^8.1", 32 | "illuminate/support": "^5.7|^6.0|^7.0|^8.0|^9.0|^10.0" 33 | }, 34 | "extra": { 35 | "laravel": { 36 | "providers": [ 37 | "TamerDev\\EnvironmentCommands\\EnvironmentCommandsServiceProvider" 38 | ] 39 | } 40 | }, 41 | "require-dev": { 42 | "phpunit/phpunit": "8.5.x-dev" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/EnvironmentBackupCommand.php: -------------------------------------------------------------------------------- 1 | getEnvFilePath(); 51 | $this->makeBackup($envFilePath); 52 | } catch (\Exception $e) { 53 | return $this->error($e->getMessage()); 54 | } 55 | 56 | return $this->info("A new environment backup file has been created in this path '{$this->newFilePath}'") ; 57 | } 58 | 59 | 60 | /** 61 | * get the full path of env file . 62 | * 63 | * @return string 64 | */ 65 | protected function getEnvFilePath(): string 66 | { 67 | return base_path($this->option('file')); 68 | } 69 | 70 | 71 | /** 72 | * Overwrite the contents of a file. 73 | * 74 | * @param string $path 75 | * @param string $contents 76 | * @return boolean 77 | */ 78 | protected function writeFile(string $path, string $contents): bool 79 | { 80 | $file = $this->openFile($path, 'w'); 81 | fwrite($file, $contents); 82 | 83 | return fclose($file); 84 | } 85 | 86 | /** 87 | * Open a file. 88 | * 89 | * @param string $envFilePath 90 | * @param string $mode 91 | * @return filestream 92 | */ 93 | public function openFile(string $envFilePath , string $mode ="r") 94 | { 95 | if (!file_exists($envFilePath) && $mode =="r") { 96 | throw new \Exception("The file $envFilePath does not exist "); 97 | } 98 | 99 | return fopen($envFilePath,$mode); 100 | } 101 | 102 | /** 103 | * Make a Backup from a file . 104 | * 105 | * @param string $envFilePath 106 | * @return boolean 107 | */ 108 | protected function makeBackup($envFilePath): bool 109 | { 110 | $fileContent = file_get_contents($envFilePath); 111 | $this->newFilePath =$envFilePath.".backup_".date("YmdHis"); 112 | return $this->writeFile($this->newFilePath, $fileContent); 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /src/EnvironmentCommandsServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->bind('command.env:set', EnvironmentSetCommand::class); 27 | $this->app->bind('command.env:read', EnvironmentReadCommand::class); 28 | $this->app->bind('command.env:backup', EnvironmentBackupCommand::class); 29 | $this->app->bind('command.env:restore', EnvironmentRestoreCommand::class); 30 | 31 | $this->commands([ 32 | 'command.env:set','command.env:read','command.env:backup','command.env:restore' 33 | ]); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/EnvironmentReadCommand.php: -------------------------------------------------------------------------------- 1 | getKeyArgument(); 53 | $envFilePath = $this->getEnvFilePath(); 54 | $file = fopen($envFilePath,"r"); 55 | $value = $this->readValue($file,$key); 56 | } catch (\Exception $e) { 57 | return $this->error($e->getMessage()); 58 | } 59 | 60 | return $this->getMessage($key,$value); 61 | } 62 | 63 | /** 64 | * Read Value gor given Key. 65 | * 66 | * @param file $file 67 | * @param string $key 68 | * @return string 69 | */ 70 | protected function readValue($file,$key): string 71 | { 72 | $key = strtoupper($key); 73 | $env_value=""; 74 | while(! feof($file)) 75 | { 76 | $fileLine= fgets($file) ; 77 | $parts = explode('=', $fileLine, 2); 78 | if (count($parts) == 2) { 79 | $env_key=$parts[0] ; 80 | $env_value =str_replace("\r\n","",trim($parts[1])); 81 | if($key==$env_key){ 82 | $this->key_found=true; 83 | fclose($file); 84 | return $env_value ; 85 | } 86 | } 87 | } 88 | fclose($file); 89 | 90 | return $env_value; 91 | } 92 | 93 | 94 | /** 95 | * Determine what the supplied key from the current command. 96 | * 97 | * @return string 98 | */ 99 | protected function getKeyArgument(): string 100 | { 101 | $key = $this->argument('key'); 102 | 103 | if (! $this->isValidKey($key)) { 104 | throw new InvalidArgumentException('Invalid argument key'); 105 | } 106 | 107 | return strtoupper($key); 108 | } 109 | 110 | /** 111 | * Check if a given string is valid as an environment variable key. 112 | * 113 | * @param string $key 114 | * @return boolean 115 | */ 116 | protected function isValidKey(string $key): bool 117 | { 118 | if (Str::contains($key, '=')) { 119 | throw new InvalidArgumentException("Environment key should not contain '='"); 120 | } 121 | 122 | return true; 123 | } 124 | 125 | /** 126 | * get the full path of env file . 127 | * 128 | * @return string 129 | */ 130 | protected function getEnvFilePath(): string 131 | { 132 | return base_path($this->option('file')); 133 | } 134 | 135 | /** 136 | * get message . 137 | * @param string $key 138 | * @param string $value 139 | */ 140 | protected function getMessage($key,$value) 141 | { 142 | $envFile = $this->option('file'); 143 | if($this->key_found){ 144 | $message = $this->info("Environment variable with key [{$key}] have value [{$value}] file used is $envFile "); 145 | }else{ 146 | $message = $this->info("Environment variable with key [{$key}] not found") ; 147 | } 148 | return $message; 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/EnvironmentRestoreCommand.php: -------------------------------------------------------------------------------- 1 | getBackupedEnvFilePath(); 45 | $envFilePath = $this->getEnvFilePath(); 46 | 47 | $this->makeRestore($backupedFilePath,$envFilePath); 48 | } catch (\Exception $e) { 49 | return $this->error($e->getMessage()); 50 | } 51 | 52 | return $this->info("the env file '{$envFilePath}' has been restored from this file path '{$backupedFilePath}'") ; 53 | } 54 | 55 | 56 | /** 57 | * get the full path of env file . 58 | * 59 | * @return string 60 | */ 61 | protected function getEnvFilePath(): string 62 | { 63 | return base_path($this->option('file')); 64 | } 65 | 66 | /** 67 | * get the full path of env file . 68 | * 69 | * @return string 70 | */ 71 | protected function getBackupedEnvFilePath(): string 72 | { 73 | return base_path($this->argument('backupedFileName')); 74 | } 75 | 76 | /** 77 | * Restore env file from a backup file. 78 | * 79 | * @param string $backupedFilePath 80 | * @param string $envFilePath 81 | * @return boolean 82 | */ 83 | protected function makeRestore($backupedFilePath,$envFilePath): bool 84 | { 85 | if (!file_exists($backupedFilePath) ) { 86 | throw new \Exception("The file $backupedFilePath does not exist "); 87 | } 88 | if (!file_exists($envFilePath) ) { 89 | throw new \Exception("The file $envFilePath does not exist "); 90 | } 91 | $fileContent = file_get_contents($backupedFilePath); 92 | return $this->writeFile($envFilePath, $fileContent); 93 | } 94 | 95 | /** 96 | * Overwrite the contents of a file. 97 | * 98 | * @param string $path 99 | * @param string $contents 100 | * @return boolean 101 | */ 102 | protected function writeFile(string $path, string $contents): bool 103 | { 104 | $file = $this->openFile($path, 'w'); 105 | fwrite($file, $contents); 106 | 107 | return fclose($file); 108 | } 109 | 110 | /** 111 | * Open a file. 112 | * 113 | * @param string $envFilePath 114 | * @param string $mode 115 | * @return filestream 116 | */ 117 | public function openFile(string $envFilePath , string $mode ="r") 118 | { 119 | if (!file_exists($envFilePath) && $mode =="r") { 120 | throw new \Exception("The file $envFilePath does not exist "); 121 | } 122 | 123 | return fopen($envFilePath,$mode); 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /src/EnvironmentSetCommand.php: -------------------------------------------------------------------------------- 1 | getKeyValue(); 60 | $envFilePath = $this->getEnvFilePath(); 61 | $processedFileContent = $this->getProcessedFileContent($envFilePath,$key,$value); 62 | if($this->option('backup')){ 63 | $this->makeBackup($envFilePath); 64 | } 65 | $this->writeFile($envFilePath, $processedFileContent); 66 | } catch (\Exception $e) { 67 | return $this->error($e->getMessage()); 68 | } 69 | 70 | return $this->getMessage($key,$value); 71 | } 72 | 73 | 74 | /** 75 | * Determine what the supplied key and value is from the current command. 76 | * 77 | * @return array 78 | */ 79 | protected function getKeyValue(): array 80 | { 81 | $key = $this->argument('key'); 82 | $value = $this->argument('value'); 83 | 84 | if (! $value) { 85 | $parts = explode('=', $key, 2); 86 | 87 | if (count($parts) !== 2) { 88 | throw new InvalidArgumentException('No value was set'); 89 | } 90 | 91 | $key = $parts[0]; 92 | $value = $parts[1]; 93 | } 94 | 95 | if (! $this->isValidKey($key)) { 96 | throw new InvalidArgumentException('Invalid argument key'); 97 | } 98 | 99 | if (! is_bool(strpos($value, ' '))) { 100 | $value = '"' . $value . '"'; 101 | } 102 | 103 | return [strtoupper($key), $value]; 104 | } 105 | 106 | /** 107 | * Check if a given string is valid as an environment variable key. 108 | * 109 | * @param string $key 110 | * @return boolean 111 | */ 112 | protected function isValidKey(string $key): bool 113 | { 114 | if (Str::contains($key, '=')) { 115 | throw new InvalidArgumentException("Environment key should not contain '='"); 116 | } 117 | 118 | if (!preg_match('/^[a-zA-Z_]+$/', $key)) { 119 | throw new InvalidArgumentException('Invalid environment key. Only use letters and underscores'); 120 | } 121 | 122 | if($key =="APP_KEY" ){ 123 | throw new InvalidArgumentException('Environment {APP_KEY} should not be set by this command. it is better to use the native one {php artisan key:generate}'); 124 | } 125 | 126 | return true; 127 | } 128 | 129 | /** 130 | * get the full path of env file . 131 | * 132 | * @return string 133 | */ 134 | protected function getEnvFilePath(): string 135 | { 136 | if($this->option('file')){ 137 | $envFilePath = base_path($this->option('file')); 138 | }else{ 139 | $envFilePath = app()->environmentFilePath(); 140 | } 141 | return $envFilePath; 142 | } 143 | 144 | protected function getProcessedFileContent($envFilePath,$key,$value): string 145 | { 146 | $file = $this->openFile($envFilePath); 147 | $file_content=""; 148 | while(! feof($file)) 149 | { 150 | $fileLine= fgets($file) ; 151 | $parts = explode('=', $fileLine, 2); 152 | if (count($parts) == 2) { 153 | $env_key=$parts[0] ; 154 | $env_value =str_replace("\r\n","",trim($parts[1])); 155 | if($key==$env_key){ 156 | $this->key_found=true; 157 | $this->oldValue=$env_value; 158 | $fileLine="$env_key=$value\r\n"; 159 | } 160 | } 161 | $file_content =$file_content.$fileLine; 162 | } 163 | fclose($file); 164 | 165 | if (!$this->key_found){ 166 | $file_content =$file_content."$key=$value\r\n"; 167 | } 168 | 169 | return $file_content; 170 | } 171 | 172 | /** 173 | * Overwrite the contents of a file. 174 | * 175 | * @param string $path 176 | * @param string $contents 177 | * @return boolean 178 | */ 179 | protected function writeFile(string $path, string $contents): bool 180 | { 181 | $file = $this->openFile($path, 'w'); 182 | fwrite($file, $contents); 183 | 184 | return fclose($file); 185 | } 186 | 187 | public function openFile(string $envFilePath , string $mode ="r") 188 | { 189 | if (!file_exists($envFilePath) && $mode =="r") { 190 | throw new \Exception("The file $envFilePath does not exist "); 191 | } 192 | 193 | return fopen($envFilePath,$mode); 194 | } 195 | 196 | /** 197 | * get message . 198 | * @param string $file 199 | * @param string $key 200 | */ 201 | protected function getMessage($key,$value) 202 | { 203 | if($this->key_found){ 204 | $message = $this->info("Environment variable with key '{$key}' has been changed from '{$this->oldValue}' to '{$value}'"); 205 | }else{ 206 | $message = $this->info("A new environment variable with key '{$key}' has been set to '{$value}'") ; 207 | } 208 | return $message; 209 | } 210 | 211 | 212 | protected function makeBackup($envFilePath) 213 | { 214 | $fileContent = file_get_contents($envFilePath); 215 | return $this->writeFile($envFilePath.".backup_".date("YmdHis"), $fileContent); 216 | } 217 | 218 | } 219 | --------------------------------------------------------------------------------