├── .styleci.yml ├── phpunit.xml.dist ├── src ├── Commands │ ├── ListEnv.php │ ├── GetEnv.php │ ├── DeleteEnv.php │ ├── ExampleEnv.php │ └── SetEnv.php ├── FlexEnvServiceProvider.php └── Env.php ├── composer.json ├── LICENSE.md └── CONTRIBUTING.md /.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: laravel 2 | 3 | risky: false 4 | 5 | disabled: 6 | - not_operator_with_successor_space 7 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | ./tests 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Commands/ListEnv.php: -------------------------------------------------------------------------------- 1 | all() as $key => $value) { 35 | $data[] = [$key, $value]; 36 | } 37 | 38 | return $this->table(['Key', 'Value'], $data); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sven/flex-env", 3 | "description": "Edit your .env file in Laravel directly from the command line.", 4 | "keywords": ["flexible", "env", "laravel", "artisan"], 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Sven Luijten", 9 | "email": "svenluijten1995@gmail.com", 10 | "homepage": "https://svenluijten.com" 11 | } 12 | ], 13 | "require": { 14 | "php": "^8.0", 15 | "illuminate/support": "^8.0 || ^9.0", 16 | "laravel/framework": "^8.0 || ^9.0" 17 | }, 18 | "require-dev": { 19 | "graham-campbell/testbench": "^5.0" 20 | }, 21 | "autoload": { 22 | "psr-4": { 23 | "Sven\\FlexEnv\\": "src/" 24 | } 25 | }, 26 | "autoload-dev": { 27 | "psr-4": { 28 | "Sven\\FlexEnv\\Tests\\": "tests/" 29 | } 30 | }, 31 | "extra": { 32 | "laravel": { 33 | "providers": [ 34 | "Sven\\FlexEnv\\FlexEnvServiceProvider" 35 | ] 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Commands/GetEnv.php: -------------------------------------------------------------------------------- 1 | argument('key')); 33 | $result = str_replace('"', '', $env->get($key)); 34 | 35 | if ($result == '' || is_null($result)) { 36 | return $this->error("Could not find a value for [$key] in your .env file."); 37 | } 38 | 39 | return $this->comment("The value for [$key] is \"$result\"."); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/FlexEnvServiceProvider.php: -------------------------------------------------------------------------------- 1 | commands([ 27 | Commands\SetEnv::class, 28 | Commands\GetEnv::class, 29 | Commands\DeleteEnv::class, 30 | Commands\ListEnv::class, 31 | ]); 32 | } 33 | 34 | /** 35 | * Get the services provided by the provider. 36 | * 37 | * @return array 38 | */ 39 | public function provides() 40 | { 41 | return [ 42 | Commands\SetEnv::class, 43 | Commands\GetEnv::class, 44 | Commands\DeleteEnv::class, 45 | Commands\ListEnv::class, 46 | ]; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Commands/DeleteEnv.php: -------------------------------------------------------------------------------- 1 | argument('key')); 33 | 34 | $result = $env->delete($key)->get($key); 35 | 36 | if ($result !== '' && !is_null($result)) { 37 | $env->rollback(); 38 | 39 | return $this->comment("No value was found for \"$key\" in the .env file, nothing was changed."); 40 | } 41 | 42 | return $this->comment("Successfully deleted the entry \"$key\" from your .env file."); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | Copyright (c) Sven Luijten 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. 22 | -------------------------------------------------------------------------------- /src/Commands/ExampleEnv.php: -------------------------------------------------------------------------------- 1 | option('name'); 35 | 36 | try { 37 | $env->copy( 38 | base_path($name, Env::COPY_FOR_DISTRIBUTION) 39 | ); 40 | 41 | return $this->comment("Successfully created the file [$name]"); 42 | } catch (\Exception $e) { 43 | return $this->error($e->getMessage()); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Commands/SetEnv.php: -------------------------------------------------------------------------------- 1 | argument('key')); 36 | $value = (string) $this->argument('value'); 37 | $linebreak = (bool) $this->option('line-break'); 38 | 39 | $result = $env->set($key, $value, $linebreak)->get($key); 40 | 41 | if ($result !== $value) { 42 | $env->rollback(); 43 | 44 | return $this->error('Could not set the value in your .env file, reverting...'); 45 | } 46 | 47 | return $this->comment("Successfully set [$key] to [$value] in your .env file."); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | Thank you for considering to contribute to this repository! This file will walk you through all the steps to ensure both 3 | you and I have a good time submitting and reviewing your contribution. First off, some basic rules and reading material: 4 | 5 | - Submit your work in a new branch and make the PR to the master branch. 6 | - [Write a short & descriptive commit message](http://chris.beams.io/posts/git-commit/). 7 | - Rebase before committing the final change. 8 | - Stick to [PSR-2](http://www.php-fig.org/psr/psr-2/). 9 | - Add tests if necessary and ensure all the tests are green on the final commit. 10 | - Make sure the CI tools used by the repository are all in order. If one fails, you should make it pass. 11 | 12 | ## Contributing 13 | Here are the steps to follow to contribute to this repository: 14 | 15 | - [Fork this repository on GitHub](#fork-this-repository). 16 | - [Clone your fork to your local machine](#clone-your-fork). 17 | - [Create a feature branch](#create-a-branch). 18 | - [Add an 'upstream' remote](#add-a-remote). 19 | - [Regularly pull & rebase from the upstream remote](#pull-and-rebase). 20 | - [Work on feature branch](#working-on-branch). 21 | - [Submit a pull request to the master branch](#submitting-pull-request). 22 | 23 | ### Fork this repository 24 | Fork the repository right here on GitHub. To learn more about forking a repository, visit 25 | [GitHub's help article](https://help.github.com/articles/fork-a-repo/). 26 | 27 | ### Clone your fork 28 | Clone your repository on your local machine to start work on your pull request. 29 | 30 | ```bash 31 | $ git clone git@github.com:/.git 32 | # Or if you prefer HTTPS: 33 | $ git clone https://github.com//.git 34 | 35 | $ cd 36 | ``` 37 | 38 | ### Create a branch 39 | Make your own feature branch in order not to clutter up master. 40 | 41 | ```bash 42 | # Think of a good name for your branch: 43 | # fix/typo-in-readme 44 | # feature/some-feature 45 | # bug/some-bug-you-are-fixing 46 | $ git checkout -b 47 | ``` 48 | 49 | ### Add a remote 50 | Add an 'upstream' remote to pull from and to stay up to date with the work being done in there. 51 | 52 | ```bash 53 | # List all current remotes 54 | $ git remote -v 55 | origin git@github.com//.git (fetch) 56 | origin git@github.com//.git (push) 57 | 58 | # Add a new remote called 'upstream' 59 | $ git remote add upstream git@github.com:svenluijten/.git 60 | # Or if you prefer HTTPS: 61 | $ git remote add upstream https://github.com/svenluijten/.git 62 | 63 | # The new remote should now be in the list 64 | $ git remote -v 65 | origin git@github.com//.git (fetch) 66 | origin git@github.com//.git (push) 67 | upstream git@github.com/svenluijten/.git (fetch) 68 | upstream git@github.com/svenluijten/.git (push) 69 | ``` 70 | 71 | ### Pull and rebase 72 | Pull from upstream to stay up to date with what others might be doing in this repository. Any merge conflicts that arise 73 | are your responsibility to resolve. 74 | 75 | ```bash 76 | $ git pull --rebase upstream master 77 | ``` 78 | 79 | ### Working on branch 80 | Do your magic and make your fix. I can't help you with this :wink:. Once you're happy with the result and all tests pass, 81 | go ahead and push to your feature branch. 82 | 83 | ```bash 84 | $ git push origin 85 | ``` 86 | 87 | ### Submitting pull request 88 | Now, let's head back over to this repository on GitHub and submit the pull request! 89 | -------------------------------------------------------------------------------- /src/Env.php: -------------------------------------------------------------------------------- 1 | path = $path; 36 | $this->previous = file_get_contents($path); 37 | } 38 | 39 | /** 40 | * Get an entry from the .env file by key. 41 | * 42 | * @param string $key 43 | * @return string 44 | */ 45 | public function get($key) 46 | { 47 | $env = $this->parseFile(); 48 | 49 | $result = $env->filter(function (Collection $value) use ($key) { 50 | return $value->first() == $key; 51 | })->first(); 52 | 53 | return $result instanceof Collection ? $result->get(1) : $result; 54 | } 55 | 56 | /** 57 | * Set the value of the given key to the value supplied. 58 | * 59 | * @param string $key 60 | * @param string|bool|int $value 61 | * @param bool $linebreak 62 | * @return \Sven\FlexEnv\Env 63 | */ 64 | public function set($key, $value, $linebreak = false) 65 | { 66 | $oldValue = $this->get($key); 67 | 68 | if (is_bool($value)) { 69 | $value = $value ? 'true' : 'false'; 70 | } 71 | 72 | if (preg_match('/\W\D/', $value)) { 73 | $value = "\"$value\""; 74 | } 75 | 76 | $new = $linebreak ? "\n$key=$value" : "$key=$value"; 77 | 78 | if (!is_null($oldValue)) { 79 | return $this->replaceInFile("$key=$oldValue", $new); 80 | } 81 | 82 | file_put_contents($this->getPath(), "\n$new", FILE_APPEND); 83 | 84 | return $this; 85 | } 86 | 87 | /** 88 | * Delete an entry from the .env file. 89 | * 90 | * @param string $key 91 | * @return \Sven\FlexEnv\Env 92 | */ 93 | public function delete($key) 94 | { 95 | $old = $this->get($key); 96 | 97 | $this->replaceInFile("$key=$old", ''); 98 | 99 | return $this; 100 | } 101 | 102 | /** 103 | * Gets all the key/value pairs from the .env file. 104 | * 105 | * @return array 106 | */ 107 | public function all() 108 | { 109 | $env = $this->parseFile(); 110 | $result = []; 111 | 112 | $env->each(function (Collection $value) use (&$result) { 113 | return $result[$value->first()] = $value->get(1); 114 | }); 115 | 116 | return $result; 117 | } 118 | 119 | /** 120 | * Copy the .env file to the given destination. 121 | * 122 | * @param string $destination Full path to copy the file to 123 | * @param bool $excludeValues Whether or not to include values 124 | * @return bool 125 | */ 126 | public function copy($destination, $excludeValues = false) 127 | { 128 | $env = $this->parseFile(); 129 | 130 | // 131 | } 132 | 133 | /** 134 | * Rolls the .env file back to the way it was before performing the command. 135 | * 136 | * @return \Sven\FlexEnv\Env 137 | */ 138 | public function rollback() 139 | { 140 | file_put_contents($this->getPath(), $this->previous); 141 | 142 | return $this; 143 | } 144 | 145 | /** 146 | * Get the full path to the .env file. 147 | * 148 | * @return string 149 | */ 150 | public function getPath() 151 | { 152 | return $this->path; 153 | } 154 | 155 | /** 156 | * Parse the .env file contents for easier handling. 157 | * 158 | * @return \Illuminate\Support\Collection 159 | */ 160 | private function parseFile() 161 | { 162 | $contents = file_get_contents($this->getPath()); 163 | $lines = new Collection(explode("\n", $contents)); 164 | $result = new Collection(); 165 | 166 | $lines->filter(function ($value) { 167 | return $value; 168 | })->each(function ($value) use ($result) { 169 | preg_match('/([a-zA-Z_-]+)\=(.+)/', $value, $regexResult); 170 | 171 | array_shift($regexResult); 172 | $result->push(new Collection($regexResult)); 173 | }); 174 | 175 | return $result; 176 | } 177 | 178 | /** 179 | * Replace a part of the .env file. 180 | * 181 | * @param string $old 182 | * @param string $new 183 | * @param int $append 184 | * @return \Sven\FlexEnv\Env 185 | */ 186 | public function replaceInFile($old, $new, $append = 0) 187 | { 188 | $contents = $this->previous; 189 | $replaceWith = preg_replace("~$old\n?~", "$new\n", $contents); 190 | 191 | file_put_contents($this->getPath(), $replaceWith, $append); 192 | 193 | return $this; 194 | } 195 | } 196 | --------------------------------------------------------------------------------