123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- <?php
- /**
- * @package Grav\Console\Cli
- *
- * @copyright Copyright (c) 2015 - 2023 Trilby Media, LLC. All rights reserved.
- * @license MIT License; see LICENSE file for details.
- */
- namespace Grav\Console\Cli;
- use Grav\Common\Filesystem\Folder;
- use Grav\Common\Utils;
- use Grav\Console\GravCommand;
- use RuntimeException;
- use Symfony\Component\Console\Input\InputArgument;
- use Symfony\Component\Console\Input\InputOption;
- use function count;
- /**
- * Class SandboxCommand
- * @package Grav\Console\Cli
- */
- class SandboxCommand extends GravCommand
- {
- /** @var array */
- protected $directories = [
- '/assets',
- '/backup',
- '/cache',
- '/images',
- '/logs',
- '/tmp',
- '/user/accounts',
- '/user/config',
- '/user/data',
- '/user/pages',
- '/user/plugins',
- '/user/themes',
- ];
- /** @var array */
- protected $files = [
- '/.dependencies',
- '/.htaccess',
- '/user/config/site.yaml',
- '/user/config/system.yaml',
- ];
- /** @var array */
- protected $mappings = [
- '/.gitignore' => '/.gitignore',
- '/.editorconfig' => '/.editorconfig',
- '/CHANGELOG.md' => '/CHANGELOG.md',
- '/LICENSE.txt' => '/LICENSE.txt',
- '/README.md' => '/README.md',
- '/CONTRIBUTING.md' => '/CONTRIBUTING.md',
- '/index.php' => '/index.php',
- '/composer.json' => '/composer.json',
- '/bin' => '/bin',
- '/system' => '/system',
- '/vendor' => '/vendor',
- '/webserver-configs' => '/webserver-configs',
- ];
- /** @var string */
- protected $source;
- /** @var string */
- protected $destination;
- /**
- * @return void
- */
- protected function configure(): void
- {
- $this
- ->setName('sandbox')
- ->setDescription('Setup of a base Grav system in your webroot, good for development, playing around or starting fresh')
- ->addArgument(
- 'destination',
- InputArgument::REQUIRED,
- 'The destination directory to symlink into'
- )
- ->addOption(
- 'symlink',
- 's',
- InputOption::VALUE_NONE,
- 'Symlink the base grav system'
- )
- ->setHelp("The <info>sandbox</info> command help create a development environment that can optionally use symbolic links to link the core of grav to the git cloned repository.\nGood for development, playing around or starting fresh");
- $source = getcwd();
- if ($source === false) {
- throw new RuntimeException('Internal Error');
- }
- $this->source = $source;
- }
- /**
- * @return int
- */
- protected function serve(): int
- {
- $input = $this->getInput();
- $this->destination = $input->getArgument('destination');
- // Create Some core stuff if it doesn't exist
- $error = $this->createDirectories();
- if ($error) {
- return $error;
- }
- // Copy files or create symlinks
- $error = $input->getOption('symlink') ? $this->symlink() : $this->copy();
- if ($error) {
- return $error;
- }
- $error = $this->pages();
- if ($error) {
- return $error;
- }
- $error = $this->initFiles();
- if ($error) {
- return $error;
- }
- $error = $this->perms();
- if ($error) {
- return $error;
- }
- return 0;
- }
- /**
- * @return int
- */
- private function createDirectories(): int
- {
- $io = $this->getIO();
- $io->newLine();
- $io->writeln('<comment>Creating Directories</comment>');
- $dirs_created = false;
- if (!file_exists($this->destination)) {
- Folder::create($this->destination);
- }
- foreach ($this->directories as $dir) {
- if (!file_exists($this->destination . $dir)) {
- $dirs_created = true;
- $io->writeln(' <cyan>' . $dir . '</cyan>');
- Folder::create($this->destination . $dir);
- }
- }
- if (!$dirs_created) {
- $io->writeln(' <red>Directories already exist</red>');
- }
- return 0;
- }
- /**
- * @return int
- */
- private function copy(): int
- {
- $io = $this->getIO();
- $io->newLine();
- $io->writeln('<comment>Copying Files</comment>');
- foreach ($this->mappings as $source => $target) {
- if ((string)(int)$source === (string)$source) {
- $source = $target;
- }
- $from = $this->source . $source;
- $to = $this->destination . $target;
- $io->writeln(' <cyan>' . $source . '</cyan> <comment>-></comment> ' . $to);
- @Folder::rcopy($from, $to);
- }
- return 0;
- }
- /**
- * @return int
- */
- private function symlink(): int
- {
- $io = $this->getIO();
- $io->newLine();
- $io->writeln('<comment>Resetting Symbolic Links</comment>');
- // Symlink also tests if using git.
- if (is_dir($this->source . '/tests')) {
- $this->mappings['/tests'] = '/tests';
- }
- foreach ($this->mappings as $source => $target) {
- if ((string)(int)$source === (string)$source) {
- $source = $target;
- }
- $from = $this->source . $source;
- $to = $this->destination . $target;
- $io->writeln(' <cyan>' . $source . '</cyan> <comment>-></comment> ' . $to);
- if (is_dir($to)) {
- @Folder::delete($to);
- } else {
- @unlink($to);
- }
- symlink($from, $to);
- }
- return 0;
- }
- /**
- * @return int
- */
- private function pages(): int
- {
- $io = $this->getIO();
- $io->newLine();
- $io->writeln('<comment>Pages Initializing</comment>');
- // get pages files and initialize if no pages exist
- $pages_dir = $this->destination . '/user/pages';
- $pages_files = array_diff(scandir($pages_dir), ['..', '.']);
- if (count($pages_files) === 0) {
- $destination = $this->source . '/user/pages';
- Folder::rcopy($destination, $pages_dir);
- $io->writeln(' <cyan>' . $destination . '</cyan> <comment>-></comment> Created');
- }
- return 0;
- }
- /**
- * @return int
- */
- private function initFiles(): int
- {
- if (!$this->check()) {
- return 1;
- }
- $io = $this->getIO();
- $io->newLine();
- $io->writeln('<comment>File Initializing</comment>');
- $files_init = false;
- // Copy files if they do not exist
- foreach ($this->files as $source => $target) {
- if ((string)(int)$source === (string)$source) {
- $source = $target;
- }
- $from = $this->source . $source;
- $to = $this->destination . $target;
- if (!file_exists($to)) {
- $files_init = true;
- copy($from, $to);
- $io->writeln(' <cyan>' . $target . '</cyan> <comment>-></comment> Created');
- }
- }
- if (!$files_init) {
- $io->writeln(' <red>Files already exist</red>');
- }
- return 0;
- }
- /**
- * @return int
- */
- private function perms(): int
- {
- $io = $this->getIO();
- $io->newLine();
- $io->writeln('<comment>Permissions Initializing</comment>');
- $dir_perms = 0755;
- $binaries = glob($this->destination . DS . 'bin' . DS . '*');
- foreach ($binaries as $bin) {
- chmod($bin, $dir_perms);
- $io->writeln(' <cyan>bin/' . Utils::basename($bin) . '</cyan> permissions reset to ' . decoct($dir_perms));
- }
- $io->newLine();
- return 0;
- }
- /**
- * @return bool
- */
- private function check(): bool
- {
- $success = true;
- $io = $this->getIO();
- if (!file_exists($this->destination)) {
- $io->writeln(' file: <red>' . $this->destination . '</red> does not exist!');
- $success = false;
- }
- foreach ($this->directories as $dir) {
- if (!file_exists($this->destination . $dir)) {
- $io->writeln(' directory: <red>' . $dir . '</red> does not exist!');
- $success = false;
- }
- }
- foreach ($this->mappings as $target => $link) {
- if (!file_exists($this->destination . $target)) {
- $io->writeln(' mappings: <red>' . $target . '</red> does not exist!');
- $success = false;
- }
- }
- if (!$success) {
- $io->newLine();
- $io->writeln('<comment>install should be run with --symlink|--s to symlink first</comment>');
- }
- return $success;
- }
- }
|