1
0
mirror of https://github.com/laravel/valet.git synced 2026-02-05 08:30:07 +01:00

Merge branch 'master' into master

This commit is contained in:
Florian Schwaiger
2017-05-23 17:13:13 +02:00
committed by GitHub
25 changed files with 607 additions and 246 deletions

View File

@@ -42,8 +42,28 @@ function hasInstalledPhp()
{
return $this->installed('php71')
|| $this->installed('php70')
|| $this->installed('php56')
|| $this->installed('php55');
|| $this->installed('php56');
}
/**
* Determine if a compatible nginx version is Homebrewed.
*
* @return bool
*/
function hasInstalledNginx()
{
return $this->installed('nginx')
|| $this->installed('nginx-full');
}
/**
* Return name of the nginx service installed via Homebrewed.
*
* @return string
*/
function nginxServiceName()
{
return $this->installed('nginx-full') ? 'nginx-full' : 'nginx';
}
/**
@@ -71,6 +91,8 @@ function ensureInstalled($formula, $options = [], $taps = [])
*/
function installOrFail($formula, $options = [], $taps = [])
{
info("Installing {$formula}...");
if (count($taps) > 0) {
$this->tap($taps);
}
@@ -109,7 +131,12 @@ function restartService($services)
$services = is_array($services) ? $services : func_get_args();
foreach ($services as $service) {
$this->cli->quietly('sudo brew services restart '.$service);
if ($this->installed($service)) {
info("Restarting {$service}...");
$this->cli->quietly('sudo brew services stop '.$service);
$this->cli->quietly('sudo brew services start '.$service);
}
}
}
@@ -123,9 +150,13 @@ function stopService($services)
$services = is_array($services) ? $services : func_get_args();
foreach ($services as $service) {
if ($this->installed($service)) {
info("Stopping {$service}...");
$this->cli->quietly('sudo brew services stop '.$service);
}
}
}
/**
* Determine which version of PHP is linked in Homebrew.
@@ -146,8 +177,6 @@ function linkedPhp()
return 'php70';
} elseif (strpos($resolvedPath, 'php56') !== false) {
return 'php56';
} elseif (strpos($resolvedPath, 'php55') !== false) {
return 'php55';
} else {
throw new DomainException("Unable to determine linked PHP.");
}
@@ -162,17 +191,4 @@ function restartLinkedPhp()
{
$this->restartService($this->linkedPhp());
}
/**
* Create the "sudoers.d" entry for running Brew.
*
* @return void
*/
function createSudoersEntry()
{
$this->files->ensureDirExists('/etc/sudoers.d');
$this->files->put('/etc/sudoers.d/brew', 'Cmnd_Alias BREW = /usr/local/bin/brew *
%admin ALL=(root) NOPASSWD: BREW'.PHP_EOL);
}
}

View File

@@ -28,6 +28,7 @@ function install()
$this->createSitesDirectory();
$this->createExtensionsDirectory();
$this->createLogDirectory();
$this->createCertificatesDirectory();
$this->writeBaseConfiguration();
$this->files->chown($this->path(), user());
@@ -94,6 +95,16 @@ function createLogDirectory()
$this->files->touch(VALET_HOME_PATH.'/Log/nginx-error.log');
}
/**
* Create the directory for SSL certificates.
*
* @return void
*/
function createCertificatesDirectory()
{
$this->files->ensureDirExists(VALET_HOME_PATH.'/Certificates', user());
}
/**
* Write the base, initial configuration for Valet.
*/

View File

