Add yaml configuration.
parent
270d58124e
commit
b6bae7cc9a
|
@ -1,2 +1,2 @@
|
||||||
/app/vendor
|
/app/vendor
|
||||||
/resources/data
|
/resources/data
|
||||||
|
|
|
@ -16,14 +16,9 @@
|
||||||
"require": {
|
"require": {
|
||||||
"symfony/console": "^5.2",
|
"symfony/console": "^5.2",
|
||||||
"guzzlehttp/guzzle": "^7.3",
|
"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": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"RprtCli\\": "src"
|
"RprtCli\\": "src"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "869b5ca10e2aa08f7ca5a52359743c7c",
|
"content-hash": "3ea4e40bed89e172abc2a3ddc6ff0e5d",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/guzzle",
|
"name": "guzzlehttp/guzzle",
|
||||||
|
@ -678,6 +678,56 @@
|
||||||
],
|
],
|
||||||
"time": "2021-03-28T09:42:18+00:00"
|
"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",
|
"name": "symfony/polyfill-ctype",
|
||||||
"version": "v1.22.1",
|
"version": "v1.22.1",
|
||||||
|
@ -1189,6 +1239,64 @@
|
||||||
"utf8"
|
"utf8"
|
||||||
],
|
],
|
||||||
"time": "2021-03-17T17:12:15+00:00"
|
"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": [],
|
"packages-dev": [],
|
||||||
|
|
|
@ -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'
|
|
@ -4,13 +4,28 @@ use function DI\create;
|
||||||
use function DI\get;
|
use function DI\get;
|
||||||
|
|
||||||
use RprtCli\Commands\RprtCommand;
|
use RprtCli\Commands\RprtCommand;
|
||||||
|
use RprtCli\Utils\Configuration\ConfigurationInterface;
|
||||||
|
use RprtCli\Utils\Configuration\ConfigurationService;
|
||||||
use RprtCli\Utils\CsvReport\CsvReport;
|
use RprtCli\Utils\CsvReport\CsvReport;
|
||||||
use RprtCli\Utils\CsvReport\CsvReportInterface;
|
use RprtCli\Utils\CsvReport\CsvReportInterface;
|
||||||
|
use Symfony\Component\Yaml\Yaml;
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
|
||||||
return [
|
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),
|
\GuzzleHttp\ClientInterface::class => DI\get(\GuzzleHttp\Client::class),
|
||||||
CsvReportInterface::class => DI\get(CsvReport::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(
|
RprtCommand::class => DI\create()->constructor(
|
||||||
DI\get(CsvReportInterface::class)
|
get(CsvReportInterface::class),
|
||||||
|
get(ConfigurationInterface::class)
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
namespace RprtCli\Commands;
|
namespace RprtCli\Commands;
|
||||||
|
|
||||||
|
use RprtCli\Utils\Configuration\ConfigurationInterface;
|
||||||
use RprtCli\Utils\CsvReport\CsvReportInterface;
|
use RprtCli\Utils\CsvReport\CsvReportInterface;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
@ -16,8 +17,11 @@ class RprtCommand extends Command {
|
||||||
|
|
||||||
protected $csv;
|
protected $csv;
|
||||||
|
|
||||||
public function __construct(CsvReportInterface $csv) {
|
protected $configuration;
|
||||||
|
|
||||||
|
public function __construct(CsvReportInterface $csv, ConfigurationInterface $configuration) {
|
||||||
$this->csv = $csv;
|
$this->csv = $csv;
|
||||||
|
$this->configuration = $configuration;
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,9 +51,11 @@ class RprtCommand extends Command {
|
||||||
protected function generateTable($output, $data) {
|
protected function generateTable($output, $data) {
|
||||||
// @TODO - get configuration
|
// @TODO - get configuration
|
||||||
$table = new Table($output);
|
$table = new Table($output);
|
||||||
$table->setHeaders(['Project', 'Hours']);
|
$table->setHeaders(['Project', 'Hours', 'Rate', 'Price']);
|
||||||
$rows = [];
|
$rows = [];
|
||||||
$together = 0;
|
$together = 0;
|
||||||
|
$config = $this->configuration->get('projects');
|
||||||
|
var_dump($config);
|
||||||
foreach ($data as $project => $hours) {
|
foreach ($data as $project => $hours) {
|
||||||
$row = [$project, $hours/60];
|
$row = [$project, $hours/60];
|
||||||
$together += $hours / 60;
|
$together += $hours / 60;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
namespace RprtCli\Utils\Configuration;
|
namespace RprtCli\Utils\Configuration;
|
||||||
|
|
||||||
interface PonsapiConfigInterface
|
interface ConfigurationInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Checks for config file.
|
* Checks for config 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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue