Skip to content

Commit

Permalink
feat: allow specifying extensions when installing an instance (#3655)
Browse files Browse the repository at this point in the history
* feat: allow specifying extensions when installing an instance

Useful when doing migrations where more than the default extensions are required to migrate the data to flarum. This allows quickly spinning up a flarum database with the necessary schema.

Signed-off-by: Sami Mazouz <[email protected]>

* fix: consider dependency graph before running migrations

Signed-off-by: Sami Mazouz <[email protected]>

Signed-off-by: Sami Mazouz <[email protected]>
  • Loading branch information
SychO9 authored Nov 6, 2022
1 parent f005b9e commit 69311ae
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 19 deletions.
2 changes: 1 addition & 1 deletion framework/core/src/Extension/Extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ public function setVersion($version)
/**
* Get the list of flarum extensions that this extension depends on.
*
* @param array $extensionSet: An associative array where keys are the composer package names
* @param array<string, mixed> $extensionSet: An associative array where keys are the composer package names
* of installed extensions. Used to figure out which dependencies
* are flarum extensions.
* @internal
Expand Down
12 changes: 7 additions & 5 deletions framework/core/src/Extension/ExtensionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -441,11 +441,12 @@ public static function pluckTitles(array $exts)
*
* @param Extension[] $extensionList
*
* @return array with 2 keys: 'valid' points to an ordered array of \Flarum\Extension\Extension
* 'missingDependencies' points to an associative array of extensions that could not be resolved due
* to missing dependencies, in the format extension id => array of missing dependency IDs.
* 'circularDependencies' points to an array of extensions ids of extensions
* that cannot be processed due to circular dependencies
* @return array{valid: Extension[], missingDependencies: array<string, string[]>, circularDependencies: string[]}
* 'valid' points to an ordered array of \Flarum\Extension\Extension
* 'missingDependencies' points to an associative array of extensions that could not be resolved due
* to missing dependencies, in the format extension id => array of missing dependency IDs.
* 'circularDependencies' points to an array of extensions ids of extensions
* that cannot be processed due to circular dependencies
*
* @internal
*/
Expand All @@ -471,6 +472,7 @@ public static function resolveExtensionOrder($extensionList)
$extensionIdMapping[$extension->getId()] = $extension;
}

/** @var Extension $extension */
foreach ($extensionList as $extension) {
$optionalDependencies = array_filter($extension->getOptionalDependencyIds(), function ($id) use ($extensionIdMapping) {
return array_key_exists($id, $extensionIdMapping);
Expand Down
5 changes: 4 additions & 1 deletion framework/core/src/Install/Console/FileDataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class FileDataProvider implements DataProviderInterface
protected $databaseConfiguration = [];
protected $adminUser = [];
protected $settings = [];
protected $extensions = [];

public function __construct(InputInterface $input)
{
Expand All @@ -48,6 +49,7 @@ public function __construct(InputInterface $input)
$this->databaseConfiguration = $configuration['databaseConfiguration'] ?? [];
$this->adminUser = $configuration['adminUser'] ?? [];
$this->settings = $configuration['settings'] ?? [];
$this->extensions = explode(',', $configuration['extensions'] ?? '');
} else {
throw new Exception('Configuration file does not exist.');
}
Expand All @@ -60,7 +62,8 @@ public function configure(Installation $installation): Installation
->baseUrl(BaseUrl::fromString($this->baseUrl))
->databaseConfig($this->getDatabaseConfiguration())
->adminUser($this->getAdminUser())
->settings($this->settings);
->settings($this->settings)
->extensions($this->extensions);
}

private function getDatabaseConfiguration(): DatabaseConfig
Expand Down
32 changes: 20 additions & 12 deletions framework/core/src/Install/Steps/EnableBundledExtensions.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Flarum\Database\DatabaseMigrationRepository;
use Flarum\Database\Migrator;
use Flarum\Extension\Extension;
use Flarum\Extension\ExtensionManager;
use Flarum\Install\Step;
use Flarum\Settings\DatabaseSettingsRepository;
use Illuminate\Database\ConnectionInterface;
Expand Down Expand Up @@ -80,7 +81,7 @@ public function getMessage()

public function run()
{
$extensions = $this->loadExtensions();
$extensions = ExtensionManager::resolveExtensionOrder($this->loadExtensions()->all())['valid'];

foreach ($extensions as $extension) {
$extension->migrate($this->getMigrator());
Expand All @@ -89,14 +90,15 @@ public function run()
);
}

(new DatabaseSettingsRepository($this->database))->set(
'extensions_enabled',
$extensions->keys()->toJson()
);
$extensionNames = json_encode(array_map(function (Extension $extension) {
return $extension->getId();
}, $extensions));

(new DatabaseSettingsRepository($this->database))->set('extensions_enabled', $extensionNames);
}

/**
* @return \Illuminate\Support\Collection
* @return \Illuminate\Support\Collection<Extension>
*/
private function loadExtensions()
{
Expand All @@ -106,7 +108,7 @@ private function loadExtensions()
// Composer 2.0 changes the structure of the installed.json manifest
$installed = $installed['packages'] ?? $installed;

return (new Collection($installed))
$installedExtensions = (new Collection($installed))
->filter(function ($package) {
return Arr::get($package, 'type') == 'flarum-extension';
})->filter(function ($package) {
Expand All @@ -120,13 +122,19 @@ private function loadExtensions()
$extension->setVersion(Arr::get($package, 'version'));

return $extension;
})->filter(function (Extension $extension) {
return in_array($extension->getId(), $this->enabledExtensions);
})->sortBy(function (Extension $extension) {
return $extension->getTitle();
})->mapWithKeys(function (Extension $extension) {
return [$extension->getId() => $extension];
return [$extension->name => $extension];
});

return $installedExtensions->filter(function (Extension $extension) {
return in_array($extension->getId(), $this->enabledExtensions);
})->map(function (Extension $extension) use ($installedExtensions) {
$extension->calculateDependencies($installedExtensions->map(function () {
return true;
})->toArray());

return $extension;
});
}

private function getMigrator(): Migrator
Expand Down

0 comments on commit 69311ae

Please sign in to comment.