Files
2025-09-29 00:52:08 +02:00

133 lines
4.7 KiB
Ruby
Executable File

#
# File:: lib/pipeline/scm/perforce_util.rb
# Description:: High-level Perforce utility classes and functions.
#
# Author:: David Muir <david.muir@rockstarnorth.com>
# Date:: 2 December 2009
#
# For monkey-patching functions into the SCM::Perforce class use the
# perforce_helper.rb instead.
#
#----------------------------------------------------------------------------
# Uses
#----------------------------------------------------------------------------
require 'pipeline/log/log'
require 'pipeline/os/path'
#----------------------------------------------------------------------------
# Monkey-Patching
#----------------------------------------------------------------------------
# Monkey patch the P4::Revision class to allow public access to the
# attributes member. This class varies from our documentation quite a bit.
# Ah well. Thank the Ruby stars for Monkey-Patching goodness.
class P4
class Revision
attr_reader :attributes
end
end
#----------------------------------------------------------------------------
# Implementation
#----------------------------------------------------------------------------
module Pipeline
module SCM
#
# == Description
# High-level Perforce utility classes and functions.
#
module PerforceUtil
#
# Fetch a Perforce file revision at a temporary location. The
# temporary location filename is returned.
#
# === Example
# See %TOOLSLIB%/util/perforce/p4_get_revision.rb for an example of
# this function's usage.
#
def PerforceUtil::get_file_revision_temp( log, p4, depotfile, rev )
throw ArgumentError.new( "Invalid P4 object (#{p4.class})." ) \
unless ( p4.is_a?( P4 ) )
throw ArgumentError.new( "Invalid P4::DepotFile object (#{depotfile.class})." ) \
unless ( depotfile.is_a?( P4::DepotFile ) )
throw ArgumentError.new( "Invalid P4::Revision object (#{rev.class})." ) \
unless ( rev.is_a?( P4::Revision ) )
p4.connect() unless ( p4.connected?() )
filename = depotfile.depot_file
tempclient = "#{p4.user}_get_revision_temp"
where = p4.run_where( filename ).shift()
target = OS::Path::get_directory( where['clientFile'].gsub( p4.client, tempclient ) )
target = OS::Path::combine( target, '_Get', OS::Path::get_filename( filename ) )
localnewfilename = nil
p4new = P4::new()
begin
PerforceUtil_Private::create_single_file_workspace( log, p4, p4.client, tempclient, filename, target )
# Sync the file into the new client.
p4new.port = p4.port
p4new.client = tempclient
p4new.user = p4.user
p4new.connect( ) unless ( p4new.connected?() )
puts "REV: #{rev.inspect}"
revision = rev.attributes['rev'].to_s
newfilenamewithrev = "#{filename}##{revision}"
log.info( "Syncing: #{newfilenamewithrev}." )
p4new.run_sync( '-f', newfilenamewithrev )
localfilename = p4new.run_where( filename ).shift()['path']
localnewfilename = OS::Path::combine( OS::Path::get_directory( localfilename ), OS::Path::get_basename( localfilename ) ) + "##{revision}.#{OS::Path::get_extension(localfilename)}"
log.info( "Synced. Moving file to: #{localnewfilename}." )
FileUtils::move( localfilename, localnewfilename )
ensure
p4new.disconnect( )
PerforceUtil_Private::destroy_workspace( log, p4, tempclient )
end
localnewfilename
end
#--------------------------------------------------------------------
# Private
#--------------------------------------------------------------------
private
# Private Module.
module PerforceUtil_Private
# Create a new user workspace that maps a single source file/dir
# to a single target file/dir.
def PerforceUtil_Private::create_single_file_workspace( log, p4, template, name, source, target )
log.info( "Creating Perforce client: #{name}." )
curr_client = p4.fetch_client( template )
new_client = p4.fetch_client( name )
new_client['Root'] = curr_client['Root']
new_client['Description'] = "Created by #{OS::Path::get_basename(__FILE__)}."
new_client_view = P4::Map::new( new_client._view )
new_client_view.clear( )
new_client_view.insert( source, target )
new_client['View'] = new_client_view.to_a
p4.save_client( new_client )
curr_client
end
# Destroy a user workspace. This will fail if the user has files
# checked-out.
def PerforceUtil_Private::destroy_workspace( log, p4, name )
log.info( "Destroying Perforce client: #{name}." )
p4.delete_client( name )
end
end
end # PerforceUtil module
end # SCM module
end # Pipeline module
# lib/pipeline/scm/perforce_util.rb