couch 0.2.0 → 0.2.1
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/README.rdoc +6 -88
- data/Rakefile +3 -54
- data/bin/couch +1 -7
- data/couch.gemspec +6 -72
- data/lib/couch.rb +0 -41
- metadata +9 -127
- data/.gitmodules +0 -3
- data/LICENSE +0 -20
- data/lib/couch/actions/base.rb +0 -15
- data/lib/couch/actions/pull.rb +0 -28
- data/lib/couch/actions/push.rb +0 -53
- data/lib/couch/actions/routes.rb +0 -41
- data/lib/couch/commands.rb +0 -41
- data/lib/couch/commands/destroy.rb +0 -9
- data/lib/couch/commands/generate.rb +0 -9
- data/lib/couch/commands/pull.rb +0 -4
- data/lib/couch/commands/push.rb +0 -4
- data/lib/couch/commands/routes.rb +0 -4
- data/lib/couch/design_document.rb +0 -314
- data/lib/couch/generators.rb +0 -63
- data/lib/couch/generators/application/USAGE +0 -10
- data/lib/couch/generators/application/application_generator.rb +0 -51
- data/lib/couch/generators/application/templates/README +0 -1
- data/lib/couch/generators/application/templates/_attachments/index.html +0 -11
- data/lib/couch/generators/application/templates/_attachments/stylesheets/application.css +0 -25
- data/lib/couch/generators/application/templates/_id +0 -1
- data/lib/couch/generators/application/templates/couchrc +0 -1
- data/lib/couch/generators/application/templates/gitignore +0 -0
- data/lib/couch/generators/application/templates/lib/mustache.js +0 -305
- data/lib/couch/generators/application/templates/validate_doc_update.js +0 -3
- data/lib/couch/generators/base.rb +0 -66
- data/lib/couch/generators/list/USAGE +0 -8
- data/lib/couch/generators/list/list_generator.rb +0 -9
- data/lib/couch/generators/list/templates/list.js +0 -29
- data/lib/couch/generators/named_base.rb +0 -22
- data/lib/couch/generators/scaffold/USAGE +0 -10
- data/lib/couch/generators/scaffold/scaffold_generator.rb +0 -28
- data/lib/couch/generators/show/USAGE +0 -8
- data/lib/couch/generators/show/show_generator.rb +0 -9
- data/lib/couch/generators/show/templates/show.js +0 -20
- data/lib/couch/generators/validation/USAGE +0 -9
- data/lib/couch/generators/validation/templates/validate_doc_update.js +0 -3
- data/lib/couch/generators/validation/validation_generator.rb +0 -34
- data/lib/couch/generators/view/USAGE +0 -8
- data/lib/couch/generators/view/templates/map.js +0 -5
- data/lib/couch/generators/view/view_generator.rb +0 -17
- data/lib/couch/version.rb +0 -3
- data/spec/couch/design_document_spec.rb +0 -313
- data/spec/couch_spec.rb +0 -7
- data/spec/spec.opts +0 -1
- data/spec/spec_helper.rb +0 -9
data/.gitmodules
DELETED
data/LICENSE
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
Copyright (c) 2009 Johannes J. Schmidt
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
-
a copy of this software and associated documentation files (the
|
5
|
-
"Software"), to deal in the Software without restriction, including
|
6
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
the following conditions:
|
10
|
-
|
11
|
-
The above copyright notice and this permission notice shall be
|
12
|
-
included in all copies or substantial portions of the Software.
|
13
|
-
|
14
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/lib/couch/actions/base.rb
DELETED
data/lib/couch/actions/pull.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'couch/actions/base'
|
2
|
-
require 'couch/design_document'
|
3
|
-
|
4
|
-
require "rest_client"
|
5
|
-
|
6
|
-
module Couch
|
7
|
-
module Actions
|
8
|
-
class Pull < Base
|
9
|
-
add_runtime_options!
|
10
|
-
|
11
|
-
def pull
|
12
|
-
doc = DesignDocument.new
|
13
|
-
say "Pulling %s" % doc.url
|
14
|
-
|
15
|
-
resp = RestClient.get doc.url(:attachments => true)
|
16
|
-
doc.json = resp.body
|
17
|
-
|
18
|
-
doc.write do |filename, content|
|
19
|
-
create_file filename, content
|
20
|
-
end
|
21
|
-
|
22
|
-
say "Checked out %s" % doc.rev
|
23
|
-
rescue RestClient::ResourceNotFound
|
24
|
-
say "Error: Document %s does not exist!" % doc.id
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
data/lib/couch/actions/push.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
require 'couch/actions/base'
|
2
|
-
require 'couch/design_document'
|
3
|
-
|
4
|
-
require 'pathname'
|
5
|
-
require "rest_client"
|
6
|
-
|
7
|
-
module Couch
|
8
|
-
module Actions
|
9
|
-
class Push < Base
|
10
|
-
def initialize(*args)
|
11
|
-
super
|
12
|
-
@doc = DesignDocument.new
|
13
|
-
end
|
14
|
-
|
15
|
-
def create_database_unless_exists
|
16
|
-
RestClient.put @doc.database, nil
|
17
|
-
say "Created database %s" % @doc.database
|
18
|
-
rescue RestClient::PreconditionFailed
|
19
|
-
end
|
20
|
-
|
21
|
-
def push
|
22
|
-
root = Pathname.new(destination_root)
|
23
|
-
filenames = Dir[root.join "**/*"]
|
24
|
-
filenames.map! { |file| Pathname.new file }
|
25
|
-
filenames.map! { |path| path.relative_path_from root }
|
26
|
-
filenames.delete_if { |path| !path.file? }
|
27
|
-
filenames.map!(&:to_s)
|
28
|
-
@doc.read(filenames) do |filename|
|
29
|
-
File.read File.join(destination_root, filename)
|
30
|
-
end
|
31
|
-
|
32
|
-
say "Pushing to %s" % @doc.url
|
33
|
-
|
34
|
-
resp = RestClient.put @doc.url, @doc.json
|
35
|
-
response = JSON.parse(resp.body)
|
36
|
-
|
37
|
-
if response["ok"]
|
38
|
-
@doc.rev = response["rev"]
|
39
|
-
File.open File.join(destination_root, "_rev"), "w" do |file|
|
40
|
-
file << @doc.rev
|
41
|
-
end
|
42
|
-
|
43
|
-
say "Pushed %s" % @doc.rev
|
44
|
-
else
|
45
|
-
say "Error occured: %s" % response.inspect
|
46
|
-
end
|
47
|
-
|
48
|
-
rescue RestClient::Conflict
|
49
|
-
say "Conflict! Try to pull first or delete ./_rev."
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
data/lib/couch/actions/routes.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'couch/actions/base'
|
2
|
-
|
3
|
-
module Couch
|
4
|
-
module Actions
|
5
|
-
class Routes < Base
|
6
|
-
def routes
|
7
|
-
say 'Static:'
|
8
|
-
Dir.glob(File.join(destination_root, "_attachments/*.html")).each do |file|
|
9
|
-
say ' %s' % attachment_url(file)
|
10
|
-
end
|
11
|
-
|
12
|
-
say 'Lists:'
|
13
|
-
Dir.glob(File.join(destination_root, "lists/*")).each do |list|
|
14
|
-
Dir.glob(File.join(destination_root, "views/*")).each do |view|
|
15
|
-
say ' %s' % list_url(list, view)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
say 'Shows:'
|
20
|
-
Dir.glob(File.join(destination_root, "shows/*")).each do |show|
|
21
|
-
say ' %s' % show_url(show)
|
22
|
-
say ' %s' % show_url(show, '/:id')
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
protected
|
27
|
-
|
28
|
-
def attachment_url(file)
|
29
|
-
File.join(Couch.database, '_design', File.basename(Couch.database), File.basename(file))
|
30
|
-
end
|
31
|
-
|
32
|
-
def list_url(list, view)
|
33
|
-
File.join(Couch.database, '_design', File.basename(Couch.database), '_list', File.basename(view), File.basename(list, '.js'))
|
34
|
-
end
|
35
|
-
|
36
|
-
def show_url(show, id = '/')
|
37
|
-
File.join(Couch.database, '_design', File.basename(Couch.database), '_show', File.basename(show, '.js'), id)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
data/lib/couch/commands.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
if ARGV.empty?
|
2
|
-
ARGV << '--help'
|
3
|
-
end
|
4
|
-
|
5
|
-
HELP_TEXT = <<-EOT
|
6
|
-
Usage: couch COMMAND [ARGS]
|
7
|
-
|
8
|
-
The most common couch commands are:
|
9
|
-
generate Generate new code (short-cut alias: "g")
|
10
|
-
push Push application code to CouchDB
|
11
|
-
pull Pull latest application code from CouchDB
|
12
|
-
routes List application urls
|
13
|
-
|
14
|
-
In addition to those, there are:
|
15
|
-
destroy Undo code generated with "generate"
|
16
|
-
|
17
|
-
All commands can be run with -h for more information.
|
18
|
-
EOT
|
19
|
-
|
20
|
-
|
21
|
-
case ARGV.shift
|
22
|
-
when 'g', 'generate'
|
23
|
-
require 'couch/commands/generate'
|
24
|
-
when 'destroy'
|
25
|
-
require 'couch/commands/destroy'
|
26
|
-
when 'push'
|
27
|
-
require 'couch/commands/push'
|
28
|
-
when 'pull'
|
29
|
-
require 'couch/commands/pull'
|
30
|
-
when 'routes'
|
31
|
-
require 'couch/commands/routes'
|
32
|
-
|
33
|
-
when '--help', '-h'
|
34
|
-
puts HELP_TEXT
|
35
|
-
when '--version', '-v'
|
36
|
-
require 'couch/version'
|
37
|
-
puts "Couch #{Couch::VERSION}"
|
38
|
-
else
|
39
|
-
puts "Error: Command not recognized"
|
40
|
-
puts HELP_TEXT
|
41
|
-
end
|
data/lib/couch/commands/pull.rb
DELETED
data/lib/couch/commands/push.rb
DELETED
@@ -1,314 +0,0 @@
|
|
1
|
-
require 'uri'
|
2
|
-
|
3
|
-
module Couch
|
4
|
-
class DesignDocument
|
5
|
-
# Mime type mapping from extensions
|
6
|
-
MIME_TYPE_MAPPING = {
|
7
|
-
".html" => "text/html",
|
8
|
-
".js" => "text/javascript",
|
9
|
-
".css" => "text/css",
|
10
|
-
}
|
11
|
-
|
12
|
-
# Files that should have a .js extension
|
13
|
-
JAVASCRIPT_FILES = %w[
|
14
|
-
validate_doc_update
|
15
|
-
lists/*
|
16
|
-
shows/*
|
17
|
-
updates/*
|
18
|
-
views/*/*
|
19
|
-
]
|
20
|
-
|
21
|
-
# Files that should not be included in document
|
22
|
-
EXCLUDE_FILES = %w[
|
23
|
-
README
|
24
|
-
]
|
25
|
-
|
26
|
-
attr_accessor :hash
|
27
|
-
|
28
|
-
def initialize
|
29
|
-
@hash = {}
|
30
|
-
end
|
31
|
-
|
32
|
-
# Read document from a filesystem.
|
33
|
-
#
|
34
|
-
# Takes a filename,
|
35
|
-
# many filenames,
|
36
|
-
# or an array of filenames
|
37
|
-
# and assign the return value of a yielded block to the hash.
|
38
|
-
#
|
39
|
-
# Nested hashes
|
40
|
-
# like { "hash" => { "key" => "value" } }
|
41
|
-
# can be constructed if the filename contains a slash (/),
|
42
|
-
# eg "hash/key".
|
43
|
-
#
|
44
|
-
def read(*filenames, &block)
|
45
|
-
filenames.flatten.uniq.each do |filename|
|
46
|
-
# skip exclude files
|
47
|
-
next if EXCLUDE_FILES.include?(filename)
|
48
|
-
|
49
|
-
key = filename.dup
|
50
|
-
# strip extname from javascript files
|
51
|
-
key.sub!(/\.js$/, '') if filename =~ /#{JAVASCRIPT_FILES.join('|')}/
|
52
|
-
|
53
|
-
set_hash_at key, block.call(filename)
|
54
|
-
end
|
55
|
-
|
56
|
-
map_attachments!
|
57
|
-
inject_makros!
|
58
|
-
end
|
59
|
-
|
60
|
-
# Write document to a filesystem
|
61
|
-
#
|
62
|
-
# Takes a directoy as startpoint (default is nil),
|
63
|
-
# a document hash (default is the design documents hash)
|
64
|
-
# and recursively yields all keys and values to the given block.
|
65
|
-
#
|
66
|
-
# Nested hashes
|
67
|
-
# like { "hash" => { "key" => "value" } }
|
68
|
-
# will result in the yielded filename
|
69
|
-
# "hash/key".
|
70
|
-
#
|
71
|
-
# The key "_attachments" has a special meaning:
|
72
|
-
# the value holds base64 encoded data as well as other metadata.
|
73
|
-
# This data will gets decoded and used as value for the key.
|
74
|
-
#
|
75
|
-
def write(directory = nil, doc = nil, &block)
|
76
|
-
reduce_attachments!
|
77
|
-
reject_makros!
|
78
|
-
|
79
|
-
doc ||= hash
|
80
|
-
doc.each do |key, value|
|
81
|
-
filename = directory ? File.join(directory, key) : key.dup
|
82
|
-
if value.is_a?(Hash)
|
83
|
-
write(filename, value, &block)
|
84
|
-
else
|
85
|
-
# append extname to javascript files
|
86
|
-
filename << '.js' if filename =~ /#{JAVASCRIPT_FILES.join('|')}/
|
87
|
-
block.call(filename, value)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
# Returns a JSON string representation of the documents hash
|
93
|
-
#
|
94
|
-
def json
|
95
|
-
hash.to_json
|
96
|
-
end
|
97
|
-
|
98
|
-
# Build the documents hash from a JSON string
|
99
|
-
#
|
100
|
-
def json=(json)
|
101
|
-
self.hash = JSON.parse(json)
|
102
|
-
end
|
103
|
-
|
104
|
-
|
105
|
-
# Accessor for id
|
106
|
-
def id
|
107
|
-
hash["_id"] || Couch.id
|
108
|
-
end
|
109
|
-
|
110
|
-
# Accessor for rev
|
111
|
-
def rev
|
112
|
-
hash["_rev"] || Couch.rev
|
113
|
-
end
|
114
|
-
|
115
|
-
# Updates rev in documents hash
|
116
|
-
def rev=(new_rev)
|
117
|
-
hash["_rev"] = new_rev
|
118
|
-
end
|
119
|
-
|
120
|
-
|
121
|
-
# Accessor for couch database
|
122
|
-
def database
|
123
|
-
@database ||= Couch.database
|
124
|
-
end
|
125
|
-
|
126
|
-
# Base URL for document
|
127
|
-
def base_url
|
128
|
-
@base_url ||= File.join(database, id)
|
129
|
-
end
|
130
|
-
|
131
|
-
# URL for accessing design document
|
132
|
-
#
|
133
|
-
# Takes an optional options hash
|
134
|
-
# which gets converted to url encoded options
|
135
|
-
# and appended to the documents base url
|
136
|
-
#
|
137
|
-
def url(options = {})
|
138
|
-
base_url + build_options_string(options)
|
139
|
-
end
|
140
|
-
|
141
|
-
private
|
142
|
-
|
143
|
-
def hash_at(path)
|
144
|
-
current_hash = hash
|
145
|
-
|
146
|
-
parts = path.split('/')
|
147
|
-
key = parts.pop
|
148
|
-
|
149
|
-
parts.each do |part|
|
150
|
-
current_hash[part] ||= {}
|
151
|
-
current_hash = current_hash[part]
|
152
|
-
end
|
153
|
-
|
154
|
-
current_hash[key]
|
155
|
-
end
|
156
|
-
|
157
|
-
def set_hash_at(path, value)
|
158
|
-
current_hash = hash
|
159
|
-
|
160
|
-
parts = path.split('/')
|
161
|
-
key = parts.pop
|
162
|
-
|
163
|
-
parts.each do |part|
|
164
|
-
current_hash[part] ||= {}
|
165
|
-
current_hash = current_hash[part]
|
166
|
-
end
|
167
|
-
|
168
|
-
current_hash[key] = value
|
169
|
-
end
|
170
|
-
|
171
|
-
def build_options_string(options)
|
172
|
-
return '' if options.empty?
|
173
|
-
options_array = []
|
174
|
-
options.each do |key, value|
|
175
|
-
options_array << URI.escape([key, value].join('='))
|
176
|
-
end
|
177
|
-
'?' + options_array.join("&")
|
178
|
-
end
|
179
|
-
|
180
|
-
def inject_makros!
|
181
|
-
self.hash = inject_code_makro(hash)
|
182
|
-
self.hash = inject_json_makro(hash)
|
183
|
-
end
|
184
|
-
|
185
|
-
def inject_code_makro(doc)
|
186
|
-
doc.each do |key, value|
|
187
|
-
doc[key] = if value.is_a?(String)
|
188
|
-
value.gsub(/\/\/\s*!code.*$/) do |match|
|
189
|
-
filename = match.sub(/^.*!code\s*(\S+).*$/, '\1')
|
190
|
-
hash_at File.join('lib', filename)
|
191
|
-
end
|
192
|
-
elsif value.is_a?(Hash)
|
193
|
-
inject_code_makro(value)
|
194
|
-
else
|
195
|
-
value
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
doc
|
200
|
-
end
|
201
|
-
|
202
|
-
def inject_json_makro(doc)
|
203
|
-
doc.each do |key, value|
|
204
|
-
doc[key] = if value.is_a?(String)
|
205
|
-
value.gsub(/\/\/\s*!json.*$/) do |match|
|
206
|
-
filename = match.sub(/^.*!json\s*(\S+).*$/, '\1')
|
207
|
-
'var %s = %s;' % [filename.sub(/\..*$/, ''), hash_at(File.join('lib', filename)).to_json]
|
208
|
-
end
|
209
|
-
elsif value.is_a?(Hash)
|
210
|
-
inject_json_makro(value)
|
211
|
-
else
|
212
|
-
value
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
doc
|
217
|
-
end
|
218
|
-
|
219
|
-
def reject_makros!
|
220
|
-
# TODO: recursive walk libs
|
221
|
-
libs = hash["lib"]
|
222
|
-
return if libs.nil? || libs.empty?
|
223
|
-
# Attention: replace json makros first!
|
224
|
-
self.hash = reject_json_makro(hash, libs)
|
225
|
-
self.hash = reject_code_makro(hash, libs)
|
226
|
-
end
|
227
|
-
|
228
|
-
def reject_code_makro(doc, libs)
|
229
|
-
doc = doc.dup
|
230
|
-
doc.each do |key, value|
|
231
|
-
next if key == "lib"
|
232
|
-
|
233
|
-
if value.is_a?(String)
|
234
|
-
libs.each do |name, content|
|
235
|
-
# only try substituting strings
|
236
|
-
next unless content.is_a?(String)
|
237
|
-
next unless value.include?(content)
|
238
|
-
doc[key] = value.gsub(content, "// !code #{name}")
|
239
|
-
end
|
240
|
-
elsif value.is_a?(Hash)
|
241
|
-
doc[key] = reject_code_makro(value, libs)
|
242
|
-
end
|
243
|
-
end
|
244
|
-
doc
|
245
|
-
end
|
246
|
-
|
247
|
-
def reject_json_makro(doc, libs)
|
248
|
-
doc.each do |key, value|
|
249
|
-
next if key == "lib"
|
250
|
-
if value.is_a?(String)
|
251
|
-
libs.each do |name, content|
|
252
|
-
# only try substituting strings
|
253
|
-
next unless content.is_a?(String)
|
254
|
-
json = 'var %s = %s;' % [name.sub(/\..*$/, ''), content.to_json]
|
255
|
-
next unless value.include?(json)
|
256
|
-
doc[key] = value.gsub(json, "// !json #{name}")
|
257
|
-
end
|
258
|
-
elsif value.is_a?(Hash)
|
259
|
-
doc[key] = reject_json_makro(value, libs)
|
260
|
-
end
|
261
|
-
end
|
262
|
-
doc
|
263
|
-
end
|
264
|
-
|
265
|
-
def reduce_attachments!
|
266
|
-
return hash unless hash["_attachments"]
|
267
|
-
attachments = {}
|
268
|
-
hash["_attachments"].each do |key, value|
|
269
|
-
data = value["data"]
|
270
|
-
next unless data
|
271
|
-
attachments.update key => decode_attachment(data)
|
272
|
-
end
|
273
|
-
hash.update "_attachments" => attachments
|
274
|
-
end
|
275
|
-
|
276
|
-
def map_attachments!
|
277
|
-
return unless hash["_attachments"]
|
278
|
-
attachments = {}
|
279
|
-
flatten_attachements(hash["_attachments"]).each do |key, value|
|
280
|
-
attachments.update key => {
|
281
|
-
"data" => encode_attachment(value),
|
282
|
-
"content_type" => mime_type_for(key)
|
283
|
-
}
|
284
|
-
end
|
285
|
-
self.hash.update "_attachments" => attachments
|
286
|
-
end
|
287
|
-
|
288
|
-
def flatten_attachements(doc, base = nil)
|
289
|
-
result = {}
|
290
|
-
doc.each do |key, value|
|
291
|
-
new_base = base ? [base, key].join('/') : key
|
292
|
-
if value.is_a?(Hash)
|
293
|
-
result.update flatten_attachements(value, new_base)
|
294
|
-
else
|
295
|
-
result.update new_base => value
|
296
|
-
end
|
297
|
-
end
|
298
|
-
result
|
299
|
-
end
|
300
|
-
|
301
|
-
def decode_attachment(data)
|
302
|
-
data.unpack("m").first
|
303
|
-
end
|
304
|
-
|
305
|
-
def encode_attachment(data)
|
306
|
-
[data].pack("m").gsub(/\s+/,'')
|
307
|
-
end
|
308
|
-
|
309
|
-
def mime_type_for(filename)
|
310
|
-
ext = File.extname(filename)
|
311
|
-
MIME_TYPE_MAPPING[ext] || 'text/plain'
|
312
|
-
end
|
313
|
-
end
|
314
|
-
end
|