first commit

This commit is contained in:
2024-07-15 12:33:27 +02:00
commit ce50ae282b
22084 changed files with 2623791 additions and 0 deletions

View File

@@ -0,0 +1,140 @@
<?php
namespace Grasmash\YamlCli\Command;
use Dflydev\DotAccessData\Data;
use Grasmash\YamlCli\Loader\JsonFileLoader;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Yaml\Yaml;
/**
* Class CommandBase
*
* @package Grasmash\YamlCli\Command
*/
abstract class CommandBase extends Command
{
/** @var Filesystem */
protected $fs;
/**
* @var InputInterface
*/
protected $input;
/**
* @var OutputInterface
*/
protected $output;
/** @var FormatterHelper */
protected $formatter;
/**
* Initializes the command just after the input has been validated.
*
* @param InputInterface $input An InputInterface instance
* @param OutputInterface $output An OutputInterface instance
*/
protected function initialize(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
$this->output = $output;
$this->formatter = $this->getHelper('formatter');
$this->fs = new Filesystem();
}
/**
* Loads a yaml file.
*
* @param $filename
* The file name.
*
* @return array|bool
* The parsed content of the yaml file. FALSE if an error occured.
*/
public function loadYamlFile($filename)
{
if (!file_exists($filename)) {
$this->output->writeln("<error>The file $filename does not exist.</error>");
return false;
}
try {
$contents = Yaml::parse(file_get_contents($filename));
} catch (\Exception $e) {
$this->output->writeln("<error>There was an error parsing $filename. The contents are not valid YAML.</error>");
$this->output->writeln($e->getMessage());
return false;
}
return $contents;
}
/**
* Writes YAML data to a file.
*
* @param string $filename
* The filename.
* @param Data $data
* The YAML file contents.
*
* @return bool
* TRUE if file was written successfully. Otherwise, FALSE.
*/
public function writeYamlFile($filename, $data)
{
try {
// @todo Allow the inline and indent variables to be set via command line option.
$yaml = Yaml::dump($data->export(), 3, 2);
} catch (\Exception $e) {
$this->output->writeln("<error>There was an error dumping the YAML contents for $filename.</error>");
$this->output->writeln($e->getMessage());
return false;
}
try {
// @todo Use Symfony file system instead so that exceptions can be caught.
file_put_contents($filename, $yaml);
} catch (\Exception $e) {
$this->output->writeln("<error>There was an writing to $filename.</error>");
$this->output->writeln($e->getMessage());
return false;
}
return true;
}
/**
* Checks if a key exists in an array.
*
* Supports dot notation for keys. E.g., first.second.parts.
*
* @param array $data
* The array of data that may contain key.
* @param string $key
* The array key, optionally in dot notation format.
*
* @return bool
*
*/
protected function checkKeyExists($data, $key)
{
if (!$data->has($key)) {
$this->output->writeln("<error>The key $key does not exist.");
return false;
}
return true;
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace Grasmash\YamlCli\Command;
use Dflydev\DotAccessData\Data;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Class GetTypeCommand
*
* @package Grasmash\YamlCli\Command
*/
class GetTypeCommand extends CommandBase
{
/**
* {inheritdoc}
*/
protected function configure()
{
$this
->setName('get:type')
->setDescription('Get the type of a value for a specific key in a YAML file.')
->addUsage("path/to/file.yml example.key")
->addArgument(
'filename',
InputArgument::REQUIRED,
"The filename of the YAML file"
)
->addArgument(
'key',
InputArgument::REQUIRED,
"The key for the value to get the type of, in dot notation."
);
}
/**
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
*
* @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$filename = $input->getArgument('filename');
$key = $input->getArgument('key');
$yaml_parsed = $this->loadYamlFile($filename);
if (!$yaml_parsed) {
// Exit with a status of 1.
return 1;
}
$data = new Data($yaml_parsed);
if (!$this->checkKeyExists($data, $key)) {
return 1;
}
$value = $data->get($key);
$output->writeln(trim(gettype($value)));
return 0;
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace Grasmash\YamlCli\Command;
use Dflydev\DotAccessData\Data;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Yaml\Yaml;
/**
* Class CreateProjectCommand
*
* @package Grasmash\YamlCli\Command
*/
class GetValueCommand extends CommandBase
{
/**
* {inheritdoc}
*/
protected function configure()
{
$this
->setName('get:value')
->setDescription('Get a value for a specific key in a YAML file.')
->addUsage("path/to/file.yml example.key")
->addArgument(
'filename',
InputArgument::REQUIRED,
"The filename of the YAML file"
)
->addArgument(
'key',
InputArgument::REQUIRED,
"The key for the value to get, in dot notation."
);
}
/**
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
*
* @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$filename = $input->getArgument('filename');
$key = $input->getArgument('key');
$yaml_parsed = $this->loadYamlFile($filename);
if (!$yaml_parsed) {
// Exit with a status of 1.
return 1;
}
$data = new Data($yaml_parsed);
if (!$this->checkKeyExists($data, $key)) {
return 1;
}
$value = $data->get($key);
$output->writeln(trim(Yaml::dump($value)));
return 0;
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace Grasmash\YamlCli\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Class CreateProjectCommand
*
* @package Grasmash\YamlCli\Command
*/
class LintCommand extends CommandBase
{
/**
* {inheritdoc}
*/
protected function configure()
{
$this
->setName('lint')
->setDescription('Validates that a given YAML file has valid syntax.')
->addUsage("path/to/file.yml")
->addArgument(
'filename',
InputArgument::REQUIRED,
"The filename of the YAML file"
);
}
/**
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
*
* @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$filename = $input->getArgument('filename');
$yaml_parsed = $this->loadYamlFile($filename);
if (!$yaml_parsed) {
// Exit with a status of 1.
return 1;
}
if (OutputInterface::VERBOSITY_VERBOSE === $output->getVerbosity()) {
$output->writeln("<info>The file $filename contains valid YAML.</info>");
}
return 0;
}
}

View File

@@ -0,0 +1,70 @@
<?php
namespace Grasmash\YamlCli\Command;
use Dflydev\DotAccessData\Data;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Class CreateProjectCommand
*
* @package Grasmash\YamlCli\Command
*/
class UnsetKeyCommand extends CommandBase
{
/**
* {inheritdoc}
*/
protected function configure()
{
$this
->setName('unset:key')
->setDescription('Unset a specific key in a YAML file.')
->addUsage("path/to/file.yml")
->addArgument(
'filename',
InputArgument::REQUIRED,
"The filename of the YAML file"
)
->addArgument(
'key',
InputArgument::REQUIRED,
"The key to unset, in dot notation"
);
}
/**
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
*
* @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$filename = $input->getArgument('filename');
$key = $input->getArgument('key');
$yaml_parsed = $this->loadYamlFile($filename);
if (!$yaml_parsed) {
// Exit with a status of 1.
return 1;
}
$data = new Data($yaml_parsed);
if (!$this->checkKeyExists($data, $key)) {
$this->output->writeln("<error>The key '$key' does not exist in $filename.</error>");
return 1;
}
$data->remove($key);
if ($this->writeYamlFile($filename, $data)) {
$this->output->writeln("<info>The key '$key' was removed from $filename.</info>");
return 0;
}
return 1;
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Grasmash\YamlCli\Command;
use Dflydev\DotAccessData\Data;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Class CreateProjectCommand
*
* @package Grasmash\YamlCli\Command
*/
class UpdateKeyCommand extends CommandBase
{
/**
* {inheritdoc}
*/
protected function configure()
{
$this
->setName('update:key')
->setDescription('Update a specific key in a YAML file.')
->addUsage("path/to/file.yml example.key example.new-key")
->addArgument(
'filename',
InputArgument::REQUIRED,
"The filename of the YAML file"
)
->addArgument(
'key',
InputArgument::REQUIRED,
"The original key, in dot notation"
)
->addArgument(
'new-key',
InputArgument::REQUIRED,
"The new key, in dot notation"
);
}
/**
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
*
* @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$filename = $input->getArgument('filename');
$key = $input->getArgument('key');
$new_key = $input->getArgument('new-key');
$yaml_parsed = $this->loadYamlFile($filename);
if (!$yaml_parsed) {
// Exit with a status of 1.
return 1;
}
$data = new Data($yaml_parsed);
if (!$this->checkKeyExists($data, $key)) {
$this->output->writeln("<error>The key '$key' does not exist in $filename.</error>");
return 1;
}
$value = $data->get($key);
$data->set($new_key, $value);
$data->remove($key);
if ($this->writeYamlFile($filename, $data)) {
$this->output->writeln("<info>The key '$key' was changed to '$new_key' in $filename.</info>");
return 0;
}
return 1;
}
}

View File

@@ -0,0 +1,94 @@
<?php
namespace Grasmash\YamlCli\Command;
use Dflydev\DotAccessData\Data;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Class CreateProjectCommand
*
* @package Grasmash\YamlCli\Command
*/
class UpdateValueCommand extends CommandBase
{
/**
* {inheritdoc}
*/
protected function configure()
{
$this
->setName('update:value')
->setDescription('Update the value for a specific key in a YAML file.')
->addUsage("path/to/file.yml example.key 'new value for example.key'")
->addArgument(
'filename',
InputArgument::REQUIRED,
"The filename of the YAML file"
)
->addArgument(
'key',
InputArgument::REQUIRED,
"The key for the value to set, in dot notation"
)
->addArgument(
'value',
InputArgument::REQUIRED,
"The new value"
)
->addOption('type', 't', InputOption::VALUE_REQUIRED, 'Set the variable type for the value. Accepted types are int, integer, bool, boolean, str, and string.');
}
/**
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
*
* @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$filename = $input->getArgument('filename');
$key = $input->getArgument('key');
$raw_value = $input->getArgument('value');
$yaml_parsed = $this->loadYamlFile($filename);
if ($yaml_parsed === false) {
// Exit with a status of 1.
return 1;
}
$data = new Data($yaml_parsed);
$value = $raw_value;
if ($type = $input->getOption('type')) {
$value = match ($type) {
'int', 'integer' => (int) $raw_value,
'bool', 'boolean' => (bool) $raw_value,
'float', 'double', 'real' => (float) $raw_value,
'str', 'string' => (string) $raw_value,
'null' => null,
default => throw new RuntimeException('The option type must have a value of int, integer, bool, or boolean.'),
};
} elseif (strtolower($value) === 'false') {
$value = false;
} elseif (strtolower($value) === 'true') {
$value = true;
} elseif (strtolower($value) === 'null') {
$value = null;
}
$data->set($key, $value);
if ($this->writeYamlFile($filename, $data)) {
$this->output->writeln("<info>The value for key '$key' was set to '$raw_value' (" . gettype($value) . ") in $filename.</info>");
return 0;
}
return 1;
}
}