Skip to content

Commit

Permalink
Add versioning script
Browse files Browse the repository at this point in the history
  • Loading branch information
positively-charged committed Mar 2, 2017
1 parent f2ff40d commit ed20113
Showing 1 changed file with 261 additions and 0 deletions.
261 changes: 261 additions & 0 deletions scripts/version.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
#!/usr/bin/php
<?php

/*
Manipulates version of bcc.
*/

define( 'PROJECT_DIR', dirname( __DIR__ ) );
define( 'SRC_DIR', PROJECT_DIR . '/src' );
define( 'BUILD_DIR', PROJECT_DIR . '/build' );
define( 'VERSION_FILE', BUILD_DIR . '/version.c' );
define( 'RELEASE_VERSION_FILE', SRC_DIR . '/version.c' );
define( 'EXIT_SUCCESS', 0 );
define( 'EXIT_FAILURE', 1 );

class task {
public $script_path;
public $command;
public $major_number;
public $minor_number;
public $patch_number;
// Number of compilations since the last release (public) version.
public $build_number;
public $commit;

private function __construct( $argv ) {
$this->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 );

0 comments on commit ed20113

Please sign in to comment.