diff --git a/composer.json b/composer.json
index 6ce6f96..cab6270 100644
--- a/composer.json
+++ b/composer.json
@@ -8,8 +8,9 @@
"composer-runtime-api": "^2.2",
"guzzlehttp/guzzle": "^6.5.5|^7.0.1",
"illuminate/collections": "^10.0|^11.0|^12.0|^13.0",
- "laravel/prompts": "^0.3.19",
+ "laravel/prompts": "^0.3.21",
"symfony/console": "^6.2|^7.0",
+ "symfony/polyfill-mbstring": "^1.31",
"symfony/process": "^6.0|^7.0"
},
"require-dev": {
diff --git a/src/Concerns/InteractsWithHerdOrValet.php b/src/Concerns/InteractsWithHerdOrValet.php
new file mode 100644
index 0000000..1d5698f
--- /dev/null
+++ b/src/Concerns/InteractsWithHerdOrValet.php
@@ -0,0 +1,42 @@
+runOnValetOrHerd('paths'));
+
+ return is_array($paths)
+ && (in_array(dirname($directory), $paths) || in_array(dirname($directory).DIRECTORY_SEPARATOR, $paths));
+ }
+
+ protected function generateAppUrl(string $name): string
+ {
+ $hostname = mb_strtolower($name).'.'.($this->runOnValetOrHerd('tld') ?: 'test');
+
+ return gethostbyname($hostname.'.') !== $hostname.'.' ? 'http://'.$hostname : 'http://localhost';
+ }
+
+ protected function runOnValetOrHerd(string $command): string|false
+ {
+ foreach (['herd', 'valet'] as $tool) {
+ $process = new Process([$tool, $command, '-v']);
+
+ try {
+ $process->run();
+
+ if ($process->isSuccessful()) {
+ return trim($process->getOutput());
+ }
+ } catch (ProcessStartFailedException) {
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/src/NewCommand.php b/src/NewCommand.php
index 2b5e9a0..de28802 100644
--- a/src/NewCommand.php
+++ b/src/NewCommand.php
@@ -4,6 +4,9 @@
use GuzzleHttp\Client;
use Laravel\Prompts\ConfirmPrompt;
+use Laravel\Prompts\Elements\Heading;
+use Laravel\Prompts\Elements\Link;
+use Laravel\Prompts\Elements\NumberedList;
use Laravel\Prompts\Prompt;
use Laravel\Prompts\SelectPrompt;
use Laravel\Prompts\SuggestPrompt;
@@ -22,6 +25,7 @@
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Process\Process;
+use function Laravel\Prompts\callout;
use function Laravel\Prompts\confirm;
use function Laravel\Prompts\intro;
use function Laravel\Prompts\select;
@@ -30,7 +34,7 @@
class NewCommand extends Command
{
- use Concerns\ConfiguresDatabase, Concerns\ConfiguresPrompts, Concerns\RunsCommands;
+ use Concerns\ConfiguresDatabase, Concerns\ConfiguresPrompts, Concerns\InteractsWithHerdOrValet, Concerns\RunsCommands;
const BASE_REPO = 'statamic/statamic';
const OUTPOST_ENDPOINT = 'https://outpost.statamic.com/v3/starter-kits/';
@@ -1047,11 +1051,21 @@ protected function enableStatamicPro()
*/
protected function showSuccessMessage()
{
- $this->output->writeln(PHP_EOL.' [β] Statamic was installed successfully!'.PHP_EOL);
- $this->output->writeln(' You may now enter your project directory using cd '.$this->relativePath.','.PHP_EOL);
- $this->output->writeln(' The documentation is always available at statamic.dev and you can ');
- $this->output->writeLn(' join the community on Discord at statamic.com/discord anytime.'.PHP_EOL);
- $this->output->writeLn(' Now go βΒ it\'s time to create something wonderful! π'.PHP_EOL);
+ $steps = ['cd '.$this->relativePath];
+
+ $steps[] = $this->isParkedOnHerdOrValet($this->absolutePath)
+ ? 'Open: '.new Link($this->generateAppUrl($this->name))
+ : 'composer run dev';
+
+ callout('Statamic was installed successfully!', [
+ 'You can start your local development using:',
+ new NumberedList($steps),
+ $this->output->getFormatter()->format('New to Statamic?>')
+ .' Check out our '.new Link('https://statamic.dev', 'documentation').'.'.PHP_EOL
+ .$this->output->getFormatter()->format('Need help?>')
+ .' Join the community on '.new Link('https://statamic.com/discord', 'Discord').'.',
+ new Heading('Now go β it\'s time to create something wonderful! π'),
+ ]);
return $this;
}