Skip to content

Commit

Permalink
FEATURE: Allow source- and target options to be overridden
Browse files Browse the repository at this point in the history
Adds two flags `override-source-options` and `override-target-options` that allow to overrule options for a single `import:run` invokation.

## Example

    ./flow import:run some:preset --override-source-options='{"endpoint":"https://some.tld/custom/endpoint"}'

Resolves: #6
  • Loading branch information
bwaidelich committed May 27, 2024
1 parent 57fd353 commit ae93ac4
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 16 deletions.
30 changes: 25 additions & 5 deletions Classes/Command/ImportCommandController.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,21 @@ public function importCommand(string $preset, ?bool $quiet = null, ?bool $forceU
* @param bool|null $quiet If set, no output, apart from errors, will be displayed
* @param bool|null $forceUpdates If set, all local records will be updated regardless of their version/timestamp. This is useful for node type changes that require new data to be fetched
* @param bool|null $fromFixture If set, the data will be loaded from a local fixture file instead of the configured data source
* @param string|null $overrideSourceOptions Allows to override default options for the data source via JSON, e.g. '{"endpoint":"https://some-custom.tld/endpoint"}'
* @param string|null $overrideTargetOptions Allows to override default options for the data target via JSON, e.g. '{"endpoint":"https://some-custom.tld/endpoint"}'
*/
public function runCommand(string $preset, ?bool $quiet = null, ?bool $forceUpdates = null, ?bool $fromFixture = null): void
public function runCommand(string $preset, ?bool $quiet = null, ?bool $forceUpdates = null, ?bool $fromFixture = null, ?string $overrideSourceOptions = null, ?string $overrideTargetOptions = null): void
{
if ($fromFixture === true) {
$importService = $this->importServiceFactory->createWithFixture($preset);
$customSourceOptions = self::parseJsonOption($overrideSourceOptions);
$customTargetOptions = self::parseJsonOption($overrideTargetOptions);
if ($fromFixture) {
if ($customSourceOptions !== null) {
throw new \InvalidArgumentException('The options from-fixture and override-source-options must not be combined!', 1716824420);
}
$importService = $this->importServiceFactory->createWithFixture($preset, $customTargetOptions);
} else {
$importService = $this->importServiceFactory->create($preset);
$importService = $this->importServiceFactory->create($preset, $customSourceOptions, $customTargetOptions);
}

$this->registerEventHandlers($importService, $quiet ?? false);
try {
$importService->importData($forceUpdates ?? false);
Expand Down Expand Up @@ -110,6 +116,8 @@ public function presetsCommand(): void

/**
* Displays configuration for a given preset
*
* @param string $preset The preset to show configuration for (see Wwwision.Import.presets setting)
*/
public function presetCommand(string $preset): void
{
Expand Down Expand Up @@ -164,6 +172,18 @@ private function renderResult(Result $result): void
array_map(fn (Message $message) => $this->outputLine('<success>%s</success>', [$message->render()]), $result->getNotices());
}

private static function parseJsonOption(string|null $option): ?array
{
if ($option === null) {
return null;
}
try {
return json_decode($option, true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
throw new \InvalidArgumentException(sprintf('Failed to JSON-decode option "%s": %s', $option, $e->getMessage()), 1716823861);
}
}

/**
* @param ImportService $importService
* @param bool $quiet
Expand Down
10 changes: 5 additions & 5 deletions Classes/Factory/ImportServiceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,19 @@ public function __construct(
) {
}

public function create(string $presetName): ImportService
public function create(string $presetName, array|null $customSourceOptions, array|null $customTargetOptions): ImportService
{
return new ImportService($this->presetFactory->create($this->getPresetConfiguration($presetName)));
return new ImportService($this->presetFactory->create($this->getPresetConfiguration($presetName), $customSourceOptions, $customTargetOptions));
}

public function createFromPreset(Preset $preset): ImportService
{
return new ImportService($preset);
}

public function createWithFixture(string $presetName): ImportService
public function createWithFixture(string $presetName, array|null $customTargetOptions): ImportService
{
$preset = $this->presetFactory->create($this->getPresetConfiguration($presetName));
$preset = $this->presetFactory->create($this->getPresetConfiguration($presetName), null, $customTargetOptions);
if (!isset($this->presets[$presetName]['source']['fixture']['file'])) {
throw new \RuntimeException(sprintf('Missing "source.fixture.file" configuration for preset "%s"', $presetName), 1558433554);
}
Expand All @@ -49,7 +49,7 @@ public function createWithFixture(string $presetName): ImportService

public function createWithDataSource(string $presetName, DataSourceInterface $dataSource): ImportService
{
return new ImportService($this->presetFactory->create($this->getPresetConfiguration($presetName))->withDataSource($dataSource));
return new ImportService($this->presetFactory->create($this->getPresetConfiguration($presetName), null, null)->withDataSource($dataSource));
}

public function getPresetConfiguration(string $presetName): array
Expand Down
12 changes: 9 additions & 3 deletions Classes/Factory/PresetFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ protected function __construct(
{
}

public function create(array $configuration): Preset
public function create(array $configuration, array|null $customSourceOptions, array|null $customTargetOptions): Preset
{
if (!isset($configuration['source']['factory'])) {
throw new \RuntimeException('Missing "source.factory" configuration', 1557238721);
Expand All @@ -39,15 +39,18 @@ public function create(array $configuration): Preset
throw new \RuntimeException(sprintf('The configured "source.factory" %s is not an instance of %s', $factoryClassName, DataSourceFactoryInterface::class), 1557238800);
}
$options = $configuration['source']['options'] ?? [];
if ($customSourceOptions !== null) {
$options = [...$options, ...$customSourceOptions];
}
try {
$dataSourceFactory->optionsSchema()->validate($options);
} catch (\InvalidArgumentException $e) {
throw new \RuntimeException(sprintf('Failed to create data source for factory of type %s: %s', $factoryClassName, $e->getMessage()), 1716822862, $e);
}
return $this->createWithDataSource($configuration, $dataSourceFactory->create($options));
return $this->createWithDataSource($configuration, $dataSourceFactory->create($options), $customTargetOptions);
}

public function createWithDataSource(array $configuration, DataSourceInterface $dataSource): Preset
public function createWithDataSource(array $configuration, DataSourceInterface $dataSource, array|null $customTargetOptions): Preset
{
if (!isset($configuration['mapping'])) {
throw new \RuntimeException('Missing "mapping" configuration', 1558080904);
Expand All @@ -71,6 +74,9 @@ public function createWithDataSource(array $configuration, DataSourceInterface $
throw new \RuntimeException(sprintf('The configured "target.factory" %s is not an instance of %s', $factoryClassName, DataTargetFactoryInterface::class), 1557238877);
}
$options = $configuration['target']['options'] ?? [];
if ($customTargetOptions !== null) {
$options = [...$options, ...$customTargetOptions];
}
try {
$dataTargetFactory->optionsSchema()->validate($options);
} catch (\InvalidArgumentException $e) {
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,11 @@ Synchronizes data (add, update,delete) for the given preset.
#### Options
```
--quiet If set, no output, apart from errors, will be displayed
--force-updates If set, all local records will be updated regardless of their version/timestamp. This is useful for node type changes that require new data to be fetched
--from-fixture If set, the data will be loaded from a local fixture file instead of the configured data source
--quiet If set, no output, apart from errors, will be displayed
--force-updates If set, all local records will be updated regardless of their version/timestamp. This is useful for node type changes that require new data to be fetched
--from-fixture If set, the data will be loaded from a local fixture file instead of the configured data source
--override-source-options Allows to override default options for the data source via JSON, e.g. '{"endpoint":"https://some-custom.tld/endpoint"}'
--override-target-options Allows to override default options for the data target via JSON, e.g. '{"endpoint":"https://some-custom.tld/endpoint"}'
```
### `import:prune`
Expand Down

0 comments on commit ae93ac4

Please sign in to comment.