Add yaml configuration.

master
Lio Novelli 2021-04-05 17:20:59 +02:00
parent 270d58124e
commit b6bae7cc9a
8 changed files with 270 additions and 13 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
/app/vendor
/resources/data
/resources/data

View File

@ -16,14 +16,9 @@
"require": {
"symfony/console": "^5.2",
"guzzlehttp/guzzle": "^7.3",
"php-di/php-di": "^6.3"
"php-di/php-di": "^6.3",
"symfony/yaml": "^5.2"
},
"repositories": [
{
"type": "vcs",
"url": "https://git.nixnet.services/l3n/RprtCli.git"
}
],
"autoload": {
"psr-4": {
"RprtCli\\": "src"

110
app/composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "869b5ca10e2aa08f7ca5a52359743c7c",
"content-hash": "3ea4e40bed89e172abc2a3ddc6ff0e5d",
"packages": [
{
"name": "guzzlehttp/guzzle",
@ -678,6 +678,56 @@
],
"time": "2021-03-28T09:42:18+00:00"
},
{
"name": "symfony/deprecation-contracts",
"version": "v2.2.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665",
"reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.2-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"files": [
"function.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"time": "2020-09-07T11:33:47+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.22.1",
@ -1189,6 +1239,64 @@
"utf8"
],
"time": "2021-03-17T17:12:15+00:00"
},
{
"name": "symfony/yaml",
"version": "v5.2.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "298a08ddda623485208506fcee08817807a251dd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/298a08ddda623485208506fcee08817807a251dd",
"reference": "298a08ddda623485208506fcee08817807a251dd",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/deprecation-contracts": "^2.1",
"symfony/polyfill-ctype": "~1.8"
},
"conflict": {
"symfony/console": "<4.4"
},
"require-dev": {
"symfony/console": "^4.4|^5.0"
},
"suggest": {
"symfony/console": "For validating YAML files using the lint command"
},
"bin": [
"Resources/bin/yaml-lint"
],
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Yaml\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Loads and dumps YAML files",
"homepage": "https://symfony.com",
"time": "2021-03-06T07:59:01+00:00"
}
],
"packages-dev": [],

View File

@ -0,0 +1,16 @@
##########################################
# Configuration file for RprtCli Command #
##########################################
tracking service:
youtrack:
auth token: '<value from youtrack hub>'
projects:
'<short name of first project>':
name: '<Project long name>'
pattern: '<pattern to match in data row>'
price: '<your wage>'
currency: 'EUR'
project column: 1
time column: 4
# time format m - minutes, h - hours
time format: 'm'

View File

@ -4,13 +4,28 @@ use function DI\create;
use function DI\get;
use RprtCli\Commands\RprtCommand;
use RprtCli\Utils\Configuration\ConfigurationInterface;
use RprtCli\Utils\Configuration\ConfigurationService;
use RprtCli\Utils\CsvReport\CsvReport;
use RprtCli\Utils\CsvReport\CsvReportInterface;
use Symfony\Component\Yaml\Yaml;
use GuzzleHttp\Client;
return [
'config.file' => 'rprt.config.yml',
'config.path' => '~/.config/rprt-cli/',
'guzzle' => create()->constructor(\GuzzleHttp\Client::class),
'yaml' => create()->constructor(\Symfony\Component\Yaml\Yaml::class),
\GuzzleHttp\ClientInterface::class => DI\get(\GuzzleHttp\Client::class),
CsvReportInterface::class => DI\get(CsvReport::class),
ConfigurationInterface::class => get(ConfigurationService::class),
ConfigurationService::class => create()->constructor(
get('config.path'),
get('config.file'),
get('yaml')
),
RprtCommand::class => DI\create()->constructor(
DI\get(CsvReportInterface::class)
get(CsvReportInterface::class),
get(ConfigurationInterface::class)
)
];

View File

@ -4,6 +4,7 @@
namespace RprtCli\Commands;
use RprtCli\Utils\Configuration\ConfigurationInterface;
use RprtCli\Utils\CsvReport\CsvReportInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
@ -16,8 +17,11 @@ class RprtCommand extends Command {
protected $csv;
public function __construct(CsvReportInterface $csv) {
protected $configuration;
public function __construct(CsvReportInterface $csv, ConfigurationInterface $configuration) {
$this->csv = $csv;
$this->configuration = $configuration;
parent::__construct();
}
@ -47,9 +51,11 @@ class RprtCommand extends Command {
protected function generateTable($output, $data) {
// @TODO - get configuration
$table = new Table($output);
$table->setHeaders(['Project', 'Hours']);
$table->setHeaders(['Project', 'Hours', 'Rate', 'Price']);
$rows = [];
$together = 0;
$config = $this->configuration->get('projects');
var_dump($config);
foreach ($data as $project => $hours) {
$row = [$project, $hours/60];
$together += $hours / 60;

View File

@ -4,7 +4,7 @@
namespace RprtCli\Utils\Configuration;
interface PonsapiConfigInterface
interface ConfigurationInterface
{
/**
* Checks for config file.

View File

@ -0,0 +1,117 @@
<?php
// src/Utils\Configuration/ConfigurationService.php
namespace RprtCli\Utils\Configuration;
use RprtCli\Utils\Configuration\ConfigurationInterface;
use Symfony\Component\Yaml\Yaml;
/**
* Read and write configuration.
*
* Check:
* - $HOME/.rprt.config.yaml
* - $HOME/.rprt/rprt.config.yaml
* - $HOME/.config/rprt-cli/rprt.config.yaml
*/
class ConfigurationService implements ConfigurationInterface
{
const PATHS = [
'/.',
'/.config/rprt-cli/',
'/.rprt/',
];
protected $data;
protected $default = null;
protected $configFilePath;
protected $configFileName;
/**
* Yaml service.
*
* @var \Symfony\Component\Yaml\Yaml;
*/
protected $yaml;
/**
* Construct method.
*/
function __construct(string $filepath, string $filename, Yaml $yaml) {
$file = $filepath . $filename;
$this->configFileName = $filename;
$this->configFilePath = $this->findConfig($file);
if ($this->configFilePath) {
$this->getConfig();
}
$this->yaml = $yaml;
}
/**
* Checks for config file.
*
* @return string|bool
* Full path to config file or FALSE if it doesn't exist.
*/
public function findConfig($filename) {
if (file_exists($filename)) {
return $filename;
}
foreach (self::PATHS as $path) {
$fullPath = $_SERVER['HOME'] . $path . $this->configFileName;
if (file_exists($fullPath)) {
return $fullPath;
}
}
// @TODO This should be some kind of error!
var_dump('Config File Not Found!');
return FALSE;
}
/**
* Get and read the configuration from file.
*/
public function getConfig() {
if ($this->configFilePath) {
var_dump($this->configFilePath);
$config = $this->yaml->parseFile($this->configFilePath);
$this->data = $config;
return TRUE;
}
// Maybe write an exception for missing config.
// Ask for reconfiguration.
// @TODO This should be some kind of error!
var_dump('Config File Path not found!');
return FALSE;
}
/**
* {@inheritdoc}
*/
public function get($key, $default = null) {
$this->default = $default;
$segments = explode('.', $key);
$data = $this->data;
foreach ($segments as $segment) {
if (isset($data[$segment])) {
$data = $data[$segment];
} else {
$data = $this->default;
break;
}
}
return $data;
}
/**
* {@inheritdoc}
*/
public function exists($key) {
return $this->get($key) !== $this->default;
}
}