Files
gtav-src/tools_ng/techart/script/Ruby/Global/perforce/p4utils.rb
T
2025-09-29 00:52:08 +02:00

369 lines
11 KiB
Ruby
Executable File

#
# P4 Utility Class around the RSG.SourceControl.Perforce
#
# Author:: Mark Harrison-Ball <Mark.Harrison-Ball@rockstargames.com>
# Date:: 20 May 2013 (AP3)
# Purpose:
# Used to generate a html report
# contains a list of functions to generate tablles and shit and return shit back
#
#
#
#
=begin
p4 fstat -T headRev //depot/gta5/assets/cuts/Armenian_2_MCS_6/data.cutxml
... headRev
=end
require 'RSG.SourceControl.Perforce'
require 'RSG.Base.Configuration.dll'
require 'RSG.Base.dll'
include RSG::SourceControl::Perforce
include RSG::Base::Configuration
RSG_CHANGELIST = RSG::SourceControl::Perforce::Changelist
class P4fileinfo
attr_reader :user
attr_writer :user
attr_reader :fullname
attr_writer :fullname
attr_reader :time
attr_writer :time
attr_reader :filename
attr_writer :filename
attr_reader :revision
attr_writer :revision
attr_reader :email
attr_writer :email
attr_reader :changelist
attr_writer :changelist
def initialize(change = nil)
@user = ''
@time = '01-01-01'
@filename = ''
@revision = ''
@email = ''
@changelist = 0
if change.class == RSG_CHANGELIST then
_setHeaderInfo(change)
end
end
private
# Basic Header Info
def _setHeaderInfo(change)
@user = change.username
@time = change.time
@changelist = change.number
end
end
#
# Generic list of utils to wrap around the p4 c# dll
#
#
#
class P4Utils
def initialize(log)
# Perforce initialisation.
g_Config = RSG::Base::Configuration::ConfigFactory::CreateConfig( )
#branch = g_Config.Project.DefaultBranch
@p4 = g_Config.Project.SCMConnect(log)
@g_log = log
end
public
# Find FileName/wildcard extension in single Change record
#---------------------------------------------------------
def findFilesinChange( change, file = nil )
fileList = []
change.files.each do | filename |
file_name = File.basename(filename).downcase
# Match every file
if file == "*" or file == nil then
fileList.push(filename)
# Match the extension
elsif File.extname(file_name) == File.extname(file) then
fileList.push(filename)
# explicit match Test
elsif file_name == file.downcase then
fileList.push(filename)
end
end
fileList
end
# Return Changelist objects from a set of Change records.
#---------------------------------------------------------
def get_changelists_from_changes( change_records )
changelists = []
change_records.each do |change_record|
changelist = Changelist::Create( @p4, change_record['change'].to_i )
changelists << changelist[0]
end
changelists
end
# return record of list of files in a pending changelist number
def get_changelistDescribe( currentCL )
change_records = @p4.Run( 'describe' , false, currentCL.to_s)
end
# return record of list of files in a pending changelist number
def get_changelistOpened( currentCL )
change_records = @p4.Run( 'opened' , false, '-c', currentCL.to_s)
end
# Returns currnet worksapce/users Pending chnagelists
def get_PendingChangeLists(max = 2)
change_records = @p4.Run( 'changes', true, '-c', @p4.Client, '-u', @p4.User, '-s', 'pending', '-m' ,max.to_s)
changes = get_changelists_from_changes( change_records )
end
# Returns a list of changes that needs to be sync to on the local workspace
def get_changes_toSync( depotpath = '//...', lastCL = nil)
change_records = @p4.Run( 'cstat', true, depotpath)
change_need_records = []
change_records.each do | change |
if lastCL == nil then
if not change['status'].include?('have')
change_need_records << change
end
else
if change['change'] > lastCL then
change_need_records << change
end
end
end
changes = get_changelists_from_changes( change_need_records )
end
# return a CHnage from a passed in Changelist number/string
def get_Change_from_CL( cl )
change_records = get_changelistDescribe( cl )
changes = get_changelists_from_changes( change_records )
changes[0]
end
# Return the last submitted changelist number in perforce
# Add check for p4 server disconnected
# NOTE: Can use p4 counter Change
#--------------------------------------------------------
def get_current_changelistnumber(depotpath = '//...')
change_records = @p4.Run( 'changes', true, '-m', 1.to_s, '-s', 'submitted', depotpath )
changes = get_changelists_from_changes( change_records )
changes[0].Number
end
# Returns the clients last sync'd changelist
#
#--------------------------------------------------------------------------------
def get_current_clientchangelist(depotpath = '//...')
change_records = @p4.Run( 'changes', true, '-m', '1', depotpath+'@'+@p4.Client )
changes = get_changelists_from_changes( change_records )
changes[0]
end
# Return list of changes from last changlist
#---------------------------------------------------------------------------------
def parse_p4_review(depotpath, currentCL, head = '#head')
if @g_log then
@g_log.message( "Scanning for changes since last Changelist = #{currentCL}.....")
end
g_Status = 'submitted'
change_records = @p4.Run( 'changes', true, '-s', g_Status, depotpath+'@'+currentCL.to_s+','+head.to_s )
changes = get_changelists_from_changes( change_records )
changes.each do |change|
#@g_log.message( "Changelist: #{change.Number} by #{change.Username}" )
if change.Number > currentCL
currentCL = (change.Number+1)
if @g_log then
@g_log.message( "Last Changelist = #{currentCL}")
end
end
end
return currentCL, changes
end
# Return Information about file in perforce
# Single INfo retrevval
# Need to parse in filters, i'e. 'depotFile, fileSize'
# FIELDS:
# attr-<name> -- attribute value for <name>
#attrProp-<name> -- set if attribute <name> is propagating
#clientFile -- local path (host or Perforce syntax)
#depotFile -- name in depot
#movedFile -- name in depot of moved to/from file
#path -- local path (host syntax)
#isMapped -- set if file is mapped in the client
#shelved -- set if file is shelved
#headAction -- action at head rev, if in depot
#headChange -- head rev changelist#, if in depot
#headRev -- head rev #, if in depot
#headType -- head rev type, if in depot
#headCharset -- head charset, for unicode type
#headTime -- head rev changelist time, if in depot
#headModTime -- head rev mod time, if in depot
#movedRev -- head rev # of moved file
#haveRev -- rev had on client, if on client
#desc -- change description (if -e specified)
#digest -- MD5 digest (fingerprint)
#fileSize -- file size
#action -- open action, if opened
#type -- open type, if opened
#charset -- open charset, for unicode type
#actionOwner -- user who opened file, if opened
#change -- open changelist#, if opened
#resolved -- resolved integration records
#unresolved -- unresolved integration records
#reresolvable -- reresolvable integration records
#otherOpen -- set if someone else has it open
#otherOpen# -- list of user@client with file opened
#otherLock -- set if someone else has it locked
#otherLock# -- user@client with file locked
#otherAction# -- open action, if opened by someone else
#otherChange# -- changelist, if opened by someone else
#openattr-<name> -- attribute value for <name>
#openattrProp-<name> -- set if attribute <name> is propagating
#ourLock -- set if this user/client has it locked
#resolveAction# -- pending integration record action
#resolveBaseFile# -- pending integration base file
#resolveBaseRev# -- pending integration base rev
#resolveFromFile# -- pending integration from file
#resolveStartFromRev# -- pending integration from start rev
#resolveEndFromRev# -- pending integration from end rev
#totalFileCount -- total no. of files, if sorted
#---------------------------------------------------------------------------------
def get_file_info(depotpath, filter='depotFile')
file_records = @p4.Run( 'fstat', false, '-T',filter, depotpath)
record_info = nil
if file_records.count == 1 then
# return our first record
record_info = file_records[0]
end
record_info
end
# RSG LIBS Source Control does not support user detail info so need to use standard p4 parsing
def get_user_info( fileinfo )
if fileinfo.user != '' then
file_records = @p4.Run( 'user', false, '-o',fileinfo.user)
file_records.each do |record|
fileinfo.email = record.fields['Email']
fileinfo.fullname = record.fields['FullName']
end
end
fileinfo
end
# ===== To Depreciate Function =======
# Get user Email
def get_user_email( user )
email = nil
file_records = @p4.Run( 'user', false, '-o',user)
file_records.each do |record|
email = record.fields['Email']
end
email
end
def Client()
return @p4.Client
end
def User()
return @p4.User
end
# Retunrs the number of seconds a user has before their login expires
def expires()
seconds = nil
file_records = @p4.Run( 'login', false, '-s')
file_records.each do |record|
seconds = record.fields['TicketExpiration']
end
seconds.to_i
end
# Connects to p4 with user Password, this will rest the ticket
def login(password)
@p4.Login(password)
end
# Return a pending changelist, pass in a description
def CreatePendingChangelist( desc )
@p4.create_pending_changelist( desc )
end
def DeleteChangelist(object)
@p4.Run( 'change' ,false, System::Array[System::String].new(object) )
end
# Simple Sync Method, we allow arrasy so can batch up commands into one call
def sync(object, args='')
object.unshift(args)
@p4.Run( 'sync', true, System::Array[System::String].new(object) )
end
def integ(object, args='')
object.unshift(args)
@p4.Run( 'integ', false, System::Array[System::String].new(object) )
end
def copy(object, args='')
object.unshift(args)
@p4.Run( 'copy', false, System::Array[System::String].new(object) )
end
def resolve(object, args='')
object.unshift(args)
@p4.Run( 'resolve', false, System::Array[System::String].new(object) )
end
def revert(object)
@p4.Run( 'revert', true, System::Array[System::String].new(object) )
end
def submit(object)
@p4.Run( 'submit', true, System::Array[System::String].new(object) )
end
def describe(object, args='')
object.unshift(args)
@p4.Run( 'describe', true, System::Array[System::String].new(object) )
end
def files(object, args='')
object.unshift(args)
@p4.Run( 'files', true, System::Array[System::String].new(object) )
end
end