setName('init') ->setDescription('Stage Grav 2.0 alongside this site and prepare the migration wizard.') ->addOption( 'source-url', null, InputOption::VALUE_REQUIRED, 'URL of the Grav 2.0 release zip (overrides plugin config).' ) ->addOption( 'source-zip', null, InputOption::VALUE_REQUIRED, 'Local path to a Grav 2.0 zip (overrides URL — for development).' ); } protected function serve(): int { $grav = Grav::instance(); $config = (array) $grav['config']->get('plugins.migrate-grav', []); if (!($config['enabled'] ?? false)) { $this->output->writeln('Plugin migrate-grav is not enabled.'); return 1; } $sourceUrl = $this->input->getOption('source-url'); $sourceZip = $this->input->getOption('source-zip'); if ($sourceUrl) { $config['source_url'] = $sourceUrl; } if ($sourceZip) { $config['source_local_zip'] = $sourceZip; } // Forward the site's GPM channel so Kickoff can append `?testing` to // the source URL when the user has opted into the testing channel. $config['gpm_channel'] = (string) $grav['config']->get('system.gpm.releases', 'stable'); // Forward Grav's proxy config so the zip download (Kickoff) and the // standalone wizard's outbound HTTP (via .migrating flag) both honor // system.http.proxy_url / proxy_cert_path. $config['proxy_url'] = (string) $grav['config']->get('system.http.proxy_url', ''); $config['proxy_cert_path'] = (string) $grav['config']->get('system.http.proxy_cert_path', ''); require_once dirname(__DIR__) . '/classes/Kickoff.php'; $webroot = defined('GRAV_WEBROOT') ? GRAV_WEBROOT : GRAV_ROOT; $kickoff = new Kickoff($webroot, $config); try { $payload = $kickoff->run([ 'grav_version' => GRAV_VERSION, 'admin_user' => null, 'trigger' => 'cli', ]); } catch (RuntimeException $e) { $this->output->writeln('Kickoff failed: ' . $e->getMessage()); return 1; } $this->output->writeln(''); $this->output->writeln('Grav 2.0 staged successfully.'); $this->output->writeln(''); $this->output->writeln(' Token: ' . $payload['token']); $this->output->writeln(' Stage dir: ' . $payload['stage_dir']); $this->output->writeln(' Staged zip: ' . $payload['staged_zip']); $this->output->writeln(' Wizard URL: ' . $payload['wizard_url']); $this->output->writeln(''); $this->output->writeln('Next step — open the wizard in your browser:'); $this->output->writeln(''); $this->output->writeln(' ' . $payload['wizard_url']); $this->output->writeln(''); $this->output->writeln('Important: do NOT continue inside this Grav 1.x process — the'); $this->output->writeln('wizard runs standalone to avoid file locks and library conflicts.'); return 0; } }