X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=vendor%2Fpsy%2Fpsysh%2Fsrc%2FPsy%2FCommand%2FEditCommand.php;fp=vendor%2Fpsy%2Fpsysh%2Fsrc%2FPsy%2FCommand%2FEditCommand.php;h=a1c6ee4345ae397e7be3b85510445974915e29cf;hp=0000000000000000000000000000000000000000;hb=9917807b03b64faf00f6a1f29dcb6eafc454efa5;hpb=aea91e65e895364e460983b890e295aa5d5540a5 diff --git a/vendor/psy/psysh/src/Psy/Command/EditCommand.php b/vendor/psy/psysh/src/Psy/Command/EditCommand.php new file mode 100644 index 000000000..a1c6ee434 --- /dev/null +++ b/vendor/psy/psysh/src/Psy/Command/EditCommand.php @@ -0,0 +1,187 @@ +runtimeDir = $runtimeDir; + } + + protected function configure() + { + $this + ->setName('edit') + ->setDefinition(array( + new InputArgument('file', InputArgument::OPTIONAL, 'The file to open for editing. If this is not given, edits a temporary file.', null), + new InputOption( + 'exec', + 'e', + InputOption::VALUE_NONE, + 'Execute the file content after editing. This is the default when a file name argument is not given.', + null + ), + new InputOption( + 'no-exec', + 'E', + InputOption::VALUE_NONE, + 'Do not execute the file content after editing. This is the default when a file name argument is given.', + null + ), + )) + ->setDescription('Open an external editor. Afterwards, get produced code in input buffer.') + ->setHelp('Set the EDITOR environment variable to something you\'d like to use.'); + } + + /** + * @param InputInterface $input + * @param OutputInterface $output + * + * @throws \InvalidArgumentException when both exec and no-exec flags are given or if a given variable is not found in the current context + * @throws \UnexpectedValueException if file_get_contents on the edited file returns false instead of a string + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + if ($input->getOption('exec') && + $input->getOption('no-exec')) { + throw new \InvalidArgumentException('The --exec and --no-exec flags are mutually exclusive.'); + } + + $filePath = $this->extractFilePath($input->getArgument('file')); + + $execute = $this->shouldExecuteFile( + $input->getOption('exec'), + $input->getOption('no-exec'), + $filePath + ); + + $shouldRemoveFile = false; + + if ($filePath === null) { + $filePath = tempnam($this->runtimeDir, 'psysh-edit-command'); + $shouldRemoveFile = true; + } + + $editedContent = $this->editFile($filePath, $shouldRemoveFile); + + if ($execute) { + $this->getApplication()->addInput($editedContent); + } + } + + /** + * @param bool $execOption + * @param bool $noExecOption + * @param string|null $filePath + * + * @return bool + */ + private function shouldExecuteFile($execOption, $noExecOption, $filePath) + { + if ($execOption) { + return true; + } + + if ($noExecOption) { + return false; + } + + // By default, code that is edited is executed if there was no given input file path + return $filePath === null; + } + + /** + * @param string|null $fileArgument + * + * @return string|null The file path to edit, null if the input was null, or the value of the referenced variable + * + * @throws \InvalidArgumentException If the variable is not found in the current context + */ + private function extractFilePath($fileArgument) + { + // If the file argument was a variable, get it from the context + if ($fileArgument !== null && + strlen($fileArgument) > 0 && + $fileArgument[0] === '$') { + $fileArgument = $this->context->get(preg_replace('/^\$/', '', $fileArgument)); + } + + return $fileArgument; + } + + /** + * @param string $filePath + * @param string $shouldRemoveFile + * + * @return string + * + * @throws \UnexpectedValueException if file_get_contents on $filePath returns false instead of a string + */ + private function editFile($filePath, $shouldRemoveFile) + { + $escapedFilePath = escapeshellarg($filePath); + + $pipes = array(); + $proc = proc_open((getenv('EDITOR') ?: 'nano') . " {$escapedFilePath}", array(STDIN, STDOUT, STDERR), $pipes); + proc_close($proc); + + $editedContent = @file_get_contents($filePath); + + if ($shouldRemoveFile) { + @unlink($filePath); + } + + if ($editedContent === false) { + throw new \UnexpectedValueException("Reading {$filePath} returned false"); + } + + return $editedContent; + } + + /** + * Set the Context reference. + * + * @param Context $context + */ + public function setContext(Context $context) + { + $this->context = $context; + } +}