-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from tarsana/config
add config loader to Command
- Loading branch information
Showing
14 changed files
with
320 additions
and
6 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?php namespace Tarsana\Command\Config; | ||
|
||
use Tarsana\Command\Interfaces\Config\ConfigInterface; | ||
|
||
/** | ||
* Stores and gets configuration. | ||
*/ | ||
class Config implements ConfigInterface { | ||
/** | ||
* The raw configuration data. | ||
* | ||
* @var array | ||
*/ | ||
protected $data; | ||
|
||
public function __construct(array $data) { | ||
$this->data = $data; | ||
} | ||
|
||
/** | ||
* Gets a configuration value by path. | ||
*/ | ||
public function get(string $path = null) | ||
{ | ||
if (null === $path) | ||
return $this->data; | ||
$keys = explode('.', $path); | ||
$value = $this->data; | ||
foreach ($keys as $key) { | ||
if (!is_array($value) || !array_key_exists($key, $value)) | ||
throw new \Exception("Unable to find a configuration value with path '{$path}'"); | ||
$value = $value[$key]; | ||
} | ||
return $value; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<?php namespace Tarsana\Command\Config; | ||
|
||
use Tarsana\Command\Config\Config; | ||
use Tarsana\Command\Helpers\Decoders\JsonDecoder; | ||
use Tarsana\Command\Interfaces\Config\ConfigInterface; | ||
use Tarsana\Command\Interfaces\Config\ConfigLoaderInterface; | ||
use Tarsana\IO\Interfaces\Filesystem as FilesystemInterface; | ||
|
||
/** | ||
* Loads configuration from multiple files. | ||
*/ | ||
class ConfigLoader implements ConfigLoaderInterface { | ||
|
||
protected static $decoders = [ | ||
'json' => JsonDecoder::class | ||
]; | ||
|
||
protected $fs; | ||
|
||
public function __construct(FilesystemInterface $fs) | ||
{ | ||
$this->fs = $fs; | ||
} | ||
|
||
public function load(array $paths) : ConfigInterface | ||
{ | ||
if (empty($paths)) | ||
return new Config([]); | ||
$data = []; | ||
foreach ($paths as $path) { | ||
$data[] = $this->decode($path); | ||
} | ||
$data = call_user_func_array('array_replace_recursive', $data); | ||
return new Config($data); | ||
} | ||
|
||
protected function decode(string $path) : array { | ||
if (! $this->fs->isFile($path)) | ||
return []; | ||
$file = $this->fs->file($path); | ||
$ext = $file->extension(); | ||
if (! array_key_exists($ext, static::$decoders)) | ||
throw new \Exception("Unknown configuration file extension '{$ext}'"); | ||
$decoderClass = static::$decoders[$ext]; | ||
$decoder = new $decoderClass; | ||
return $decoder->decode($file->content()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php namespace Tarsana\Command\Helpers\Decoders; | ||
|
||
use Tarsana\Command\Interfaces\Helpers\DecoderInterface; | ||
|
||
|
||
class JsonDecoder implements DecoderInterface { | ||
|
||
public function decode(string $text) : array | ||
{ | ||
return json_decode($text, true); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?php namespace Tarsana\Command\Interfaces\Config; | ||
|
||
/** | ||
* Stores and gets configuration. | ||
*/ | ||
interface ConfigInterface { | ||
/** | ||
* Gets a configuration value by path. | ||
*/ | ||
public function get(string $path); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?php namespace Tarsana\Command\Interfaces\Config; | ||
|
||
use Tarsana\Command\Interfaces\Config\ConfigInterface; | ||
|
||
/** | ||
* Loads configuration from multiple files. | ||
*/ | ||
interface ConfigLoaderInterface { | ||
|
||
public function load(array $paths) : ConfigInterface; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?php namespace Tarsana\Command\Interfaces\Helpers; | ||
|
||
|
||
interface DecoderInterface { | ||
|
||
public function decode(string $text) : array; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php namespace Tarsana\Command\Tests\Acceptance; | ||
|
||
use Tarsana\Command\Command as C; | ||
use Tarsana\Tester\CommandTestCase; | ||
|
||
|
||
class LoadsConfigurationTest extends CommandTestCase { | ||
|
||
public function test_it_loads_configuration() { | ||
$c = C::create(function($app) { | ||
$app->configPaths(['/home/user/.config.json', 'config.json']); | ||
|
||
$name = $app->config('name'); | ||
$repoURL = $app->config('repo.url'); | ||
$app->console()->line("{$name}:{$repoURL}"); | ||
}); | ||
|
||
$this->fs | ||
->file('/home/user/.config.json', true) | ||
->content(json_encode(['name' => 'user'])); | ||
|
||
$this->fs | ||
->file('config.json', true) | ||
->content(json_encode(['repo' => ['url' => 'tarsana']])); | ||
|
||
$this->command($c) | ||
->prints('user:tarsana<br>'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<?php namespace Tarsana\Command\Tests\Unit\Config; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use Tarsana\Command\Config\Config; | ||
use Tarsana\Command\Config\ConfigLoader; | ||
use Tarsana\IO\Filesystem; | ||
use Tarsana\IO\Filesystem\Adapters\Memory; | ||
|
||
|
||
class ConfigLoaderTest extends TestCase { | ||
|
||
protected $fs; | ||
protected $loader; | ||
|
||
public function setUp() { | ||
$adapter = new Memory; | ||
$adapter->mkdir('.', 0777, true); | ||
$this->fs = new Filesystem('.', $adapter); | ||
$this->loader = new ConfigLoader($this->fs); | ||
} | ||
|
||
public function test_it_loads_single_config() { | ||
$data = ['name' => 'foo', 'repo' => 'bar']; | ||
$this->fs->file('config.json', true) | ||
->content(json_encode($data)); | ||
$this->assertEquals($data, $this->loader->load(['config.json'])->get()); | ||
} | ||
|
||
public function test_it_loads_many_configs() { | ||
$data1 = ['name' => 'foo', 'repo' => 'bar']; | ||
$data2 = ['repo' => ['type' => 'git']]; | ||
$data3 = ['repo' => ['name' => 'baz'], 'descr' => 'blabla']; | ||
$merged = ['name' => 'foo', 'repo' => ['type' => 'git', 'name' => 'baz'], 'descr' => 'blabla']; | ||
|
||
$this->fs->file('/opt/command/config.json', true)->content(json_encode($data1)); | ||
$this->fs->file('/home/user/config.json', true)->content(json_encode($data2)); | ||
$this->fs->file('config.json', true)->content(json_encode($data3)); | ||
|
||
$this->assertEquals($merged, $this->loader->load([ | ||
'/opt/command/config.json', | ||
'/home/user/config.json', | ||
'/projects/config.json', // this is missing | ||
'config.json' | ||
])->get()); | ||
} | ||
|
||
public function test_it_loads_empty_config_when_no_path_is_given() { | ||
$this->assertEquals([], $this->loader->load([])->get()); | ||
} | ||
|
||
/** | ||
* @expectedException Exception | ||
*/ | ||
public function test_it_throws_exception_when_unknown_extension() { | ||
$this->fs->file('config.xml', true); | ||
$this->loader->load(['config.xml']); | ||
} | ||
|
||
} |
Oops, something went wrong.