couch_docs 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +10 -0
- data/README.rdoc +9 -4
- data/Rakefile +3 -1
- data/bin/couch-docs +2 -0
- data/couch_docs.gemspec +20 -21
- data/fixtures/_design/__lib/foo.js +1 -0
- data/fixtures/_design/x/z.js +2 -0
- data/lib/couch_docs/command_line.rb +118 -11
- data/lib/couch_docs/design_directory.rb +59 -2
- data/lib/couch_docs/store.rb +12 -3
- data/lib/couch_docs.rb +22 -8
- data/spec/couch_docs_spec.rb +192 -8
- metadata +16 -14
data/History.txt
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
== 1.1.0 / 2010-03-13
|
2
|
+
|
3
|
+
* Better command line experience.
|
4
|
+
* Default to current directory.
|
5
|
+
* Print help without args / better format (optparse).
|
6
|
+
* Support the !code macro from couchapp.
|
7
|
+
* Support a flag (-d) to only work on design docs.
|
8
|
+
* Can create the DB if it doesn't already exist
|
9
|
+
* Command line can be used to watch for local changes to be pushed immediately to the CouchDB server.
|
10
|
+
|
1
11
|
== 1.0.0 / 2009-08-09
|
2
12
|
|
3
13
|
* Update the couch-docs script to be able to dump a CouchDB database
|
data/README.rdoc
CHANGED
@@ -16,11 +16,15 @@ Manage CouchDB views and documents.
|
|
16
16
|
(e.g. <tt>_design/recipes/count_by_month/map.js</tt>) into CouchDB
|
17
17
|
design documents.
|
18
18
|
|
19
|
+
* Support for the <tt>!code</tt> macro from couchapp (useful for
|
20
|
+
DRYing up map/reduce views as well as list/show documents.
|
21
|
+
|
19
22
|
* Dump documents stored in CouchDB to the filesystem.
|
20
23
|
|
21
24
|
* Script (couch-docs) to restore / backup CouchDB database.
|
22
25
|
|
23
|
-
*
|
26
|
+
* Multiple options including a directory watcher for uploading
|
27
|
+
directory changes
|
24
28
|
|
25
29
|
* A progress bar would be helpful.
|
26
30
|
|
@@ -34,7 +38,7 @@ Manage CouchDB views and documents.
|
|
34
38
|
couch-docs dump "http://localhost:5984/db" path/to/dump_dir/
|
35
39
|
|
36
40
|
# For loading documents from the filesystem into CouchDB
|
37
|
-
couch-docs load
|
41
|
+
couch-docs load "http://localhost:5984/db" path/to/dump_dir/
|
38
42
|
|
39
43
|
|
40
44
|
In code:
|
@@ -62,16 +66,17 @@ Manage CouchDB views and documents.
|
|
62
66
|
* CouchDB
|
63
67
|
* JSON
|
64
68
|
* RestClient
|
69
|
+
* DirectoryWatcher
|
65
70
|
|
66
71
|
== INSTALL:
|
67
72
|
|
68
|
-
* sudo gem install
|
73
|
+
* sudo gem install couch_docs
|
69
74
|
|
70
75
|
== LICENSE:
|
71
76
|
|
72
77
|
(The MIT License)
|
73
78
|
|
74
|
-
Copyright (c)
|
79
|
+
Copyright (c) 2010
|
75
80
|
|
76
81
|
Permission is hereby granted, free of charge, to any person obtaining
|
77
82
|
a copy of this software and associated documentation files (the
|
data/Rakefile
CHANGED
@@ -27,11 +27,13 @@ PROJ.rubyforge.name = 'couch_docs'
|
|
27
27
|
|
28
28
|
PROJ.spec.opts << '--color'
|
29
29
|
|
30
|
-
PROJ.gem.dependencies = %w{json rest-client}
|
30
|
+
#PROJ.gem.dependencies = %w{json rest-client}
|
31
|
+
PROJ.gem.development_dependencies << 'rspec'
|
31
32
|
|
32
33
|
PROJ.readme_file = 'README.rdoc'
|
33
34
|
|
34
35
|
depend_on 'rest-client'
|
35
36
|
depend_on 'json'
|
37
|
+
depend_on 'directory_watcher'
|
36
38
|
|
37
39
|
# EOF
|
data/bin/couch-docs
CHANGED
data/couch_docs.gemspec
CHANGED
@@ -2,48 +2,47 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{couch_docs}
|
5
|
-
s.version = "1.
|
5
|
+
s.version = "1.1.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Chris Strom"]
|
9
|
-
s.date = %q{
|
9
|
+
s.date = %q{2010-03-11}
|
10
10
|
s.default_executable = %q{couch-docs}
|
11
11
|
s.description = %q{Manage CouchDB views and documents.}
|
12
12
|
s.email = %q{chris@eeecooks.com}
|
13
13
|
s.executables = ["couch-docs"]
|
14
14
|
s.extra_rdoc_files = ["History.txt", "README.rdoc", "bin/couch-docs"]
|
15
|
-
s.files = ["History.txt", "README.rdoc", "Rakefile", "bin/couch-docs", "couch_docs.gemspec", "fixtures/_design/a/b/c.js", "fixtures/_design/a/b/d.js", "fixtures/bar.json", "fixtures/foo.json", "lib/couch_docs.rb", "lib/couch_docs/command_line.rb", "lib/couch_docs/design_directory.rb", "lib/couch_docs/document_directory.rb", "lib/couch_docs/store.rb", "spec/couch_docs_spec.rb", "spec/spec_helper.rb", "test/test_couch_docs.rb"]
|
16
|
-
s.has_rdoc = true
|
15
|
+
s.files = ["History.txt", "README.rdoc", "Rakefile", "bin/couch-docs", "couch_docs.gemspec", "fixtures/_design/__lib/foo.js", "fixtures/_design/a/b/c.js", "fixtures/_design/a/b/d.js", "fixtures/_design/x/z.js", "fixtures/bar.json", "fixtures/foo.json", "lib/couch_docs.rb", "lib/couch_docs/command_line.rb", "lib/couch_docs/design_directory.rb", "lib/couch_docs/document_directory.rb", "lib/couch_docs/store.rb", "spec/couch_docs_spec.rb", "spec/spec_helper.rb", "test/test_couch_docs.rb"]
|
17
16
|
s.homepage = %q{http://github.com/eee-c/couch_docs}
|
18
17
|
s.rdoc_options = ["--main", "README.rdoc"]
|
19
18
|
s.require_paths = ["lib"]
|
20
19
|
s.rubyforge_project = %q{couch_docs}
|
21
|
-
s.rubygems_version = %q{1.3.
|
20
|
+
s.rubygems_version = %q{1.3.5}
|
22
21
|
s.summary = %q{Manage CouchDB views and documents}
|
23
22
|
s.test_files = ["test/test_couch_docs.rb"]
|
24
23
|
|
25
24
|
if s.respond_to? :specification_version then
|
26
25
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
27
|
-
s.specification_version =
|
26
|
+
s.specification_version = 3
|
28
27
|
|
29
28
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
30
|
-
s.add_runtime_dependency(%q<
|
31
|
-
s.add_runtime_dependency(%q<
|
32
|
-
s.add_runtime_dependency(%q<
|
33
|
-
s.
|
34
|
-
s.add_development_dependency(%q<
|
29
|
+
s.add_runtime_dependency(%q<rest-client>, [">= 1.1.0"])
|
30
|
+
s.add_runtime_dependency(%q<json>, [">= 1.2.0"])
|
31
|
+
s.add_runtime_dependency(%q<directory_watcher>, [">= 1.3.1"])
|
32
|
+
s.add_development_dependency(%q<bones>, [">= 2.5.0"])
|
33
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
35
34
|
else
|
36
|
-
s.add_dependency(%q<
|
37
|
-
s.add_dependency(%q<
|
38
|
-
s.add_dependency(%q<
|
39
|
-
s.add_dependency(%q<
|
40
|
-
s.add_dependency(%q<
|
35
|
+
s.add_dependency(%q<rest-client>, [">= 1.1.0"])
|
36
|
+
s.add_dependency(%q<json>, [">= 1.2.0"])
|
37
|
+
s.add_dependency(%q<directory_watcher>, [">= 1.3.1"])
|
38
|
+
s.add_dependency(%q<bones>, [">= 2.5.0"])
|
39
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
41
40
|
end
|
42
41
|
else
|
43
|
-
s.add_dependency(%q<
|
44
|
-
s.add_dependency(%q<
|
45
|
-
s.add_dependency(%q<
|
46
|
-
s.add_dependency(%q<
|
47
|
-
s.add_dependency(%q<
|
42
|
+
s.add_dependency(%q<rest-client>, [">= 1.1.0"])
|
43
|
+
s.add_dependency(%q<json>, [">= 1.2.0"])
|
44
|
+
s.add_dependency(%q<directory_watcher>, [">= 1.3.1"])
|
45
|
+
s.add_dependency(%q<bones>, [">= 2.5.0"])
|
46
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
48
47
|
end
|
49
48
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
function foo () { return "foo"; }
|
@@ -1,27 +1,134 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'pp'
|
3
|
+
require 'directory_watcher'
|
4
|
+
|
1
5
|
module CouchDocs
|
2
6
|
class CommandLine
|
7
|
+
COMMANDS = %w{push dump}
|
8
|
+
DEPRECATED_COMMANDS = %w{load}
|
9
|
+
|
3
10
|
def self.run(*args)
|
4
11
|
CommandLine.new(*args).run
|
5
12
|
end
|
6
13
|
|
7
|
-
|
14
|
+
attr_reader :command, :options
|
8
15
|
|
9
16
|
def initialize(args)
|
10
|
-
|
11
|
-
@options = args
|
17
|
+
parse_options(args)
|
12
18
|
end
|
13
19
|
|
14
20
|
def run
|
15
21
|
case command
|
16
22
|
when "dump"
|
17
|
-
CouchDocs.dump(
|
18
|
-
|
19
|
-
|
20
|
-
when "
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
CouchDocs.dump(@options[:couchdb_url],
|
24
|
+
@options[:target_dir],
|
25
|
+
@options[:dump])
|
26
|
+
when "push"
|
27
|
+
if @options[:destructive]
|
28
|
+
CouchDocs.destructive_database_create(options[:couchdb_url])
|
29
|
+
end
|
30
|
+
|
31
|
+
dw = DirectoryWatcher.new @options[:target_dir]
|
32
|
+
dw.glob = '**/*'
|
33
|
+
dw.interval = 2.0
|
34
|
+
|
35
|
+
dw.add_observer do |*args|
|
36
|
+
puts "Updating documents on CouchDB Server..."
|
37
|
+
CouchDocs.put_dir(@options[:couchdb_url],
|
38
|
+
@options[:target_dir])
|
39
|
+
end
|
40
|
+
|
41
|
+
if @options[:watch]
|
42
|
+
dw.start
|
43
|
+
|
44
|
+
begin
|
45
|
+
sleep 30 while true
|
46
|
+
rescue Interrupt
|
47
|
+
dw.stop
|
48
|
+
puts
|
49
|
+
end
|
50
|
+
else
|
51
|
+
dw.run_once
|
52
|
+
end
|
53
|
+
when "load" # DEPRECATED
|
54
|
+
CouchDocs.put_dir(@options[:target_dir],
|
55
|
+
@options[:couchdb_url])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def parse_options(args)
|
60
|
+
@options = { :target_dir => "." }
|
61
|
+
|
62
|
+
options_parser = OptionParser.new do |opts|
|
63
|
+
opts.banner = "Usage: couch-docs push|dump [OPTIONS] couchdb_url [target_dir]"
|
64
|
+
|
65
|
+
opts.separator ""
|
66
|
+
opts.separator "If a target_dir is not specified, the current working directory will be used."
|
67
|
+
|
68
|
+
opts.separator ""
|
69
|
+
opts.separator "Push options:"
|
70
|
+
|
71
|
+
opts.on("-R", "--destructive",
|
72
|
+
"Drop the couchdb_uri (if it exists) and create a new database") do
|
73
|
+
@options[:destructive] = true
|
74
|
+
end
|
75
|
+
|
76
|
+
# TODO: bulk_docs in 1.2
|
77
|
+
# opts.on("-b", "--bulk [BATCH_SIZE=1000]", Integer,
|
78
|
+
# "Use bulk insert when pushing new documents") do |batch_size|
|
79
|
+
# @options[:bulk] = true
|
80
|
+
# @options[:batch_size] = batch_size || 1000
|
81
|
+
# end
|
82
|
+
|
83
|
+
opts.on("-w", "--watch", "Watch the directory for changes, uploading when detected") do
|
84
|
+
@options[:watch] = true
|
85
|
+
end
|
86
|
+
|
87
|
+
opts.separator ""
|
88
|
+
opts.separator "Dump options:"
|
89
|
+
|
90
|
+
opts.on("-d", "--design", "Only dump design documents") do
|
91
|
+
@options[:dump] = :design
|
92
|
+
end
|
93
|
+
opts.on("-D", "--data", "Only dump data documents") do
|
94
|
+
@options[:dump] = :doc
|
95
|
+
end
|
96
|
+
|
97
|
+
opts.separator ""
|
98
|
+
opts.separator "Common options:"
|
99
|
+
|
100
|
+
opts.on_tail("-v", "--version", "Show version") do
|
101
|
+
puts File.basename($0) + " " + CouchDocs::VERSION
|
102
|
+
exit
|
103
|
+
end
|
104
|
+
|
105
|
+
# No argument, shows at tail. This will print an options summary.
|
106
|
+
# Try it and see!
|
107
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
108
|
+
puts opts
|
109
|
+
exit
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
begin
|
114
|
+
options_parser.parse!(args)
|
115
|
+
additional_help = "#{options_parser.banner}\n\nTry --help for more options."
|
116
|
+
unless (COMMANDS+DEPRECATED_COMMANDS).include? args.first
|
117
|
+
puts "invalid command: \"#{args.first}\". Must be one of #{COMMANDS.join(', ')}.\n\n"
|
118
|
+
puts additional_help
|
119
|
+
exit
|
120
|
+
end
|
121
|
+
@command = args.shift
|
122
|
+
unless args.first
|
123
|
+
puts "Missing required couchdb_uri argument.\n\n"
|
124
|
+
puts additional_help
|
125
|
+
exit
|
126
|
+
end
|
127
|
+
@options[:couchdb_url] = args.shift
|
128
|
+
@options[:target_dir] = args.shift if (args.size >= 1)
|
129
|
+
|
130
|
+
rescue OptionParser::InvalidOption => e
|
131
|
+
raise e
|
25
132
|
end
|
26
133
|
end
|
27
134
|
end
|
@@ -25,6 +25,8 @@ module CouchDocs
|
|
25
25
|
@couch_view_dir = path
|
26
26
|
end
|
27
27
|
|
28
|
+
# Load
|
29
|
+
|
28
30
|
def to_hash
|
29
31
|
Dir["#{couch_view_dir}/**/*.js"].inject({}) do |memo, filename|
|
30
32
|
DesignDirectory.
|
@@ -38,9 +40,64 @@ module CouchDocs
|
|
38
40
|
gsub(/#{couch_view_dir}\/?/, '').
|
39
41
|
split(/\//) +
|
40
42
|
[
|
41
|
-
File.basename(filename, '.js'),
|
42
|
-
|
43
|
+
File.basename(filename, '.js').gsub(/%2F/, '/'),
|
44
|
+
read_value(filename)
|
43
45
|
]
|
44
46
|
end
|
47
|
+
|
48
|
+
def read_value(filename)
|
49
|
+
File.
|
50
|
+
readlines(filename).
|
51
|
+
map { |line| process_code_macro(line) }.
|
52
|
+
join
|
53
|
+
end
|
54
|
+
|
55
|
+
def process_code_macro(line)
|
56
|
+
if line =~ %r{\s*//\s*!code\s*(\S+)\s*}
|
57
|
+
"// !begin code #{$1}\n" +
|
58
|
+
read_from_lib($1) +
|
59
|
+
"// !end code #{$1}\n"
|
60
|
+
else
|
61
|
+
line
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def read_from_lib(path)
|
66
|
+
File.read("#{couch_view_dir}/__lib/#{path}")
|
67
|
+
end
|
68
|
+
|
69
|
+
# Store
|
70
|
+
|
71
|
+
def store_document(doc)
|
72
|
+
id = doc['_id']
|
73
|
+
self.save_js(nil, id, doc)
|
74
|
+
end
|
75
|
+
|
76
|
+
def save_js(rel_path, key, value)
|
77
|
+
if value.is_a? Hash
|
78
|
+
value.each_pair do |k, v|
|
79
|
+
next if k == '_id'
|
80
|
+
self.save_js([rel_path, key].compact.join('/'), k, v)
|
81
|
+
|
82
|
+
end
|
83
|
+
else
|
84
|
+
path = couch_view_dir + '/' + rel_path
|
85
|
+
FileUtils.mkdir_p(path)
|
86
|
+
|
87
|
+
file = File.new("#{path}/#{key.gsub(/\//, '%2F')}.js", "w+")
|
88
|
+
file.write(remove_code_macros(value))
|
89
|
+
file.close
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def remove_code_macros(js)
|
94
|
+
js =~ %r{// !begin code ([.\w]+)$}m
|
95
|
+
lib = $1
|
96
|
+
if lib and js =~ %r{// !end code #{lib}$}m
|
97
|
+
remove_code_macros(js.sub(%r{// !begin code #{lib}.+// !end code #{lib}}m, "// !code #{lib}"))
|
98
|
+
else
|
99
|
+
js
|
100
|
+
end
|
101
|
+
end
|
45
102
|
end
|
46
103
|
end
|
data/lib/couch_docs/store.rb
CHANGED
@@ -6,13 +6,14 @@ module CouchDocs
|
|
6
6
|
class Store
|
7
7
|
include Enumerable
|
8
8
|
|
9
|
-
attr_accessor :url
|
9
|
+
attr_accessor :url, :design_docs_only
|
10
10
|
|
11
11
|
# Initialize a CouchDB store object. Requires a URL for the
|
12
12
|
# target CouchDB database.
|
13
13
|
#
|
14
|
-
def initialize(url)
|
14
|
+
def initialize(url, options={})
|
15
15
|
@url = url
|
16
|
+
@design_docs_only = (options[:only] == :design)
|
16
17
|
end
|
17
18
|
|
18
19
|
# Loads all supplied design documents in the current store.
|
@@ -45,6 +46,12 @@ module CouchDocs
|
|
45
46
|
:content_type => 'application/json'
|
46
47
|
end
|
47
48
|
|
49
|
+
def self.post(path, doc)
|
50
|
+
RestClient.post path,
|
51
|
+
doc.to_json,
|
52
|
+
:content_type => 'application/json'
|
53
|
+
end
|
54
|
+
|
48
55
|
def self.delete(path)
|
49
56
|
# retrieve existing to obtain the revision
|
50
57
|
old = self.get(path)
|
@@ -56,7 +63,9 @@ module CouchDocs
|
|
56
63
|
end
|
57
64
|
|
58
65
|
def each
|
59
|
-
|
66
|
+
all_url = "#{url}/_all_docs" +
|
67
|
+
(design_docs_only ? '?startkey=%22_design%22&endkey=%22_design0%22' : "")
|
68
|
+
Store.get(all_url)['rows'].each do |rec|
|
60
69
|
yield Store.get("#{url}/#{rec['id']}?attachments=true")
|
61
70
|
end
|
62
71
|
end
|
data/lib/couch_docs.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
1
3
|
module CouchDocs
|
2
4
|
|
3
5
|
# :stopdoc:
|
4
|
-
VERSION = '1.
|
6
|
+
VERSION = '1.1.0'
|
5
7
|
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
6
8
|
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
7
9
|
# :startdoc:
|
@@ -49,13 +51,25 @@ module CouchDocs
|
|
49
51
|
# Dump all documents located at <tt>db_uri</tt> into the directory
|
50
52
|
# <tt>dir</tt>
|
51
53
|
#
|
52
|
-
def self.dump(db_uri, dir)
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
54
|
+
def self.dump(db_uri, dir, only=nil)
|
55
|
+
null_dir = OpenStruct.new(:store_document => nil)
|
56
|
+
|
57
|
+
doc_dir = (only == :design) ?
|
58
|
+
null_dir : DocumentDirectory.new(dir)
|
59
|
+
design_dir = (only == :doc) ?
|
60
|
+
null_dir : DesignDirectory.new(dir)
|
61
|
+
|
62
|
+
store = Store.new(db_uri, :only => only)
|
63
|
+
store.map.each do |doc|
|
64
|
+
doc.delete('_rev')
|
65
|
+
(doc['_id'] =~ /^_design/ ? design_dir : doc_dir).
|
66
|
+
store_document(doc)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Create or recreate the database located at <tt>db_uri</tt>
|
71
|
+
def self.destructive_database_create(db_uri)
|
72
|
+
Store.put!(db_uri, "")
|
59
73
|
end
|
60
74
|
|
61
75
|
# Returns the library path for the module. If any arguments are given,
|
data/spec/couch_docs_spec.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), %w[spec_helper])
|
2
2
|
|
3
3
|
describe CouchDocs do
|
4
|
+
it "should be able to create (or delete/create) a DB" do
|
5
|
+
Store.
|
6
|
+
should_receive(:put!).
|
7
|
+
with("couchdb_url", anything())
|
8
|
+
|
9
|
+
CouchDocs.destructive_database_create("couchdb_url")
|
10
|
+
end
|
11
|
+
|
4
12
|
it "should be able to load design and normal documents" do
|
5
13
|
CouchDocs.
|
6
14
|
should_receive(:put_design_dir).
|
@@ -51,7 +59,10 @@ describe CouchDocs do
|
|
51
59
|
@store = mock("Store")
|
52
60
|
Store.stub!(:new).and_return(@store)
|
53
61
|
|
54
|
-
@
|
62
|
+
@des_dir = mock("Design Directory").as_null_object
|
63
|
+
DesignDirectory.stub!(:new).and_return(@des_dir)
|
64
|
+
|
65
|
+
@dir = mock("Document Directory").as_null_object
|
55
66
|
DocumentDirectory.stub!(:new).and_return(@dir)
|
56
67
|
end
|
57
68
|
it "should be able to store all CouchDB documents on the filesystem" do
|
@@ -78,6 +89,24 @@ describe CouchDocs do
|
|
78
89
|
|
79
90
|
CouchDocs.dump("uri", "fixtures")
|
80
91
|
end
|
92
|
+
it "should not dump regular docs when asked for only design docs" do
|
93
|
+
@store.stub!(:map).
|
94
|
+
and_return([{'foo' => 'bar'}])
|
95
|
+
|
96
|
+
@dir.
|
97
|
+
should_not_receive(:store_document)
|
98
|
+
|
99
|
+
CouchDocs.dump("uri", "fixtures", :design)
|
100
|
+
end
|
101
|
+
it "should not dump design docs when asked for only regular docs" do
|
102
|
+
@store.stub!(:map).
|
103
|
+
and_return([{'_id' => '_design/foo'}])
|
104
|
+
|
105
|
+
@des_dir.
|
106
|
+
should_not_receive(:store_document)
|
107
|
+
|
108
|
+
CouchDocs.dump("uri", "fixtures", :doc)
|
109
|
+
end
|
81
110
|
end
|
82
111
|
end
|
83
112
|
|
@@ -262,17 +291,126 @@ describe DesignDirectory do
|
|
262
291
|
end
|
263
292
|
|
264
293
|
it "should assemble all documents into a single docs structure" do
|
265
|
-
@it.to_hash.
|
294
|
+
@it.to_hash['a'].
|
266
295
|
should == {
|
267
|
-
'a' => {
|
268
296
|
'b' => {
|
269
297
|
'c' => 'function(doc) { return true; }',
|
270
298
|
'd' => 'function(doc) { return true; }'
|
271
299
|
}
|
272
300
|
}
|
301
|
+
end
|
273
302
|
|
303
|
+
it "should process code macros when assembling" do
|
304
|
+
@it.to_hash['x'].
|
305
|
+
should == {
|
306
|
+
'z' =>
|
307
|
+
"// !begin code foo.js\n" +
|
308
|
+
"function foo () { return \"foo\"; }\n" +
|
309
|
+
"// !end code foo.js\n" +
|
310
|
+
"function bar () { return \"bar\"; }\n"
|
274
311
|
}
|
275
312
|
end
|
313
|
+
|
314
|
+
it "should work with absolute !code paths"
|
315
|
+
|
316
|
+
it "should replace !code macros with the contents of the referenced file in lib" do
|
317
|
+
@it.stub!(:read_from_lib).and_return("awesome javascript")
|
318
|
+
|
319
|
+
@it.
|
320
|
+
process_code_macro(" // !code foo/bar.js ").
|
321
|
+
should =~ /awesome javascript/
|
322
|
+
end
|
323
|
+
|
324
|
+
it "should not affect normal lines when processing macros" do
|
325
|
+
@it.
|
326
|
+
process_code_macro(" var foo = 'bar'; ").
|
327
|
+
should == " var foo = 'bar'; "
|
328
|
+
end
|
329
|
+
|
330
|
+
it "should find files with relative paths in __lib" do
|
331
|
+
File.
|
332
|
+
should_receive(:read).
|
333
|
+
with("fixtures/_design/__lib/foo.js")
|
334
|
+
|
335
|
+
@it.read_from_lib("foo.js")
|
336
|
+
end
|
337
|
+
|
338
|
+
end
|
339
|
+
|
340
|
+
context "saving a JS attribute" do
|
341
|
+
before(:each) do
|
342
|
+
@it = DesignDirectory.new("/tmp")
|
343
|
+
|
344
|
+
FileUtils.stub!(:mkdir_p)
|
345
|
+
@file = mock("File").as_null_object
|
346
|
+
File.stub!(:new).and_return(@file)
|
347
|
+
end
|
348
|
+
|
349
|
+
it "should not store _id" do
|
350
|
+
File.
|
351
|
+
should_not_receive(:new).
|
352
|
+
with("/tmp/_design/foo/_id.js", "w+")
|
353
|
+
|
354
|
+
@it.save_js(nil, "_design/foo", { "_id" => "_design/foo"})
|
355
|
+
end
|
356
|
+
|
357
|
+
it "should create map the design document attribute to the filesystem" do
|
358
|
+
FileUtils.
|
359
|
+
should_receive(:mkdir_p).
|
360
|
+
with("/tmp/_design/foo")
|
361
|
+
|
362
|
+
@it.save_js("_design/foo", "bar", "json")
|
363
|
+
end
|
364
|
+
|
365
|
+
it "should store the attribute to the filesystem" do
|
366
|
+
File.
|
367
|
+
should_receive(:new).
|
368
|
+
with("/tmp/_design/foo/bar.js", "w+")
|
369
|
+
|
370
|
+
@it.save_js("_design/foo", "bar", "json")
|
371
|
+
end
|
372
|
+
|
373
|
+
it "should store hash values to the filesystem" do
|
374
|
+
File.
|
375
|
+
should_receive(:new).
|
376
|
+
with("/tmp/_design/foo/bar/baz.js", "w+")
|
377
|
+
|
378
|
+
@it.save_js("_design/foo", "bar", { "baz" => "json" })
|
379
|
+
end
|
380
|
+
|
381
|
+
it "should store the attribute to the filesystem" do
|
382
|
+
@file.
|
383
|
+
should_receive(:write).
|
384
|
+
with("json")
|
385
|
+
|
386
|
+
@it.save_js("_design/foo", "bar", "json")
|
387
|
+
end
|
388
|
+
|
389
|
+
it "should store the attributes with slashes to the filesystem" do
|
390
|
+
File.
|
391
|
+
should_receive(:new).
|
392
|
+
with("/tmp/_design/foo/bar%2Fbaz.js", "w+")
|
393
|
+
|
394
|
+
@it.save_js("_design/foo", "bar/baz", "json")
|
395
|
+
end
|
396
|
+
|
397
|
+
it "should strip lib code when dumping" do
|
398
|
+
js = <<_JS
|
399
|
+
// !begin code foo.js
|
400
|
+
function foo () { return 'foo'; }
|
401
|
+
// !end code foo.js
|
402
|
+
// !begin code bar.js
|
403
|
+
function bar () { return 'bar'; }
|
404
|
+
// !end code bar.js
|
405
|
+
function baz () { return 'baz'; }
|
406
|
+
_JS
|
407
|
+
|
408
|
+
@it.
|
409
|
+
remove_code_macros(js).
|
410
|
+
should == "// !code foo.js\n" +
|
411
|
+
"// !code bar.js\n" +
|
412
|
+
"function baz () { return 'baz'; }\n"
|
413
|
+
end
|
276
414
|
end
|
277
415
|
end
|
278
416
|
|
@@ -297,15 +435,61 @@ describe CommandLine do
|
|
297
435
|
end
|
298
436
|
|
299
437
|
context "an instance that dumps a CouchDB database" do
|
300
|
-
|
438
|
+
it "should dump CouchDB documents from uri to dir when run" do
|
301
439
|
@it = CommandLine.new(['dump', 'uri', 'dir'])
|
440
|
+
|
441
|
+
CouchDocs.
|
442
|
+
should_receive(:dump).
|
443
|
+
with("uri", "dir", nil)
|
444
|
+
|
445
|
+
@it.run
|
302
446
|
end
|
303
447
|
|
304
|
-
it "should
|
448
|
+
it "should be able to dump only design documents" do
|
449
|
+
@it = CommandLine.new(['dump', 'uri', 'dir', '-d'])
|
450
|
+
|
305
451
|
CouchDocs.
|
306
452
|
should_receive(:dump).
|
307
|
-
with("uri", "dir")
|
453
|
+
with("uri", "dir", :design)
|
454
|
+
|
455
|
+
@it.run
|
456
|
+
end
|
457
|
+
|
458
|
+
it "should be able to dump only regular documents" do
|
459
|
+
@it = CommandLine.new(['dump', 'uri', 'dir', '-D'])
|
460
|
+
|
461
|
+
CouchDocs.
|
462
|
+
should_receive(:dump).
|
463
|
+
with("uri", "dir", :doc)
|
464
|
+
|
465
|
+
@it.run
|
466
|
+
end
|
467
|
+
end
|
308
468
|
|
469
|
+
context "pushing" do
|
470
|
+
before(:each) do
|
471
|
+
CouchDocs.stub!(:put_dir)
|
472
|
+
|
473
|
+
@dw = mock("Directory Watcher").as_null_object
|
474
|
+
DirectoryWatcher.stub!(:new).and_return(@dw)
|
475
|
+
end
|
476
|
+
|
477
|
+
it "should know watch" do
|
478
|
+
@it = CommandLine.new(%w(push uri dir -w))
|
479
|
+
@it.options[:watch].should be_true
|
480
|
+
end
|
481
|
+
|
482
|
+
it "should run once normally" do
|
483
|
+
@dw.should_receive(:run_once)
|
484
|
+
|
485
|
+
@it = CommandLine.new(%w(push uri dir))
|
486
|
+
@it.run
|
487
|
+
end
|
488
|
+
|
489
|
+
it "should start a watcher with -w" do
|
490
|
+
@dw.should_receive(:start)
|
491
|
+
|
492
|
+
@it = CommandLine.new(%w(push uri dir -w))
|
309
493
|
@it.run
|
310
494
|
end
|
311
495
|
end
|
@@ -315,9 +499,9 @@ describe CommandLine do
|
|
315
499
|
@it = CommandLine.new(['load', 'dir', 'uri'])
|
316
500
|
end
|
317
501
|
|
318
|
-
it "should
|
502
|
+
it "should load CouchDB documents from dir to uri when run" do
|
319
503
|
CouchDocs.
|
320
|
-
should_receive(:
|
504
|
+
should_receive(:put_dir).
|
321
505
|
with("uri", "dir")
|
322
506
|
|
323
507
|
@it.run
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: couch_docs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Strom
|
@@ -9,58 +9,58 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-03-11 00:00:00 -05:00
|
13
13
|
default_executable: couch-docs
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
16
|
+
name: rest-client
|
17
17
|
type: :runtime
|
18
18
|
version_requirement:
|
19
19
|
version_requirements: !ruby/object:Gem::Requirement
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version:
|
23
|
+
version: 1.1.0
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
|
-
name:
|
26
|
+
name: json
|
27
27
|
type: :runtime
|
28
28
|
version_requirement:
|
29
29
|
version_requirements: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 1.2.0
|
34
34
|
version:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
|
-
name:
|
36
|
+
name: directory_watcher
|
37
37
|
type: :runtime
|
38
38
|
version_requirement:
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
41
|
- - ">="
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 1.
|
43
|
+
version: 1.3.1
|
44
44
|
version:
|
45
45
|
- !ruby/object:Gem::Dependency
|
46
|
-
name:
|
47
|
-
type: :
|
46
|
+
name: bones
|
47
|
+
type: :development
|
48
48
|
version_requirement:
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
51
|
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
53
|
+
version: 2.5.0
|
54
54
|
version:
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rspec
|
57
57
|
type: :development
|
58
58
|
version_requirement:
|
59
59
|
version_requirements: !ruby/object:Gem::Requirement
|
60
60
|
requirements:
|
61
61
|
- - ">="
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version:
|
63
|
+
version: "0"
|
64
64
|
version:
|
65
65
|
description: Manage CouchDB views and documents.
|
66
66
|
email: chris@eeecooks.com
|
@@ -78,8 +78,10 @@ files:
|
|
78
78
|
- Rakefile
|
79
79
|
- bin/couch-docs
|
80
80
|
- couch_docs.gemspec
|
81
|
+
- fixtures/_design/__lib/foo.js
|
81
82
|
- fixtures/_design/a/b/c.js
|
82
83
|
- fixtures/_design/a/b/d.js
|
84
|
+
- fixtures/_design/x/z.js
|
83
85
|
- fixtures/bar.json
|
84
86
|
- fixtures/foo.json
|
85
87
|
- lib/couch_docs.rb
|
@@ -117,7 +119,7 @@ requirements: []
|
|
117
119
|
rubyforge_project: couch_docs
|
118
120
|
rubygems_version: 1.3.5
|
119
121
|
signing_key:
|
120
|
-
specification_version:
|
122
|
+
specification_version: 3
|
121
123
|
summary: Manage CouchDB views and documents
|
122
124
|
test_files:
|
123
125
|
- test/test_couch_docs.rb
|