Skip to content

Commit

Permalink
Merge pull request #321 from GrahamCampbell/direct-load
Browse files Browse the repository at this point in the history
Support direct loading with a string
  • Loading branch information
GrahamCampbell authored Jan 24, 2019
2 parents 13be13d + 2e03131 commit 736602f
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 32 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "3.1-dev"
"dev-master": "3.2-dev"
}
}
}
67 changes: 67 additions & 0 deletions src/Environment/Adapter/ArrayAdapter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace Dotenv\Environment\Adapter;

use PhpOption\None;
use PhpOption\Some;

class ArrayAdapter implements AdapterInterface
{
/**
* The variables and their values.
*
* @return array<string|null>
*/
private $variables = [];

/**
* Determines if the adapter is supported.
*
* @return bool
*/
public function isSupported()
{
return true;
}

/**
* Get an environment variable, if it exists.
*
* @param string $name
*
* @return \PhpOption\Option
*/
public function get($name)
{
if (array_key_exists($name, $this->variables)) {
return Some::create($this->variables[$name]);
}

return None::create();
}

/**
* Set an environment variable.
*
* @param string $name
* @param string|null $value
*
* @return void
*/
public function set($name, $value = null)
{
$this->variables[$name] = $value;
}

/**
* Clear an environment variable.
*
* @param string $name
*
* @return void
*/
public function clear($name)
{
unset($this->variables[$name]);
}
}
33 changes: 23 additions & 10 deletions src/Loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,29 +79,45 @@ public function setImmutable($immutable = false)
}

/**
* Load `.env` file in given directory.
* Load the environment file from disk.
*
* @throws \Dotenv\Exception\InvalidPathException|\Dotenv\Exception\InvalidFileException
*
* @return array<string|null>
*/
public function load()
{
return $this->loadDirect(
self::findAndRead($this->filePaths)
);
}

/**
* Directly load the given string.
*
* @param string $content
*
* @throws \Dotenv\Exception\InvalidFileException
*
* @return array<string|null>
*/
public function loadDirect($content)
{
return $this->processEntries(
Lines::process(self::readLines($this->filePaths))
Lines::process(preg_split("/(\r\n|\n|\r)/", $content))
);
}

/**
* Attempt to read the lines from the files in order.
* Attempt to read the files in order.
*
* @param string[] $filePaths
*
* @throws \Dotenv\Exception\InvalidPathException
*
* @return string[]
*/
private static function readLines(array $filePaths)
private static function findAndRead(array $filePaths)
{
if ($filePaths === []) {
throw new InvalidPathException('At least one environment file path must be provided.');
Expand All @@ -120,20 +136,17 @@ private static function readLines(array $filePaths)
}

/**
* Read from the file, auto detecting line endings.
* Read the given file.
*
* @param string $filePath
*
* @return \PhpOption\Option
*/
private static function readFromFile($filePath)
{
$autodetect = ini_get('auto_detect_line_endings');
ini_set('auto_detect_line_endings', '1');
$lines = @file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
ini_set('auto_detect_line_endings', $autodetect);
$content = @file_get_contents($filePath);

return Option::fromValue($lines, false);
return Option::fromValue($content, false);
}

/**
Expand Down
23 changes: 2 additions & 21 deletions tests/Dotenv/LinesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,9 @@

class LinesTest extends TestCase
{
/**
* @var string|false
*/
protected $autodetect;

public function setUp()
{
$this->autodetect = ini_get('auto_detect_line_endings');
ini_set('auto_detect_line_endings', '1');
}

public function tearDown()
{
ini_set('auto_detect_line_endings', $this->autodetect);
}

public function testProcess()
{
$content = file(
dirname(__DIR__).'/fixtures/env/assertions.env',
FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES
);
$content = file_get_contents(dirname(__DIR__).'/fixtures/env/assertions.env');

$expected = [
'ASSERTVAR1=val1',
Expand All @@ -40,6 +21,6 @@ public function testProcess()
"ASSERTVAR9=\"\n\"",
];

$this->assertSame($expected, Lines::process($content));
$this->assertSame($expected, Lines::process(preg_split("/(\r\n|\n|\r)/", $content)));
}
}
21 changes: 21 additions & 0 deletions tests/Dotenv/LoaderTest.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

use Dotenv\Environment\Adapter\ArrayAdapter;
use Dotenv\Environment\DotenvFactory;
use Dotenv\Loader;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -124,4 +125,24 @@ public function testLoaderWithOneGoodPath()

$this->assertCount(4, $loader->load());
}

public function testLoaderWithNoAdapters()
{
$loader = (new Loader([], new DotenvFactory([])));

$content = "NVAR1=\"Hello\"\nNVAR2=\"World!\"\nNVAR3=\"{\$NVAR1} {\$NVAR2}\"\nNVAR4=\"\${NVAR1} \${NVAR2}\"";
$expected = ['NVAR1' => 'Hello', 'NVAR2' => 'World!', 'NVAR3' => '{$NVAR1} {$NVAR2}', 'NVAR4' => '${NVAR1} ${NVAR2}'];

$this->assertSame($expected, $loader->loadDirect($content));
}

public function testLoaderWithArrayAdapter()
{
$loader = (new Loader([], new DotenvFactory([new ArrayAdapter()])));

$content = "NVAR1=\"Hello\"\nNVAR2=\"World!\"\nNVAR3=\"{\$NVAR1} {\$NVAR2}\"\nNVAR4=\"\${NVAR1} \${NVAR2}\"";
$expected = ['NVAR1' => 'Hello', 'NVAR2' => 'World!', 'NVAR3' => '{$NVAR1} {$NVAR2}', 'NVAR4' => 'Hello World!'];

$this->assertSame($expected, $loader->loadDirect($content));
}
}
3 changes: 3 additions & 0 deletions tests/fixtures/env/assertions.env
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
ASSERTVAR1=val1

ASSERTVAR2=""

ASSERTVAR3="val3 "
ASSERTVAR4="0" # empty looking value
ASSERTVAR5=#foo
ASSERTVAR6="val1
val2"
ASSERTVAR7="
val3" #


ASSERTVAR8="val3
"
ASSERTVAR9="
Expand Down

0 comments on commit 736602f

Please sign in to comment.