diff --git a/src/Command/TagRebuildRunJobCommand.php b/src/Command/TagRebuildRunJobCommand.php index 840a471..9e1592b 100644 --- a/src/Command/TagRebuildRunJobCommand.php +++ b/src/Command/TagRebuildRunJobCommand.php @@ -12,11 +12,12 @@ use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\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: 'mto:agent:tags:job:run', - description: 'Run a single tag rebuild job (export tags.ndjson + build vector_tags.index) with lock' + description: 'Run a tag rebuild job (export tags.ndjson + build vector_tags.index) with lock' )] final class TagRebuildRunJobCommand extends Command { @@ -31,21 +32,42 @@ final class TagRebuildRunJobCommand extends Command protected function configure(): void { - $this->addArgument('jobId', InputArgument::REQUIRED, 'TagRebuildJob UUID'); + $this + ->addArgument('jobId', InputArgument::OPTIONAL, 'Existing TagRebuildJob UUID') + ->addOption('create', null, InputOption::VALUE_NONE, 'Create and immediately run a new TagRebuildJob'); } protected function execute(InputInterface $input, OutputInterface $output): int { - $jobId = (string) $input->getArgument('jobId'); + $jobId = $input->getArgument('jobId'); + $create = (bool) $input->getOption('create'); - /** @var TagRebuildJob|null $job */ - $job = $this->em->getRepository(TagRebuildJob::class)->find($jobId); - - if (!$job instanceof TagRebuildJob) { - $output->writeln('Job not found.'); + if (!$create && !$jobId) { + $output->writeln('You must provide either a jobId or use --create.'); return Command::FAILURE; } + if ($create && $jobId) { + $output->writeln('Use either jobId OR --create, not both.'); + return Command::FAILURE; + } + + if ($create) { + $job = new TagRebuildJob(); + $this->em->persist($job); + $this->em->flush(); + $jobId = $job->getId(); + $output->writeln('Created new TagRebuildJob: ' . $jobId . ''); + } else { + /** @var TagRebuildJob|null $job */ + $job = $this->em->getRepository(TagRebuildJob::class)->find($jobId); + + if (!$job instanceof TagRebuildJob) { + $output->writeln('Job not found.'); + return Command::FAILURE; + } + } + $fh = null; try { @@ -53,6 +75,7 @@ final class TagRebuildRunJobCommand extends Command // LOCK INITIALIZATION // --------------------------------------------------------- $lockDir = \dirname($this->lockFilePath); + if (!\is_dir($lockDir) && !@\mkdir($lockDir, 0775, true) && !\is_dir($lockDir)) { throw new \RuntimeException('Cannot create lock directory.'); } @@ -85,7 +108,7 @@ final class TagRebuildRunJobCommand extends Command throw new \RuntimeException('Export failed: NDJSON file missing.'); } - if (isset($export['count']) && (int)$export['count'] === 0) { + if (isset($export['count']) && (int) $export['count'] === 0) { throw new \RuntimeException('Export produced zero tags.'); } @@ -107,8 +130,10 @@ final class TagRebuildRunJobCommand extends Command } catch (\Throwable $e) { - $job->markFailed($e->getMessage()); - $this->em->flush(); + if (isset($job)) { + $job->markFailed($e->getMessage()); + $this->em->flush(); + } $output->writeln('FAILED: ' . $e->getMessage() . '');