-
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2062 from hydephp/interactive-component-publisher…
…-command [2.x] Interactive component publisher command
- Loading branch information
Showing
11 changed files
with
924 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Hyde\Console\Helpers; | ||
|
||
use Laravel\Prompts\Prompt; | ||
use Symfony\Component\Console\Input\InputInterface; | ||
|
||
/** | ||
* @internal This class contains internal helpers for interacting with the console, and for easier testing. | ||
* | ||
* @codeCoverageIgnore This class provides internal testing helpers and does not need to be tested. | ||
*/ | ||
class ConsoleHelper | ||
{ | ||
/** Allows for mocking the Windows OS check. Remember to clear the mock after the test. */ | ||
protected static ?bool $enableLaravelPrompts = null; | ||
|
||
public static function clearMocks(): void | ||
{ | ||
static::$enableLaravelPrompts = null; | ||
} | ||
|
||
public static function disableLaravelPrompts(): void | ||
{ | ||
static::$enableLaravelPrompts = false; | ||
} | ||
|
||
public static function mockWindowsOs(bool $isWindowsOs): void | ||
{ | ||
static::$enableLaravelPrompts = ! $isWindowsOs; | ||
} | ||
|
||
public static function canUseLaravelPrompts(InputInterface $input): bool | ||
{ | ||
if (static::$enableLaravelPrompts !== null) { | ||
return static::$enableLaravelPrompts; | ||
} | ||
|
||
return $input->isInteractive() && windows_os() === false && Prompt::shouldFallback() === false; | ||
} | ||
} |
87 changes: 87 additions & 0 deletions
87
packages/framework/src/Console/Helpers/InteractivePublishCommandHelper.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Hyde\Console\Helpers; | ||
|
||
use Hyde\Facades\Filesystem; | ||
use Illuminate\Support\Arr; | ||
use Illuminate\Support\Str; | ||
|
||
/** | ||
* @internal This class offloads logic from the PublishViewsCommand class and should not be used elsewhere. | ||
*/ | ||
class InteractivePublishCommandHelper | ||
{ | ||
/** @var array<string, string> Map of source files to target files */ | ||
protected array $publishableFilesMap; | ||
|
||
protected readonly int $originalFileCount; | ||
|
||
/** @param array<string, string> $publishableFilesMap */ | ||
public function __construct(array $publishableFilesMap) | ||
{ | ||
$this->publishableFilesMap = $publishableFilesMap; | ||
$this->originalFileCount = count($publishableFilesMap); | ||
} | ||
|
||
/** @return array<string, string> */ | ||
public function getFileChoices(): array | ||
{ | ||
return Arr::mapWithKeys($this->publishableFilesMap, /** @return array<string, string> */ function (string $target, string $source): array { | ||
return [$source => $this->pathRelativeToDirectory($source, $this->getBaseDirectory())]; | ||
}); | ||
} | ||
|
||
/** | ||
* Only publish the selected files. | ||
* | ||
* @param array<string> $selectedFiles Array of selected file paths, matching the keys of the publishableFilesMap. | ||
*/ | ||
public function only(array $selectedFiles): void | ||
{ | ||
$this->publishableFilesMap = Arr::only($this->publishableFilesMap, $selectedFiles); | ||
} | ||
|
||
/** Find the most specific common parent directory path for the files, trimming as much as possible whilst keeping specificity and uniqueness. */ | ||
public function getBaseDirectory(): string | ||
{ | ||
$partsMap = collect($this->publishableFilesMap)->map(function (string $file): array { | ||
return explode('/', $file); | ||
}); | ||
|
||
$commonParts = $partsMap->reduce(function (array $carry, array $parts): array { | ||
return array_intersect($carry, $parts); | ||
}, $partsMap->first()); | ||
|
||
return implode('/', $commonParts); | ||
} | ||
|
||
public function publishFiles(): void | ||
{ | ||
foreach ($this->publishableFilesMap as $source => $target) { | ||
Filesystem::ensureDirectoryExists(dirname($target)); | ||
Filesystem::copy($source, $target); | ||
} | ||
} | ||
|
||
public function formatOutput(string $group): string | ||
{ | ||
$fileCount = count($this->publishableFilesMap); | ||
$publishedOneFile = $fileCount === 1; | ||
$publishedAllGroups = $group === 'all'; | ||
$publishedAllFiles = $fileCount === $this->originalFileCount; | ||
$selectedFilesModifier = $publishedAllFiles ? 'all' : 'selected'; | ||
|
||
return match (true) { | ||
$publishedAllGroups => sprintf('Published all %d files to [%s]', $fileCount, $this->getBaseDirectory()), | ||
$publishedOneFile => sprintf('Published selected file to [%s]', reset($this->publishableFilesMap)), | ||
default => sprintf('Published %s [%s] files to [%s]', $selectedFilesModifier, Str::singular($group), $this->getBaseDirectory()) | ||
}; | ||
} | ||
|
||
protected function pathRelativeToDirectory(string $source, string $directory): string | ||
{ | ||
return Str::after($source, basename($directory).'/'); | ||
} | ||
} |
Oops, something went wrong.