Misc fixes and improvements
* Added request logging to com.noccy.apiclient * Added plugin com.noccy.watcher * Added pipe command and filter support * Fixes and stubs
This commit is contained in:
92
src/Commands/PipeCommand.php
Normal file
92
src/Commands/PipeCommand.php
Normal file
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace Spark\Commands;
|
||||
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Spark\Commands\Command;
|
||||
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("fdin", null, InputOption::VALUE_REQUIRED, "Input fd, for reading from", 0);
|
||||
$this->addOption("fdout", null, InputOption::VALUE_REQUIRED, "Output fd, for writing to", 1);
|
||||
$this->addOption("fderr", null, InputOption::VALUE_REQUIRED, "Error 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);
|
||||
});
|
||||
}
|
||||
|
||||
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 = "php://fd/".$input->getOption("fdin");
|
||||
$fdout = "php://fd/".$input->getOption("fdout");
|
||||
$fderr = "php://fd/".$input->getOption("fderr");
|
||||
|
||||
$filtername = $input->getArgument("filter");
|
||||
if ($filtername) {
|
||||
$filter = get_filter($filtername);
|
||||
} else {
|
||||
$filter = null;
|
||||
}
|
||||
|
||||
$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;
|
@ -153,6 +153,25 @@ class Environment
|
||||
}
|
||||
|
||||
SparkApplication::$instance->getPluginManager()->initializePlugins();
|
||||
|
||||
$this->loadResources();
|
||||
}
|
||||
|
||||
private function loadResources()
|
||||
{
|
||||
$resourceFile = $this->getConfigDirectory() . "/resources.json";
|
||||
if (!file_exists($resourceFile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$json = json_decode(
|
||||
file_get_contents($resourceFile),
|
||||
true
|
||||
);
|
||||
foreach ($json['resources'] as $name=>$uri) {
|
||||
[$type, $uri] = explode("+", $uri, 2);
|
||||
create_resource($name, $type, uri:$uri);
|
||||
}
|
||||
}
|
||||
|
||||
public static function createFromDirectory(string|null $directory=null, bool $parents=false): Environment
|
||||
|
@ -27,6 +27,9 @@ class ResourceManager
|
||||
|
||||
public function createNamedResource(string $name, string $type, array $options)
|
||||
{
|
||||
if (array_key_exists($name, $this->namedResources)) {
|
||||
fprintf(STDERR, "warning: Redefining named resource %s\n", $name);
|
||||
}
|
||||
$resource = $this->createResource($type, $options);
|
||||
$this->namedResources[$name] = $resource;
|
||||
return $resource;
|
||||
@ -46,4 +49,4 @@ class ResourceManager
|
||||
{
|
||||
return $this->resourceTypes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ class SparkApplication extends Application
|
||||
$this->add(new Commands\ResourcesCommand());
|
||||
$this->add(new Commands\ReplCommand());
|
||||
$this->add(new Commands\InitCommand());
|
||||
$this->add(new Commands\PipeCommand());
|
||||
|
||||
$this->get("list")->setHidden(true);
|
||||
$this->get("completion")->setHidden(true);
|
||||
|
@ -85,6 +85,7 @@ if ($doAliases) {
|
||||
$file .= "alias sparksh=\"spark repl\"\n";
|
||||
$file .= "alias sparker=\"spark run\"\n";
|
||||
$file .= "alias sparkplug=\"spark plugins\"\n";
|
||||
$file .= "alias sparkpipe=\"spark pipe\"\n";
|
||||
file_put_contents(getenv("HOME")."/.bash_aliases.new", $file);
|
||||
rename(getenv("HOME")."/.bash_aliases", getenv("HOME")."/.bash_aliases.bak");
|
||||
rename(getenv("HOME")."/.bash_aliases.new", getenv("HOME")."/.bash_aliases");
|
||||
|
Reference in New Issue
Block a user