#!/usr/bin/ruby # # Triggers: # jobmerge form-in job "jobmerge.rb %formfile% %user%" # # FILL THIS IN OR THIS TRIGGER WILL NOT WORK! p4port = '1666' # P4PORT p4user = 'bruno' # P4USER p4passwd = nil # P4PASSWD mdate = 'Date' # Your 'date always' job field specdepot = 'spec' # The Depot name of your spec depot specsuffix = '.p4s' # The Suffix of your spec depot # THIS IS OPTIONAL STUFF THAT YOU MAY SET OR IGNORE accept_yours = # Accept 'yours' for these fields' conflicts. [ 'User' ] accept_theirs = # Accept 'theirs' for these fields' conflicts. [ ] ignore_users = # Accept 'theirs' for these users' conflicts. [ 'bruno' ] # OKAY ALL DONE CONFIGURING, GOOD JOB! if( ARGV.length < 1 ) puts 'Dude, where\'s my %formfile%?' exit 1 end formfile = ARGV[0] user = ARGV[1] require "P4" p4 = P4.new p4.port = p4port p4.user = p4user p4.password = p4passwd p4.connect begin # Garbage 'job -o' to load jobspec. Boo. p4.fetch_job( 'jobspec' ) # Now the "yours" spec, from user. yours = p4.parse_job( File.open( formfile ).read ) exit if yours.empty? exit if yours['Job'].nil? exit if yours[mdate].nil? # Now the "theirs" spec, from db. theirs = p4.fetch_job( yours['Job'] ) exit if theirs.empty? exit if theirs[mdate].nil? # Is yours already up to date? If so we're done. exit if theirs[mdate] == yours[mdate] # Now the "base" spec, from depot. bpath = '//' + specdepot + '/job/' + yours['Job'] + specsuffix bpath += '@' + yours[mdate] print = p4.run_print( bpath ) bspec = '' print.each{ |block| bspec += block if block.class == String } base = p4.parse_job( bspec ) exit if base.empty? exit if base[mdate] != yours[mdate] # Now we do a 3-way merge. base.permitted_fields.each do |field| yours[field] = theirs[field] if yours[field] == base[field] next if theirs[field] == yours[field] next if theirs[field] == base[field] next if accept_yours.include?( field ) if accept_theirs.include?( field ) or ignore_users.include?( user ) yours[field] = theirs[field] next end puts "Warning: conflicting edits made to #{field}!" # This would be a good place to try actually merging the # differing fields. exit end # And write it back out. result = File.open( formfile, 'w' ) result.write( p4.format_job( yours ) ) rescue P4Exception puts 'Jobmerge trigger encountered an error:' p4.errors.each { |e| puts( e ) } ensure p4.disconnect end