Skip to content

Commit 88cc8a3

Browse files
committed
Allow to expose ports
1 parent b86f9ce commit 88cc8a3

9 files changed

+69
-25
lines changed

Diff for: 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
}

Diff for: 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();

Diff for: src/ExerciseRunner/CliRunner.php

+6-3
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ public function run(ExecutionContext $context, OutputInterface $output): bool
222222
$context->getStudentExecutionDirectory(),
223223
$context->getEntryPoint(),
224224
$args,
225+
$scenario->getExposedPorts(),
225226
);
226227

227228
$process->start();
@@ -231,6 +232,7 @@ public function run(ExecutionContext $context, OutputInterface $output): bool
231232
$process->wait(function ($outputType, $outputBuffer) use ($output) {
232233
$output->write($outputBuffer);
233234
});
235+
234236
$output->emptyLine();
235237

236238
if (!$process->isSuccessful()) {
@@ -254,7 +256,7 @@ public function run(ExecutionContext $context, OutputInterface $output): bool
254256
*/
255257
private function executePhpFile(ExecutionContext $context, CliScenario $scenario, string $workingDirectory, string $fileName, Collection $args, string $type): string
256258
{
257-
$process = $this->getPhpProcess($workingDirectory, $fileName, $args);
259+
$process = $this->getPhpProcess($workingDirectory, $fileName, $args, $scenario->getExposedPorts());
258260

259261
$process->start();
260262
$this->eventDispatcher->dispatch(
@@ -271,11 +273,12 @@ private function executePhpFile(ExecutionContext $context, CliScenario $scenario
271273

272274
/**
273275
* @param Collection<int, string> $args
276+
* @param list<int> $exposedPorts
274277
*/
275-
private function getPhpProcess(string $workingDirectory, string $fileName, Collection $args): Process
278+
private function getPhpProcess(string $workingDirectory, string $fileName, Collection $args, array $exposedPorts): Process
276279
{
277280
return $this->processFactory->create(
278-
new ProcessInput('php', [$fileName, ...$args->getArrayCopy()], $workingDirectory, []),
281+
new ProcessInput('php', [$fileName, ...$args->getArrayCopy()], $workingDirectory, [], $exposedPorts),
279282
);
280283
}
281284
}

Diff for: 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 {

Diff for: 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)),

Diff for: 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;

Diff for: test/Process/DockerProcessFactoryTest.php

+7-7
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public function testCreateThrowsExceptionIfDockerNotFound(): void
2121
->willReturn(null);
2222

2323
$factory = new DockerProcessFactory('/docker-dir', 'php8appreciate', '/composer/cache/dir', $finder);
24-
$input = new ProcessInput('composer', [], __DIR__, []);
24+
$input = new ProcessInput('composer', [], __DIR__, [], []);
2525

2626
$factory->create($input);
2727
}
@@ -35,7 +35,7 @@ public function testCreate(): void
3535
->willReturn('/usr/local/bin/docker');
3636

3737
$factory = new DockerProcessFactory('/docker-dir', 'php8appreciate', '/composer/cache/dir', $finder);
38-
$input = new ProcessInput('php', [], __DIR__, []);
38+
$input = new ProcessInput('php', [], __DIR__, [], []);
3939

4040
$process = $factory->create($input);
4141
$cmd = "'/usr/local/bin/docker' 'compose' '-p' 'php8appreciate' '-f' '.docker/runtime/docker-compose.yml'";
@@ -53,7 +53,7 @@ public function testCreateMountsComposerCacheDirIfExecutableIsComposer(): void
5353
->willReturn('/usr/local/bin/docker');
5454

5555
$factory = new DockerProcessFactory('/docker-dir', 'php8appreciate', '/composer/cache/dir', $finder);
56-
$input = new ProcessInput('composer', [], __DIR__, []);
56+
$input = new ProcessInput('composer', [], __DIR__, [], []);
5757

5858
$process = $factory->create($input);
5959
$cmd = "'/usr/local/bin/docker' 'compose' '-p' 'php8appreciate' '-f' '.docker/runtime/docker-compose.yml'";
@@ -71,7 +71,7 @@ public function testCreateWithArgs(): void
7171
->willReturn('/usr/local/bin/docker');
7272

7373
$factory = new DockerProcessFactory('/docker-dir', 'php8appreciate', '/composer/cache/dir', $finder);
74-
$input = new ProcessInput('php', ['one', 'two'], __DIR__, []);
74+
$input = new ProcessInput('php', ['one', 'two'], __DIR__, [], []);
7575

7676
$process = $factory->create($input);
7777
$cmd = "'/usr/local/bin/docker' 'compose' '-p' 'php8appreciate' '-f' '.docker/runtime/docker-compose.yml'";
@@ -89,7 +89,7 @@ public function testCreateWithEnv(): void
8989
->willReturn('/usr/local/bin/docker');
9090

9191
$factory = new DockerProcessFactory('/docker-dir', 'php8appreciate', '/composer/cache/dir', $finder);
92-
$input = new ProcessInput('php', ['one', 'two'], __DIR__, ['SOME_VAR' => 'value']);
92+
$input = new ProcessInput('php', ['one', 'two'], __DIR__, ['SOME_VAR' => 'value'], []);
9393

9494
$process = $factory->create($input);
9595
$cmd = "'/usr/local/bin/docker' 'compose' '-p' 'php8appreciate' '-f' '.docker/runtime/docker-compose.yml'";
@@ -107,7 +107,7 @@ public function testWithInput(): void
107107
->willReturn('/usr/local/bin/docker');
108108

109109
$factory = new DockerProcessFactory('/composer-dir', 'php8appreciate', '/composer/cache/dir', $finder);
110-
$input = new ProcessInput('php', [], __DIR__, [], 'someinput');
110+
$input = new ProcessInput('php', [], __DIR__, [], [], 'someinput');
111111

112112
$process = $factory->create($input);
113113
$cmd = "'/usr/local/bin/docker' 'compose' '-p' 'php8appreciate' '-f' '.docker/runtime/docker-compose.yml'";
@@ -125,7 +125,7 @@ public function testSolutionDirectoryIsPassedAsEnvVar(): void
125125
->willReturn('/usr/local/bin/docker');
126126

127127
$factory = new DockerProcessFactory('/docker-dir', 'php8appreciate', '/composer/cache/dir', $finder);
128-
$input = new ProcessInput('php', ['one', 'two'], __DIR__, ['SOME_VAR' => 'value']);
128+
$input = new ProcessInput('php', ['one', 'two'], __DIR__, ['SOME_VAR' => 'value'], []);
129129

130130
$process = $factory->create($input);
131131
$cmd = "'/usr/local/bin/docker' 'compose' '-p' 'php8appreciate' '-f' '.docker/runtime/docker-compose.yml'";

Diff for: test/Process/HostProcessFactoryTest.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public function testCreateThrowsExceptionIfExecutableNotFound(): void
2121
->willReturn(null);
2222

2323
$factory = new HostProcessFactory($finder);
24-
$input = new ProcessInput('composer', [], __DIR__, []);
24+
$input = new ProcessInput('composer', [], __DIR__, [], []);
2525

2626
$factory->create($input);
2727
}
@@ -35,7 +35,7 @@ public function testCreate(): void
3535
->willReturn('/usr/local/bin/composer');
3636

