class Plugin

def self.find(name)

def self.find(name)
  new(name)
end

def git_url?

def git_url?
  @uri =~ /^git:\/\// || @uri =~ /\.git$/
end

def guess_name(url)

def guess_name(url)
  @name = File.basename(url)
  if @name == 'trunk' || @name.empty?
    @name = File.basename(File.dirname(url))
  end
  @name.gsub!(/\.git$/, '') if @name =~ /\.git$/
end

def info

def info
  tmp = "#{rails_env.root}/_tmp_about.yml"
  if svn_url?
    cmd = "svn export #{@uri} \"#{rails_env.root}/#{tmp}\""
    puts cmd if $verbose
    system(cmd)
  end
  open(svn_url? ? tmp : File.join(@uri, 'about.yml')) do |stream|
    stream.read
  end rescue "No about.yml found in #{uri}"
ensure
  FileUtils.rm_rf tmp if svn_url?
end

def initialize(uri, name = nil)

def initialize(uri, name = nil)
  @uri = uri
  guess_name(uri)
end

def install(method=nil, options = {})

def install(method=nil, options = {})
  method ||= rails_env.best_install_method?
  if :http == method
    method = :export if svn_url?
    method = :git    if git_url?
  end
  uninstall if installed? and options[:force]
  unless installed?
    send("install_using_#{method}", options)
    run_install_hook
  else
    puts "already installed: #{name} (#{uri}).  pass --force to reinstall"
  end
end

def install_using_checkout(options = {})

def install_using_checkout(options = {})
  svn_command :checkout, options
end

def install_using_export(options = {})

def install_using_export(options = {})
  svn_command :export, options
end

def install_using_externals(options = {})

def install_using_externals(options = {})
  externals = rails_env.externals
  externals.push([@name, uri])
  rails_env.externals = externals
  install_using_checkout(options)
end

def install_using_git(options = {})

def install_using_git(options = {})
  root = rails_env.root
  mkdir_p(install_path = "#{root}/vendor/plugins/#{name}")
  Dir.chdir install_path do
    init_cmd = "git init"
    init_cmd += " -q" if options[:quiet] and not $verbose
    puts init_cmd if $verbose
    system(init_cmd)
    base_cmd = "git pull --depth 1 #{uri}"
    base_cmd += " -q" if options[:quiet] and not $verbose
    base_cmd += " #{options[:revision]}" if options[:revision]
    puts base_cmd if $verbose
    if system(base_cmd)
      puts "removing: .git .gitignore" if $verbose
      rm_rf %w(.git .gitignore)
    else
      rm_rf install_path
    end
  end
end

def install_using_http(options = {})

def install_using_http(options = {})
  root = rails_env.root
  mkdir_p "#{root}/vendor/plugins/#{@name}"
  Dir.chdir "#{root}/vendor/plugins/#{@name}" do
    puts "fetching from '#{uri}'" if $verbose
    fetcher = RecursiveHTTPFetcher.new(uri, -1)
    fetcher.quiet = true if options[:quiet]
    fetcher.fetch
  end
end

def installed?

def installed?
  File.directory?("#{rails_env.root}/vendor/plugins/#{name}") \
    or rails_env.externals.detect{ |name, repo| self.uri == repo }
end

def rails_env

def rails_env
  @rails_env || RailsEnvironment.default
end

def run_install_hook

def run_install_hook
  install_hook_file = "#{rails_env.root}/vendor/plugins/#{name}/install.rb"
  load install_hook_file if File.exist? install_hook_file
end

def run_uninstall_hook

def run_uninstall_hook
  uninstall_hook_file = "#{rails_env.root}/vendor/plugins/#{name}/uninstall.rb"
  load uninstall_hook_file if File.exist? uninstall_hook_file
end

def svn_command(cmd, options = {})

def svn_command(cmd, options = {})
  root = rails_env.root
  mkdir_p "#{root}/vendor/plugins"
  base_cmd = "svn #{cmd} #{uri} \"#{root}/vendor/plugins/#{name}\""
  base_cmd += ' -q' if options[:quiet] and not $verbose
  base_cmd += " -r #{options[:revision]}" if options[:revision]
  puts base_cmd if $verbose
  system(base_cmd)
end

def svn_url?

def svn_url?
  @uri =~ /svn(?:\+ssh)?:\/\/*/
end

def to_s

def to_s
  "#{@name.ljust(30)}#{@uri}"
end

def uninstall

def uninstall
  path = "#{rails_env.root}/vendor/plugins/#{name}"
  if File.directory?(path)
    puts "Removing 'vendor/plugins/#{name}'" if $verbose
    run_uninstall_hook
    rm_r path
  else
    puts "Plugin doesn't exist: #{path}"
  end
  if rails_env.use_externals?
    # clean up svn:externals
    externals = rails_env.externals
    externals.reject!{|n, u| name == n or name == u}
    rails_env.externals = externals
  end
end