228 lines
8.2 KiB
Ruby
Executable File
228 lines
8.2 KiB
Ruby
Executable File
# File:: buildp4.rb
|
|
# Description:: Runs a script which builds some files, these files are then checked in p4 if it has changed.
|
|
# the destination files MUST already exist in perforce, since adding new files has it complications over multiple p4 servers.
|
|
#
|
|
# Also due to a lack of time on my milestone - this script will have to be very much so limited in scope of what it does - I've decided not to support
|
|
# multiple p4 servers - it's actually a lot more complex than I first though when dealing with wildcards / files that may or may not exists in either
|
|
# p4 and may need added or edited.
|
|
#
|
|
# Author:: Derek Ward <derek.ward@rockstarnorth.com>
|
|
# Date:: 14th October 2010
|
|
#
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Uses
|
|
#-----------------------------------------------------------------------------
|
|
require 'pipeline/os/path'
|
|
require 'pipeline/os/getopt'
|
|
require 'pipeline/log/log'
|
|
|
|
include Pipeline
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Constants
|
|
#-----------------------------------------------------------------------------
|
|
|
|
OPTIONS = [
|
|
[ '--checkout', '-ch', Getopt::REQUIRED, 'files to checkout that may or may not get built.' ],
|
|
[ '--nosync', '-ns', Getopt::OPTIONAL, 'files not to sync.' ],
|
|
[ '--command', '-co', Getopt::REQUIRED, 'script command to run including args' ],
|
|
[ '--desc', '-d', Getopt::REQUIRED, 'description for checkin.' ],
|
|
[ '--disablecheckin', '-dc', Getopt::BOOLEAN, 'prevent checkin ( for development )' ],
|
|
[ '--rage', '-r', Getopt::BOOLEAN, 'p4 server to operate on is the rage server' ],
|
|
[ '--submit_on_error', '-e', Getopt::BOOLEAN, 'submit changelist on error?' ]
|
|
]
|
|
|
|
INFO = "[colourise=black]INFO_MSG: "
|
|
INFO_BLUE = "[colourise=blue]INFO_MSG: "
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Implementation
|
|
#-----------------------------------------------------------------------------
|
|
|
|
class BuildP4
|
|
def initialize(checkout, desc, command, rage_p4, enable_checkin, submit_on_error, nosync)
|
|
@checkout = checkout
|
|
@desc = desc
|
|
@command = command.gsub(">",">")
|
|
@enable_checkin = enable_checkin
|
|
|
|
puts "#{INFO_BLUE} Checkin is enabled" if @enable_checkin
|
|
puts "#{INFO_BLUE} Checkin is disabled" unless @enable_checkin
|
|
|
|
@rage_p4 = rage_p4
|
|
@submit_on_error = submit_on_error
|
|
@nosync = nosync
|
|
end
|
|
|
|
#-------------------------------------------------------------------------
|
|
# --- Control logic
|
|
#-------------------------------------------------------------------------
|
|
def run( config )
|
|
sync_check_out( config )
|
|
error_count = run_script()
|
|
submit() if not ( @submit_on_error and error_count > 0 )
|
|
error_count
|
|
end
|
|
|
|
#-------------------------------------------------------------------------
|
|
# --- Establish SCM connection, sync to files, and checkout
|
|
#-------------------------------------------------------------------------
|
|
def sync_check_out( config )
|
|
|
|
puts "#{INFO_BLUE} Creating p4"
|
|
@p4 = @rage_p4 ? SCM::Perforce::create( config.sc_rage_server, config.sc_rage_username, config.sc_rage_workspace ) :
|
|
SCM::Perforce::create( config.sc_server, config.sc_username, config.sc_workspace )
|
|
|
|
puts "#{INFO_BLUE} #{@checkout_files}"
|
|
@checkout_files = @checkout.split
|
|
@nosync_files = @nosync.split
|
|
|
|
puts "#{INFO_BLUE} Connecting to p4 servers"
|
|
raise Exception if not @p4
|
|
|
|
@p4.connect( )
|
|
raise Exception if not @p4.connected?
|
|
|
|
puts "#{INFO_BLUE} Creating CL"
|
|
@change_id = @p4.create_changelist( "buildp4 generated file @ #{Time.now} on #{ENV["COMPUTERNAME"]}\n#{@desc}" )
|
|
raise Exception if @change_id.nil?
|
|
puts "#{INFO_BLUE}Changelist #{@change_id} is created"
|
|
|
|
@checkout_files.each do |depot_filename|
|
|
if (not @nosync_files.include? depot_filename)
|
|
puts "#{INFO_BLUE} Syncing #{depot_filename}"
|
|
@p4.run_sync( depot_filename )
|
|
end
|
|
|
|
puts "Checking out #{depot_filename} in CL #{@change_id.to_s}"
|
|
@p4.run_edit( '-c', @change_id.to_s, depot_filename )
|
|
|
|
puts "Reopening #{depot_filename} in CL #{@change_id.to_s}"
|
|
@p4.run_reopen( '-c', @change_id.to_s, depot_filename )
|
|
end
|
|
end
|
|
|
|
#-------------------------------------------------------------------------
|
|
# --- Run the script - yields to block if given.
|
|
#-------------------------------------------------------------------------
|
|
def run_script()
|
|
|
|
error_count = 0
|
|
|
|
if (block_given?)
|
|
yield( @checkout_files, error_count )
|
|
else
|
|
|
|
# Run script
|
|
|
|
cmd = @command
|
|
puts "#{INFO_BLUE} Executing #{cmd}...\n"
|
|
|
|
status, stdout, stderr = systemu(cmd)
|
|
|
|
puts "#{INFO_BLUE} \n...Completed"
|
|
|
|
$stderr.puts( cmd ) if ( stderr.length > 0 )
|
|
|
|
stderr.each do |err|
|
|
error_count += 1
|
|
$stderr.puts "Error: #{err}"
|
|
end
|
|
|
|
stdout.each_with_index do |out, idx|
|
|
puts out
|
|
end
|
|
end
|
|
|
|
error_count
|
|
end
|
|
|
|
#-------------------------------------------------------------------------
|
|
# --- Submit changes
|
|
#-------------------------------------------------------------------------
|
|
def submit()
|
|
puts "#{INFO_BLUE}Reverting unchanged files #{@change_id}"
|
|
@p4.run_revert( '-a', '-c', @change_id.to_s, '//...')
|
|
|
|
files = @p4.run_opened( '-c', @change_id.to_s )
|
|
raise Exception if files.nil?
|
|
|
|
puts "#{INFO_BLUE}There are #{files.size} files to submit."
|
|
files.each do |file|
|
|
puts "#{INFO_BLUE}#{file['depotFile']} has been updated and will be submitted."
|
|
end
|
|
|
|
if ( @enable_checkin )
|
|
if ( files.size > 0 )
|
|
puts "#{INFO_BLUE}Submitting file currently in #{@change_id}"
|
|
submit_result = @p4.run_submit( '-c', @change_id.to_s )
|
|
puts "#{INFO_BLUE} Submit result : #{submit_result.to_s}"
|
|
elsif ( 0 == files.size )
|
|
puts "#{INFO_BLUE}Deleting #{@change_id} no files changed."
|
|
@p4.run_change('-d', @change_id.to_s)
|
|
end
|
|
else
|
|
puts "#{INFO_BLUE}Checkin is disabled the CL is pending."
|
|
end
|
|
end
|
|
|
|
end # class BuildP4
|
|
|
|
#-----------------------------------------------------------------------------
|
|
#-----------------------------------------------------------------------------
|
|
#-----------------------------------------------------------------------------
|
|
|
|
|
|
if ( __FILE__ == $0 ) then
|
|
|
|
error_count = 0
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Code
|
|
#-----------------------------------------------------------------------------
|
|
begin
|
|
#-------------------------------------------------------------------------
|
|
# Entry-Point
|
|
#-------------------------------------------------------------------------
|
|
|
|
g_AppName = File::basename( __FILE__, '.rb' )
|
|
g_Config = Pipeline::Config.instance()
|
|
g_Log = Log.new( g_AppName )
|
|
|
|
#-------------------------------------------------------------------------
|
|
# Parse & validate Command Line
|
|
#-------------------------------------------------------------------------
|
|
opts, trailing = OS::Getopt.getopts( OPTIONS )
|
|
if ( opts['help'] ) then
|
|
puts OS::Getopt.usage( OPTIONS )
|
|
response = message_box( "#{g_AppName} will exit.",g_AppName, BUTTONS_OK, ICON_QUESTION)
|
|
Process.exit!( 1 )
|
|
end
|
|
|
|
g_checkout = ( nil == opts['checkout'] ) ? nil : opts['checkout']
|
|
g_nosync = ( nil == opts['nosync'] ) ? nil : opts['nosync']
|
|
g_desc = ( nil == opts['desc'] ) ? nil : opts['desc']
|
|
g_command = ( nil == opts['command'] ) ? nil : opts['command']
|
|
g_enable_checkin = ( nil == opts['disablecheckin'] ) ? true : false
|
|
g_rage_p4 = ( nil == opts['rage'] ) ? false : true
|
|
g_submit_on_error = ( nil == opts['submit_on_error'] ) ? false : true
|
|
|
|
build_p4 = BuildP4.new(g_checkout, g_desc, g_command, g_rage_p4, g_enable_checkin, g_submit_on_error, g_nosync)
|
|
|
|
error_count = build_p4.run( g_Config )
|
|
|
|
rescue Exception => ex
|
|
|
|
puts "#{g_AppName} unhandled exception: #{ex.message}"
|
|
puts "Call stack:"
|
|
puts ex.backtrace.join( "\n\t" )
|
|
end
|
|
|
|
Process.exit! error_count
|
|
end
|
|
|
|
# buildp4.rb
|
|
#-----------------------------------------------------------------------------
|
|
#-----------------------------------------------------------------------------
|
|
#----------------------------------------------------------------------------- |