3737
$factory = new HostProcessFactory($finder);
38-
$input = new ProcessInput('composer', [], __DIR__, []);
38+
$input = new ProcessInput('composer', [], __DIR__, [], []);
3939

4040
$process = $factory->create($input);
4141
static::assertSame("'/usr/local/bin/composer'", $process->getCommandLine());
@@ -50,7 +50,7 @@ public function testCreateWithArgs(): void
5050
->willReturn('/usr/local/bin/composer');
5151

5252
$factory = new HostProcessFactory($finder);
53-
$input = new ProcessInput('composer', ['one', 'two'], __DIR__, []);
53+
$input = new ProcessInput('composer', ['one', 'two'], __DIR__, [], []);
5454

5555
$process = $factory->create($input);
5656
static::assertSame("'/usr/local/bin/composer' 'one' 'two'", $process->getCommandLine());
@@ -65,7 +65,7 @@ public function testCreateWithEnv(): void
6565
->willReturn('/usr/local/bin/composer');
6666

6767
$factory = new HostProcessFactory($finder);
68-
$input = new ProcessInput('composer', ['one', 'two'], __DIR__, ['SOME_VAR' => 'value']);
68+
$input = new ProcessInput('composer', ['one', 'two'], __DIR__, ['SOME_VAR' => 'value'], []);
6969

7070
$process = $factory->create($input);
7171
static::assertSame(['SOME_VAR' => 'value'], $process->getEnv());
@@ -80,7 +80,7 @@ public function testWithInput(): void
8080
->willReturn('/usr/local/bin/composer');
8181

8282
$factory = new HostProcessFactory($finder);
83-
$input = new ProcessInput('composer', [], __DIR__, [], 'someinput');
83+
$input = new ProcessInput('composer', [], __DIR__, [], [], 'someinput');
8484

8585
$process = $factory->create($input);
8686
static::assertSame('someinput', $process->getInput());

Diff for: test/Process/ProcessInputTest.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ class ProcessInputTest extends TestCase
99
{
1010
public function testProcessInput(): void
1111
{
12-
$input = new ProcessInput('composer', ['one', 'two'], __DIR__, ['SOME_VAR' => 'value'], 'input');
12+
$input = new ProcessInput('composer', ['one', 'two'], __DIR__, ['SOME_VAR' => 'value'], [], 'input');
1313

1414
static::assertSame('composer', $input->getExecutable());
1515
static::assertSame(['one', 'two'], $input->getArgs());
1616
static::assertSame(__DIR__, $input->getWorkingDirectory());
1717
static::assertSame(['SOME_VAR' => 'value'], $input->getEnv());
18+
static::assertSame([], $input->getExposedPorts());
1819
static::assertSame('input', $input->getInput());
1920
}
2021
}

0 commit comments

Comments
 (0)