Skip to content

Commit 5529871

Browse files
committed
feature #994 feat: support for compose.yml (dunglas)
This PR was submitted for the 2.x branch but it was squashed and merged into the 1.x branch instead. Discussion ---------- feat: support for compose.yml Docker Compose now recommends using a definition file named `compose.yaml` and also supports `compose.yml` (the legacy `docker-compose.ya?ml` are still supported): https://docs.docker.com/compose/compose-file/03-compose-file/ This PR adds support for `compose.ya?ml` file to Flex, and changes the name of the generated file to `compose.yaml`, according to Docker best practices. Closes #992. Commits ------- 5c98476 feat: support for compose.yml
2 parents 884a881 + 5c98476 commit 5529871

File tree

2 files changed

+54
-23
lines changed

2 files changed

+54
-23
lines changed

src/Configurator/DockerComposeConfigurator.php

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323
use Symfony\Flex\Update\RecipeUpdate;
2424

2525
/**
26-
* Adds services and volumes to docker-compose.yml file.
26+
* Adds services and volumes to compose.yaml file.
2727
*
28-
* @author Kévin Dunglas <[email protected]>
28+
* @author Kévin Dunglas <[email protected]>
2929
*/
3030
class DockerComposeConfigurator extends AbstractConfigurator
3131
{
@@ -145,9 +145,20 @@ public static function shouldConfigureDockerRecipe(Composer $composer, IOInterfa
145145
*/
146146
private function normalizeConfig(array $config): array
147147
{
148-
foreach ($config as $val) {
149-
// Support for the short syntax recipe syntax that modifies docker-compose.yml only
150-
return isset($val[0]) ? ['docker-compose.yml' => $config] : $config;
148+
foreach ($config as $key => $val) {
149+
// Support for the short recipe syntax that modifies compose.yaml only
150+
if (isset($val[0])) {
151+
return ['compose.yaml' => $config];
152+
}
153+
154+
if (!str_starts_with($key, 'docker-')) {
155+
continue;
156+
}
157+
158+
// If the recipe still use the legacy "docker-compose.yml" names, remove the "docker-" prefix and change the extension
159+
$newKey = pathinfo(substr($key, 7), \PATHINFO_FILENAME).'.yaml';
160+
$config[$newKey] = $val;
161+
unset($config[$key]);
151162
}
152163

153164
return $config;
@@ -159,11 +170,13 @@ private function normalizeConfig(array $config): array
159170
private function findDockerComposeFile(string $rootDir, string $file): ?string
160171
{
161172
if (isset($_SERVER['COMPOSE_FILE'])) {
173+
$filenameToFind = pathinfo($file, \PATHINFO_FILENAME);
162174
$separator = $_SERVER['COMPOSE_PATH_SEPARATOR'] ?? ('\\' === \DIRECTORY_SEPARATOR ? ';' : ':');
163175

164176
$files = explode($separator, $_SERVER['COMPOSE_FILE']);
165177
foreach ($files as $f) {
166-
if ($file !== basename($f)) {
178+
$filename = pathinfo($f, \PATHINFO_FILENAME);
179+
if ($filename !== $filenameToFind && "docker-$filenameToFind" !== $filename) {
167180
continue;
168181
}
169182

@@ -180,10 +193,13 @@ private function findDockerComposeFile(string $rootDir, string $file): ?string
180193
// COMPOSE_FILE not set, or doesn't contain the file we're looking for
181194
$dir = $rootDir;
182195
do {
183-
// Test with the ".yaml" extension if the file doesn't end up with ".yml".
184196
if (
185197
$this->filesystem->exists($dockerComposeFile = sprintf('%s/%s', $dir, $file)) ||
186-
$this->filesystem->exists($dockerComposeFile = substr($dockerComposeFile, 0, -2).'aml')
198+
// Test with the ".yml" extension if the file doesn't end up with ".yaml"
199+
$this->filesystem->exists($dockerComposeFile = substr($dockerComposeFile, 0, -3).'ml') ||
200+
// Test with the legacy "docker-" suffix if "compose.ya?ml" doesn't exist
201+
$this->filesystem->exists($dockerComposeFile = sprintf('%s/docker-%s', $dir, $file)) ||
202+
$this->filesystem->exists($dockerComposeFile = substr($dockerComposeFile, 0, -3).'ml')
187203
) {
188204
return $dockerComposeFile;
189205
}
@@ -359,7 +375,7 @@ private static function askDockerSupport(IOInterface $io, Recipe $recipe): strin
359375
$io->writeError(sprintf(' - <warning> %s </> %s', $warning, $recipe->getFormattedOrigin()));
360376
$question = ' The recipe for this package contains some Docker configuration.
361377
362-
This may create/update <comment>docker-compose.yml</comment> or update <comment>Dockerfile</comment> (if it exists).
378+
This may create/update <comment>compose.yaml</comment> or update <comment>Dockerfile</comment> (if it exists).
363379
364380
Do you want to include Docker configuration from recipes?
365381
[<comment>y</>] Yes

tests/Configurator/DockerComposeConfiguratorTest.php

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
use Symfony\Flex\Update\RecipeUpdate;
2424

2525
/**
26-
* @author Kévin Dunglas <[email protected]>
26+
* @author Kévin Dunglas <[email protected]>
2727
*/
2828
class DockerComposeConfiguratorTest extends TestCase
2929
{
@@ -166,18 +166,33 @@ protected function tearDown(): void
166166
putenv('COMPOSER='.$this->originalEnvComposer);
167167

168168
(new Filesystem())->remove([
169+
FLEX_TEST_DIR.'/compose.yml',
169170
FLEX_TEST_DIR.'/docker-compose.yml',
171+
FLEX_TEST_DIR.'/compose.override.yml',
170172
FLEX_TEST_DIR.'/docker-compose.override.yml',
173+
FLEX_TEST_DIR.'/compose.yaml',
171174
FLEX_TEST_DIR.'/docker-compose.yaml',
172175
FLEX_TEST_DIR.'/composer.json',
176+
FLEX_TEST_DIR.'/child/compose.override.yaml',
173177
FLEX_TEST_DIR.'/child/docker-compose.override.yaml',
174178
FLEX_TEST_DIR.'/child',
175179
]);
176180
}
177181

178-
public function testConfigure()
182+
public static function dockerComposerFileProvider(): iterable
179183
{
180-
$dockerComposeFile = FLEX_TEST_DIR.'/docker-compose.yaml';
184+
yield ['compose.yaml'];
185+
yield ['compose.yml'];
186+
yield ['docker-compose.yaml'];
187+
yield ['docker-compose.yml'];
188+
}
189+
190+
/**
191+
* @dataProvider dockerComposerFileProvider
192+
*/
193+
public function testConfigure(string $fileName)
194+
{
195+
$dockerComposeFile = FLEX_TEST_DIR."/$fileName";
181196
file_put_contents($dockerComposeFile, self::ORIGINAL_CONTENT);
182197

183198
$this->configurator->configure($this->recipeDb, self::CONFIG_DB, $this->lock);
@@ -205,7 +220,7 @@ public function testConfigure()
205220
###< doctrine/doctrine-bundle ###
206221

207222
YAML
208-
);
223+
);
209224

210225
$this->configurator->unconfigure($this->recipeDb, self::CONFIG_DB, $this->lock);
211226
$this->assertEquals(self::ORIGINAL_CONTENT, file_get_contents($dockerComposeFile));
@@ -216,7 +231,7 @@ public function testNotConfiguredIfConfigSet()
216231
$this->package->setExtra(['symfony' => ['docker' => false]]);
217232
$this->configurator->configure($this->recipeDb, self::CONFIG_DB, $this->lock);
218233

219-
$this->assertFileDoesNotExist(FLEX_TEST_DIR.'/docker-compose.yml');
234+
$this->assertFileDoesNotExist(FLEX_TEST_DIR.'/docker-compose.yaml');
220235
}
221236

222237
/**
@@ -235,9 +250,9 @@ public function testPreferenceAskedInteractively(string $userInput, bool $expect
235250
$this->configurator->configure($this->recipeDb, self::CONFIG_DB, $this->lock);
236251

237252
if ($expectedIsConfigured) {
238-
$this->assertFileExists(FLEX_TEST_DIR.'/docker-compose.yml');
253+
$this->assertFileExists(FLEX_TEST_DIR.'/compose.yaml');
239254
} else {
240-
$this->assertFileDoesNotExist(FLEX_TEST_DIR.'/docker-compose.yml');
255+
$this->assertFileDoesNotExist(FLEX_TEST_DIR.'/compose.yaml');
241256
}
242257

243258
$composerJsonData = json_decode(file_get_contents($composerJsonPath), true);
@@ -270,7 +285,7 @@ public function testEnvVarUsedForDockerConfirmation()
270285
$this->configurator->configure($this->recipeDb, self::CONFIG_DB, $this->lock);
271286
unset($_SERVER['SYMFONY_DOCKER']);
272287

273-
$this->assertFileExists(FLEX_TEST_DIR.'/docker-compose.yml');
288+
$this->assertFileExists(FLEX_TEST_DIR.'/compose.yaml');
274289

275290
$composerJsonData = json_decode(file_get_contents($composerJsonPath), true);
276291
$this->assertArrayHasKey('extra', $composerJsonData);
@@ -316,7 +331,7 @@ public function testConfigureFileWithExistingVolumes()
316331
###< doctrine/doctrine-bundle ###
317332

318333
YAML
319-
);
334+
);
320335

321336
$this->configurator->unconfigure($this->recipeDb, self::CONFIG_DB, $this->lock);
322337
// Not the same original, we have an extra breaks line
@@ -411,7 +426,7 @@ public function testConfigureFileWithExistingMarks()
411426
###< doctrine/doctrine-bundle ###
412427

413428
YAML
414-
);
429+
);
415430

416431
$this->configurator->unconfigure($recipe, $config, $this->lock);
417432
$this->assertEquals($originalContent, file_get_contents($dockerComposeFile));
@@ -526,7 +541,7 @@ public function testConfigureMultipleFiles()
526541
###< doctrine/doctrine-bundle ###
527542

528543
YAML
529-
);
544+
);
530545
}
531546

532547
$this->configurator->unconfigure($this->recipeDb, self::CONFIG_DB_MULTIPLE_FILES, $this->lock);
@@ -571,7 +586,7 @@ public function testConfigureEnvVar()
571586
###< doctrine/doctrine-bundle ###
572587

573588
YAML
574-
);
589+
);
575590
}
576591

577592
$this->configurator->unconfigure($this->recipeDb, self::CONFIG_DB_MULTIPLE_FILES, $this->lock);
@@ -624,7 +639,7 @@ public function testConfigureFileInParentDir()
624639

625640
public function testConfigureWithoutExistingDockerComposeFiles()
626641
{
627-
$dockerComposeFile = FLEX_TEST_DIR.'/docker-compose.yml';
642+
$dockerComposeFile = FLEX_TEST_DIR.'/compose.yaml';
628643
$defaultContent = "version: '3'\n";
629644

630645
$this->configurator->configure($this->recipeDb, self::CONFIG_DB, $this->lock);
@@ -653,7 +668,7 @@ public function testConfigureWithoutExistingDockerComposeFiles()
653668
###< doctrine/doctrine-bundle ###
654669

655670
YAML
656-
);
671+
);
657672

658673
$this->configurator->unconfigure($this->recipeDb, self::CONFIG_DB, $this->lock);
659674
$this->assertEquals(trim($defaultContent), file_get_contents($dockerComposeFile));

0 commit comments

Comments
 (0)