Skip to content

Commit a2cdb65

Browse files
committed
Allow to expose ports
1 parent 6f461ac commit a2cdb65

File tree

6 files changed

+57
-12
lines changed

6 files changed

+57
-12
lines changed

src/Exercise/Scenario/ExerciseScenario.php

+20
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ abstract class ExerciseScenario
99
*/
1010
private array $files = [];
1111

12+
/**
13+
* @var list<int>
14+
*/
15+
private array $exposedPorts = [];
16+
1217
public function withFile(string $relativeFileName, string $content): static
1318
{
1419
$this->files[$relativeFileName] = $content;
@@ -23,4 +28,19 @@ public function getFiles(): array
2328
{
2429
return $this->files;
2530
}
31+
32+
public function exposePort(int $port): static
33+
{
34+
$this->exposedPorts = [$port];
35+
36+
return $this;
37+
}
38+
39+
/**
40+
* @return list<int>
41+
*/
42+
public function getExposedPorts(): array
43+
{
44+
return $this->exposedPorts;
45+
}
2646
}

src/ExerciseRunner/CgiRunner.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ private function executePhpFile(
215215
RequestInterface $request,
216216
string $type,
217217
): ResponseInterface {
218-
$process = $this->getPhpProcess($workingDirectory, $fileName, $request);
218+
$process = $this->getPhpProcess($workingDirectory, $fileName, $request, $scenario->getExposedPorts());
219219

220220
$process->start();
221221
$this->eventDispatcher->dispatch(
@@ -238,11 +238,9 @@ private function executePhpFile(
238238
}
239239

240240
/**
241-
* @param string $fileName
242-
* @param RequestInterface $request
243-
* @return Process
241+
* @param list<int> $exposedPorts
244242
*/
245-
private function getPhpProcess(string $workingDirectory, string $fileName, RequestInterface $request): Process
243+
private function getPhpProcess(string $workingDirectory, string $fileName, RequestInterface $request, array $exposedPorts): Process
246244
{
247245
$env = [
248246
'REQUEST_METHOD' => $request->getMethod(),
@@ -270,6 +268,7 @@ private function getPhpProcess(string $workingDirectory, string $fileName, Reque
270268
],
271269
$workingDirectory,
272270
$env,
271+
$exposedPorts,
273272
$content,
274273
);
275274

@@ -311,6 +310,7 @@ public function run(ExecutionContext $context, OutputInterface $output): bool
311310
$context->getStudentExecutionDirectory(),
312311
$context->getEntryPoint(),
313312
$event->getRequest(),
313+
$scenario->getExposedPorts(),
314314
);
315315

316316
$process->start();

src/ExerciseRunner/CliRunner.php

+8-3
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ public function run(ExecutionContext $context, OutputInterface $output): bool
206206
$scenario = $this->exercise->defineTestScenario();
207207

208208
$this->environmentManager->prepareStudent($context, $scenario);
209+
$this->environmentManager->prepareReference($context, $scenario);
210+
209211

210212
$this->eventDispatcher->dispatch(new CliExerciseRunnerEvent('cli.run.start', $context, $scenario));
211213

@@ -222,6 +224,7 @@ public function run(ExecutionContext $context, OutputInterface $output): bool
222224
$context->getStudentExecutionDirectory(),
223225
$context->getEntryPoint(),
224226
$args,
227+
$scenario->getExposedPorts(),
225228
);
226229

227230
$process->start();
@@ -231,6 +234,7 @@ public function run(ExecutionContext $context, OutputInterface $output): bool
231234
$process->wait(function ($outputType, $outputBuffer) use ($output) {
232235
$output->write($outputBuffer);
233236
});
237+
234238
$output->emptyLine();
235239

236240
if (!$process->isSuccessful()) {
@@ -254,7 +258,7 @@ public function run(ExecutionContext $context, OutputInterface $output): bool
254258
*/
255259
private function executePhpFile(ExecutionContext $context, CliScenario $scenario, string $workingDirectory, string $fileName, Collection $args, string $type): string
256260
{
257-
$process = $this->getPhpProcess($workingDirectory, $fileName, $args);
261+
$process = $this->getPhpProcess($workingDirectory, $fileName, $args, $scenario->getExposedPorts());
258262

259263
$process->start();
260264
$this->eventDispatcher->dispatch(
@@ -271,11 +275,12 @@ private function executePhpFile(ExecutionContext $context, CliScenario $scenario
271275

272276
/**
273277
* @param Collection<int, string> $args
278+
* @param list<int> $exposedPorts
274279
*/
275-
private function getPhpProcess(string $workingDirectory, string $fileName, Collection $args): Process
280+
private function getPhpProcess(string $workingDirectory, string $fileName, Collection $args, array $exposedPorts): Process
276281
{
277282
return $this->processFactory->create(
278-
new ProcessInput('php', [$fileName, ...$args->getArrayCopy()], $workingDirectory, []),
283+
new ProcessInput('php', [$fileName, ...$args->getArrayCopy()], $workingDirectory, [], $exposedPorts),
279284
);
280285
}
281286
}

src/Listener/PrepareSolutionListener.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function __invoke(ExerciseRunnerEvent $event): void
4141
//only install if vendor folder not available
4242
if (!file_exists(sprintf('%s/vendor', $event->getContext()->getReferenceExecutionDirectory()))) {
4343
$process = $this->processFactory->create(
44-
new ProcessInput('composer', ['install', '--no-interaction'], $event->getContext()->getReferenceExecutionDirectory(), []),
44+
new ProcessInput('composer', ['install', '--no-interaction'], $event->getContext()->getReferenceExecutionDirectory(), [], []),
4545
);
4646

4747
try {

src/Process/DockerProcessFactory.php

+13-3
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,18 @@ public function create(ProcessInput $processInput): Process
4040
$env[] = $key . '=' . $value;
4141
}
4242

43+
$ports = [];
44+
foreach ($processInput->getExposedPorts() as $port) {
45+
$ports[] = '-p';
46+
$ports[] = $port . ':' . $port;
47+
}
48+
4349
$env[] = '-e';
4450
$env[] = 'COMPOSER_HOME=/tmp/composer';
4551

46-
return new Process(
52+
$p = new Process(
4753
[
48-
...$this->baseComposeCommand($mounts, $env),
54+
...$this->baseComposeCommand($mounts, $env, $ports),
4955
'runtime',
5056
$processInput->getExecutable(),
5157
...$processInput->getArgs(),
@@ -59,14 +65,17 @@ public function create(ProcessInput $processInput): Process
5965
$processInput->getInput(),
6066
30,
6167
);
68+
69+
return $p;
6270
}
6371

6472
/**
6573
* @param array<string> $mounts
6674
* @param array<string> $env
75+
* @param list<string> $ports
6776
* @return array<string>
6877
*/
69-
private function baseComposeCommand(array $mounts, array $env): array
78+
private function baseComposeCommand(array $mounts, array $env, array $ports): array
7079
{
7180
$dockerPath = $this->executableFinder->find('docker');
7281
if ($dockerPath === null) {
@@ -85,6 +94,7 @@ private function baseComposeCommand(array $mounts, array $env): array
8594
getmyuid() . ':' . getmygid(),
8695
'--rm',
8796
...$env,
97+
...$ports,
8898
'-w',
8999
'/solution',
90100
...array_merge(...array_map(fn($mount) => ['-v', $mount], $mounts)),

src/Process/ProcessInput.php

+10
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ class ProcessInput
77
/**
88
* @param list<string> $args
99
* @param array<string, string> $env
10+
* @param list<int> $exposedPorts
1011
*/
1112
public function __construct(
1213
private string $executable,
1314
private array $args,
1415
private string $workingDirectory,
1516
private array $env,
17+
private array $exposedPorts,
1618
private ?string $input = null,
1719
) {}
1820

@@ -42,6 +44,14 @@ public function getEnv(): array
4244
return $this->env;
4345
}
4446

47+
/**
48+
* @return list<int>
49+
*/
50+
public function getExposedPorts(): array
51+
{
52+
return $this->exposedPorts;
53+
}
54+
4555
public function getInput(): ?string
4656
{
4757
return $this->input;

0 commit comments

Comments
 (0)