Skip to content

Commit 5e3e624

Browse files
committed
fix #226 - base path in AnonymiationConfig and related documentation
1 parent ea798c7 commit 5e3e624

File tree

14 files changed

+108
-16
lines changed

14 files changed

+108
-16
lines changed

docs/content/anonymization/core-anonymizers.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ This page list all *Anonymizers* provided by *DbToolsBundle*.
1919
<!--@include: ./core-anonymizers/lorem-ipsum.md-->
2020
<!--@include: ./core-anonymizers/address.md-->
2121
<!--@include: ./core-anonymizers/iban-bic.md-->
22+
<!--@include: ./core-anonymizers/file-resolution.md-->
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
## File name resolution
2+
3+
In various places you can configure relative file names in order to load data,
4+
here is how relative file names are resolved.
5+
**All relative file names will be considered relative to a given _base path_.**
6+
7+
The default base path is always stable but depends upon your selected flavor.
8+
9+
@todo examples
10+
11+
@@@ symfony
12+
13+
When parsing Symfony configuration, base path will always be the project
14+
directory, known as `%kernel.project_dir%` variable in Symfony configuration.
15+
This is the directory where your `composer.json` file.
16+
17+
@todo examples
18+
19+
@@@
20+
@@@ laravel
21+
22+
When parsing Laravel configuration, base path will always be the project
23+
directory, as returned by the `base_path()` Laravel function.
24+
25+
@todo examples
26+
27+
@@@
28+
@@@ standalone docker
29+
30+
When parsing configuration in the standalone CLI version or in docker context,
31+
base path will be currently being parsed Yaml file.
32+
33+
:::tip
34+
If you set the `workdir` option in your configuration file, then it will
35+
override the file directory and use it as the base path.
36+
37+
@todo link to `workdir` documentation
38+
:::
39+
@@@

src/Anonymization/Config/AnonymizerConfig.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,11 @@ public function __construct(
1313
public readonly string $targetName,
1414
public readonly string $anonymizer,
1515
public readonly Options $options,
16+
/**
17+
* Root directory in which this anonymizer configuration was in the
18+
* first place. This allows implementations to use it in order, for
19+
* example, to load files using a relative path.
20+
*/
21+
public readonly string $basePath,
1622
) {}
1723
}

src/Anonymization/Config/Loader/ArrayLoader.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ class ArrayLoader implements LoaderInterface
1515
public function __construct(
1616
private array $data,
1717
private string $connectionName = 'default',
18+
/**
19+
* Root directory from which the configuration was loaded. It allows
20+
* later file loading (for example, when sources are CSV or TXT files).
21+
*/
22+
private readonly string $basePath,
1823
) {}
1924

2025
#[\Override]
@@ -51,6 +56,7 @@ public function load(AnonymizationConfig $config): void
5156
$target,
5257
$targetConfig['anonymizer'],
5358
new Options($targetConfig['options']),
59+
$this->basePath,
5460
));
5561
}
5662
}

src/Anonymization/Config/Loader/AttributesLoader.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ class AttributesLoader implements LoaderInterface
1515
{
1616
public function __construct(
1717
private EntityManagerProvider $entityManagerProvider,
18+
/**
19+
* Root directory from which the configuration was loaded. It allows
20+
* later file loading (for example, when sources are CSV or TXT files).
21+
*/
22+
private readonly string $basePath,
1823
) {}
1924

2025
#[\Override]
@@ -62,6 +67,7 @@ public function load(AnonymizationConfig $config): void
6267
$anonymization->type . '_' . $key,
6368
$anonymization->type,
6469
new Options($anonymization->options),
70+
$this->basePath,
6571
));
6672
}
6773
}
@@ -78,6 +84,7 @@ public function load(AnonymizationConfig $config): void
7884
$metadata->getColumnName($fieldName),
7985
$propertyConfig->type,
8086
new Options($propertyConfig->options),
87+
$this->basePath,
8188
));
8289
}
8390
}
@@ -109,6 +116,7 @@ public function load(AnonymizationConfig $config): void
109116
$columnName,
110117
$anonymization->type,
111118
new Options($anonymization->options),
119+
$this->basePath,
112120
));
113121
}
114122
}

src/Anonymization/Config/Loader/PhpFileLoader.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,20 @@ class PhpFileLoader extends ArrayLoader
1111
public function __construct(
1212
private string $file,
1313
string $connectionName = 'default',
14+
/**
15+
* Root directory from which the configuration was loaded. It allows
16+
* later file loading (for example, when sources are CSV or TXT files).
17+
*
18+
* If not set, the file directory will be used instead. If set, it will
19+
* override the file directory.
20+
*/
21+
?string $basePath = null,
1422
) {
15-
parent::__construct([], $connectionName);
23+
// @todo dirname() is purely soft logic, it does not imply any
24+
// syscalls, whereas realpah() may.
25+
$basePath ??= \realpath(\dirname($file));
26+
27+
parent::__construct([], $connectionName, $basePath);
1628
}
1729

1830
#[\Override]

