/** * @return int|void */ public function __invoke() { $currentExercise = $this->userState->getCurrentExercise(); $exercise = $this->exerciseRepository->findByName($currentExercise); $markDown = file_get_contents($exercise->getProblem()); $doc = $this->markdownRenderer->render($markDown); $doc = str_replace('{appname}', $this->appName, $doc); $this->output->write($doc); }
/** * @return int|void */ public function __invoke() { if (!$this->userState->isAssignedExercise()) { $this->output->printError("No active exercises. Select one from the menu"); return 1; } $currentExercise = $this->userState->getCurrentExercise(); $exercise = $this->exerciseRepository->findByName($currentExercise); $markDown = file_get_contents($exercise->getProblem()); $doc = $this->markdownRenderer->render($markDown); $doc = str_replace('{appname}', $this->appName, $doc); $this->output->write($doc); }
/** * @param CliMenu $menu */ public function __invoke(CliMenu $menu) { $menu->close(); $item = $menu->getSelectedItem(); $exercise = $this->exerciseRepository->findByName($item->getText()); $exercises = $this->exerciseRepository->findAll(); $this->userState->setCurrentExercise($item->getText()); $this->userStateSerializer->serialize($this->userState); $numExercises = count($exercises); $exerciseIndex = array_search($exercise, $exercises) + 1; $output = "\n"; $output .= $this->color->__invoke(' LEARN YOU THE PHP FOR MUCH WIN! ')->magenta()->bold() . "\n"; $output .= $this->color->__invoke('*********************************')->magenta()->bold() . "\n"; $output .= "\n"; $output .= $this->color->__invoke(" " . $exercise->getName())->yellow()->bold() . "\n"; $output .= $this->color->__invoke(sprintf(" Exercise %d of %d\n\n", $exerciseIndex, $numExercises))->yellow(); $content = file_get_contents($exercise->getProblem()); $doc = $this->markdownRenderer->render($content); $doc = str_replace('{appname}', $this->appName, $doc); $output .= $doc; $output .= "\n"; $output .= $this->helpLine('To print these instructions again, run', 'print'); $output .= $this->helpLine('To execute your program in a test environment, run', 'run program.php'); $output .= $this->helpLine('To verify your program, run', 'verify program.php'); $output .= $this->helpLine('For help run', 'help'); $output .= "\n\n"; $this->output->write($output); }
/** * @param ExerciseInterface $exercise * @param UserState $userState * @param OutputInterface $output */ private function renderSuccessInformation(ExerciseInterface $exercise, UserState $userState, OutputInterface $output) { $output->emptyLine(); $output->writeLine($this->style(" PASS!", ['green', 'bg_default', 'bold'])); $output->emptyLine(); $output->writeLine("Here's the official solution in case you want to compare notes:"); $output->writeLine($this->lineBreak()); foreach ($exercise->getSolution()->getFiles() as $file) { $output->writeLine($this->style($file->getRelativePath(), ['bold', 'cyan', 'underline'])); $output->emptyLine(); $code = $file->getContents(); if (pathinfo($file->getRelativePath(), PATHINFO_EXTENSION) === 'php') { $code = $this->syntaxHighlighter->highlight($code); } //make sure there is a new line at the end $code = preg_replace('/\\n$/', '', $code) . "\n"; $output->write($code); $output->writeLine($this->lineBreak()); } $completedCount = count($userState->getCompletedExercises()); $numExercises = $this->exerciseRepository->count(); $output->writeLine(sprintf('You have %d challenges left.', $numExercises - $completedCount)); $output->writeLine(sprintf('Type "%s" to show the menu.', $this->appName)); $output->emptyLine(); }
/** * Runs a student's solution by invoking PHP via the `php-cgi` binary, populating all the super globals with * the information from the request objects returned from the exercise. The exercise can return multiple * requests so the solution will be invoked for however many requests there are. * * Running only runs the student's solution, the reference solution is not run and no verification is performed, * the output of the student's solution is written directly to the output. * * Events dispatched (for each request): * * * cgi.run.student-execute.pre * * cgi.run.student.executing * * @param string $fileName The absolute path to the student's solution. * @param OutputInterface $output A wrapper around STDOUT. * @return bool If the solution was successfully executed, eg. exit code was 0. */ public function run($fileName, OutputInterface $output) { $success = true; foreach ($this->exercise->getRequests() as $i => $request) { $event = $this->eventDispatcher->dispatch(new CgiExecuteEvent('cgi.run.student-execute.pre', $request)); $process = $this->getProcess($fileName, $event->getRequest()); $output->writeTitle("Request"); $output->emptyLine(); $output->writeRequest($request); $output->writeTitle("Output"); $output->emptyLine(); $process->start(); $this->eventDispatcher->dispatch(new CgiExecuteEvent('cgi.run.student.executing', $request, ['output' => $output])); $process->wait(function ($outputType, $outputBuffer) use($output) { $output->write($outputBuffer); }); $output->emptyLine(); if (!$process->isSuccessful()) { $success = false; } $output->lineBreak(); } return $success; }
/** * Runs a student's solution by invoking PHP via the `php-cgi` binary, populating all the super globals with * the information from the request objects returned from the exercise. The exercise can return multiple * requests so the solution will be invoked for however many requests there are. * * Running only runs the student's solution, the reference solution is not run and no verification is performed, * the output of the student's solution is written directly to the output. * * Events dispatched (for each request): * * * cgi.run.student-execute.pre * * cgi.run.student.executing * * @param Input $input The command line arguments passed to the command. * @param OutputInterface $output A wrapper around STDOUT. * @return bool If the solution was successfully executed, eg. exit code was 0. */ public function run(Input $input, OutputInterface $output) { $this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cgi.run.start', $this->exercise, $input)); $success = true; foreach ($this->exercise->getRequests() as $i => $request) { $event = $this->eventDispatcher->dispatch(new CgiExecuteEvent('cgi.run.student-execute.pre', $request)); $process = $this->getProcess($input->getArgument('program'), $event->getRequest()); $output->writeTitle("Request"); $output->emptyLine(); $output->write($this->requestRenderer->renderRequest($request)); $output->writeTitle("Output"); $output->emptyLine(); $process->start(); $this->eventDispatcher->dispatch(new CgiExecuteEvent('cgi.run.student.executing', $request, ['output' => $output])); $process->wait(function ($outputType, $outputBuffer) use($output) { $output->write($outputBuffer); }); $output->emptyLine(); if (!$process->isSuccessful()) { $success = false; } $output->lineBreak(); } $this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cgi.run.finish', $this->exercise, $input)); return $success; }
/** * Runs a student's solution by invoking PHP from the CLI passing the arguments gathered from the exercise * as command line arguments to PHP. * * Running only runs the student's solution, the reference solution is not run and no verification is performed, * the output of the student's solution is written directly to the output. * * Events dispatched: * * * cli.run.student-execute.pre * * cli.run.student.executing * * @param Input $input The command line arguments passed to the command. * @param OutputInterface $output A wrapper around STDOUT. * @return bool If the solution was successfully executed, eg. exit code was 0. */ public function run(Input $input, OutputInterface $output) { $this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cli.run.start', $this->exercise, $input)); $success = true; foreach ($this->preserveOldArgFormat($this->exercise->getArgs()) as $i => $args) { /** @var CliExecuteEvent $event */ $event = $this->eventDispatcher->dispatch(new CliExecuteEvent('cli.run.student-execute.pre', new ArrayObject($args))); $args = $event->getArgs(); if (count($args)) { $glue = max(array_map('strlen', $args->getArrayCopy())) > 30 ? "\n" : ', '; $output->writeTitle('Arguments'); $output->write(implode($glue, $args->getArrayCopy())); $output->emptyLine(); } $output->writeTitle("Output"); $process = $this->getPhpProcess($input->getArgument('program'), $args); $process->start(); $this->eventDispatcher->dispatch(new CliExecuteEvent('cli.run.student.executing', $args, ['output' => $output])); $process->wait(function ($outputType, $outputBuffer) use($output) { $output->write($outputBuffer); }); $output->emptyLine(); if (!$process->isSuccessful()) { $success = false; } $output->lineBreak(); } $this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cli.run.finish', $this->exercise, $input)); return $success; }
/** * @param string $fileName * @param OutputInterface $output * @return bool */ public function run($fileName, OutputInterface $output) { /** @var CliExecuteEvent $event */ $event = $this->eventDispatcher->dispatch(new CliExecuteEvent('cli.run.user-execute.pre', new ArrayObject($this->exercise->getArgs()))); $args = $event->getArgs(); if (count($args)) { $glue = max(array_map('strlen', $args->getArrayCopy())) > 30 ? "\n" : ', '; $output->writeTitle('Arguments'); $output->write(implode($glue, $args->getArrayCopy())); $output->emptyLine(); } $output->writeTitle("Output"); $process = $this->getPhpProcess($fileName, $args); $process->start(); $this->eventDispatcher->dispatch(new CliExecuteEvent('cli.run.executing', $args, ['output' => $output])); $process->wait(function ($outputType, $outputBuffer) use($output) { $output->writeLine($outputBuffer); }); return $process->isSuccessful(); }
/** * @param array $failures * @param int $padLength * @param ExerciseInterface $exercise * @param OutputInterface $output */ private function renderErrorInformation(array $failures, $padLength, ExerciseInterface $exercise, OutputInterface $output) { foreach ($failures as list($failure, $message)) { $output->writeLine($this->center($this->style(str_repeat(' ', $padLength), ['bg_red']))); $output->writeLine($this->center($this->style(\mb_str_pad($message, $padLength), ['bg_red']))); $output->writeLine($this->center($this->style(str_repeat(' ', $padLength), ['bg_red']))); $output->emptyLine(); $output->write($this->renderResult($failure)); } $output->lineBreak(); $output->emptyLine(); $output->emptyLine(); $this->fullWidthBlock($output, 'Your solution was unsuccessful!', ['white', 'bg_red', 'bold']); $output->emptyLine(); $output->writeLine($this->center(sprintf(" Your solution to %s didn't pass. Try again!", $exercise->getName()))); $output->emptyLine(); $output->emptyLine(); }