Skip to content
Open
Show file tree
Hide file tree
Changes from 8 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
26 changes: 25 additions & 1 deletion bin/phpmnd
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,28 @@ if (false === $loaded) {
ini_set('xdebug.max_nesting_level', 10000);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one file is the one i need to take a better look :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it doesn't sit right here, but can't think of a better way via Symfony/Console. We're basically checking if no command is sent, and prefixing run. We have a run command since adding multiple commands (even two for self-update) seems to require abandoning a default command. Also, the using setDefaultCommand method for Application doesn't accept arguments so that's not a solution.

Not sure if these are specific design decisions (or just limitations) by the Symfony team, or I'm just missing something obvious that would make that prepareArgv function go away.


$application = new Povils\PHPMND\Console\Application;
$application->run();
$application->add(new Povils\PHPMND\Console\Command);
if ('phar:' === substr(__FILE__, 0, 5)) {
$application->add(new Povils\PHPMND\Console\Command\SelfUpdate);
}

$output = new Symfony\Component\Console\Output\ConsoleOutput();
$input = new \Symfony\Component\Console\Input\ArgvInput(prepareArgv());
$application->run($input, $output);

function prepareArgv()
{
$argv = $_SERVER['argv'];

$found = false;

if (isset($argv[1]) && ('run' === $argv[1] || 'self-update' === $argv[1])) {
$found = true;
}

if (!$found) {
array_splice($argv, 1, 0, ['run']);
}

return $argv;
}
3 changes: 2 additions & 1 deletion box.json.dist
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
"phar-io/manifest",
"phar-io/version",
"theseer/tokenizer",
"sebastian/object-reflector"
"sebastian/object-reflector",
"squizlabs/php_codesniffer"
],
"in": [
"vendor"
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
},
"require-dev": {
"phpunit/phpunit": "^5.7 || ^6.0",
"squizlabs/php_codesniffer": "^2.8.1"
"squizlabs/php_codesniffer": "^2.8.1",
"padraic/phar-updater": "^1.0.3"
},
"autoload": {
"psr-4": {
Expand Down
36 changes: 3 additions & 33 deletions src/Console/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,37 +19,7 @@ class Application extends BaseApplication

public function __construct()
{
parent::__construct('phpmnd', self::VERSION);
}

/**
* @inheritdoc
*/
protected function getCommandName(InputInterface $input)
{
return self::COMMAND_NAME;
}

/**
* @inheritdoc
*/
protected function getDefaultCommands()
{
$defaultCommands = parent::getDefaultCommands();
$defaultCommands[] = new Command;

return $defaultCommands;
}

/**
* @inheritdoc
*/
public function getDefinition()
{
$inputDefinition = parent::getDefinition();
$inputDefinition->setArguments();

return $inputDefinition;
parent::__construct(self::COMMAND_NAME, self::VERSION);
}

/**
Expand All @@ -70,8 +40,8 @@ public function doRun(InputInterface $input, OutputInterface $output)
exit;
}

if (null === $input->getFirstArgument()) {
$input = new ArrayInput(['--help']);
if ('run' === (string) $input) {
$input = new ArrayInput(['run','--help']);
}

parent::doRun($input, $output);
Expand Down
3 changes: 2 additions & 1 deletion src/Console/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ class Command extends BaseCommand
protected function configure()
{
$this
->setName('phpmnd')
->setName('run')
->setDescription('Runs PHPMND. Executed by default when no other command provided.')
->setDefinition(
[
new InputArgument(
Expand Down
224 changes: 224 additions & 0 deletions src/Console/Command/SelfUpdate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
<?php

namespace Povils\PHPMND\Console\Command;

use Povils\PHPMND\Console\Application;
use Symfony\Component\Console\Command\Command as BaseCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Humbug\SelfUpdate\Updater;
use Humbug\SelfUpdate\Strategy\GithubStrategy;

class SelfUpdate extends BaseCommand
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make protected methods,properties to private :)

{

/**
* Packagist package name
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PACKAGIST_PACKAGE_NAME and you dont need comment

*/
const PACKAGE_NAME = 'povils/phpmnd';
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this belongs to Application i think so


/**
* This is the remote file name, not local name.
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove comment and name constant REMOTE_FILENAME :)

*/
const FILE_NAME = 'phpmnd.phar';

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

/**
* @var string
*/
protected $version;

/**
* Setup command and arguments.
*/
protected function configure()
{
$this
->setName('self-update')
->setDescription('Update phpmnd.phar to most recent stable build.')
->addOption(
'stable',
's',
InputOption::VALUE_NONE,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can probably be deleted. If support is needed for non-stable releases (alphas, betas, RCs) alternative stability flags can be passed into phar-updater.

'Update to most recent stable version of PHPMND tagged on Github.'
)
->addOption(
'rollback',
'r',
InputOption::VALUE_NONE,
'Rollback to previous version of PHPMND if available on filesystem.'
)
->addOption(
'check',
'c',
InputOption::VALUE_NONE,
'Checks what updates are available.'
)
;
}

/**
* Execute the command.
*
* @param InputInterface $input
* @param OutputInterface $output
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->output = $output;
$this->version = $this->getApplication()->getVersion();

/**
* Check for ancilliary options
*/
if ($input->getOption('rollback')) {
$this->rollback();
return;
}

if ($input->getOption('check')) {
$this->printAvailableUpdates();
return;
}

$this->updateToStableBuild();
}

/**
* Perform update using phar-updater configured for stable versions.
*/
protected function updateToStableBuild()
{
$this->update($this->getStableUpdater());
}

/**
* Get phar-updater instance.
*/
protected function getStableUpdater()
{
$updater = new Updater(null, false);
$updater->setStrategy(Updater::STRATEGY_GITHUB);
return $this->getGithubReleasesUpdater($updater);
}

/**
* Perform in-place update of phar.
*/
protected function update(Updater $updater)
{
$this->output->writeln('Updating...'.PHP_EOL);
try {
$result = $updater->update();

$newVersion = $updater->getNewVersion();
$oldVersion = $updater->getOldVersion();

if ($result) {
$this->output->writeln('<fg=green>PHPMND has been updated.</fg=green>');
$this->output->writeln(sprintf(
'<fg=green>Current version is:</fg=green> <options=bold>%s</options=bold>.',
$newVersion
));
$this->output->writeln(sprintf(
'<fg=green>Previous version was:</fg=green> <options=bold>%s</options=bold>.',
$oldVersion
));
} else {
$this->output->writeln('<fg=green>PHPMND is currently up to date.</fg=green>');
$this->output->writeln(sprintf(
'<fg=green>Current version is:</fg=green> <options=bold>%s</options=bold>.',
$oldVersion
));
}
} catch (\Exception $e) {
$this->output->writeln(sprintf('Error: <fg=yellow>%s</fg=yellow>', $e->getMessage()));
}
$this->output->write(PHP_EOL);
}

/**
* Attempt to rollback to the previous phar version.
*/
protected function rollback()
{
$updater = new Updater(null, false);
try {
$result = $updater->rollback();
if ($result) {
$this->output->writeln('<fg=green>PHPMND has been rolled back to prior version.</fg=green>');
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is different from <fg=green> ? I would prefer use , , and so on

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your preference didn't show up in comment (probably github markdown parser rendering as HTML tag).

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

damn :D <info>, <danger>, <warning>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:D Updated. Check if those are in line with what you would prefer.

Copy link
Copy Markdown
Contributor Author

@padraic padraic May 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, seem to be getting ignored for some reason in actual output (at least here). May need to check that tomorrow.

} else {
$this->output->writeln('<fg=red>Rollback failed for reasons unknown.</fg=red>');
}
} catch (\Exception $e) {
$this->output->writeln(sprintf('Error: <fg=yellow>%s</fg=yellow>', $e->getMessage()));
}
}

protected function printAvailableUpdates()
{
$this->printCurrentLocalVersion();
$this->printCurrentStableVersion();
}

/**
* Print the current version of the phar in use.
*/
protected function printCurrentLocalVersion()
{
$this->output->writeln(sprintf(
'Your current local build version is: <options=bold>%s</options=bold>',
$this->version
));
}

/**
* Send updater to version printer.
*/
protected function printCurrentStableVersion()
{
$this->printVersion($this->getStableUpdater());
}

/**
* Print a remotely available version.
* @param Updater $updater
*/
protected function printVersion(Updater $updater)
{
$stability = 'stable';
try {
if ($updater->hasUpdate()) {
$this->output->writeln(sprintf(
'The current %s build available remotely is: <options=bold>%s</options=bold>',
$stability,
$updater->getNewVersion()
));
} elseif (false == $updater->getNewVersion()) {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getNewVersion returns bool?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, it does. There's an implementation shortfall in the phar-updater library, where this avoids calling Packagist twice. Something to be fixed there in a future version.

$this->output->writeln(sprintf('There are no new %s builds available.', $stability));
} else {
$this->output->writeln(sprintf('You have the current %s build installed.', $stability));
}
} catch (\Exception $e) {
$this->output->writeln(sprintf('Error: <fg=yellow>%s</fg=yellow>', $e->getMessage()));
}
}

/**
* Configure phar-updater with local phar details.
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment doesnt match with method name. In other words get rid of comment :)

* @param Updater $updater
* @return Updater
*/
protected function getGithubReleasesUpdater(Updater $updater)
{
$updater->getStrategy()->setPackageName(self::PACKAGE_NAME);
$updater->getStrategy()->setPharName(self::FILE_NAME);
$updater->getStrategy()->setCurrentLocalVersion($this->version);
return $updater;
}
}