src/Anonymization/Config/Loader/YamlLoader.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,20 @@ class YamlLoader extends ArrayLoader
1111
public function __construct(
1212
private string $file,
1313
string $connectionName = 'default',
14+
/**
15+
* Root directory from which the configuration was loaded. It allows
16+
* later file loading (for example, when sources are CSV or TXT files).
17+
*
18+
* If not set, the file directory will be used instead. If set, it will
19+
* override the file directory.
20+
*/
21+
?string $basePath = null,
1422
) {
15-
parent::__construct([], $connectionName);
23+
// @todo dirname() is purely soft logic, it does not imply any
24+
// syscalls, whereas realpah() may.
25+
$basePath ??= \realpath(\dirname($file));
26+
27+
parent::__construct([], $connectionName, $basePath);
1628
}
1729

1830
#[\Override]

src/Bridge/Laravel/DbToolsServiceProvider.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ function (AnonymizatorFactory $factory, Application $app): void {
144144
/** @var Repository $config */
145145
$config = $app->make('config');
146146

147+
$workdir = $config->get('db-tools.workdir', $app->basePath());
148+
147149
foreach ($config->get('db-tools.anonymization_files', []) as $connectionName => $file) {
148150
// 0 is not a good index for extension, this fails for false and 0.
149151
if (!($pos = \strrpos($file, '.'))) {
@@ -155,8 +157,8 @@ function (AnonymizatorFactory $factory, Application $app): void {
155157

156158
$ext = \substr($file, $pos + 1);
157159
$loader = match ($ext) {
158-
'php' => new PhpFileLoader($file, $connectionName),
159-
'yml', 'yaml' => new YamlLoader($file, $connectionName),
160+
'php' => new PhpFileLoader($file, $connectionName, $workdir),
161+
'yml', 'yaml' => new YamlLoader($file, $connectionName, $workdir),
160162
default => throw new ConfigurationException(\sprintf(
161163
"File extension \"%s\" is unsupported (given path: \"%s\").",
162164
$ext,
@@ -168,7 +170,7 @@ function (AnonymizatorFactory $factory, Application $app): void {
168170
}
169171

170172
foreach ($config->get('db-tools.anonymization', []) as $connectionName => $array) {
171-
$factory->addConfigurationLoader(new ArrayLoader($array, $connectionName));
173+
$factory->addConfigurationLoader(new ArrayLoader($array, $connectionName, $workdir));
172174
}
173175
}
174176
);

src/Bridge/Standalone/Bootstrap.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,10 @@ public static function bootstrap(array $config = [], array $configFiles = [], ?L
237237
$anonymizatorFactory = new AnonymizatorFactory($databaseSessionRegistry, $anonymizerRegistry, $logger);
238238

239239
foreach (($config['anonymization_files'] ?? []) as $connectionName => $file) {
240-
$anonymizatorFactory->addConfigurationLoader(new YamlLoader($file, $connectionName));
240+
$anonymizatorFactory->addConfigurationLoader(new YamlLoader($file, $connectionName, $config['workdir']));
241241
}
242242
foreach (($config['anonymization'] ?? []) as $connectionName => $array) {
243-
$anonymizatorFactory->addConfigurationLoader(new ArrayLoader($array, $connectionName));
243+
$anonymizatorFactory->addConfigurationLoader(new ArrayLoader($array, $connectionName, $config['workdir']));
244244
}
245245

246246
$backupperFactory = new BackupperFactory($databaseSessionRegistry, $configRegistry, $logger);

src/Bridge/Symfony/DependencyInjection/Compiler/DbToolsPass.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1313
use Symfony\Component\DependencyInjection\ContainerBuilder;
1414
use Symfony\Component\DependencyInjection\Definition;
15+
use Symfony\Component\DependencyInjection\Parameter;
1516
use Symfony\Component\DependencyInjection\Reference;
1617

1718
class DbToolsPass implements CompilerPassInterface
@@ -49,7 +50,7 @@ private function registerArrayLoader(array $data, string $connectionName, Contai
4950
{
5051
$definition = new Definition();
5152
$definition->setClass(ArrayLoader::class);
52-
$definition->setArguments([$data, $connectionName]);
53+
$definition->setArguments([$data, $connectionName, new Parameter('kernel.project_dir')]);
5354

5455
$loaderId = 'db_tools.anonymization.loader.array.' . $connectionName;
5556
$container->setDefinition($loaderId, $definition);
@@ -61,7 +62,7 @@ private function registerYamlLoader(string $file, string $connectionName, Contai
6162
{
6263
$definition = new Definition();
6364
$definition->setClass(YamlLoader::class);
64-
$definition->setArguments([$file, $connectionName]);
65+
$definition->setArguments([$file, $connectionName, new Parameter('kernel.project_dir')]);
6566

6667
$loaderId = 'db_tools.anonymization.loader.yaml.' . $connectionName;
6768
$container->setDefinition($loaderId, $definition);
@@ -73,7 +74,7 @@ private function registerAttributesLoader(ContainerBuilder $container): string
7374
{
7475
$definition = new Definition();
7576
$definition->setClass(AttributesLoader::class);
76-
$definition->setArguments([new Reference('doctrine.orm.command.entity_manager_provider')]);
77+
$definition->setArguments([new Reference('doctrine.orm.command.entity_manager_provider'), new Parameter('kernel.project_dir')]);
7778

7879
$loaderId = 'db_tools.anonymization.loader.attributes';
7980
$container->setDefinition($loaderId, $definition);

0 commit comments

Comments
 (0)