# # File:: %RS_TOOLSLIB%/util/maps/map_export_times.rb # Description:: Generate CSV of laatest map export times # # Usage: # %RS_TOOLSIR% map_export_times.rb # # Example: # # %RS_TOOLSIR% map_export_times.rb # #----------------------------------------------------------------------------- # Uses #----------------------------------------------------------------------------- require 'RSG.Base.dll' require 'RSG.Base.Configuration.dll' require 'RSG.Base.Windows.dll' require 'RSG.Pipeline.Core.dll' require 'RSG.Pipeline.Content.dll' require 'RSG.Pipeline.Services.dll' require 'RSG.SourceControl.Perforce.dll' include RSG::Base::Configuration include RSG::Base::Logging include RSG::Base::Logging::Universal include RSG::Base::OS include RSG::Base::Windows include RSG::Pipeline::Core include RSG::Pipeline::Content require 'mscorlib' require 'System.Core' include System::Collections::Generic include System::IO using_clr_extensions System::Linq #using_clr_extensions RSG::Pipeline::Content::Algorithm require 'pipeline/os/options' include Pipeline #----------------------------------------------------------------------------- # Constants #----------------------------------------------------------------------------- AUTHOR = 'RSGEDI Tools' EMAIL = 'RSGEDI Tools <*tools@rockstarnorth.com>' OPTIONS = [ ] #----------------------------------------------------------------------------- # Functions #----------------------------------------------------------------------------- def usage( options ) puts "#{__FILE__}" puts "Usage:" puts options.usage() exit( 1 ) end def find_processes_with_output( tree, node ) tree.Processes.Where( lambda { |p| p.Outputs.Contains( node ) } ) end def find_fstat_client_record( recordset, client_filename ) recordset.Records.Where( lambda { |r| 0 == System::String::Compare( Path::GetFullPath( r['clientFile'] ), Path::GetFullPath( client_filename ), true ) } ).FirstOrDefault() end def process( log, p4, branch ) processors = ProcessorCollection::new( branch.Project.Config ) tree = Factory::CreateTree( branch, processors ) p4_art_fstat = p4.Run( 'fstat', true, #'-T', '"clientFile,headModTime"', Path::Combine( branch.Art, 'Models', '...' ) ) p4_export_fstat = p4.Run( 'fstat', true, #'-T', '"clientFile,headModTime"', Path::Combine( branch.Export, 'levels', 'gta5', '...' ) ) log.Message( "#{p4_art_fstat.Records.Length} art assets." ) log.Message( "#{p4_export_fstat.Records.Length} export assets." ) # Walk the content-tree map objects; using fstat records to find any # export data that is behind the source art data. map_processes = tree.Processes.Where( lambda { |p| p.Processor.Name == 'RSG.Pipeline.Processor.Map.PreProcess' } ) log.Message( "#{map_processes.Count()} map processes found." ) # Pen CSV, create header. fp = File::open( "c:\\maps_export_times.csv", 'w' ) fp.write( "Container,Export Zip,Last Export Zip Submit Time\n" ) map_processes.each do |p| p.Inputs.each do |input| export_zip_node = input export_zip_filename = input.AbsolutePath export_xml_filename = Path::ChangeExtension( export_zip_filename, '.xml' ) input_process = find_processes_with_output( tree, export_zip_node ) source_filename = input_process.First().Inputs.First().AbsolutePath export_record = find_fstat_client_record( p4_export_fstat, export_xml_filename ) log.Error( "Export record not found: #{export_zip_filename}." ) if ( export_record.nil? ) if ( not export_record.nil? ) then log.Message( "#{export_record['clientFile']} ==> #{export_record['headModTime']}" ) exportDateTime = p4.ConvertDate( export_record['headModTime'] ).ToString() fp.write( "#{Path::GetFileNameWithoutExtension(export_record['clientFile'])},#{export_record['clientFile']},#{exportDateTime}\n" ) end end end fp.close() end #----------------------------------------------------------------------------- # Entry-Point #----------------------------------------------------------------------------- if ( __FILE__ == $0 ) then # Initialise log and console output. #LogFactory.Initialize() LogFactory.CreateApplicationConsoleLogTarget( ) g_Log = LogFactory.ApplicationLog g_Options = OS::Options::new( OPTIONS ) begin if ( g_Options.is_enabled?( 'help' ) ) usage( g_Options ) end g_Config = g_Options.command_options.Config g_Project = g_Options.command_options.Project g_BranchName = g_Options.has_option?( 'branch' ) ? g_Options.get( 'branch' ) : g_Project.DefaultBranchName g_Branch = g_Project.Branches[g_BranchName] if ( g_Project.Branches.ContainsKey( g_BranchName ) ) if ( g_Branch.nil? ) then g_Log.Error( "Invalid branch '#{g_BranchName}' for project '#{g_Project.UIName}'." ) exit( 1 ) end begin p4 = g_Project.SCMConnect( ) process( g_Log, p4, g_Branch ) ensure p4.Disconnect( ) end g_Log.Message( "Done." ) rescue SystemExit => ex LogFactory.ApplicationShutdown() exit( ex.status ) rescue Exception => ex g_Log.ToolException( ex, "Exception during #{__FILE__}." ) puts "Exception during #{__FILE__}: #{ex.message}" puts ex.backtrace.join("\n") exit( 1 ) end end # %RS_TOOLSLIB%/util/maps/map_export_times.rb