VendorPublishCommand.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * This file is part of Hyperf.
  5. *
  6. * @link https://www.hyperf.io
  7. * @document https://hyperf.wiki
  8. * @contact group@hyperf.io
  9. * @license https://github.com/hyperf/hyperf/blob/master/LICENSE
  10. */
  11. namespace Hyperf\Devtool;
  12. use Hyperf\Collection\Arr;
  13. use Hyperf\Command\Annotation\Command;
  14. use Hyperf\Support\Composer;
  15. use Hyperf\Support\Filesystem\Filesystem;
  16. use Symfony\Component\Console\Command\Command as SymfonyCommand;
  17. use Symfony\Component\Console\Input\InputArgument;
  18. use Symfony\Component\Console\Input\InputInterface;
  19. use Symfony\Component\Console\Input\InputOption;
  20. use Symfony\Component\Console\Output\OutputInterface;
  21. #[Command]
  22. class VendorPublishCommand extends SymfonyCommand
  23. {
  24. protected ?OutputInterface $output = null;
  25. protected bool $force = false;
  26. public function __construct(protected Filesystem $filesystem)
  27. {
  28. parent::__construct('vendor:publish');
  29. }
  30. protected function configure()
  31. {
  32. $this->setDescription('Publish any publishable configs from vendor packages.')
  33. ->addArgument('package', InputArgument::REQUIRED, 'The package file you want to publish.')
  34. ->addOption('id', 'i', InputOption::VALUE_OPTIONAL, 'The id of the package you want to publish.', null)
  35. ->addOption('show', 's', InputOption::VALUE_OPTIONAL, 'Show all packages can be publish.', false)
  36. ->addOption('force', 'f', InputOption::VALUE_OPTIONAL, 'Overwrite any existing files', false);
  37. }
  38. protected function execute(InputInterface $input, OutputInterface $output): int
  39. {
  40. $this->output = $output;
  41. $this->force = $input->getOption('force') !== false;
  42. $package = $input->getArgument('package');
  43. $show = $input->getOption('show') !== false;
  44. $id = $input->getOption('id');
  45. $extra = Composer::getMergedExtra()[$package] ?? null;
  46. if (empty($extra)) {
  47. $output->writeln(sprintf('<fg=red>package [%s] misses `extra` field in composer.json.</>', $package));
  48. return SIGTERM;
  49. }
  50. $provider = Arr::get($extra, 'hyperf.config');
  51. $config = (new $provider())();
  52. $publish = Arr::get($config, 'publish');
  53. if (empty($publish)) {
  54. $output->writeln(sprintf('<fg=red>No file can be published from package [%s].</>', $package));
  55. return SIGTERM;
  56. }
  57. if ($show) {
  58. foreach ($publish as $item) {
  59. $out = '';
  60. foreach ($item as $key => $value) {
  61. $out .= sprintf('%s: %s', $key, $value) . PHP_EOL;
  62. }
  63. $output->writeln(sprintf('<fg=green>%s</>', $out));
  64. }
  65. return 0;
  66. }
  67. if ($id) {
  68. $item = Arr::where($publish, function ($item) use ($id) {
  69. return $item['id'] == $id;
  70. });
  71. if (empty($item)) {
  72. $output->writeln(sprintf('<fg=red>No file can be published from [%s].</>', $id));
  73. return SIGTERM;
  74. }
  75. return $this->copy($package, $item);
  76. }
  77. return $this->copy($package, $publish);
  78. }
  79. protected function copy($package, $items)
  80. {
  81. foreach ($items as $item) {
  82. if (! isset($item['id'], $item['source'], $item['destination'])) {
  83. continue;
  84. }
  85. $id = $item['id'];
  86. $source = $item['source'];
  87. $destination = $item['destination'];
  88. if (! $this->force && $this->filesystem->exists($destination)) {
  89. $this->output->writeln(sprintf('<fg=red>[%s] already exists.</>', $destination));
  90. continue;
  91. }
  92. if (! $this->filesystem->exists($dirname = dirname($destination))) {
  93. $this->filesystem->makeDirectory($dirname, 0755, true);
  94. }
  95. if ($this->filesystem->isDirectory($source)) {
  96. $this->filesystem->copyDirectory($source, $destination);
  97. } else {
  98. $this->filesystem->copy($source, $destination);
  99. }
  100. $this->output->writeln(sprintf('<fg=green>[%s] publishes [%s] successfully.</>', $package, $id));
  101. }
  102. return 0;
  103. }
  104. }