Skip to content

Commit

Permalink
Initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcinOrlowski committed Apr 14, 2016
0 parents commit d8ec16e
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.idea/

# Vagrant VM
.vagrant/

# Vim tmp files
*.swp

# Composer files
vendor/
composer.lock
80 changes: 80 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# DotEnv building Helper #

DotEnv file (`.env`) are often used as runtime configuration files (i.e. Laravel based PHP projects)
and are not stored in your repository, so if you use Continuous Integration (CI) tools like Team City,
you need to create that `.env` file before tests can be started. DotEnv Helper is created to help
you with step.

The main assumption is that you usually have file like `.env.dist` in your repository (so people
know how to create production `.env`). DotEnv helper reads that file and tries to get values
for keys present in the file by looking into environmental variables or command line arguments
to produce populated, ready to use DotEnv file. Having `.env` created that way lets you keep all
needed runtime configuration (i.e. API keys etc) directly in CI configuration, in run step in Team City.

**NOTE:** To avoid accidental overwrites this tool only echoes content of echoed file, so to create
physical `.env` file for your code you need to redirect stdout with regular ` ... > .env`.

## Env variable subsitution ##

Let's assume our `.env.dist` looks like this:

KEY=val
BAR=zen
FOO=

then knowing you want to have own value set for `KEY` you set your build
step in CI as shell script:

export KEY=bar
vendor/bin/process-env .env.dist > .env

which shall produce `.env` file with content as follow:

KEY=bar
BAR=zen
FOO=

As you noticed, original value of `KEY` is replaced with what we provided, while `BAR`
and `FOO`, for which we did not provide replacements, were copied unaltered.


## Argument subsitution ##

Aside of env variables you can also pass `key=val` arguments to `process-env` achieve the same
goal:

vendor/bin/process-env .env.dist KEY=bar > .env

**IMPORTANT:** first argument always refers to source env file.


## Combined substitution ##

Both substitution methods can be used together. When key is provided as argument and
also exists as Env variable, then command line provided value will be used:

export KEY=bar
vendor/bin/process-env .env.dist KEY=foo > .env

will produce:

KEY=foo
BAR=zen
FOO=


## Installation ##

Use composer to install this package as your development dependency:

composer require --dev marcin-orlowski/dotenv-helper


It will install `process-env` script in usual `vendor/bin` folder.


## License ##

* Written and copyrighted by Marcin Orlowski
* Response Builder is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)

101 changes: 101 additions & 0 deletions bin/process-env
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!//usr/bin/php -q
<?php
/**
* Little tool to help build DotEnv files from templates
*
* @author Marcin Orlowski <mail (#) marcinorlowski (.) com>
* @copyright 2016 Marcin Orlowski
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link https://github.com/MarcinOrlowski/dotenv-helper
*/

/**
* Aborts script execution with custom message and return code.
*
* @param string $msg Message to display.
* @param integer $code Code to be returned.
*
* @return void
*/
function abort($msg, $code = 1)
{
echo $msg;
exit($code);
}

/******************************************************/

if ($_SERVER['argc'] < 2) {
abort(sprintf("Usage: %s .env.dist [KEY=VAL KEY2=VAL2...]\n", $_SERVER['argv'][0]));
}

$file_in = $_SERVER['argv'][1];

if (file_exists($file_in)) {
$content = file($file_in, FILE_IGNORE_NEW_LINES);
$out = [];
if ($content !== false) {
// key=val mapping built from provided arguments
$map = [];

// if key=val mappings are given as argument, populate
// $map array with this data
if ($_SERVER['argc'] > 2) {
for ($i = 2; $i < $_SERVER['argc']; $i++) {
$entry = $_SERVER['argv'][ $i ];
$pos = strpos($entry, '=');
if ($pos !== false) {
$key = substr($entry, 0, $pos);
$val = substr($entry, ($pos + 1));
$map[ $key ] = $val;
}
}
}

foreach ($content as $line) {
switch (substr(trim($line), 0, 1)) {
// copy comment lines unprocessed
case '#':
$out[] = $line;
break;

default:
$pos = strpos($line, '=');
$new_val = null;

// if we have assignment entry, check if there's
// anything matching in $map. If not, look for env
// variable with that name. If still nothing found
// copy it as is
if ($pos !== false) {
$key = substr($line, 0, $pos);
if (array_key_exists($key, $map)) {
$new_val = "{$key}={$map[$key]}";
} else {
$val = getenv($key);
if ($val !== false) {
$new_val = "{$key}={$val}";
}
}
}

if (is_null($new_val)) {
$new_val = $line;
}

$out[] = $new_val;
break;
}
}

// output content of processed .env
echo implode("\n", $out);
} else {
abort("Failed processing '{$file_in}' source file\n");
}
} else {
abort("Source file '{$file_in}' not found\n");
}

// done
exit(0);
30 changes: 30 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "marcin-orlowski/dotenv-helper",
"description": "Little tool to help build DotEnv (.env) files from templates",
"minimum-stability": "stable",
"license": "MIT",
"keywords": [
"dotenv",
"laravel",
"helper",
"continous-integration",
"ci",
"teamcity",
"travis",
"dev-tools"
],
"bin": [
"bin/process-env"
],
"authors": [
{
"name": "Marcin Orlowski"
}
],
"require": {
"php": ">=5.1.2"
},
"require-dev": {
"marcin-orlowski/coding-standard": "^1.0"
}
}

0 comments on commit d8ec16e

Please sign in to comment.