@@ -2,6 +2,8 @@
namespace Valet;
use DomainException;
class Nginx
{
var $brew;
@@ -9,6 +11,7 @@ class Nginx
var $files;
var $configuration;
var $site;
const NGINX_CONF = '/usr/local/etc/nginx/nginx.conf';
/**
* Create a new Nginx instance.
@@ -37,7 +40,9 @@ function __construct(Brew $brew, CommandLine $cli, Filesystem $files,
*/
function install()
{
$this->brew->ensureInstalled('nginx', ['--with-http2']);
if (!$this->brew->hasInstalledNginx()) {
$this->brew->installOrFail('nginx', ['--with-http2']);
}
$this->installConfiguration();
$this->installServer();
@@ -51,10 +56,12 @@ function install()
*/
function installConfiguration()
{
info('Installing nginx configuration...');
$contents = $this->files->get(__DIR__.'/../stubs/nginx.conf');
$this->files->putAsUser(
'/usr/local/etc/nginx/nginx.conf',
static::NGINX_CONF,
str_replace(['VALET_USER', 'VALET_HOME_PATH'], [user(), VALET_HOME_PATH], $contents)
);
}
@@ -92,6 +99,8 @@ function installServer()
*/
function installNginxDirectory()
{
info('Installing nginx directory...');
if (! $this->files->isDir($nginxDirectory = VALET_HOME_PATH.'/Nginx')) {
$this->files->mkdirAsUser($nginxDirectory);
}
@@ -101,6 +110,19 @@ function installNginxDirectory()
$this->rewriteSecureNginxFiles();
}
/**
* Check nginx.conf for errors.
*/
private function lint()
{
$this->cli->quietly(
'sudo nginx -c '.static::NGINX_CONF.' -t',
function ($exitCode, $outputMessage) {
throw new DomainException("Nginx cannot start, please check your nginx.conf [$exitCode: $outputMessage].");
}
);
}
/**
* Generate fresh Nginx servers for existing secure sites.
*
@@ -120,7 +142,9 @@ function rewriteSecureNginxFiles()
*/
function restart()
{
$this->cli->quietly('sudo brew services restart nginx');
$this->lint();
$this->brew->restartService($this->brew->nginxServiceName());
}
/**
@@ -130,7 +154,9 @@ function restart()
*/
function stop()
{
$this->cli->quietly('sudo brew services stop nginx');
info('Stopping nginx....');
$this->cli->quietly('sudo brew services stop '. $this->brew->nginxServiceName());
}
/**

View File

@@ -36,10 +36,7 @@ function __construct(Brew $brew, CommandLine $cli, Filesystem $files)
*/
function install()
{
if (! $this->brew->installed('php71') &&
! $this->brew->installed('php70') &&
! $this->brew->installed('php56') &&
! $this->brew->installed('php55')) {
if (! $this->brew->hasInstalledPhp()) {
$this->brew->ensureInstalled('php71', [], $this->taps);
}
@@ -57,6 +54,8 @@ function install()
*/
function updateConfiguration()
{
info('Updating PHP configuration...');
$contents = $this->files->get($this->fpmConfigPath());
$contents = preg_replace('/^user = .+$/m', 'user = '.user(), $contents);
@@ -67,6 +66,16 @@ function updateConfiguration()
$contents = preg_replace('/^;?listen\.mode = .+$/m', 'listen.mode = 0777', $contents);
$this->files->put($this->fpmConfigPath(), $contents);
$contents = $this->files->get(__DIR__.'/../stubs/php-memory-limits.ini');
$destFile = dirname($this->fpmConfigPath());
$destFile = str_replace('/php-fpm.d', '', $destFile);
$destFile .= '/conf.d/php-memory-limits.ini';
$this->files->ensureDirExists(dirname($destFile), user());
$this->files->putAsUser($destFile, $contents);
}
/**
@@ -76,8 +85,6 @@ function updateConfiguration()
*/
function restart()
{
$this->stop();
$this->brew->restartLinkedPhp();
}
@@ -88,7 +95,7 @@ function restart()
*/
function stop()
{
$this->brew->stopService('php55', 'php56', 'php70', 'php71');
$this->brew->stopService('php56', 'php70', 'php71');
}
/**
@@ -102,7 +109,6 @@ function fpmConfigPath()
'php71' => '/usr/local/etc/php/7.1/php-fpm.d/www.conf',
'php70' => '/usr/local/etc/php/7.0/php-fpm.d/www.conf',
'php56' => '/usr/local/etc/php/5.6/php-fpm.conf',
'php55' => '/usr/local/etc/php/5.5/php-fpm.conf',
];
return $confLookup[$this->brew->linkedPhp()];

View File

@@ -59,6 +59,57 @@ function link($target, $link)
return $linkPath.'/'.$link;
}
/**
* Pretty print out all links in Valet.
*
* @return \Illuminate\Support\Collection
*/
function links() {
$certsPath = VALET_HOME_PATH.'/Certificates';
$this->files->ensureDirExists($certsPath, user());
$certs = $this->getCertificates($certsPath);
return $this->getLinks(VALET_HOME_PATH.'/Sites', $certs);
}
/**
* Get all certificates from config folder.
*
* @param string $path
* @return \Illuminate\Support\Collection
*/
function getCertificates($path)
{
return collect($this->files->scanDir($path))->filter(function ($value, $key) {
return ends_with($value, '.crt');
})->map(function ($cert) {
return substr($cert, 0, -8);
})->flip();
}
/**
* Get list of links and present them formatted.
*
* @param string $path
* @param \Illuminate\Support\Collection $certs
* @return \Illuminate\Support\Collection
*/
function getLinks($path, $certs)
{
$config = $this->config->read();
return collect($this->files->scanDir($path))->mapWithKeys(function ($site) use ($path) {
return [$site => $this->files->readLink($path.'/'.$site)];
})->map(function ($path, $site) use ($certs, $config) {
$secured = $certs->has($site);
$url = ($secured ? 'https': 'http').'://'.$site.'.'.$config['domain'];
return [$site, $secured ? ' X': '', $url, $path];
});
}
/**
* Unlink the given symbolic link.
*
@@ -117,7 +168,7 @@ function secured()
{
return collect($this->files->scandir($this->certificatesPath()))
->map(function ($file) {
return str_replace(['.key', '.csr', '.crt'], '', $file);
return str_replace(['.key', '.csr', '.crt', '.conf'], '', $file);
})->unique()->values()->all();
}
@@ -151,12 +202,15 @@ function createCertificate($url)
$keyPath = $this->certificatesPath().'/'.$url.'.key';
$csrPath = $this->certificatesPath().'/'.$url.'.csr';
$crtPath = $this->certificatesPath().'/'.$url.'.crt';
$confPath = $this->certificatesPath().'/'.$url.'.conf';
$this->buildCertificateConf($confPath, $url);
$this->createPrivateKey($keyPath);
$this->createSigningRequest($url, $keyPath, $csrPath);
$this->createSigningRequest($url, $keyPath, $csrPath, $confPath);
$this->cli->runAsUser(sprintf(
'openssl x509 -req -days 365 -in %s -signkey %s -out %s', $csrPath, $keyPath, $crtPath
'openssl x509 -req -days 365 -in %s -signkey %s -out %s -extensions v3_req -extfile %s',
$csrPath, $keyPath, $crtPath, $confPath
));
$this->trustCertificate($crtPath);
@@ -179,11 +233,11 @@ function createPrivateKey($keyPath)
* @param string $keyPath
* @return void
*/
function createSigningRequest($url, $keyPath, $csrPath)
function createSigningRequest($url, $keyPath, $csrPath, $confPath)
{
$this->cli->runAsUser(sprintf(
'openssl req -new -subj "/C=/ST=/O=/localityName=/commonName=%s/organizationalUnitName=/emailAddress=/" -key %s -out %s -passin pass:',
$url, $keyPath, $csrPath
'openssl req -new -key %s -out %s -subj "/C=/ST=/O=/localityName=/commonName=*.%s/organizationalUnitName=/emailAddress=/" -config %s -passin pass:',
$keyPath, $csrPath, $url, $confPath
));
}
@@ -200,6 +254,18 @@ function trustCertificate($crtPath)
));
}
/**
* Build the SSL config for the given URL.
*
* @param string $url
* @return string
*/
function buildCertificateConf($path, $url)
{
$config = str_replace('VALET_DOMAIN', $url, $this->files->get(__DIR__.'/../stubs/openssl.conf'));
$this->files->putAsUser($path, $config);
}
/**
* Build the TLS secured Nginx server for the given URL.
*
@@ -228,6 +294,7 @@ function unsecure($url)
if ($this->files->exists($this->certificatesPath().'/'.$url.'.crt')) {
$this->files->unlink(VALET_HOME_PATH.'/Nginx/'.$url);
$this->files->unlink($this->certificatesPath().'/'.$url.'.conf');
$this->files->unlink($this->certificatesPath().'/'.$url.'.key');
$this->files->unlink($this->certificatesPath().'/'.$url.'.csr');
$this->files->unlink($this->certificatesPath().'/'.$url.'.crt');

View File

@@ -32,19 +32,6 @@ function symlinkToUsersBin()
$this->cli->runAsUser('ln -s '.realpath(__DIR__.'/../../valet').' '.$this->valetBin);
}
/**
* Create the "sudoers.d" entry for running Valet.
*
* @return void
*/
function createSudoersEntry()
{
$this->files->ensureDirExists('/etc/sudoers.d');
$this->files->put('/etc/sudoers.d/valet', 'Cmnd_Alias VALET = /usr/local/bin/valet *
%admin ALL=(root) NOPASSWD: VALET'.PHP_EOL);
}
/**
* Get the paths to all of the Valet extensions.
*

View File

@@ -12,7 +12,18 @@ class CraftValetDriver extends ValetDriver
*/
public function serves($sitePath, $siteName, $uri)
{
return is_dir($sitePath.'/craft');
return file_exists($sitePath.'/craft');
}
/**
* Determine the name of the directory where the front controller lives.
*
* @param string $sitePath
* @return string
*/
public function frontControllerDirectory($sitePath)
{
return is_file($sitePath.'/craft') ? 'web' : 'public';
}
/**
@@ -25,7 +36,9 @@ public function serves($sitePath, $siteName, $uri)
*/
public function isStaticFile($sitePath, $siteName, $uri)
{
if ($this->isActualFile($staticFilePath = $sitePath.'/public'.$uri)) {
$frontControllerDirectory = $this->frontControllerDirectory($sitePath);
if ($this->isActualFile($staticFilePath = $sitePath.'/'.$frontControllerDirectory.$uri)) {
return $staticFilePath;
}
@@ -42,8 +55,10 @@ public function isStaticFile($sitePath, $siteName, $uri)
*/
public function frontControllerPath($sitePath, $siteName, $uri)
{
$frontControllerDirectory = $this->frontControllerDirectory($sitePath);
// Default index path
$indexPath = $sitePath.'/public/index.php';
$indexPath = $sitePath.'/'.$frontControllerDirectory.'/index.php';
$scriptName = '/index.php';
// Check if the first URL segment matches any of the defined locales

View File

@@ -0,0 +1,151 @@
<?php
class Magento2ValetDriver extends ValetDriver
{
/**
* Holds the MAGE_MODE from app/etc/config.php or $ENV
*
* @var string
*/
private $mageMode;
/**
* Determine if the driver serves the request.
*
* @param string $sitePath
* @param string $siteName
* @param string $uri
* @return boolean
*/
public function serves($sitePath, $siteName, $uri)
{
return file_exists($sitePath . '/bin/magento') && file_exists($sitePath . '/pub/index.php');
}
/**
* Determine if the incoming request is for a static file.
*
* @param string $sitePath
* @param string $siteName
* @param string $uri
* @return string|false
*/
public function isStaticFile($sitePath, $siteName, $uri)
{
$this->checkMageMode($sitePath);
$uri = $this->handleForVersions($uri);
$route = parse_url(substr($uri, 1))['path'];
$pub = '';
if ('developer' === $this->mageMode) {
$pub = 'pub/';
}
if (!$this->isPubDirectory($sitePath, $route, $pub)) {
return false;
}
$magentoPackagePubDir = $sitePath;
if ('developer' !== $this->mageMode) {
$magentoPackagePubDir .= '/pub';
}
$file = $magentoPackagePubDir . '/' . $route;
if (file_exists($file)) {
return $magentoPackagePubDir . $uri;
}
if (strpos($route, $pub . 'static/') === 0) {
$route = preg_replace('#' . $pub . 'static/#', '', $route, 1);
$_GET['resource'] = $route;
include $magentoPackagePubDir . '/' . $pub . 'static.php';
exit;
}
if (strpos($route, $pub . 'media/') === 0) {
include $magentoPackagePubDir . '/' . $pub . 'get.php';
exit;
}
return false;
}
/**
* Rewrite URLs that look like "versions12345/" to remove
* the versions12345/ part
*
* @param string $route
*/
private function handleForVersions($route)
{
return preg_replace('/version\d*\//', '', $route);
}
/**
* Determine the current MAGE_MODE
*
* @param string $sitePath
*/
private function checkMageMode($sitePath)
{
if (null !== $this->mageMode) {
// We have already figure out mode, no need to check it again
return;
}
if (!file_exists($sitePath . '/index.php')) {
$this->mageMode = 'production'; // Can't use developer mode without index.php in project root
return;
}
$mageConfig = [];
if (file_exists($sitePath . '/app/etc/env.php')) {
$mageConfig = require $sitePath . '/app/etc/env.php';
}
if (array_key_exists('MAGE_MODE', $mageConfig)) {
$this->mageMode = $mageConfig['MAGE_MODE'];
}
}
/**
* Checks to see if route is referencing any directory inside pub. This is a dynamic check so that if any new
* directories are added to pub this driver will not need to be updated.
*
* @param string $sitePath
* @param string $route
* @param string $pub
* @return bool
*/
private function isPubDirectory($sitePath, $route, $pub = '')
{
$sitePath .= '/pub/';
$dirs = glob($sitePath . '*', GLOB_ONLYDIR);
$dirs = str_replace($sitePath, '', $dirs);
foreach ($dirs as $dir) {
if (strpos($route, $pub . $dir . '/') === 0) {
return true;
}
}
return false;
}
/**
* Get the fully resolved path to the application's front controller.
*
* @param string $sitePath
* @param string $siteName
* @param string $uri
* @return string
*/
public function frontControllerPath($sitePath, $siteName, $uri)
{
$this->checkMageMode($sitePath);
if ('developer' === $this->mageMode) {
return $sitePath . '/index.php';
}
return $sitePath . '/pub/index.php';
}
}

View File

@@ -13,7 +13,9 @@ class SymfonyValetDriver extends ValetDriver
public function serves($sitePath, $siteName, $uri)
{
return (file_exists($sitePath.'/web/app_dev.php') || file_exists($sitePath.'/web/app.php')) &&
(file_exists($sitePath.'/app/AppKernel.php'));
(file_exists($sitePath.'/app/AppKernel.php')) || (file_exists($sitePath.'/web/index.php')) &&
(file_exists($sitePath.'/src/Kernel.php'))
;
}
/**
@@ -47,6 +49,8 @@ public function frontControllerPath($sitePath, $siteName, $uri)
return $frontControllerPath;
} elseif (file_exists($frontControllerPath = $sitePath.'/web/app.php')) {
return $frontControllerPath;
} elseif (file_exists($frontControllerPath = $sitePath.'/web/index.php')) {
return $frontControllerPath;
}
}
}

View File

@@ -54,6 +54,7 @@ public static function assign($sitePath, $siteName, $uri)
$drivers[] = 'WordPressValetDriver';
$drivers[] = 'BedrockValetDriver';
$drivers[] = 'ContaoValetDriver';
$drivers[] = 'SymfonyValetDriver';
$drivers[] = 'CraftValetDriver';
$drivers[] = 'StatamicValetDriver';
@@ -62,13 +63,13 @@ public static function assign($sitePath, $siteName, $uri)
$drivers[] = 'SculpinValetDriver';
$drivers[] = 'JigsawValetDriver';
$drivers[] = 'KirbyValetDriver';
$drivers[] = 'ContaoValetDriver';
$drivers[] = 'KatanaValetDriver';
$drivers[] = 'JoomlaValetDriver';
$drivers[] = 'DrupalValetDriver';
$drivers[] = 'Concrete5ValetDriver';
$drivers[] = 'Typo3ValetDriver';
$drivers[] = 'NeosValetDriver';
$drivers[] = 'Magento2ValetDriver';
$drivers[] = 'BasicValetDriver';

View File

@@ -27,3 +27,4 @@
require_once __DIR__.'/Concrete5ValetDriver.php';
require_once __DIR__.'/Typo3ValetDriver.php';
require_once __DIR__.'/NeosValetDriver.php';
require_once __DIR__.'/Magento2ValetDriver.php';

View File

@@ -11,8 +11,8 @@
exit(1);
}
if (version_compare(PHP_VERSION, '5.5.9', '<')) {
echo "Valet requires PHP 5.5.9 or later.";
if (version_compare(PHP_VERSION, '5.6.0', '<')) {
echo "Valet requires PHP 5.6 or later.";
exit(1);
}

View File

@@ -2,6 +2,8 @@
use Illuminate\Container\Container;
use Symfony\Component\Process\Process;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Helper\Table;
/**
* Define the ~/.valet path as a constant.
@@ -32,6 +34,22 @@ function warning($output)
output('<fg=red>'.$output.'</>');
}
/**
* Output a table to the console.
*
* @param array $headers
* @param array $rows
* @return void
*/
function table(array $headers = [], array $rows = [])
{
$table = new Table(new ConsoleOutput);
$table->setHeaders($headers)->setRows($rows);
$table->render();
}
/**
* Output the given text to the console.
*
@@ -44,7 +62,7 @@ function output($output)
return;
}
(new Symfony\Component\Console\Output\ConsoleOutput)->writeln($output);
(new ConsoleOutput)->writeln($output);
}
if (! function_exists('resolve')) {
@@ -130,6 +148,24 @@ function tap($value, callable $callback)
}
}
if (! function_exists('ends_with')) {
/**
* Determine if a given string ends with a given substring.
*
* @param string $haystack
* @param string|array $needles
* @return bool
*/
function ends_with($haystack, $needles) {
foreach ((array) $needles as $needle) {
if (substr($haystack, -strlen($needle)) === (string) $needle) {
return true;
}
}
return false;
}
}
/**
* Get the user
*/

View File

@@ -11,6 +11,7 @@ http {
sendfile on;
keepalive_timeout 65;
client_max_body_size 128M;
gzip on;
gzip_comp_level 5;

25
cli/stubs/openssl.conf Normal file
View File

@@ -0,0 +1,25 @@
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
[req_distinguished_name]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = MN
localityName = Locality Name (eg, city)
localityName_default = Minneapolis
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = Domain Control Validated
commonName = Internet Widgits Ltd
commonName_max = 64
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = VALET_DOMAIN
DNS.2 = *.VALET_DOMAIN

View File

@@ -0,0 +1,8 @@
; Max memory per instance
memory_limit = 128M
;The maximum size of an uploaded file.
upload_max_filesize = 128M
;Sets max size of post data allowed. This setting also affects file upload. To upload large files, this value must be larger than upload_max_filesize
post_max_size = 128M

View File

@@ -1,12 +1,12 @@
server {
listen 80;
server_name VALET_SITE;
server_name VALET_SITE www.VALET_SITE *.VALET_SITE;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name VALET_SITE;
server_name VALET_SITE www.VALET_SITE *.VALET_SITE;
root /;
charset utf-8;
@@ -20,7 +20,7 @@ server {
ssl_certificate_key VALET_KEY;
location / {
rewrite ^ VALET_SERVER_PATH?$query_string last;
rewrite ^ VALET_SERVER_PATH last;
}
location = /favicon.ico { access_log off; log_not_found off; }

View File

@@ -2,7 +2,6 @@ server {
listen 80 default_server;
root /;
charset utf-8;
client_max_body_size 128M;
location /VALET_STATIC_PREFIX/ {
internal;

View File

@@ -18,7 +18,7 @@
*/
Container::setInstance(new Container);
$version = '2.0.3';
$version = '2.0.4';
$app = new Application('Laravel Valet', $version);
@@ -43,16 +43,18 @@
DnsMasq::install();
Nginx::restart();
Valet::symlinkToUsersBin();
Brew::createSudoersEntry();
Valet::createSudoersEntry();
output(PHP_EOL.'<info>Valet installed successfully!</info>');
})->descriptions('Install the Valet services');
/**
* Most commands are available only if valet is installed.
*/
if (is_dir(VALET_HOME_PATH)) {
/**
* Get or set the domain currently being used by Valet.
*/
$app->command('domain [domain]', function ($domain = null) {
$app->command('domain [domain]', function ($domain = null) {
if ($domain === null) {
return info(Configuration::read()['domain']);
}
@@ -68,55 +70,61 @@
Nginx::restart();
info('Your Valet domain has been updated to ['.$domain.'].');
})->descriptions('Get or set the domain used for Valet sites');
})->descriptions('Get or set the domain used for Valet sites');
/**
/**
* Add the current working directory to the paths configuration.
*/
$app->command('park [path]', function ($path = null) {
$app->command('park [path]', function ($path = null) {
Configuration::addPath($path ?: getcwd());
info(($path === null ? "This" : "The [{$path}]") . " directory has been added to Valet's paths.");
})->descriptions('Register the current working (or specified) directory with Valet');
})->descriptions('Register the current working (or specified) directory with Valet');
/**
/**
* Remove the current working directory from the paths configuration.
*/
$app->command('forget [path]', function ($path = null) {
$app->command('forget [path]', function ($path = null) {
Configuration::removePath($path ?: getcwd());
info(($path === null ? "This" : "The [{$path}]") . " directory has been removed from Valet's paths.");
})->descriptions('Remove the current working (or specified) directory from Valet\'s list of paths');
})->descriptions('Remove the current working (or specified) directory from Valet\'s list of paths');
/**
/**
* Register a symbolic link with Valet.
*/
$app->command('link [name]', function ($name) {
$app->command('link [name] [--secure]', function ($name, $secure) {
$linkPath = Site::link(getcwd(), $name = $name ?: basename(getcwd()));
info('A ['.$name.'] symbolic link has been created in ['.$linkPath.'].');
})->descriptions('Link the current working directory to Valet');
/**
if ($secure) {
$this->runCommand('secure '.$name);
}
})->descriptions('Link the current working directory to Valet');
/**
* Display all of the registered symbolic links.
*/
$app->command('links', function () {
passthru('ls -la '.VALET_HOME_PATH.'/Sites');
})->descriptions('Display all of the registered Valet links');
$app->command('links', function () {
$links = Site::links();
/**
table(['Site', 'SSL', 'URL', 'Path'], $links->all());
})->descriptions('Display all of the registered Valet links');
/**
* Unlink a link from the Valet links directory.
*/
$app->command('unlink [name]', function ($name) {
$app->command('unlink [name]', function ($name) {
Site::unlink($name = $name ?: basename(getcwd()));
info('The ['.$name.'] symbolic link has been removed.');
})->descriptions('Remove the specified Valet link');
})->descriptions('Remove the specified Valet link');
/**
/**
* Secure the given domain with a trusted TLS certificate.
*/
$app->command('secure [domain]', function ($domain = null) {
$app->command('secure [domain]', function ($domain = null) {
$url = ($domain ?: Site::host(getcwd())).'.'.Configuration::read()['domain'];
Site::secure($url);
@@ -126,12 +134,12 @@
Nginx::restart();
info('The ['.$url.'] site has been secured with a fresh TLS certificate.');
})->descriptions('Secure the given domain with a trusted TLS certificate');
})->descriptions('Secure the given domain with a trusted TLS certificate');
/**
/**
* Stop serving the given domain over HTTPS and remove the trusted TLS certificate.
*/
$app->command('unsecure [domain]', function ($domain = null) {
$app->command('unsecure [domain]', function ($domain = null) {
$url = ($domain ?: Site::host(getcwd())).'.'.Configuration::read()['domain'];
Site::unsecure($url);
@@ -141,12 +149,12 @@
Nginx::restart();
info('The ['.$url.'] site will now serve traffic over HTTP.');
})->descriptions('Stop serving the given domain over HTTPS and remove the trusted TLS certificate');
})->descriptions('Stop serving the given domain over HTTPS and remove the trusted TLS certificate');
/**
/**
* Determine which Valet driver the current directory is using.
*/
$app->command('which', function () {
$app->command('which', function () {
require __DIR__.'/drivers/require.php';
$driver = ValetDriver::assign(getcwd(), basename(getcwd()), '/');
@@ -156,12 +164,12 @@
} else {
warning('Valet could not determine which driver to use for this site.');
}
})->descriptions('Determine which Valet driver serves the current working directory');
})->descriptions('Determine which Valet driver serves the current working directory');
/**
/**
* Display all of the registered paths.
*/
$app->command('paths', function () {
$app->command('paths', function () {
$paths = Configuration::read()['paths'];
if (count($paths) > 0) {
@@ -169,83 +177,84 @@
} else {
info('No paths have been registered.');
}
})->descriptions('Get all of the paths registered with Valet');
})->descriptions('Get all of the paths registered with Valet');
/**
* Open the current directory in the browser.
/**
* Open the current or given directory in the browser.
*/
$app->command('open', function () {
$url = "http://".Site::host(getcwd()).'.'.Configuration::read()['domain'].'/';
$app->command('open [domain]', function ($domain = null) {
$url = "http://".($domain ?: Site::host(getcwd())).'.'.Configuration::read()['domain'];
passthru("open ".escapeshellarg($url));
})->descriptions('Open the site for the current directory in your browser');
})->descriptions('Open the site for the current (or specified) directory in your browser');
/**
/**
* Generate a publicly accessible URL for your project.
*/
$app->command('share', function () {
$app->command('share', function () {
warning("It looks like you are running `cli/valet.php` directly, please use the `valet` script in the project root instead.");
})->descriptions('Generate a publicly accessible URL for your project');
})->descriptions('Generate a publicly accessible URL for your project');
/**
/**
* Echo the currently tunneled URL.
*/
$app->command('fetch-share-url', function () {
$app->command('fetch-share-url', function () {
output(Ngrok::currentTunnelUrl());
})->descriptions('Get the URL to the current Ngrok tunnel');
})->descriptions('Get the URL to the current Ngrok tunnel');
/**
/**
* Start the daemon services.
*/
$app->command('start', function () {
$app->command('start', function () {
PhpFpm::restart();
Nginx::restart();
info('Valet services have been started.');
})->descriptions('Start the Valet services');
})->descriptions('Start the Valet services');
/**
/**
* Restart the daemon services.
*/
$app->command('restart', function () {
$app->command('restart', function () {
PhpFpm::restart();
Nginx::restart();
info('Valet services have been restarted.');
})->descriptions('Restart the Valet services');
})->descriptions('Restart the Valet services');
/**
/**
* Stop the daemon services.
*/
$app->command('stop', function () {
$app->command('stop', function () {
PhpFpm::stop();
Nginx::stop();
info('Valet services have been stopped.');
})->descriptions('Stop the Valet services');
})->descriptions('Stop the Valet services');
/**
/**
* Uninstall Valet entirely.
*/
$app->command('uninstall', function () {
$app->command('uninstall', function () {
Nginx::uninstall();
info('Valet has been uninstalled.');
})->descriptions('Uninstall the Valet services');
})->descriptions('Uninstall the Valet services');
/**
/**
* Determine if this is the latest release of Valet.
*/
$app->command('on-latest-version', function () use ($version) {
$app->command('on-latest-version', function () use ($version) {
if (Valet::onLatestVersion($version)) {
output('YES');
} else {
output('NO');
}
})->descriptions('Determine if this is the latest version of Valet');
})->descriptions('Determine if this is the latest version of Valet');
}
/**
* Load all of the Valet extensions.

View File

@@ -24,7 +24,7 @@
}
},
"require": {
"php": ">=5.5.9",
"php": ">=5.6",
"illuminate/container": "~5.1",
"mnapoli/silly": "~1.0",
"symfony/process": "~2.7|~3.0",
@@ -33,7 +33,7 @@
},
"require-dev": {
"mockery/mockery": "0.9.*",
"phpunit/phpunit": ">=4.8.24"
"phpunit/phpunit": "~5.7"
},
"bin": [
"valet"

View File

@@ -1,10 +1,11 @@
# Laravel Valet
<p align="center"><img src="https://laravel.com/assets/img/components/logo-valet.svg"></p>
[![Build Status](https://travis-ci.org/laravel/valet.svg?branch=master)](https://travis-ci.org/laravel/valet)
[![Total Downloads](https://poser.pugx.org/laravel/valet/d/total.svg)](https://packagist.org/packages/laravel/valet)
[![Latest Stable Version](https://poser.pugx.org/laravel/valet/v/stable.svg)](https://packagist.org/packages/laravel/valet)
[![Latest Unstable Version](https://poser.pugx.org/laravel/valet/v/unstable.svg)](https://packagist.org/packages/laravel/valet)
[![License](https://poser.pugx.org/laravel/valet/license.svg)](https://packagist.org/packages/laravel/valet)
<p align="center">
<a href="https://travis-ci.org/laravel/valet"><img src="https://travis-ci.org/laravel/valet.svg" alt="Build Status"></a>
<a href="https://packagist.org/packages/laravel/valet"><img src="https://poser.pugx.org/laravel/valet/d/total.svg" alt="Total Downloads"></a>
<a href="https://packagist.org/packages/laravel/valet"><img src="https://poser.pugx.org/laravel/valet/v/stable.svg" alt="Latest Stable Version"></a>
<a href="https://packagist.org/packages/laravel/valet"><img src="https://poser.pugx.org/laravel/valet/license.svg" alt="License"></a>
</p>
## Introduction
@@ -18,24 +19,6 @@ ## Official Documentation
Documentation for Valet can be found on the [Laravel website](https://laravel.com/docs/valet).
## Upgrading To Valet 2.0
Valet 2.0 transitions Valet's underlying web server from Caddy to Nginx. Before upgrading to this version you should run the following commands to stop and uninstall the existing Caddy daemon:
```
valet stop
valet uninstall
```
Next, you should upgrade to the latest version of Valet. Depending on how you installed Valet, this is typically done through Git or Composer. Once the fresh Valet source code has been downloaded, you should run the `install` command:
```
valet install
valet restart
```
After upgrading, it may be necessary to re-park or re-link your sites.
## License
Laravel Valet is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)

View File

@@ -63,11 +63,16 @@ function valet_support_xip_io($domain)
* Determine the fully qualified path to the site.
*/
$valetSitePath = null;
$domain = array_slice(explode('.', $siteName), -1)[0];
foreach ($valetConfig['paths'] as $path) {
if (is_dir($path.'/'.$siteName)) {
$valetSitePath = $path.'/'.$siteName;
break;
}
if (is_dir($path.'/'.$domain)) {
$valetSitePath = $path.'/'.$domain;
break;
}
}

View File

@@ -69,21 +69,18 @@ public function test_has_installed_php_indicates_if_php_is_installed_via_brew()
$brew->shouldReceive('installed')->once()->with('php71')->andReturn(true);
$brew->shouldReceive('installed')->with('php70')->andReturn(true);
$brew->shouldReceive('installed')->with('php56')->andReturn(true);
$brew->shouldReceive('installed')->with('php55')->andReturn(true);
$this->assertTrue($brew->hasInstalledPhp());
$brew = Mockery::mock(Brew::class.'[installed]', [new CommandLine, new Filesystem]);
$brew->shouldReceive('installed')->once()->with('php70')->andReturn(true);
$brew->shouldReceive('installed')->with('php71')->andReturn(false);
$brew->shouldReceive('installed')->with('php56')->andReturn(false);
$brew->shouldReceive('installed')->with('php55')->andReturn(false);
$this->assertTrue($brew->hasInstalledPhp());
$brew = Mockery::mock(Brew::class.'[installed]', [new CommandLine, new Filesystem]);
$brew->shouldReceive('installed')->once()->with('php71')->andReturn(false);
$brew->shouldReceive('installed')->once()->with('php70')->andReturn(false);
$brew->shouldReceive('installed')->once()->with('php56')->andReturn(false);
$brew->shouldReceive('installed')->once()->with('php55')->andReturn(false);
$this->assertFalse($brew->hasInstalledPhp());
}
@@ -102,7 +99,9 @@ public function test_tap_taps_the_given_homebrew_repository()
public function test_restart_restarts_the_service_using_homebrew_services()
{
$cli = Mockery::mock(CommandLine::class);
$cli->shouldReceive('quietly')->once()->with('sudo brew services restart dnsmasq');
$cli->shouldReceive('runAsUser')->once()->with('brew list | grep dnsmasq')->andReturn('dnsmasq');
$cli->shouldReceive('quietly')->once()->with('sudo brew services stop dnsmasq');
$cli->shouldReceive('quietly')->once()->with('sudo brew services start dnsmasq');
swap(CommandLine::class, $cli);
resolve(Brew::class)->restartService('dnsmasq');
}
@@ -111,6 +110,7 @@ public function test_restart_restarts_the_service_using_homebrew_services()
public function test_stop_stops_the_service_using_homebrew_services()
{
$cli = Mockery::mock(CommandLine::class);
$cli->shouldReceive('runAsUser')->once()->with('brew list | grep dnsmasq')->andReturn('dnsmasq');
$cli->shouldReceive('quietly')->once()->with('sudo brew services stop dnsmasq');
swap(CommandLine::class, $cli);
resolve(Brew::class)->stopService('dnsmasq');

View File

@@ -25,6 +25,8 @@ public function tearDown()
public function test_fpm_is_configured_with_the_correct_user_group_and_port()
{
copy(__DIR__.'/files/fpm.conf', __DIR__.'/output/fpm.conf');
mkdir(__DIR__.'/output/conf.d');
copy(__DIR__.'/files/php-memory-limits.ini', __DIR__.'/output/conf.d/php-memory-limits.ini');
resolve(StubForUpdatingFpmConfigFiles::class)->updateConfiguration();
$contents = file_get_contents(__DIR__.'/output/fpm.conf');
$this->assertContains(sprintf("\nuser = %s", user()), $contents);

View File

@@ -0,0 +1,8 @@
; Max memory per instance
memory_limit = 128M
;The maximum size of an uploaded file.
upload_max_filesize = 128M
;Sets max size of post data allowed. This setting also affects file upload. To upload large files, this value must be larger than upload_max_filesize
post_max_size = 128M