#!/usr/bin/env ruby

commands = %w{pull push}

command = ARGV[0]

if !commands.include?(command)
  puts <<-USAGE
Usage: script/views (pull|push) my-database-name
For help on pull and push run script/views (pull|push) without a database name.
USAGE
  exit
end

if ARGV.length == 1
  case command
  when "pull"
    puts <<-PULL
script/views pull my-database-name [id prefix (default is _design)]

I will automagically create a "views" directory in your current working directory if none exists.
Then I copy the design documents and views into a directory structure like:

./views/my-design-doc/view-name-map.js
./views/my-design-doc/view-name-reduce.js

If your view names don't end in "map" or "reduce" I'll add those suffixes as a pull. On push I'll put them in new locations corresponding to these new names (overwriting the old design documents). I'm opinionated, but if these conventions don't work for you, the source code is right here.
    
    PULL
  when "push"
    puts <<-PUSH
script/views push my-database-name

I'll push all the files in your views directory to the specified database. Because CouchDB caches the results of view calculation by function content, there's no performance penalty for duplicating the map function twice, which I'll do if you have a reduce function. This makes it possible to browse the results of just the map, which can be useful for both queries and debugging.

./views/my-design-doc/view-name-map.js
./views/my-design-doc/view-name-reduce.js

  Pushed to =>

  http://localhost:5984/my-database-name/_design/my-design-doc
    {
      "views" : {
        "view-name-map" : {
          "map" : "### contents of view-name-map.js ###"
        },
        "view-name-reduce" : {
          "map" : "### contents of view-name-map.js ###",
          "reduce" : "### contents of view-name-reduce.js ###"
        },
      }
    }
PUSH
  end
  exit
end

dbname = ARGV[1]
dirname = ARGV[2] || "views"
prefix = ARGV[3] || "_design"

puts "Running #{command} into #{prefix} on #{dbname} from directory #{dirname}."

# __END__

require File.expand_path(File.dirname(__FILE__)) + '/../lib/couchrest'
require 'fileutils'

module Enumerable
  def group_by
    inject({}) do |groups, element|
      (groups[yield(element)] ||= []) << element
      groups
    end
  end if RUBY_VERSION < '1.9'
end

# connect to couchdb
cr = CouchRest::FileManager.new(dbname, "http://localhost:5984")
case command
when "pull"
  cr.pull_views(dirname)
when "push"
  cr.push_views(dirname)
end