Files
gtav-src/tools_ng/lib/util/buildp4.rb
T
2025-09-29 00:52:08 +02:00

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("&gt;",">")
@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
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------