/
design_directory.rb
127 lines (110 loc) · 3.31 KB
/
design_directory.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# couch_docs
# by Chris Strom
# http://github.com/eee-c/couch_docs
# (used to be couch_design_docs)
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# 'Software'), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class Hash
def deep_merge(other)
self.merge(other) do |key, oldval, newval|
oldval.deep_merge(newval)
end
end
end
module CouchDocs
class DesignDirectory
attr_accessor :couch_view_dir
def self.a_to_hash(a)
key = a.first
if (a.length > 2)
{ key => a_to_hash(a[1,a.length]) }
else
{ key => a.last }
end
end
def initialize(path)
Dir.new(path) # Just checkin'
@couch_view_dir = path
end
# Load
def to_hash
Dir["#{couch_view_dir}/**/*.js"].inject({}) do |memo, filename|
DesignDirectory.
a_to_hash(expand_file(filename)).
deep_merge(memo)
end
end
def expand_file(filename)
File.dirname(filename).
gsub(/#{couch_view_dir}\/?/, '').
split(/\//) +
[
File.basename(filename, '.js').gsub(/%2F/, '/'),
read_value(filename)
]
end
def read_value(filename)
File.
readlines(filename).
map { |line| process_code_macro(line) }.
join
end
def process_code_macro(line)
if line =~ %r{\s*//\s*!code\s*(\S+)\s*}
"// !begin code #{$1}\n" +
read_from_lib($1) +
"// !end code #{$1}\n"
else
line
end
end
def read_from_lib(path)
File.read("#{couch_view_dir}/__lib/#{path}")
end
# Store
def store_document(doc)
id = doc['_id']
self.save_js(nil, id, doc)
end
def save_js(rel_path, key, value)
if value.is_a? Hash
value.each_pair do |k, v|
next if k == '_id'
self.save_js([rel_path, key].compact.join('/'), k, v)
end
else
path = couch_view_dir + '/' + rel_path
FileUtils.mkdir_p(path)
file = File.new("#{path}/#{key.gsub(/\//, '%2F')}.js", "w+")
file.write(remove_code_macros(value))
file.close
end
end
def remove_code_macros(js)
js =~ %r{// !begin code ([.\w]+)$}m
lib = $1
if lib and js =~ %r{// !end code #{lib}$}m
remove_code_macros(js.sub(%r{// !begin code #{lib}.+// !end code #{lib}}m, "// !code #{lib}"))
else
js
end
end
end
end