├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── composer.json ├── phpunit.xml.dist └── src ├── lib └── KevinGH │ └── Amend │ ├── Command.php │ └── Helper.php └── tests ├── KevinGH └── Amend │ └── Tests │ ├── CommandTest.php │ └── HelperTest.php └── load.php /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | /bin/ 3 | /coverage/ 4 | /src/vendors/ 5 | 6 | /*.iml 7 | /composer.lock 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.3 5 | - 5.4 6 | 7 | before_script: 8 | - composer self-update 9 | - composer install --dev -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Kevin Herrera 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Amend 2 | ===== 3 | 4 | [![Build Status](https://secure.travis-ci.org/kherge/Amend.png?branch=master)](http://travis-ci.org/kherge/Amend) 5 | 6 | Integrates [Phar Update](https://github.com/herrera-io/php-phar-update) to [Symfony Console](https://github.com/symfony/Console). 7 | 8 | Summary 9 | ------- 10 | 11 | Uses the Phar Update library to: 12 | 13 | 1. check for newer versions of the Phar 14 | 1. download the Phar 15 | - verify download by SHA1 checksum, and public key if available 16 | 1. replace running Phar with downloaded update 17 | 18 | Installation 19 | ------------ 20 | 21 | Add it to your list of Composer dependencies: 22 | 23 | ```sh 24 | $ composer require kherge/amend=3.* 25 | ``` 26 | 27 | Usage 28 | ----- 29 | 30 | ```php 31 | setManifestUri('http://box-project.org/manifest.json'); 39 | 40 | $app = new Application(); 41 | $app->getHelperSet()->set(new Helper()); 42 | $app->add($command); 43 | ``` -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kherge/amend", 3 | "description": "Integrates Phar Update to Symfony Console.", 4 | "keywords": ["phar", "update", "console"], 5 | "homepage": "http://github.com/box-project/amend", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Kevin Herrera", 10 | "email": "kevin@herrera.io", 11 | "homepage": "http://kevin.herrera.io" 12 | } 13 | ], 14 | "support": { 15 | "issues": "https://github.com/box-project/amend/issues", 16 | "source": "https://github.com/box-project/amend" 17 | }, 18 | "require": { 19 | "php": ">=5.3.3", 20 | "herrera-io/phar-update": "~2.0", 21 | "symfony/console": "^2.1|^3.0" 22 | }, 23 | "require-dev": { 24 | "herrera-io/box": "~1.0", 25 | "herrera-io/phpunit-test-case": "1.*", 26 | "phpunit/phpunit": "3.7.*" 27 | }, 28 | "autoload": { 29 | "psr-0": { 30 | "KevinGH\\Amend": "src/lib" 31 | } 32 | }, 33 | "config": { 34 | "bin-dir": "bin", 35 | "vendor-dir": "src/vendors" 36 | }, 37 | "extra": { 38 | "branch-alias": { 39 | "dev-master": "3.0-dev" 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | src/lib/ 15 | 16 | 17 | 18 | 19 | src/tests/ 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/lib/KevinGH/Amend/Command.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class Command extends Base 18 | { 19 | /** 20 | * Disable the ability to upgrade? 21 | * 22 | * @var boolean 23 | */ 24 | private $disableUpgrade = false; 25 | 26 | /** 27 | * The manifest file URI. 28 | * 29 | * @var string 30 | */ 31 | private $manifestUri; 32 | 33 | /** 34 | * {@inheritDoc} 35 | * 36 | * @param string $name The command name. 37 | * @param boolean $disable Disable upgrading? 38 | */ 39 | public function __construct($name, $disable = false) 40 | { 41 | $this->disableUpgrade = $disable; 42 | 43 | parent::__construct($name); 44 | } 45 | 46 | /** 47 | * Sets the manifest URI. 48 | * 49 | * @param string $uri The URI. 50 | */ 51 | public function setManifestUri($uri) 52 | { 53 | $this->manifestUri = $uri; 54 | } 55 | 56 | /** 57 | * @override 58 | */ 59 | protected function configure() 60 | { 61 | $this->setDescription('Updates the application.'); 62 | $this->addOption( 63 | 'pre', 64 | 'p', 65 | InputOption::VALUE_NONE, 66 | 'Allow pre-release updates.' 67 | ); 68 | $this->addOption( 69 | 'redo', 70 | 'r', 71 | InputOption::VALUE_NONE, 72 | 'Redownload update if already using current version.' 73 | ); 74 | 75 | if (false === $this->disableUpgrade) { 76 | $this->addOption( 77 | 'upgrade', 78 | 'u', 79 | InputOption::VALUE_NONE, 80 | 'Upgrade to next major release, if available.' 81 | ); 82 | } 83 | } 84 | 85 | /** 86 | * @override 87 | */ 88 | protected function execute(InputInterface $input, OutputInterface $output) 89 | { 90 | if (null === $this->manifestUri) { 91 | throw new LogicException( 92 | 'No manifest URI has been configured.' 93 | ); 94 | } 95 | 96 | $output->writeln('Looking for updates...'); 97 | 98 | /** @var $amend Helper */ 99 | $amend = $this->getHelper('amend'); 100 | $manager = $amend->getManager($this->manifestUri); 101 | 102 | if ($manager->update( 103 | $this->getApplication()->getVersion(), 104 | $this->disableUpgrade ?: (false === $input->getOption('upgrade')), 105 | $input->getOption('pre') 106 | )){ 107 | $output->writeln('Update successful!'); 108 | } else { 109 | $output->writeln('Already up-to-date.'); 110 | } 111 | } 112 | } -------------------------------------------------------------------------------- /src/lib/KevinGH/Amend/Helper.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | class Helper extends Base 15 | { 16 | /** 17 | * The update manager. 18 | * 19 | * @var Manager 20 | */ 21 | private $manager; 22 | 23 | /** 24 | * Returns the update manager. 25 | * 26 | * @param string $uri The manifest file URI. 27 | * 28 | * @return Manager The update manager. 29 | */ 30 | public function getManager($uri) 31 | { 32 | return new Manager(Manifest::loadFile($uri)); 33 | } 34 | 35 | /** 36 | * {@inheritDoc} 37 | */ 38 | public function getName() 39 | { 40 | return 'amend'; 41 | } 42 | } -------------------------------------------------------------------------------- /src/tests/KevinGH/Amend/Tests/CommandTest.php: -------------------------------------------------------------------------------- 1 | command->setManifestUri('http://example.com/test.json'); 31 | 32 | $this->assertEquals( 33 | 'http://example.com/test.json', 34 | $this->getPropertyValue($this->command, 'manifestUri') 35 | ); 36 | } 37 | 38 | public function testConfigure() 39 | { 40 | $definition = $this->command->getDefinition(); 41 | 42 | $this->assertTrue($definition->hasOption('redo')); 43 | $this->assertTrue($definition->hasOption('upgrade')); 44 | } 45 | 46 | public function testConfigureDisabled() 47 | { 48 | $command = new Command('upgrade', true); 49 | $definition = $command->getDefinition(); 50 | 51 | $this->assertTrue($definition->hasOption('redo')); 52 | $this->assertFalse($definition->hasOption('upgrade')); 53 | } 54 | 55 | public function testExecuteNoManifest() 56 | { 57 | $app = new Application('Test', '1.0.0'); 58 | $app->getHelperSet()->set(new Helper()); 59 | $app->add(new Command('upgrade')); 60 | 61 | $tester = new CommandTester($app->get('upgrade')); 62 | 63 | $this->setExpectedException( 64 | 'LogicException', 65 | 'No manifest URI has been configured.' 66 | ); 67 | 68 | $tester->execute(array('command' => 'upgrade')); 69 | } 70 | 71 | public function testExecute() 72 | { 73 | $_SERVER['argv'][0] = $this->createPhar('a.phar', 'alpha'); 74 | 75 | $b = $this->createPhar('b.phar', 'beta'); 76 | 77 | $manifest = $this->createFile(); 78 | 79 | file_put_contents($manifest, json_encode(array( 80 | array( 81 | 'name' => 'a.phar', 82 | 'sha1' => sha1_file($b), 83 | 'url' => $b, 84 | 'version' => '1.2.0' 85 | ), 86 | array( 87 | 'name' => 'a.phar', 88 | 'sha1' => 'abcdef0123abcdef0123abcdef0123abcdef0123', 89 | 'url' => 'file:///does/not/exist', 90 | 'version' => '2.0.0' 91 | ) 92 | ))); 93 | 94 | $command = new Command('upgrade', true); 95 | $command->setManifestUri($manifest); 96 | 97 | $app = new Application('Test', '1.0.0'); 98 | $app->getHelperSet()->set(new Helper()); 99 | $app->add($command); 100 | 101 | $tester = new CommandTester($app->get('upgrade')); 102 | $tester->execute(array('command' => 'upgrade')); 103 | 104 | $this->assertRegExp( 105 | '/Update successful!/', 106 | $tester->getDisplay() 107 | ); 108 | 109 | $this->assertEquals( 110 | 'beta', 111 | exec('php ' . escapeshellarg($_SERVER['argv'][0])) 112 | ); 113 | } 114 | 115 | public function testExecuteCurrent() 116 | { 117 | $manifest = $this->createFile(); 118 | 119 | file_put_contents($manifest, '[]'); 120 | 121 | $command = new Command('upgrade', true); 122 | $command->setManifestUri($manifest); 123 | 124 | $app = new Application('Test', '1.0.0'); 125 | $app->getHelperSet()->set(new Helper()); 126 | $app->add($command); 127 | 128 | $tester = new CommandTester($app->get('upgrade')); 129 | $tester->execute(array('command' => 'upgrade')); 130 | 131 | $this->assertRegExp( 132 | '/Already up-to-date\./', 133 | $tester->getDisplay() 134 | ); 135 | } 136 | 137 | protected function createPhar($name, $echo) 138 | { 139 | unlink($file = $this->createFile($name)); 140 | 141 | $box = Box::create($file); 142 | $box->addFromString( 143 | 'index.php', 144 | 'command = new Command('upgrade'); 155 | } 156 | } -------------------------------------------------------------------------------- /src/tests/KevinGH/Amend/Tests/HelperTest.php: -------------------------------------------------------------------------------- 1 | createFile(); 27 | 28 | file_put_contents($file, '[]'); 29 | 30 | $this->assertInstanceOf( 31 | 'Herrera\\Phar\\Update\\Manager', 32 | $this->helper->getManager($file) 33 | ); 34 | } 35 | 36 | public function testGetName() 37 | { 38 | $this->assertEquals('amend', $this->helper->getName()); 39 | } 40 | 41 | protected function setUp() 42 | { 43 | $this->helper = new Helper(); 44 | } 45 | } -------------------------------------------------------------------------------- /src/tests/load.php: -------------------------------------------------------------------------------- 1 | add(null, __DIR__); 6 | 7 | --------------------------------------------------------------------------------