Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions modules/system/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,11 @@ protected function registerConsole()
$this->registerConsoleCommand('create.settings', \System\Console\CreateSettings::class);
$this->registerConsoleCommand('create.test', \System\Console\CreateTest::class);

$this->app->singleton(Console\VendorPublish::class, function ($app) {
return new Console\VendorPublish($app['files']);
});
$this->commands(Console\VendorPublish::class);

$this->registerConsoleCommand('winter.up', \System\Console\WinterUp::class);
$this->registerConsoleCommand('winter.down', \System\Console\WinterDown::class);
$this->registerConsoleCommand('winter.update', \System\Console\WinterUpdate::class);
Expand Down
4 changes: 1 addition & 3 deletions modules/system/console/PluginList.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
<?php namespace System\Console;

use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Helper\TableSeparator;
use System\Models\PluginVersion;
use Winter\Storm\Console\Command;

Expand Down Expand Up @@ -43,7 +41,7 @@ public function handle()
}

$rows = [];
foreach ($allPlugins as $plugin) {
foreach ($allPlugins->sortBy('code') as $plugin) {
$rows[] = [
$plugin->code,
$plugin->version,
Expand Down
80 changes: 80 additions & 0 deletions modules/system/console/VendorPublish.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

namespace System\Console;

use Illuminate\Foundation\Console\VendorPublishCommand;
use Illuminate\Foundation\Events\VendorTagPublished;

class VendorPublish extends VendorPublishCommand
{
use Traits\HasPluginArgument;

/**
* The console command signature.
*
* @var string
*/
protected $signature = 'vendor:publish
{plugin? : The plugin to publish assets to. <info>(eg: Winter.Blog)</info>}
{--existing : Publish and overwrite only the files that have already been published}
{--force : Overwrite any existing files}
{--all : Publish assets for all service providers without prompt}
{--provider= : The service provider that has assets you want to publish}
{--tag=* : One or many tags that have assets you want to publish}';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Publish any publishable assets from vendor packages to the specified plugin.';

/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
$this->validateProvidedPlugin();

parent::handle();
}

/**
* Publishes the assets for a tag.
*
* @param string $tag
* @return mixed
*/
protected function publishTag($tag)
{
/**
* @TODO: Continue here:
* - Temporarily override the internal paths for:
* - config_path() -> plugin/config
* - resource_path() -> plugin/resources (May want to do some magic rewriting of resources/views to plugin/views or just add support for the resources folder in a plugin)
* - database_path() -> plugin/updates/$tag/ (May want to add support for integrating the migrations in order to the version.yaml file, same as create:migration)
*/
$pathsToPublish = $this->pathsToPublish($tag);

if ($publishing = count($pathsToPublish) > 0) {
$this->components->info(sprintf(
'Publishing %sassets',
$tag ? "[$tag] " : '',
));
}

foreach ($pathsToPublish as $from => $to) {
$this->publishItem($from, $to);
}

if ($publishing === false) {
$this->components->info('No publishable resources for tag ['.$tag.'].');
} else {
$this->laravel['events']->dispatch(new VendorTagPublished($tag, $pathsToPublish));

$this->newLine();
}
}
}
57 changes: 55 additions & 2 deletions modules/system/console/traits/HasPluginArgument.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
use InvalidArgumentException;
use System\Classes\PluginBase;
use System\Classes\PluginManager;
use Throwable;
use Winter\Storm\Support\Arr;

use function Laravel\Prompts\search;
use function Laravel\Prompts\select;

/**
* Console Command Trait that provides autocompletion for the "plugin" argument
Expand All @@ -22,6 +27,8 @@ trait HasPluginArgument
*/
// protected $validatePluginInput = true;

protected ?PluginBase $plugin = null;

/**
* Return available plugins for autocompletion of the "plugin" argument
*/
Expand All @@ -45,7 +52,33 @@ public function suggestPluginValues()
}
}

return $plugins;
return Arr::sort($plugins);
}

/**
* Prompt for which provider or tag to publish.
*/
protected function promptForPlugin(): ?string
{
$choices = $this->suggestPluginValues();

$choice = windows_os()
? select(
"Which plugin would you like to select?",
$choices,
scroll: 15,
)
: search(
label: "Which plugin would you like to select?",
placeholder: 'Search...',
options: fn ($search) => array_values(array_filter(
$choices,
fn ($choice) => str_contains(strtolower($choice), strtolower($search))
)),
scroll: 15,
);

return $choice;
}

/**
Expand All @@ -55,7 +88,7 @@ public function suggestPluginValues()
public function getPluginIdentifier($identifier = null): string
{
$pluginManager = PluginManager::instance();
$pluginName = $identifier ?? $this->argument('plugin');
$pluginName = $identifier ?? $this->argument('plugin') ?? $this->promptForPlugin();
$pluginName = $pluginManager->normalizeIdentifier($pluginName);

if (
Expand All @@ -76,4 +109,24 @@ public function getPlugin($identifier = null): ?PluginBase
{
return PluginManager::instance()->findByIdentifier($this->getPluginIdentifier($identifier));
}

/**
* Validates that the provided plugin can be accessed
*
* @throws InvalidArgumentException if it cannot be
*/
public function validateProvidedPlugin()
{
if (!$this->plugin) {
try {
$this->plugin = $this->getPlugin();
} catch (Throwable $e) {
throw new InvalidArgumentException(sprintf(
'Provided plugin "%s" failed to load: %s',
$this->argument('plugin'),
$e->getMessage()
));
}
}
}
}
Loading