%PDF- %PDF-
Direktori : /www/loslex/demo/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Console/ |
Current File : /www/loslex/demo/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Console/PublishCommand.php |
<?php namespace Sentry\Laravel\Console; use Exception; use Illuminate\Console\Command; use Illuminate\Support\Str; use RuntimeException; use Sentry\Dsn; use Sentry\Laravel\ServiceProvider; use Symfony\Component\Process\Process; class PublishCommand extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'sentry:publish {--dsn=} {--without-performance-monitoring} {--without-test} {--without-javascript-sdk}'; /** * The console command description. * * @var string */ protected $description = 'Publishes and configures the Sentry config.'; protected const SDK_CHOICE_BROWSER = 'JavaScript (default)'; protected const SDK_CHOICE_VUE = 'Vue.js'; protected const SDK_CHOICE_REACT = 'React'; protected const SDK_CHOICE_ANGULAR = 'Angular'; protected const SDK_CHOICE_SVELTE = 'Svelte'; /** * Execute the console command. * * @return int */ public function handle(): int { $arg = []; $env = []; $dsn = $this->option('dsn'); if (!empty($dsn) || !$this->isEnvKeySet('SENTRY_LARAVEL_DSN')) { if (empty($dsn)) { $dsnFromInput = $this->askForDsnInput(); if (empty($dsnFromInput)) { $this->error('Please provide a valid DSN using the `--dsn` option or setting `SENTRY_LARAVEL_DSN` in your `.env` file!'); return 1; } $dsn = $dsnFromInput; } $env['SENTRY_LARAVEL_DSN'] = $dsn; $arg['--dsn'] = $dsn; } $testCommandPrompt = 'Do you want to send a test event to Sentry?'; if ($this->confirm('Enable Performance Monitoring?', !$this->option('without-performance-monitoring'))) { $testCommandPrompt = 'Do you want to send a test event & transaction to Sentry?'; $env['SENTRY_TRACES_SAMPLE_RATE'] = '1.0'; $arg['--transaction'] = true; } elseif ($this->isEnvKeySet('SENTRY_TRACES_SAMPLE_RATE')) { $env['SENTRY_TRACES_SAMPLE_RATE'] = '0'; } if ($this->confirm($testCommandPrompt, !$this->option('without-test'))) { $testResult = $this->call('sentry:test', $arg); if ($testResult === 1) { return 1; } } $this->info('Publishing Sentry config...'); $this->call('vendor:publish', ['--provider' => ServiceProvider::class]); if (!$this->setEnvValues($env)) { return 1; } if ($this->confirm('Do you want to install one of our JavaScript SDKs?', !$this->option('without-javascript-sdk'))) { $this->installJavaScriptSdk(); } return 0; } private function setEnvValues(array $values): bool { $envFilePath = app()->environmentFilePath(); $envFileContents = file_get_contents($envFilePath); if (!$envFileContents) { $this->error('Could not read `.env` file!'); return false; } if (count($values) > 0) { foreach ($values as $envKey => $envValue) { if ($this->isEnvKeySet($envKey, $envFileContents)) { $envFileContents = preg_replace("/^{$envKey}=.*?[\s$]/m", "{$envKey}={$envValue}\n", $envFileContents); $this->info("Updated {$envKey} with new value in your `.env` file."); } else { $envFileContents .= "{$envKey}={$envValue}\n"; $this->info("Added {$envKey} to your `.env` file."); } } } if (!file_put_contents($envFilePath, $envFileContents)) { $this->error('Updating the `.env` file failed!'); return false; } return true; } private function isEnvKeySet(string $envKey, ?string $envFileContents = null): bool { $envFileContents = $envFileContents ?? file_get_contents(app()->environmentFilePath()); return (bool)preg_match("/^{$envKey}=.*?[\s$]/m", $envFileContents); } private function askForDsnInput(): string { if ($this->option('no-interaction')) { return ''; } while (true) { $this->info(''); $this->question('Please paste the DSN here'); $dsn = $this->ask('DSN'); // In case someone copies it with SENTRY_LARAVEL_DSN= or SENTRY_DSN= $dsn = Str::after($dsn, '='); try { Dsn::createFromString($dsn); return $dsn; } catch (Exception $e) { // Not a valid DSN do it again $this->error('The DSN is not valid, please make sure to paste a valid DSN!'); } } } private function installJavaScriptSdk(): void { $framework = $this->choice( 'Which frontend framework are you using?', [ self::SDK_CHOICE_BROWSER, self::SDK_CHOICE_VUE, self::SDK_CHOICE_REACT, self::SDK_CHOICE_ANGULAR, self::SDK_CHOICE_SVELTE, ], self::SDK_CHOICE_BROWSER ); $snippet = ''; switch ($framework) { case self::SDK_CHOICE_BROWSER: $this->updateNodePackages(function ($packages) { return [ '@sentry/browser' => '^7.40.0', ] + $packages; }); $snippet = file_get_contents(__DIR__ . '/../../../../stubs/sentry-javascript/browser.js'); break; case self::SDK_CHOICE_VUE: $this->updateNodePackages(function ($packages) { return [ '@sentry/vue' => '^7.40.0', ] + $packages; }); $snippet = file_get_contents(__DIR__ . '/../../../../stubs/sentry-javascript/vue.js'); break; case self::SDK_CHOICE_REACT: $this->updateNodePackages(function ($packages) { return [ '@sentry/react' => '^7.40.0', ] + $packages; }); $snippet = file_get_contents(__DIR__ . '/../../../../stubs/sentry-javascript/react.js'); break; case self::SDK_CHOICE_ANGULAR: $this->updateNodePackages(function ($packages) { return [ '@sentry/angular' => '^7.40.0', ] + $packages; }); $snippet = file_get_contents(__DIR__ . '/../../../../stubs/sentry-javascript/angular.js'); break; case self::SDK_CHOICE_SVELTE: $this->updateNodePackages(function ($packages) { return [ '@sentry/svelte' => '^7.40.0', ] + $packages; }); $snippet = file_get_contents(__DIR__ . '/../../../../stubs/sentry-javascript/svelte.js'); break; } $env['VITE_SENTRY_DSN_PUBLIC'] ='"${SENTRY_LARAVEL_DSN}"'; $this->setEnvValues($env); if (file_exists(base_path('pnpm-lock.yaml'))) { $this->runCommands(['pnpm install']); } elseif (file_exists(base_path('yarn.lock'))) { $this->runCommands(['yarn install']); } else { $this->runCommands(['npm install']); } $this->newLine(); $this->components->info('Sentry JavaScript SDK installed successfully.'); $this->line('Put the following snippet into your JavaScript entry file:'); $this->newLine(); $this->line('<bg=blue>' . $snippet . '</>'); $this->newLine(); $this->line('For the best Sentry experience, we recommend you to set up dedicated projects for your Laravel and JavaScript applications.'); } private function updateNodePackages(callable $callback) { if (! file_exists(base_path('package.json'))) { return; } $packages = json_decode(file_get_contents(base_path('package.json')), true); $packages['dependencies'] = $callback( array_key_exists('dependencies', $packages) ? $packages['dependencies'] : [], 'dependencies' ); ksort($packages['dependencies']); file_put_contents( base_path('package.json'), json_encode($packages, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT).PHP_EOL ); } private function runCommands($commands) { $process = Process::fromShellCommandline(implode(' && ', $commands), null, null, null, null); if ('\\' !== DIRECTORY_SEPARATOR && file_exists('/dev/tty') && is_readable('/dev/tty')) { try { $process->setTty(true); } catch (RuntimeException $e) { $this->output->writeln(' <bg=yellow;fg=black> WARN </> '.$e->getMessage().PHP_EOL); } } $process->run(function ($type, $line) { $this->output->write(' '.$line); }); } }