├── scripts ├── local-install ├── compile └── phprelease.php ├── tests ├── bootstrap.php ├── data │ ├── test.php │ └── test2.php └── PHPRelease │ ├── Services │ └── PackagistServiceTest.php │ ├── Tasks │ └── BumpVersionTest.php │ └── VersionParserTest.php ├── phprelease ├── .travis.yml ├── package.ini ├── bin └── phprelease ├── phprelease.ini ├── src └── PHPRelease │ ├── Command │ ├── TagCommand.php │ ├── ReleaseCommand.php │ ├── InitCommand.php │ └── BumpCommand.php │ ├── Tasks │ ├── PEAR.php │ ├── Pyrus.php │ ├── OnionBuild.php │ ├── ComposerArchive.php │ ├── GitTag.php │ ├── BaseTask.php │ ├── GitAdd.php │ ├── GitCommit.php │ ├── PHPUnit.php │ ├── GitPushTags.php │ ├── GitPush.php │ └── BumpVersion.php │ ├── VersionParser.php │ ├── Services │ └── PackagistService.php │ ├── VersionReader.php │ └── Console.php ├── composer.json ├── phpunit.xml └── README.md /scripts/local-install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cp -v phprelease ~/bin 3 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | " 7 | -------------------------------------------------------------------------------- /scripts/compile: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | php bin/phprelease --debug archive --app-bootstrap --executable --no-compress --exclude tests 4 | mv -v output.phar phprelease 5 | chmod +x phprelease 6 | -------------------------------------------------------------------------------- /bin/phprelease: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | add('PHPRelease','src'); 5 | $app = PHPRelease\Console::getInstance(); 6 | $app->run( $argv ); 7 | -------------------------------------------------------------------------------- /phprelease.ini: -------------------------------------------------------------------------------- 1 | 2 | Steps = PHPUnit, BumpVersion, scripts/compile, scripts/local-install, GitAdd, GitCommit, GitTag, GitPush, GitPushTags 3 | VersionFrom = src/PHPRelease/Console.php 4 | 5 | [GitAdd] 6 | Paths[] = src 7 | Paths[] = tests 8 | -------------------------------------------------------------------------------- /src/PHPRelease/Command/TagCommand.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | * 11 | */ 12 | $app = PHPRelease\Console::getInstance(); 13 | $app->run( $argv ); 14 | -------------------------------------------------------------------------------- /src/PHPRelease/Tasks/ComposerArchive.php: -------------------------------------------------------------------------------- 1 | $regs[1], 12 | 'minor' => (@$regs[2] ?: 0), 13 | 'patch' => (@$regs[3] ?: 0), 14 | 'stability' => (@$regs[4] ?: null), 15 | ); 16 | } 17 | return array(); 18 | } 19 | 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/PHPRelease/Command/InitCommand.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | tests 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/PHPRelease/Tasks/GitTag.php: -------------------------------------------------------------------------------- 1 | getConfig(); 12 | $version = isset($config['GitTagPrefix']) ? $config['GitTagPrefix'] : ''; 13 | $version .= $this->getApplication()->getCurrentVersion(); 14 | $this->logger->info("===> Tagging as $version"); 15 | $lastline = system("git tag \"$version\"", $retval); 16 | return $retval == 0; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/PHPRelease/Services/PackagistServiceTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped('PackagistServiceTest requires PACKAGIST_USERNAME and PACKAGIST_APITOKEN to be setup.'); 13 | } 14 | $service = new PackagistService($username, $apiToken); 15 | $result = $service->updatePackage('https://github.com/c9s/PHPRelease'); 16 | var_dump($result); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/PHPRelease/Tasks/BaseTask.php: -------------------------------------------------------------------------------- 1 | config = $config; 18 | $this->configAccessor = new Accessor($this->config); 19 | } 20 | 21 | public function getConfig() 22 | { 23 | return $this->config; 24 | } 25 | 26 | public function config($key) { 27 | return $this->configAccessor->lookup($key); 28 | } 29 | 30 | public function options($options) { } 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/PHPRelease/Command/BumpCommand.php: -------------------------------------------------------------------------------- 1 | add('major','bump major version'); 12 | $opts->add('minor','bump minor version'); 13 | $opts->add('s|stability:','set stability'); 14 | foreach( array('dev','rc','beta','alpha','stable') as $s ) { 15 | $opts->add($s, "set stability to $s."); 16 | } 17 | } 18 | 19 | public function execute() 20 | { 21 | if ( file_exists('composer.json') ) { 22 | // trying to read the version 23 | } 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/PHPRelease/Tasks/GitAdd.php: -------------------------------------------------------------------------------- 1 | getConfig(); 21 | if ( isset($config['GitAdd']['Paths']) ) { 22 | foreach( $config['GitAdd']['Paths'] as $path ) { 23 | passthru("git add -v ",$retval); 24 | if ($retval != 0) { 25 | return false; 26 | } 27 | } 28 | } 29 | return true; 30 | } 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/PHPRelease/Tasks/GitCommit.php: -------------------------------------------------------------------------------- 1 | add('m|message:', 'commit message.'); 11 | } 12 | 13 | public function execute() 14 | { 15 | if ( isset($this->options->message) === true ) { 16 | $msg = $this->options->message; 17 | } else { 18 | $version = $this->getApplication()->getCurrentVersion(); 19 | $msg = "Checking in changes prior to tagging of version $version."; 20 | } 21 | 22 | passthru("git commit -a -m '$msg'", $retval); 23 | return $retval == 0; 24 | } 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/PHPRelease/Tasks/PHPUnit.php: -------------------------------------------------------------------------------- 1 | config('PHPUnit.Debug')) { 13 | $command[] = '--debug'; 14 | } 15 | if ($this->config('PHPUnit.Verbose')) { 16 | $command[] = '--verbose'; 17 | } 18 | if ($configFile = $this->config('PHPUnit.Configuration')) { 19 | $command[] = '--configuration'; 20 | $command[] = $configFile; 21 | } 22 | 23 | passthru(join(' ', $command), $retval); 24 | return $retval == 0; 25 | } 26 | } 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/PHPRelease/Tasks/GitPushTags.php: -------------------------------------------------------------------------------- 1 | add('remote+','git remote names for pushing.'); 12 | } 13 | 14 | public function execute() 15 | { 16 | $remotes = array(); 17 | if ( $this->options->remote && in_array('all',$this->options->remote) ) { 18 | $remotes = explode("\n",trim(shell_exec('git remote'))); 19 | } elseif ( $this->options->remote ) { 20 | $remotes = $this->options->remote; 21 | } else { 22 | $remotes = explode("\n",trim(shell_exec('git remote'))); 23 | } 24 | foreach ( $remotes as $remote ) { 25 | passthru("git push $remote --tags", $retval); 26 | if ( $retval != 0 ) 27 | return false; 28 | } 29 | return true; 30 | } 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/PHPRelease/Tasks/GitPush.php: -------------------------------------------------------------------------------- 1 | add('remote+','git remote names for pushing.'); 9 | } 10 | 11 | public function execute() 12 | { 13 | $branch = system('git rev-parse --abbrev-ref HEAD'); 14 | $remotes = array(); 15 | if ( $this->options->remote && in_array('all',$this->options->remote) ) { 16 | $remotes = explode("\n",trim(shell_exec('git remote'))); 17 | } elseif ( $this->options->remote ) { 18 | $remotes = $this->options->remote; 19 | } else { 20 | $remotes = explode("\n",trim(shell_exec('git remote'))); 21 | } 22 | foreach ( $remotes as $remote ) { 23 | $this->logger->info("---> Pushing to remote $remote..."); 24 | passthru("git push $remote $branch", $retval); 25 | if ( $retval != 0 ) 26 | return false; 27 | } 28 | return true; 29 | } 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /tests/PHPRelease/Tasks/BumpVersionTest.php: -------------------------------------------------------------------------------- 1 | parseVersionString('1.2.3'); 10 | ok($info); 11 | 12 | $b->bumpPatchVersion($info); 13 | is(4,$info['patch']); 14 | 15 | $b->bumpMinorVersion($info); 16 | is(3,$info['minor']); 17 | is(0,$info['patch']); 18 | 19 | $b->bumpMajorVersion($info); 20 | is(2,$info['major']); 21 | is(0,$info['minor']); 22 | // is('0.0.2',$b->bumpPatchVersion('0.0.1')); 23 | } 24 | 25 | public function testPHPDocVersionParsing() 26 | { 27 | $reader = new PHPRelease\VersionReader; 28 | is('0.0.1',$reader->readFromSourceFile("tests/data/test.php")); 29 | } 30 | 31 | public function testClassVersionConstParsing() 32 | { 33 | $reader = new PHPRelease\VersionReader; 34 | is('0.0.1',$reader->readFromSourceFile("tests/data/test2.php")); 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /tests/PHPRelease/VersionParserTest.php: -------------------------------------------------------------------------------- 1 | parseVersionString('1.2.3'); 9 | ok($info); 10 | is(1,$info['major']); 11 | is(2,$info['minor']); 12 | is(3,$info['patch']); 13 | ok( ! $info['stability'] ); 14 | } 15 | 16 | public function testVersionWithRCStability() 17 | { 18 | $p = new PHPRelease\VersionParser; 19 | $info = $p->parseVersionString('1.2.3-rc'); 20 | ok($info); 21 | is(1,$info['major']); 22 | is(2,$info['minor']); 23 | is(3,$info['patch']); 24 | is( 'rc', $info['stability'] ); 25 | } 26 | 27 | public function testVersionWithAlphaStability() 28 | { 29 | $p = new PHPRelease\VersionParser; 30 | $info = $p->parseVersionString('1.2.3-alpha'); 31 | ok($info); 32 | is(1,$info['major']); 33 | is(2,$info['minor']); 34 | is(3,$info['patch']); 35 | is( 'alpha', $info['stability'] ); 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/PHPRelease/Services/PackagistService.php: -------------------------------------------------------------------------------- 1 | username = $username; 14 | $this->apiToken = $apiToken; 15 | } 16 | 17 | 18 | /** 19 | * POST to https://packagist.org/api/update-package?username=c9s&apiToken=API_TOKEN 20 | * 21 | * The command: 22 | * 23 | * curl -XPOST -H'content-type:application/json' \ 24 | * 'https://packagist.org/api/update-package?username=c9s&apiToken=API_TOKEN' \ 25 | * -d'{"repository":{"url":"https://github.com/c9s/PHPRelease"}}' 26 | */ 27 | public function updatePackage($packageUrl) 28 | { 29 | $agent = new CurlAgent; 30 | $response = $agent->post("https://packagist.org/api/update-package?username={$this->username}&apiToken={$this->apiToken}", json_encode([ 31 | 'repository' => ['url' => $packageUrl], 32 | ]), [ 'Content-Type: application/json' ]); 33 | if ($response) { 34 | $result = $response->decodeBody(); 35 | return $result; 36 | } 37 | return false; 38 | } 39 | } 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/PHPRelease/VersionReader.php: -------------------------------------------------------------------------------- 1 | readFromSourceFile($file) ) { 16 | return $versionString; 17 | } 18 | } 19 | } 20 | 21 | public function readFromSourceFile($file) 22 | { 23 | $content = file_get_contents($file); 24 | // find class const 25 | if ( preg_match( self::classVersionPattern, $content, $regs) ) { 26 | return $regs[1]; 27 | } elseif ( preg_match( self::phpdocVersionPattern, $content, $regs) ) { 28 | return $regs[1]; 29 | } 30 | } 31 | 32 | public function readFromPackageINI() 33 | { 34 | if ( file_exists("package.ini") ) { 35 | $config = parse_ini_file("package.ini",true); 36 | if ( isset($config['package']['version']) ) { 37 | return $config['package']['version']; 38 | } 39 | } 40 | } 41 | 42 | public function readFromComposerJson() 43 | { 44 | if ( file_exists("composer.json") ) { 45 | $composer = json_decode(file_get_contents("composer.json"),true); 46 | if ( isset($composer['version']) ) { 47 | return $composer['version']; 48 | } 49 | } 50 | } 51 | 52 | } 53 | 54 | 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PHPRelease 2 | ========== 3 | [![Latest Stable Version](https://poser.pugx.org/corneltek/phprelease/v/stable)](https://packagist.org/packages/corneltek/phprelease) [![Total Downloads](https://poser.pugx.org/corneltek/phprelease/downloads)](https://packagist.org/packages/corneltek/phprelease) [![Latest Unstable Version](https://poser.pugx.org/corneltek/phprelease/v/unstable)](https://packagist.org/packages/corneltek/phprelease) [![License](https://poser.pugx.org/corneltek/phprelease/license)](https://packagist.org/packages/corneltek/phprelease) 4 | [![Build Status](https://travis-ci.org/c9s/PHPRelease.svg?branch=master)](https://travis-ci.org/c9s/PHPRelease) 5 | 6 | The simplest way to define your release process. 7 | 8 | Features 9 | --------- 10 | 11 | - Automatically version bumping for Composer, Onion, PHPDoc or Class constant. 12 | - Support version parsing from PHPDoc or class const. 13 | - Git tagging, pushing. 14 | - Simplest config. 15 | 16 | Install 17 | ------- 18 | 19 | ```sh 20 | $ curl -OLSs https://raw.github.com/c9s/PHPRelease/master/phprelease 21 | $ chmod +x phprelease 22 | $ mv phprelease /usr/bin 23 | ``` 24 | 25 | ### Including phprelease in your project 26 | 27 | Simplfy run composer require to include the package: 28 | 29 | composer require --dev corneltek/phprelease 30 | 31 | Usage 32 | ----- 33 | 34 | Create phprelease.ini config file by a simple command: 35 | 36 | 37 | ```sh 38 | $ phprelease init 39 | ``` 40 | 41 | The above command creates a `phprelease.ini` config file, you can also edit it 42 | by yourself: 43 | 44 | ```ini 45 | Steps = PHPUnit, BumpVersion, GitTag, GitPush, GitPushTags 46 | ``` 47 | 48 | The release steps may contains script files, you can simply insert the script 49 | path and phprelease will run it for you. the return code 0 means we are going 50 | to the next step. 51 | 52 | ```ini 53 | Steps = BumpVersion, scripts/compile, GitTag 54 | 55 | ``` 56 | 57 | Then, to release your package, simply type: 58 | 59 | ```sh 60 | $ phprelease 61 | ``` 62 | 63 | Bumping Version 64 | --------------- 65 | 66 | To bump major version and do release: 67 | 68 | $ phprelease --bump-major 69 | ===> Bumping version from 2.2.3 => 3.0.0 70 | 71 | To bump minor version and do release: 72 | 73 | $ phprelease --bump-minor 74 | ===> Bumping version from 2.2.3 => 2.3.0 75 | 76 | To bump minor version and set the stability suffix: 77 | 78 | $ phprelease --bump-minor --dev 79 | ===> Bumping version from 2.2.3 => 2.3.0-dev 80 | 81 | $ phprelease --bump-minor --beta 82 | ===> Bumping version from 2.2.3 => 2.3.0-beta 83 | 84 | $ phprelease --bump-minor --rc 85 | ===> Bumping version from 2.2.3 => 2.3.0-rc 86 | 87 | $ phprelease --bump-minor --rc1 88 | ===> Bumping version from 2.2.3 => 2.3.0-rc1 89 | 90 | $ phprelease --bump-minor --rc2 91 | ===> Bumping version from 2.2.3 => 2.3.0-rc2 92 | 93 | $ phprelease --bump-minor --stable 94 | ===> Bumping version from 2.2.3 => 2.3.0 95 | 96 | To use a version prefix for the git tag, add this key to your phprelease.ini: 97 | 98 | ```ini 99 | GitTagPrefix = v. 100 | ``` 101 | 102 | This will result in something like: 103 | 104 | $ phprelease 105 | ===> Version bump from 2.2.3 to 2.3.0 106 | ===> Running PHPRelease\Tasks\GitTag 107 | ===> Tagging as v.1.2.2 108 | 109 | Configuring GitAdd Task 110 | ------------------------ 111 | 112 | To use GitAdd Task, you may simply add the config below to your phprelease.ini: 113 | 114 | ```ini 115 | [GitAdd] 116 | Paths[] = src/ 117 | Paths[] = tests/ 118 | ``` 119 | 120 | Skipping Specific Step 121 | -------------------------- 122 | 123 | ```sh 124 | $ phprelease --skip BumpVersion 125 | ``` 126 | 127 | Getting Version From PHP Source File 128 | ------------------------------------- 129 | 130 | If you defined your version string in your PHP source file or class const, 131 | to bump version from php source file, you can simply define a `VersionFrom` option: 132 | 133 | 134 | ```ini 135 | ; to read version from php class file or from phpdoc "@VERSION ..." 136 | VersionFrom = src/PHPRelease/Console.php 137 | ``` 138 | 139 | 140 | Task Options 141 | ------------ 142 | 143 | Each task has its own options, run help command, you should see the options from these tasks: 144 | 145 | $ phprelease help 146 | PHPRelease - The Fast PHP Release Manager 147 | 148 | Usage 149 | phprelease [options] [command] [argument1 argument2...] 150 | 151 | Options 152 | -v, --verbose Print verbose message. 153 | -d, --debug Print debug message. 154 | -q, --quiet Be quiet. 155 | -h, --help help 156 | --version show version 157 | --dry dryrun mode. 158 | --bump-major bump major (X) version. 159 | --bump-minor bump minor (Y) version. 160 | --bump-patch bump patch (Z) version, this is the default. 161 | -s, --stability set stability 162 | --dev set stability to dev. 163 | --rc set stability to rc. 164 | --rc1 set stability to rc1. 165 | --rc2 set stability to rc2. 166 | --rc3 set stability to rc3. 167 | --rc4 set stability to rc4. 168 | --rc5 set stability to rc5. 169 | --beta set stability to beta. 170 | --alpha set stability to alpha. 171 | --stable set stability to stable. 172 | --remote + git remote names for pushing. 173 | 174 | 175 | So to bump the major verion, simply pass the flag: 176 | 177 | phprelease --bump-major 178 | 179 | You can also test your release steps in dry-run mode: 180 | 181 | phprelease --dryrun 182 | 183 | 184 | Built-In Tasks 185 | -------------- 186 | 187 | BumpVersion 188 | GitCommit 189 | GitPush 190 | GitPushTags 191 | GitTag 192 | PHPUnit 193 | 194 | 195 | Hacking 196 | ------- 197 | 198 | 1. For this project. 199 | 200 | 2. Get composer, and run: 201 | 202 | composer install --dev 203 | 204 | 3. Hack! 205 | -------------------------------------------------------------------------------- /src/PHPRelease/Tasks/BumpVersion.php: -------------------------------------------------------------------------------- 1 | add('bump-major','bump major (X) version.'); 12 | $opts->add('bump-minor','bump minor (Y) version.'); 13 | $opts->add('bump-patch','bump patch (Z) version, this is the default.'); 14 | $opts->add('prompt-version','prompt for version'); 15 | 16 | $opts->add('s|stability:','set stability'); 17 | foreach( $this->getStabilityKeys() as $s ) { 18 | $opts->add($s, "set stability to $s."); 19 | } 20 | } 21 | 22 | public function getStabilityKeys() 23 | { 24 | return array('dev','rc','rc1','rc2','rc3','rc4','rc5','beta','alpha','stable'); 25 | } 26 | 27 | public function replaceVersionFromSourceFile($file, $newVersionString) 28 | { 29 | $content = file_get_contents($file); 30 | $content = preg_replace( VersionReader::classVersionPattern, "const VERSION = \"$newVersionString\";" , $content); 31 | $content = preg_replace( VersionReader::phpdocVersionPattern, "@VERSION $newVersionString", $content); 32 | return file_put_contents($file, $content); 33 | } 34 | 35 | public function execute() 36 | { 37 | $versionString = $this->getCurrentVersion(); 38 | $versionParser = new VersionParser; 39 | $versionInfo = $versionParser->parseVersionString($versionString); 40 | 41 | if ( $this->options->{"bump-major"} ) { 42 | $this->bumpMajorVersion($versionInfo); 43 | } elseif ( $this->options->{"bump-minor"} ) { 44 | $this->bumpMinorVersion($versionInfo); 45 | } elseif ( $this->options->{"bump-patch"} ) { 46 | $this->bumpPatchVersion($versionInfo); 47 | } else { 48 | // this is the default behavior 49 | $this->bumpPatchVersion($versionInfo); 50 | } 51 | 52 | 53 | if ( $s = $this->options->stability ) { 54 | if ( $s === "stable" ) { 55 | unset( $versionInfo['stability'] ); 56 | } else { 57 | $versionInfo['stability'] = $s; 58 | } 59 | } else { 60 | foreach( $this->getStabilityKeys() as $s ) { 61 | if ( $this->options->{$s} ) { 62 | $versionInfo['stability'] = $s; 63 | break; 64 | } 65 | if ( $s === "stable" ) { 66 | unset( $versionInfo['stability'] ); 67 | break; 68 | } 69 | } 70 | } 71 | 72 | 73 | $newVersionString = $this->createVersionString($versionInfo); 74 | 75 | $this->logger->info("Current Version: $versionString"); 76 | 77 | if ( $this->options->{"prompt-version"} ) { 78 | if ( $input = $this->ask("New Version [$newVersionString]:") ) { 79 | $newVersionString = $input; 80 | } 81 | } 82 | 83 | $this->logger->info("===> Version bump from $versionString to $newVersionString"); 84 | 85 | 86 | $versionFromFiles = $this->getVersionFromFiles(); 87 | foreach( $versionFromFiles as $file ) { 88 | if ( false === $this->replaceVersionFromSourceFile($file, $newVersionString) ) { 89 | $this->logger->error("Version update failed: $file"); 90 | } 91 | } 92 | $this->writeVersionToPackageINI($newVersionString); 93 | $this->writeVersionToComposerJson($newVersionString); 94 | } 95 | 96 | public function getVersionFromFiles() 97 | { 98 | if ($file = $this->config('BumpVersion.VersionFrom')) { 99 | return preg_split('#\s*,\s*#', $file); 100 | } 101 | if ($file = $this->config('VersionFrom')) { 102 | return preg_split('#\s*,\s*#', $file); 103 | } 104 | return array(); 105 | } 106 | 107 | public function getCurrentVersion() 108 | { 109 | // XXX: Refactor to FindVersion task. 110 | $reader = new VersionReader; 111 | $versionFromFiles = $this->getVersionFromFiles(); 112 | if (! empty($versionFromFiles)) { 113 | if ( $versionString = $reader->readFromSourceFiles($versionFromFiles) ) { 114 | $this->logger->debug("Found version from source files."); 115 | return $versionString; 116 | } 117 | } 118 | 119 | if ( $versionString = $reader->readFromComposerJson() ) { 120 | $this->logger->debug("Found version from composer.json"); 121 | return $versionString; 122 | } 123 | 124 | if ( $versionString = $reader->readFromPackageINI() ) { 125 | $this->logger->debug("Found version from package.ini"); 126 | return $versionString; 127 | } 128 | $this->logger->error("Version string not found, aborting..."); 129 | return false; 130 | } 131 | 132 | public function writeVersionToPackageINI($newVersion) 133 | { 134 | if ( file_exists("package.ini") ) { 135 | $this->logger->debug("Writing version info from package.ini"); 136 | $content = file_get_contents("package.ini"); 137 | if ( preg_replace('#^version\s+=\s+.*?$#ims', "version = $newVersion", $content) ) { 138 | return file_put_contents("package.ini", $content); 139 | } 140 | } 141 | } 142 | 143 | public function writeVersionToComposerJson($newVersion) 144 | { 145 | if ( file_exists("composer.json") ) { 146 | $this->logger->debug("Writing version info from composer.json"); 147 | $composer = json_decode(file_get_contents("composer.json"),true); 148 | $composer['version'] = $newVersion; 149 | return file_put_contents("composer.json", json_encode($composer,JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); 150 | } 151 | } 152 | 153 | public function bumpMinorVersion(& $versionInfo) 154 | { 155 | $versionInfo['minor'] = (@$versionInfo['minor'] ?: 0) + 1; 156 | $versionInfo['patch'] = 0; 157 | } 158 | 159 | public function bumpMajorVersion(& $versionInfo) 160 | { 161 | $versionInfo['major'] = (@$versionInfo['major'] ?: 0) + 1; 162 | $versionInfo['minor'] = 0; 163 | $versionInfo['patch'] = 0; 164 | } 165 | 166 | public function bumpPatchVersion(& $versionInfo) 167 | { 168 | $versionInfo['patch'] = (@$versionInfo['patch'] ?: 0) + 1; 169 | } 170 | 171 | public function createVersionString($info) 172 | { 173 | $str = sprintf('%d.%d.%d', $info['major'], $info['minor'] , $info['patch'] ); 174 | if ( isset($info['stability']) && $info['stability'] != 'stable' ) { 175 | $str .= '-' . $info['stability']; 176 | } 177 | return $str; 178 | } 179 | } 180 | 181 | 182 | -------------------------------------------------------------------------------- /src/PHPRelease/Console.php: -------------------------------------------------------------------------------- 1 | add('dryrun','dryrun mode.'); 37 | $opts->add('skip+', 'Skip specific step'); 38 | $opts->add('no-autoload','Skip autoload'); 39 | 40 | // Inherit the options from the sub-tasks 41 | foreach($this->getTaskObjects() as $task) { 42 | $task->options($opts); 43 | } 44 | } 45 | 46 | public function init() 47 | { 48 | parent::init(); 49 | $this->addCommand('init'); 50 | } 51 | 52 | public function findTaskClass($step) 53 | { 54 | if ( class_exists( $step, true ) ) { 55 | return $step; 56 | } else { 57 | // built-in task 58 | $class = 'PHPRelease\\Tasks\\' . $step; 59 | if ( class_exists($class, true ) ) { 60 | return $class; 61 | } 62 | } 63 | } 64 | 65 | public function createTaskObject($class) 66 | { 67 | $task = $this->createCommand($class); 68 | $task->setConfig($this->getConfig()); 69 | 70 | // $task->setOptions( ); 71 | return $task; 72 | } 73 | 74 | public function getTaskObjects() 75 | { 76 | $tasks = array(); 77 | $steps = $this->getSteps(); 78 | foreach( $steps as $step ) { 79 | if (file_exists($step) || findbin($step)) { 80 | continue; 81 | } 82 | 83 | $taskClass = $this->findTaskClass($step); 84 | if (! $taskClass) { 85 | throw new RuntimeException("Task class $taskClass for $step not found."); 86 | } 87 | $task = $this->createTaskObject($taskClass); 88 | $tasks[] = $task; 89 | } 90 | return $tasks; 91 | } 92 | 93 | 94 | public function getVersionFromFiles() 95 | { 96 | if ( isset($this->config['VersionFrom']) && $this->config['VersionFrom'] ) { 97 | return preg_split('#\s*,\s*#', $this->config['VersionFrom']); 98 | } 99 | return array(); 100 | } 101 | 102 | public function getCurrentVersion() 103 | { 104 | // XXX: Refactor to FindVersion task. 105 | $reader = new VersionReader; 106 | $versionFromFiles = $this->getVersionFromFiles(); 107 | if ( ! empty($versionFromFiles) ) { 108 | if ( $versionString = $reader->readFromSourceFiles($versionFromFiles) ) { 109 | $this->logger->debug("Found version from source files."); 110 | return $versionString; 111 | } 112 | } 113 | 114 | if ( $versionString = $reader->readFromComposerJson() ) { 115 | $this->logger->debug("Found version from composer.json"); 116 | return $versionString; 117 | } 118 | 119 | if ( $versionString = $reader->readFromPackageINI() ) { 120 | $this->logger->debug("Found version from package.ini"); 121 | return $versionString; 122 | } 123 | 124 | $this->logger->error("Version string not found, aborting..."); 125 | return false; 126 | } 127 | 128 | public function runSteps($steps, $dryrun = false) 129 | { 130 | foreach( $steps as $step ) { 131 | if ( file_exists( $step ) || findbin($step) ) { 132 | $this->logger->info("===> Running $step"); 133 | if ( ! $dryrun ) { 134 | $lastline = system($step, $retval); 135 | if ( $retval ) { 136 | $this->logger->error($lastline); 137 | $this->logger->error("===> $step failed, aborting..."); 138 | exit(0); 139 | } 140 | } 141 | continue; 142 | } 143 | 144 | $taskClass = $this->findTaskClass($step); 145 | if ( ! $taskClass ) { 146 | $this->logger->error("===> Task $step not found, aborting..."); 147 | exit(0); 148 | } 149 | 150 | $task = $this->createTaskObject($taskClass); 151 | $task->setOptions($this->options); 152 | 153 | $this->logger->info("===> Running $taskClass"); 154 | if ( ! $dryrun ) { 155 | $retval = $task->execute(); 156 | if ( false === $retval ) { 157 | $this->logger->error("===> $taskClass failed, aborting..."); 158 | exit(0); 159 | } 160 | } 161 | } 162 | } 163 | 164 | 165 | public function getSteps() 166 | { 167 | $config = $this->getConfig(); 168 | $steps = array(); 169 | if ( isset($config['Steps']) ) { 170 | $steps = preg_split('#\s*,\s*#', $config['Steps'] ); 171 | } 172 | 173 | if ( $this->options && $this->options->skip ) { 174 | $keys = array_combine( $steps , $steps ); 175 | foreach( $this->options->skip as $s ) { 176 | unset($keys[$s]); 177 | } 178 | $steps = array_keys($keys); 179 | } 180 | return $steps; 181 | } 182 | 183 | public function getConfig() 184 | { 185 | if ( $this->config ) { 186 | return $this->config; 187 | } 188 | 189 | if ( file_exists('phprelease.ini') ) { 190 | $config = parse_ini_file('phprelease.ini'); 191 | return $this->config = $config; 192 | } 193 | return $this->config = array(); 194 | } 195 | 196 | public function execute() 197 | { 198 | if ( ! file_exists('phprelease.ini') ) { 199 | throw new RuntimeException("phprelease.ini not found, please run `phprelease init` command to get one."); 200 | } 201 | 202 | if ( ! $this->options->{'no-interact'}) { 203 | $input = $this->ask("Are you sure you want to release? [Y/n]"); 204 | if ( ! in_array($input, array('Y', 'y', ''))) { 205 | return; 206 | } 207 | } 208 | 209 | if ( ! $this->options->{'no-autoload'} ) { 210 | $config = $this->getConfig(); 211 | if ( isset($config['Autoload']) ) { 212 | if ( $a = $config['Autoload'] ) { 213 | $this->logger->info("===> Found autoload script, loading $a"); 214 | $loader = require $a; 215 | } 216 | } 217 | elseif ( file_exists('vendor/autoload.php') ) { 218 | $this->logger->info("===> Found autoload script from composer, loading..."); 219 | $loader = require "vendor/autoload.php"; 220 | } 221 | } 222 | 223 | $steps = $this->getSteps(); 224 | $this->runSteps($steps, $this->options->dryrun); 225 | } 226 | } 227 | --------------------------------------------------------------------------------