Skip to content

Parse output from composer and list missing extensions #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Oct 26, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions app/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
use PhpSchool\WorkshopManager\Command\UninstallWorkshop;
use PhpSchool\WorkshopManager\Command\UpdateWorkshop;
use PhpSchool\WorkshopManager\Command\VerifyInstall;
use PhpSchool\WorkshopManager\ComposerInstaller;
use PhpSchool\WorkshopManager\ComposerInstallerFactory;
use PhpSchool\WorkshopManager\Downloader;
use PhpSchool\WorkshopManager\Filesystem;
use PhpSchool\WorkshopManager\Installer\Installer;
use PhpSchool\WorkshopManager\Installer\Uninstaller;
use PhpSchool\WorkshopManager\Installer\Updater;
use PhpSchool\WorkshopManager\IOFactory;
use PhpSchool\WorkshopManager\Linker;
use PhpSchool\WorkshopManager\ManagerState;
use PhpSchool\WorkshopManager\Repository\InstalledWorkshopRepository;
Expand Down Expand Up @@ -125,14 +125,13 @@
);
}),
Installer::class => \DI\factory(function (ContainerInterface $c) {
$io = $c->get(IOFactory::class)->getNullableIO($c->get(InputInterface::class), $c->get(OutputInterface::class));
return new Installer(
$c->get(InstalledWorkshopRepository::class),
$c->get(RemoteWorkshopRepository::class),
$c->get(Linker::class),
$c->get(Filesystem::class),
$c->get('appDir'),
new ComposerInstallerFactory($c->get(Factory::class), $io),
$c->get(ComposerInstaller::class),
$c->get(Client::class),
$c->get(VersionChecker::class)
);
Expand All @@ -159,14 +158,14 @@
Client::class => \DI\factory(function (ContainerInterface $c) {
return new Client;
}),
Factory::class => \DI\object(),
IOFactory::class => \DI\object(),
IOInterface::class => \DI\factory(function (ContainerInterface $c) {
return $c->get(IOFactory::class)->getIO(
ComposerInstaller::class => function (ContainerInterface $c) {
return new ComposerInstaller(
$c->get(InputInterface::class),
$c->get(OutputInterface::class)
$c->get(OutputInterface::class),
new Factory
);
}),
},
Factory::class => \DI\object(),
InputInterface::class => \Di\factory(function () {
return new \Symfony\Component\Console\Input\ArgvInput($_SERVER['argv']);
}),
Expand Down
6 changes: 5 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@
"symfony/filesystem": "^3.1",
"tm/tooly-composer-script": "^1.0",
"padraic/phar-updater": "^1.0",
"samsonasik/package-versions": "^1.0"
"samsonasik/package-versions": "^1.0",
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*",
"ext-zip": "*"
},
"require-dev": {
"phpunit/phpunit": "~5.4",
Expand Down
13 changes: 10 additions & 3 deletions src/Command/InstallWorkshop.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,17 @@ public function __invoke(OutputInterface $output, $workshopName)
''
]);
} catch (ComposerFailureException $e) {
$message = " <error> There was a problem installing dependencies for \"%s\". Try running in verbose";
$message .= " mode to see the composer error: %s </error>\n";
$message = " <error> There was a problem installing dependencies for \"%s\".%s Try running in verbose";
$message .= " mode to see more details: %s </error>\n";

$output->writeln(sprintf($message, $workshopName, $this->getCommand()));
$output->writeln(
sprintf(
$message,
$workshopName,
$e->getMessage() ? sprintf(' %s', $e->getMessage()) : '',
$this->getCommand()
)
);
} catch (\Exception $e) {
$output->writeln(
sprintf(" <error> An unknown error occurred: \"%s\" </error>\n", $e->getMessage())
Expand Down
38 changes: 32 additions & 6 deletions src/Command/VerifyInstall.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
*/
class VerifyInstall
{
/**
* @var array
*/
private static $requiredExtensions = ['json', 'zip', 'mbstring', 'curl'];

/**
* @var InputInterface
*/
Expand All @@ -26,6 +31,7 @@ class VerifyInstall
*/
private $workshopHomeDirectory;


/**
* @param InputInterface $input
* @param OutputInterface $output
Expand All @@ -44,9 +50,9 @@ public function __invoke()

$style->title("Verifying your installation");


if (strpos(getenv('PATH'), sprintf('%s/bin', $this->workshopHomeDirectory)) !== false) {
$style->success('Your $PATH environment variable is configured correctly');
$style->success('Your $PATH environment variable is configured correctly.');
} else {
$style->error('The PHP School bin directory is not in your PATH variable.');

Expand All @@ -68,13 +74,33 @@ public function __invoke()
''
]);
}

if (version_compare(PHP_VERSION, '5.6')) {
$message = 'Your PHP version is at least 5.6, which is required by this tool. Be aware that some ';
$message .= 'workshops may require a higher version of PHP, so you may not be able to install them.';
$style->success($message);
$message = 'Your PHP version is %s, PHP 5.6 is the minimum supported version for this tool. Please note ';
$message .= 'that some workshops may require a higher version of PHP, so you may not be able to install ';
$message .= 'them without upgrading PHP.';
$style->success(sprintf($message, PHP_VERSION));
} else {
$style->error('You need a PHP version of at least 5.6 to use PHP School.');
}

$missingExtensions = array_filter(static::$requiredExtensions, function ($extension) {
return !extension_loaded($extension);
});

array_walk($missingExtensions, function ($missingExtension) use ($style) {
$style->error(
sprintf(
'The %s extension is missing - use your preferred package manager to install it.',
$missingExtension
)
);
});

if (empty($missingExtensions)) {
$message = 'All required PHP extensions are installed. Please note that some workshops may require ';
$message .= 'additional PHP extensions.';
$style->success($message);
}
}
}
81 changes: 81 additions & 0 deletions src/ComposerInstaller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

namespace PhpSchool\WorkshopManager;

use Composer\Factory;
use Composer\Installer;
use Composer\IO\ConsoleIO;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\StreamOutput;

/**
* @author Aydin Hassan <[email protected]>
*/
class ComposerInstaller
{
/**
* @var InputInterface
*/
private $input;

/**
* @var OutputInterface
*/
private $output;

/**
* @var Factory
*/
private $composerFactory;

/**
* @param InputInterface $input
* @param OutputInterface $output
* @param Factory $composerFactory
*/
public function __construct(InputInterface $input, OutputInterface $output, Factory $composerFactory)
{
$this->input = $input;
$this->output = $output;
$this->composerFactory = $composerFactory;
}

/**
* @param string $pathToComposerProject
* @return InstallResult
*/
public function install($pathToComposerProject)
{
if ($this->output->isVerbose()) {
$output = $this->output;
} else {
//write all output in verbose mode to a temp stream
//so we don't write it out when not in verbose mode
$output = new StreamOutput(
fopen('php://memory', 'w'),
OutputInterface::VERBOSITY_VERY_VERBOSE,
$this->output->isDecorated(),
$this->output->getFormatter()
);
}

$wrappedOutput = new RecordingOutput($output);
$io = new ConsoleIO($this->input, $wrappedOutput, new HelperSet);

$composer = $this->composerFactory->createComposer(
$io,
sprintf('%s/composer.json', rtrim($pathToComposerProject, '/')),
false,
$pathToComposerProject
);

return new InstallResult(
Installer::create($io, $composer)->run(),
$wrappedOutput->getOutput()
);
}
}
51 changes: 0 additions & 51 deletions src/ComposerInstallerFactory.php

This file was deleted.

16 changes: 14 additions & 2 deletions src/Exception/ComposerFailureException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,26 @@
* Class ComposerFailureException
* @author Michael Woodward <[email protected]>
*/
final class ComposerFailureException extends \RuntimeException
class ComposerFailureException extends \RuntimeException
{
/**
* @param \Exception $e
* @return ComposerFailureException
* @return self
*/
public static function fromException(\Exception $e)
{
return new self($e->getMessage());
}

/**
* @param array $missingExtensions
* @return self
*/
public static function fromMissingExtensions(array $missingExtensions)
{
$message = 'This workshop requires some extra PHP extensions. Please install them';
$message .= ' and try again. Required extensions are %s.';

return new self(sprintf($message, implode(', ', $missingExtensions)));
}
}
44 changes: 0 additions & 44 deletions src/IOFactory.php

This file was deleted.

Loading