Class SpecSaver
In: specsaver.rb
Parent: Object

Main top level class for co-ordinating the run. Here we can trap Perforce exceptions and look after the overall environment.

Methods
counter=    counter?    create_client    debug    have_flags?    init_client    init_workspace    method_missing    new    update   
Public Class methods
new()

Constructor

# File specsaver.rb, line 585
    def initialize

	@flags	= Hash.new

	# Perforce client for handling tagged output
	@p4t = P4.new
	@p4t.parse_forms
	@p4t.exception_level = 1
	@p4t.port 	= P4PORT
	@p4t.user 	= P4USER
	@p4t.password 	= P4PASSWD
	@p4t.client 	= P4CLIENT
	@p4t.connect

	# Perforce client for non-tagged output
	@p4u = P4.new
	@p4u.exception_level = 1
	@p4u.port 	= P4PORT
	@p4u.user 	= P4USER
	@p4u.password 	= P4PASSWD
	@p4u.client 	= P4CLIENT
	@p4u.connect

	# Set the client root
	@root		= CLIENTROOT

	init_client()
    end
Public Instance methods
debug( level )

Set the debug level. Useful levels are:

    0 (default)    - No debug output
    1              - Some debug output
    2              - More debug output

What more could you want?

# File specsaver.rb, line 623
    def debug( level )
	$stderr.puts( "Setting debug level to #{level}" )
	@p4u.disconnect
	@p4t.disconnect
	@p4u.debug = level
	@p4t.debug = level
	@p4u.connect
	@p4t.connect
    end
update()

Main interface method. Update all requested specs.

# File specsaver.rb, line 636
    def update

	# Timestamp for this run
	now = Time.now.to_i

	# time of last update 
	since = counter?

	begin
	    branches = BranchMgr.new( @root, @p4t, @p4u )
	    clients  = ClientMgr.new( @root, @p4t, @p4u )
	    depots   = DepotMgr.new(  @root, @p4t, @p4u )
	    groups   = GroupMgr.new(  @root, @p4t, @p4u )
	    jobs     = JobMgr.new(    @root, @p4t, @p4u )
	    labels   = LabelMgr.new(  @root, @p4t, @p4u )
	    users    = UserMgr.new(   @root, @p4t, @p4u )
	    config   = ConfigMgr.new( @root, @p4t, @p4u )

	    branches.update( since ) 	if ( self.branches?	)
	    clients.update( since )	if ( self.clients?	)
	    depots.update( since )	if ( self.depots?	)
	    groups.update( since )	if ( self.groups?	)
	    jobs.update( since )	if ( self.jobs?		)
	    labels.update( since )	if ( self.labels?	)
	    users.update( since )	if ( self.users?	)

	    if ( self.config? )
		config.update( "protect", "protections" )
		config.update( "jobspec", "jobspec" )
		config.update( "typemap", "typemap" )
	    end

	    # Save the counter.
	    self.counter = now
	rescue P4Exception
	    @p4t.errors.each{ |e| puts( e ) }
	    @p4u.errors.each{ |e| puts( e ) }
	end
    end
have_flags?()

Test whether or not any flags at all have been set.

# File specsaver.rb, line 679
    def have_flags?
	return ! @flags.empty?
    end
method_missing( m, *args )

Resolve missing methods by looking in the flags hash. This is used to implement get and set methods for specifying which types of spec should be archived. If the method name ends in a "?" it's a getter, if not, it's a setter.

# File specsaver.rb, line 689
    def method_missing( m, *args )
	method = m.to_s
	if ( method !~ /\?$/ )
	    # Assignment
	    return @flags[ method ] = true
	else
	    method.gsub!( "\\?$", "" )
	end

	if ( @flags.has_key?( method ) )
	    @flags[ method ] 
	elsif ( @flags.has_key?( "all" ) )
	    @flags[ "all" ]
	else
	    false
	end
    end
Protected Instance methods
init_client()

Initialise the client environment. Check whether or not the client workspace exists, and if not, create it. Then create any missing directories and sync to the head revision.

# File specsaver.rb, line 714
    def init_client()
	begin
	    @p4t.run_info.each do
		|line|
		create_client() if ( line =~ /^Client unknown./ )
	    end
	    init_workspace()
	    @p4t.run_sync
	rescue P4Exception
	    @p4t.errors.each { |e| puts( e ) }
	    raise
	end
    end
init_workspace()

Initialises the workspace by pre-creating a directory for each spec type ready for the workspace files to be written into.

# File specsaver.rb, line 732
    def init_workspace()
	Dir.mkdir( @root ) unless ( File.exists?( @root ) )
	SPECS.each do
	    |type|
	    dir = @root + "/" + type
	    Dir.mkdir( dir ) unless ( File.exists?( dir ) )
	end
    end
create_client()

Automatically create the client workspace if necessary. This ensures that specsaver.rb is less prone to dodgy client views than scripts that require the client to be pre-created.

# File specsaver.rb, line 746
    def create_client()
	begin
	    spec = @p4t.fetch_client
	    spec[ "Description" 	] = "Client for spec versioning script"
	    spec[ "Root"		] = @root

	    # Don't use String#gsub! it seems to cause problems
	    opt = spec[ "Options" ].gsub( "normdir", "rmdir" )
	    spec[ "Options" ] = opt

	    spec[ "View" ] = Array.new
	    spec[ "View" ].push( SPEC_PATH + "/... //" + @p4t.client? + "/..." )

	    @p4t.save_client( spec )
	rescue P4Exception
	    @p4t.errors.each { |e| puts( e ) }
	end
    end
counter?()

Get the value of the SPEC_COUNTER. This is used as a timestamp rather than a traditional counter.

# File specsaver.rb, line 769
    def counter?
	c = @p4t.run_counter( SPEC_COUNTER ).shift.to_i
	return c
    end
counter=( val )

Update the SPEC_COUNTER with a new value.

# File specsaver.rb, line 777
    def counter=( val )
	@p4t.run_counter( SPEC_COUNTER, val )
	true
    end