From ed2011301ac2dde85fc81d8c200510420169d687 Mon Sep 17 00:00:00 2001 From: Positron Date: Thu, 2 Mar 2017 14:48:30 -0500 Subject: [PATCH] Add versioning script --- scripts/version.php | 261 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100755 scripts/version.php diff --git a/scripts/version.php b/scripts/version.php new file mode 100755 index 00000000..e3b6d8f0 --- /dev/null +++ b/scripts/version.php @@ -0,0 +1,261 @@ +#!/usr/bin/php +script_path = $argv[ 0 ]; + $this->command = ''; + $this->major_number = 0; + $this->minor_number = 0; + $this->patch_number = 0; + $this->build_number = 0; + $this->commit = ''; + } + + private function read_command() { + $options = getopt( '', array( + 'help', + 'show', + 'bump-major', + 'bump-minor', + 'bump-patch', + 'bump-build', + 'reset', + ) ); + if ( count( $options ) > 0 ) { + $this->command = key( $options ); + } + } + + private function execute_command() { + switch ( $this->command ) { + case 'help': + $this->handle_help(); + break; + case 'show': + $this->handle_show(); + break; + case 'bump-major': + $this->handle_bump_major(); + break; + case 'bump-minor': + $this->handle_bump_minor(); + break; + case 'bump-patch': + $this->handle_bump_patch(); + break; + case 'bump-build': + $this->handle_bump_build(); + break; + case 'reset': + $this->handle_reset(); + break; + case '': + $this->handle_empty(); + break; + default: + $this->show_err( + "unhandled command: " . $this->command ); + $this->bail(); + } + } + + private function handle_help() { + $this->show_help(); + } + + private function show_help() { + printf( + "Usage: %s [option]\n" . + "Options:\n" . + " --help Show this help information\n" . + " --show Show current version\n" . + " --bump-major Bump major number of version\n" . + " --bump-minor Bump minor number of version\n" . + " --bump-patch Bump patch number of version\n" . + " --bump-build Bump build number of version\n" . + " --reset Set version back to the initial version\n", + $this->script_path ); + } + + private function handle_show() { + $this->load_version(); + printf( "%s\n", $this->encode_version() ); + } + + private function load_version() { + $contents = @file_get_contents( VERSION_FILE ); + if ( $contents === false ) { + $this->show_err(); + $this->bail(); + } + $matches = array(); + $result = preg_match( '/const char\* c_version = "([^"]+)";$/', + $contents, $matches ); + if ( $result !== 1 ) { + $this->show_err( 'version file (' . VERSION_FILE . + ') of incorrect format' ); + $this->bail(); + } + $this->decode_version( $matches[ 1 ] ); + } + + private function save_version( $release_version = false ) { + $version = $this->encode_version(); + $this->write_version_file( VERSION_FILE, $version ); + if ( $release_version ) { + $this->write_version_file( RELEASE_VERSION_FILE, $version ); + } + } + + private function write_version_file( $file, $version ) { + $written = @file_put_contents( $file, sprintf( + "// NOTE: This file is automatically generated by this script: \n" . + "// %s\n" . + "const char* c_version = \"%s\";\n", __FILE__, $version ) ); + if ( $written === false ) { + $this->show_err(); + $this->bail(); + } + } + + private function encode_version() { + $version = sprintf( '%d.%d.%d', + $this->major_number, + $this->minor_number, + $this->patch_number ); + if ( $this->is_development_version() ) { + $version = sprintf( '%s+%s.%d', + $version, + $this->get_latest_commit_hash(), + $this->build_number ); + } + return $version; + } + + private function is_development_version() { + // A nonzero build number indicates a development version. + return ( $this->build_number > 0 ); + } + + private function decode_version( $version ) { + $matches = array(); + $result = preg_match( + '/^([0-9]+)\.([0-9]+)\.([0-9]+)(\+([a-z0-9]+)\.([0-9]+))?$/', + $version, $matches ); + if ( $result !== 1 ) { + $this->show_err( "version string of incorrect format" ); + $this->bail(); + } + $this->major_number = ( int ) $matches[ 1 ]; + $this->minor_number = ( int ) $matches[ 2 ]; + $this->patch_number = ( int ) $matches[ 3 ]; + if ( count( $matches ) == 7 ) { + $this->commit = $matches[ 5 ]; + $this->build_number = ( int ) $matches[ 6 ]; + } + } + + private function get_latest_commit_hash() { + $code = 1; + $lines = array(); + exec( 'git --no-pager log -n 1 --pretty="%H"', $lines, $code ); + if ( ! ( $code == 0 && count( $lines ) == 1 ) ) { + $this->showErr( 'could not get hash of latest commit' ); + $this->bail(); + } + return $lines[ 0 ]; + } + + private function handle_bump_major() { + $this->load_version(); + ++$this->major_number; + $this->minor_number = 0; + $this->patch_number = 0; + $this->build_number = 0; + $this->save_version( true ); + } + + private function handle_bump_minor() { + $this->load_version(); + ++$this->minor_number; + $this->patch_number = 0; + $this->build_number = 0; + $this->save_version( true ); + } + + private function handle_bump_patch() { + $this->load_version(); + ++$this->patch_number; + $this->build_number = 0; + $this->save_version( true ); + } + + private function handle_bump_build() { + $this->load_version(); + ++$this->build_number; + $this->save_version(); + } + + private function handle_reset() { + $this->save_version( true ); + } + + private function handle_empty() { + $this->show_help(); + $this->bail(); + } + + private function show_err( $msg = '' ) { + $prefix = sprintf( '%s', basename( $this->script_path ) ); + if ( $msg == '' ) { + $err = error_get_last(); + if ( $err !== null ) { + $prefix = sprintf( '%s:%d', $prefix, $err[ 'line' ] ); + $msg = $err[ 'message' ]; + } + } + printf( "%s: error: %s\n", $prefix, $msg ); + } + + private function bail() { + throw new Exception(); + } + + public static function run( $argv ) { + try { + $task = new task( $argv ); + $task->read_command(); + $task->execute_command(); + exit( EXIT_SUCCESS ); + } + catch ( Exception $e ) { + exit( EXIT_FAILURE ); + } + } +}; + +task::run( $argv ); \ No newline at end of file