124 lines
4.0 KiB
PHP
124 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace Spark\Commands;
|
|
|
|
use Symfony\Component\Console\Attribute\AsCommand;
|
|
use Spark\Commands\Command;
|
|
use Spark\Pipe\Filters\ProgressFilter;
|
|
use Spark\Pipe\Pipeline;
|
|
use Symfony\Component\Console\Input\InputArgument;
|
|
use Symfony\Component\Console\Input\InputInterface;
|
|
use Symfony\Component\Console\Input\InputOption;
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
|
|
|
#[AsCommand(name:'pipe', description:'Filter or analyze data piped through the command')]
|
|
class PipeCommand extends Command
|
|
{
|
|
public static string $HelpText;
|
|
|
|
protected function configure()
|
|
{
|
|
$this->addOption("list-filters", null, InputOption::VALUE_NONE, "List the defined filters");
|
|
$this->addOption("input", "i", InputOption::VALUE_REQUIRED, "Input file or fd, for reading from", 0);
|
|
$this->addOption("output", "o", InputOption::VALUE_REQUIRED, "Output file or fd, for writing to", 1);
|
|
$this->addOption("error", "e", InputOption::VALUE_REQUIRED, "Error file or fd, for progress report and status", 2);
|
|
$this->addArgument("filter", InputArgument::OPTIONAL, "Pipe filter");
|
|
$this->addArgument("args", InputArgument::OPTIONAL|InputArgument::IS_ARRAY, "Arguments to the script");
|
|
$this->registerDefaultFilters();
|
|
$this->setHelp(self::$HelpText);
|
|
}
|
|
|
|
private function registerDefaultFilters()
|
|
{
|
|
register_filter("base64encode", "base64_encode");
|
|
register_filter("base64decode", "base64_decode");
|
|
register_filter("passwordhash", function ($in) {
|
|
$trimmed = rtrim($in, "\n\r");
|
|
$hashed = password_hash($trimmed, PASSWORD_BCRYPT);
|
|
return str_replace($trimmed, $hashed, $in);
|
|
});
|
|
register_filter("progress", ProgressFilter::class);
|
|
}
|
|
|
|
protected function execute(InputInterface $input, OutputInterface $output)
|
|
{
|
|
$env = $this->getEnvironment();
|
|
|
|
if ($input->getOption("list-filters")) {
|
|
$output->writeln(join(" ", get_registered_filters()));
|
|
return Command::SUCCESS;
|
|
}
|
|
|
|
$fdin = $input->getOption("input");
|
|
$fdout = $input->getOption("output");
|
|
$fderr = $input->getOption("error");
|
|
|
|
|
|
$filterargs = $input->getArgument('args');
|
|
$args = [];
|
|
foreach ($filterargs as $arg) {
|
|
if (str_contains($arg, '=')) {
|
|
[$k,$v] = explode("=", $arg, 2);
|
|
$args[$k] = $v;
|
|
} else {
|
|
if (str_starts_with($arg, 'no-')) {
|
|
$args[substr($arg,3)] = false;
|
|
} else {
|
|
$args[$arg] = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
$filtername = $input->getArgument("filter");
|
|
if ($filtername) {
|
|
$filter = get_filter($filtername, $args);
|
|
} else {
|
|
$filter = null;
|
|
}
|
|
|
|
|
|
$pipeline = new Pipeline();
|
|
$pipeline->setInputFile($fdin);
|
|
$pipeline->setOutputFile($fdout);
|
|
if ($filter) {
|
|
$pipeline->addFilter($filter);
|
|
}
|
|
|
|
$pipeline->run();
|
|
|
|
/*
|
|
$fin = fopen($fdin, "rb");
|
|
$fout = fopen($fdout, "wb");
|
|
while (!feof($fin)) {
|
|
$buf = fgets($fin);
|
|
if (is_callable($filter)) $buf = $filter($buf);
|
|
fputs($fout, $buf);
|
|
}
|
|
*/
|
|
|
|
return Command::SUCCESS;
|
|
}
|
|
}
|
|
|
|
PipeCommand::$HelpText = <<<HELP
|
|
|
|
The <info>pipe</> command is used to filter data, or to track piping of data.
|
|
|
|
\$ <comment>echo "mypassword" | spark pipe hashpassword > hashedpassword.txt</>
|
|
\$ <comment>cat file.sql | spark pipe sqlinfo | mysql</>
|
|
\$ <comment>cat input | spark pipe progress sizefrom=input | somecommand</>
|
|
|
|
<options=bold>Registering filters</>
|
|
|
|
To register a new filter, use the <info>register_filter</> helper function:
|
|
|
|
<comment>register_filter("myfilter", function (\$in) {
|
|
return strtolower(\$in);
|
|
});</>
|
|
|
|
The filter will be available like any built-in:
|
|
|
|
<comment>\$ cat file | spark pipe myfilter > outfile</>
|
|
|
|
HELP;
|