module Hoe::Perforce

def define_perforce_tasks

def define_perforce_tasks
  warn :define_perforce_tasks if $DEBUG
  desc "branch the project from dev to version dir"
  task :branch do
    original_dir = File.basename(Dir.pwd)
    Dir.chdir ".."
    target_dir = File.directory?(version) ? version : original_dir
    branching  = target_dir == original_dir && target_dir != version
    pkg = File.basename(Dir.pwd)
    begin
      p4_integrate original_dir, version if branching
      validate_manifest_file version
      p4_submit "Branching #{pkg} to version #{version}" if branching
    rescue => e
      warn e
      p4_revert version
      raise e
    end
    Dir.chdir version
  end
  task :prerelease => :branch
  task :postrelease => :announce do
    system 'rake clean'
  end
  desc "Generate historical flog/flay data for all releases"
  task :history do
    p4_history
  end
end

def initialize_perforce

def initialize_perforce
  self.perforce_ignore = []
end

def p4_history

def p4_history
  history p4_versions do |version|
    Dir.chdir "../#{version}" do
      flog_flay
    end
  end
end

def p4_integrate from, to

def p4_integrate from, to
  opened = `p4 opened #{from}/... #{to}/... 2>&1`
  raise "You have files open" if opened =~ /\/\/[^#]+#\d+/
  p4sh "p4 integrate #{from}/... #{to}/..."
end

def p4_revert dir

def p4_revert dir
  puts "reverting #{dir}"
  p4sh "p4 revert #{dir}/..."
end

def p4_submit description

def p4_submit description
  p4sh "p4 submit -d #{description.inspect} ..."
end

def p4_versions

def p4_versions
  dirs = Dir["../[0-9]*"].sort_by { |s| Gem::Version.new(File.basename(s)) }
  dirs << "../dev"
  dirs.map { |d| File.basename d }
end

def p4sh cmd

def p4sh cmd
  sh "#{cmd};"
end

def validate_manifest_file manifest_dir

def validate_manifest_file manifest_dir
  manifest_file = "#{manifest_dir}/Manifest.txt"
  raise "#{manifest_file} does not exist" unless test ?f, manifest_file
  manifest = File.new(manifest_file).readlines.map { |x| x.strip }
  manifest -= perforce_ignore
  exclusions = with_config do |config, _|
    config["exclude"]
  end
  local_manifest = []
  Dir.chdir manifest_dir do
    system 'rake clean'
    Find.find '.' do |f|
      next if f =~ exclusions
      local_manifest << f.sub(/^\.\//, '') if File.file? f
    end
  end
  local_manifest -= perforce_ignore
  extra_files   = local_manifest - manifest
  missing_files = manifest - local_manifest
  msg = []
  unless extra_files.empty? then
    msg << "You have files that are not in your manifest"
    msg << "  #{extra_files.inspect}"
  end
  unless missing_files.empty? then
    msg << "You have files that are missing from your manifest"
    msg << "  #{missing_files.inspect}"
  end
  raise msg.join("\n") unless msg.empty?
end