ENHANCEMENT Improve upgrade experience for beta3 -> beta4 upgrade

This commit is contained in:
Damian Mooyman 2017-10-10 15:23:00 +13:00
parent 5d6a10ca58
commit 11b2c74533
No known key found for this signature in database
GPG Key ID: 78B823A10DE27D1A
6 changed files with 198 additions and 21 deletions

View File

@ -951,3 +951,5 @@ skipConfigs:
excludedPaths:
- '*fixtures*'
- '*vendor*'
doctorTasks:
SilverStripe\Dev\Upgrade\UpgradeBootstrap: src/Dev/Upgrade/UpgradeBootstrap.php

View File

@ -78,7 +78,7 @@ some automated processes that users can run to
This section describes the processes which every project upgrading to 4.0 should follow. This should be followed
as a standard first point of upgrade.
#### Upgrade your rewrite rules
#### Upgrade project index.php and .htaccess rewrites
The location of SilverStripe's "entry file" has changed. Your project and server environment will need
to adjust the path to this file from `framework/main.php` to `index.php`.
@ -87,8 +87,19 @@ please consult the [installation guides](getting_started/installation/).
Since 4.0, URL rewrite capabilities are required,
unless you PHP's built-in webserver through [silverstripe/serve](https://github.com/silverstripe/silverstripe-serve).
The `index.php` file should already exist in your project,
but needs its content replaced:
The [upgrader tool](https://github.com/silverstripe/silverstripe-upgrader/) has a task runner which
automates this process for you.
```
composer global require silverstripe/upgrader
cd ~/Project/Root
~/.composer/vendor/bin/upgrade-code doctor
```
This will ensure that your `.htaccess` and `index.php` are set to a reasonable default value
for a clean installation.
After upgrade the `index.php` should look something similar to the below:
```php
<?php

View File

@ -65,6 +65,7 @@ class TempFolder
*/
protected static function getTempParentFolder($base)
{
$base = rtrim($base, '/\\');
// first, try finding a silverstripe-cache dir built off the base path
$tempPath = $base . DIRECTORY_SEPARATOR . 'silverstripe-cache';
if (@file_exists($tempPath)) {

View File

@ -2,6 +2,7 @@
namespace SilverStripe\Dev\Install;
use BadMethodCallException;
use Exception;
use InvalidArgumentException;
use SilverStripe\Core\TempFolder;
@ -16,8 +17,25 @@ use SilverStripe\Core\TempFolder;
*/
class InstallRequirements
{
/**
* List of errors
*
* @var array
*/
protected $errors = [];
/**
* List of warnings
*
* @var array
*/
protected $warnings = [];
/**
* List of tests
*
* @var array
*/
protected $tests = [];
/**
@ -26,6 +44,28 @@ class InstallRequirements
*/
protected $originalIni = [];
/**
* Base path
* @var
*/
protected $baseDir;
public function __construct($basePath = null)
{
if ($basePath) {
$this->baseDir = $basePath;
} elseif (defined('BASE_PATH')) {
$this->baseDir = BASE_PATH;
} else {
throw new BadMethodCallException("No BASE_PATH defined");
}
}
public function getBaseDir()
{
return rtrim($this->baseDir, '/\\') . '/';
}
/**
* Check the database configuration. These are done one after another
* starting with checking the database function exists in PHP, and
@ -217,6 +257,8 @@ class InstallRequirements
'',
));
$this->requireWriteable('index.php', array("File permissions", "Is the index.php file writeable?", null));
if ($isApache) {
$this->checkApacheVersion(array(
"Webserver Configuration",
@ -251,7 +293,7 @@ class InstallRequirements
$this->requireWriteable('assets', array("File permissions", "Is the assets/ directory writeable?", null));
try {
$tempFolder = TempFolder::getTempFolder(BASE_PATH);
$tempFolder = TempFolder::getTempFolder($this->getBaseDir());
} catch (Exception $e) {
$tempFolder = false;
}
@ -732,8 +774,25 @@ class InstallRequirements
*/
public function checkModuleExists($dirname)
{
$path = $this->getBaseDir() . $dirname;
return file_exists($path) && ($dirname == 'mysite' || file_exists($path . '/_config.php'));
// Mysite is base-only and doesn't need _config.php to be counted
if ($dirname === 'mysite') {
return file_exists($this->getBaseDir() . $dirname);
}
$paths = [
"vendor/silverstripe/{$dirname}/",
"{$dirname}/",
];
foreach ($paths as $path) {
$checks = ['_config', '_config.php'];
foreach ($checks as $check) {
if (file_exists($this->getBaseDir() . $path . $check)) {
return true;
}
}
}
return false;
}
/**
@ -828,7 +887,7 @@ class InstallRequirements
$this->testing($testDetails);
try {
$tempFolder = TempFolder::getTempFolder(BASE_PATH);
$tempFolder = TempFolder::getTempFolder($this->getBaseDir());
} catch (Exception $e) {
$tempFolder = false;
}
@ -1070,14 +1129,6 @@ class InstallRequirements
}
}
// Must be PHP4 compatible
var $baseDir;
public function getBaseDir()
{
return BASE_PATH . '/';
}
public function testing($testDetails)
{
if (!$testDetails) {

View File

@ -20,12 +20,6 @@ use SilverStripe\Security\Security;
*/
class Installer extends InstallRequirements
{
public function __construct()
{
// Cache the baseDir value
$this->getBaseDir();
}
protected function installHeader()
{
?>
@ -86,6 +80,7 @@ class Installer extends InstallRequirements
}
// Write all files
$this->writeIndexPHP();
$this->writeConfigPHP($config);
$this->writeConfigYaml($config);
$this->writeConfigEnv($config);
@ -199,6 +194,31 @@ HTML;
return $this->errors;
}
protected function writeIndexPHP()
{
$content = <<<'PHP'
<?php
use SilverStripe\Control\HTTPApplication;
use SilverStripe\Control\HTTPRequestBuilder;
use SilverStripe\Core\CoreKernel;
use SilverStripe\Core\Startup\ErrorControlChainMiddleware;
require __DIR__ . '/vendor/autoload.php';
// Build request and detect flush
$request = HTTPRequestBuilder::createFromEnvironment();
// Default application
$kernel = new CoreKernel(BASE_PATH);
$app = new HTTPApplication($kernel);
$app->addMiddleware(new ErrorControlChainMiddleware($app));
$response = $app->handle($request);
$response->output();
PHP;
$this->writeToFile('index.php', $content);
}
/**
* Write all .env files
*

View File

@ -0,0 +1,92 @@
<?php
namespace SilverStripe\Dev\Upgrade;
use BadMethodCallException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Provides upgrade interface for bootstrapping.
*
* Note: This class is intended to be loaded from outside of a SilverStripe application
* and should not reference any SilverStripe API.
*
* See https://github.com/silverstripe/silverstripe-upgrader/ for information
* on running this task.
*/
class UpgradeBootstrap
{
/**
* List of files to install.
* Set to true if the file should be re-installed if it doesn't exist.
*
* @var array
*/
protected $files = [
'.htaccess' => true,
'index.php' => true,
'install.php' => false,
];
/**
* @param InputInterface $input
* @param OutputInterface $output
* @param $basePath
*/
public function __invoke(InputInterface $input, OutputInterface $output, $basePath)
{
// Fail if destination isn't writable
$this->ensureWritable($basePath);
// Check source
$source = $basePath . '/vendor/silverstripe/recipe-core';
if (!is_dir($source)) {
throw new BadMethodCallException("silverstripe/recipe-core is not installed.");
}
// Copy scaffolded files from recipe-core
$output->writeln("Upgrading project bootstrapping files:");
foreach ($this->files as $file => $canCreate) {
$fileSource = $source . '/' . $file;
$fileDest = $basePath . '/' . $file;
// Skip if we should only upgrade existing files
if (!$canCreate && !file_exists($fileDest)) {
continue;
}
$output->writeln(" - Upgrading <info>{$file}</info>");
$this->copyFile(
$fileSource,
$fileDest
);
}
}
/**
* Ensure path is writable
*
* @param string $path
*/
protected function ensureWritable($path)
{
if (!is_writable($path)) {
throw new BadMethodCallException("Path $path is not writable");
}
}
/**
* Copy file
*
* @param string $source
* @param string $dest
*/
protected function copyFile($source, $dest)
{
// Ensure existing file can be overwritten
if (file_exists($dest)) {
$this->ensureWritable($dest);
}
file_put_contents($dest, file_get_contents($source));
}
}