Virtual base class for handling all types of spec. For each spec you want
to manage, derive a class which must implement at least the following
methods:
list_specs - list specs ("p4 clients"/"p4 labels" etc.)
spec_file - Locate spec file in workspace
Optionally, you may also want to override the changed? method used to
determine whether or not a spec has changed since the last time it was
archived. The default method uses the "Update" timestamp in the
spec, but not all specs have this. If in doubt, changed? should just
evaluate to true anyway, and let the "p4 revert -a" sort it out.
new( root, p4tagged, p4untagged )
|
Constructor: Supply the client root, and two P4 instances, one with tagged
mode enabled, and one without.
# File specsaver.rb, line 127
def initialize( root, p4tagged, p4untagged )
@root = root
@p4t = p4tagged
@p4u = p4untagged
@modlist = Hash.new
end
Updates the archives for all specs of the specified type. This is the main
public interface method for this class
# File specsaver.rb, line 138
def update( type, since )
list_specs.each do
|spec|
save_spec( type, spec ) if ( changed?( spec, since ) )
end
submit( description() )
end
Protected Instance methods |
Method to determine whether or not a spec has changed since the specified
timestamp. The default implementation uses the "Update" field of
the spec, but this is not available in all types of spec so this method
should be overridden for those specs. Where there is no easy way to decide
whether or not a spec has changed, override implementations of this method
should just return true and let the "p4 revert -a" sort it all
out.
# File specsaver.rb, line 157
def changed?( spec, stamp )
spec[ "Update" ].to_i > stamp
end
add_edit_file( path, name )
|
Opens the specified file for add or edit as appropriate
# File specsaver.rb, line 164
def add_edit_file( path, name )
fs = @p4t.run_fstat( path ).shift
if ( fs )
@p4t.run_edit( path )
else
@p4t.run_add( "-t", "text", path )
fs = @p4t.run_fstat( path ).shift
end
@modlist[ fs[ "depotFile" ] ] = name
end
Compute the name of a spec from its type. Necessary because the field for
jobs is "Job" whilst for clients it's "client" ...
# File specsaver.rb, line 179
def type2name( type, spec )
return spec[ type ] if spec.has_key?( type )
return spec[ type.capitalize ] if spec.has_key?( type.capitalize )
raise( RuntimeError, "Can't determine object name from type" )
end
Save the named spec into its text file version. As we don't want the spec
in parsed form for this we use the non-tagged P4 instance here to run the
"p4 xxxx -o" and the output of that command is written to the
workspace file.
# File specsaver.rb, line 191
def save_spec( type, spec )
path = spec_file( spec )
name = type2name( type, spec )
add_edit_file( path, name )
form = eval( }@p4u.fetch_#{type}( "#{name}" )} )
write_ws_file( path, form )
end
write_ws_file( path, form )
|
Method to write form data into the workspace file
# File specsaver.rb, line 203
def write_ws_file( path, form )
File.open( path, "w+" ) do
|file|
file.write( form )
end
end
Revert all unchanged files and remove them from the modlist.
# File specsaver.rb, line 213
def revert_unchanged()
@p4t.run_revert( "-a" ).each do
|r|
r = r.sub( /\#\d+.*/, "" )
@modlist.delete( r ) if @modlist.has_key?( r )
end
end
Submit the changelist and write out a message including the list of objects
being updated.
# File specsaver.rb, line 225
def submit( desc )
revert_unchanged()
change = @p4t.fetch_change
if ( change.has_key?( "Files" ) )
change[ "Description" ] = desc
@p4t.submit_spec( change )
puts( desc + "\n\t" + @modlist.values.sort.join( "\n\t" ) )
end
@modlist = Hash.new
end