diff options
-rw-r--r-- | README.markdown | 6 | ||||
-rw-r--r-- | lib/puppet/provider/vcsrepo/p4.rb | 76 |
2 files changed, 67 insertions, 15 deletions
diff --git a/README.markdown b/README.markdown index 575950c..d977886 100644 --- a/README.markdown +++ b/README.markdown @@ -346,15 +346,15 @@ defining `p4config`. If a configuration is defined, then the environment variab #####To create/update and sync a Perforce workspace -To sync a depot path to head (latest): +To sync a depot path to head, ensure `latest`: vcsrepo { "/path/to/repo": - ensure => present, + ensure => latest, provider => p4, source => '//depot/branch/...' } -For a specific changelist, use `revision`: +For a specific changelist, ensure `present` and specify a `revision`: vcsrepo { "/path/to/repo": ensure => present, diff --git a/lib/puppet/provider/vcsrepo/p4.rb b/lib/puppet/provider/vcsrepo/p4.rb index 612cc56..da9c953 100644 --- a/lib/puppet/provider/vcsrepo/p4.rb +++ b/lib/puppet/provider/vcsrepo/p4.rb @@ -7,7 +7,7 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d def create # create or update client - create_client(client_name, @resource.value(:path)) + create_client(client_name) # if source provided, sync client source = @resource.value(:source) @@ -63,13 +63,19 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d def revision args = ['cstat'] args.push(@resource.value(:source)) - hash = p4(args) + hash = p4(args, {:marshal => false}) + hash = marshal_cstat(hash) - if hash['status'] == "have" - return hash['change'].to_i - else - return 0 + revision = 0 + if hash && hash['code'] != 'error' + hash['data'].each do |c| + if c['status'] == 'have' + change = c['change'].to_i + revision = change if change > revision + end + end end + return revision end def revision=(desired) @@ -93,7 +99,7 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d Puppet.debug "Syncing: #{source}" args = ['sync'] if revision - args.push(source + "@" + revision) + args.push(source + "@#{revision}") else args.push(source) end @@ -127,11 +133,29 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d # Params: # +client+:: Name of client workspace # +path+:: The Root location of the Perforce client workspace - def create_client(client, path) + def create_client(client) Puppet.debug "Creating client: #{client}" + + # fetch client spec hash = parse_client(client) - hash['Root'] = path + hash['Root'] = @resource.value(:path) hash['Description'] = "Generated by Puppet VCSrepo" + + # check is source is a Stream + source = @resource.value(:source) + if source + parts = source.split(/\//) + if parts && parts.length >= 4 + source = "//" + parts[2] + "/" + parts[3] + streams = p4(['streams', source], {:raise => false}) + if streams['code'] == "stat" + hash['Stream'] = streams['Stream'] + notice "Streams" + streams['Stream'].inspect + end + end + end + + # save client spec save_client(hash) end @@ -212,9 +236,11 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d end # Raise errors, Perforce or Exec - if(opts[:raise]) - p4_err = "P4: " + hash['data'] if(hash['code'] == 'error') - raise Puppet::DevError, "#{p4_err}\n#{e.read}\nExit: #{t.value}" if(t.value != 0) + if(opts[:raise] && !e.eof && t.value != 0) + raise Puppet::Error, "\nP4: #{e.read}" + end + if(opts[:raise] && hash['code'] == 'error' && t.value != 0) + raise Puppet::Error, "\nP4: #{hash['data']}" end end @@ -222,4 +248,30 @@ Puppet::Type.type(:vcsrepo).provide(:p4, :parent => Puppet::Provider::Vcsrepo) d return hash end + # helper method as cstat does not Marshal + def marshal_cstat(hash) + data = hash['data'] + code = 'error' + + list = Array.new + change = Hash.new + data.each_line do |l| + p = /^\.\.\. (.*) (.*)$/ + m = p.match(l) + if m + change[m[1]] = m[2] + if m[1] == 'status' + code = 'stat' + list.push change + change = Hash.new + end + end + end + + hash = Hash.new + hash.store 'code', code + hash.store 'data', list + return hash + end + end |