new capabilities for couchapp script

This commit is contained in:
Chris Anderson 2008-10-28 09:56:42 -07:00
parent 387bd704ef
commit b62b77eee5
4 changed files with 88 additions and 17 deletions

View file

@ -189,7 +189,7 @@ module CouchRest
def push_app(appdir, appname)
libs = []
viewdir = File.join(appdir,"views")
attachdir = File.join(appdir,"attachments")
attachdir = File.join(appdir,"_attachments")
views, lang = read_design_views(viewdir)
# attachments = read_attachments(attachdir)
docid = "_design/#{appname}"
@ -199,28 +199,61 @@ module CouchRest
design['language'] = lang
@db.save(design)
push_directory(attachdir, docid)
# puts views.inspect
push_fields(appdir, docid)
end
def push_fields(appdir, docid)
fields = {}
(Dir["#{appdir}/**/*.*"] -
Dir["#{appdir}/views/**/*.*"] -
Dir["#{appdir}/doc.json"] -
Dir["#{appdir}/_attachments/**/*.*"]).each do |file|
farray = file.sub(appdir, '').sub(/^\//,'').split('/')
myfield = fields
while farray.length > 1
front = farray.shift
myfield[front] = {}
myfield = myfield[front]
end
# todo: json
fname, fext = farray.shift.split('.')
fguts = File.open(file).read
if fext == 'json'
myfield[fname] = JSON.parse(fguts)
else
myfield[fname] = fguts
end
end
if File.exists?("#{appdir}/doc.json")
default_json = JSON.parse(File.open("#{appdir}/doc.json").read)
end
design = @db.get(docid) rescue {}
design.merge!(fields)
design.merge!(default_json) if default_json
@db.save(design)
end
# Generate an application in the given directory.
# This is a class method because it doesn't depend on
# specifying a database.
def self.generate_app(app_dir)
def self.generate_app(app_dir)
FileUtils.mkdir_p(app_dir)
FileUtils.mkdir_p(File.join(app_dir,"attachments"))
FileUtils.mkdir_p(File.join(app_dir,"_attachments"))
FileUtils.mkdir_p(File.join(app_dir,"views"))
FileUtils.mkdir_p(File.join(app_dir,"foo"))
index_template = File.join(File.expand_path(File.dirname(__FILE__)), 'templates','index.html')
index_dest = File.join(app_dir,"attachments","index.html")
FileUtils.cp(index_template, index_dest)
map_template = File.join(File.expand_path(File.dirname(__FILE__)), 'templates','example-map.js')
map_dest = File.join(app_dir,"views","example-map.js")
FileUtils.cp(map_template, map_dest)
rereduce_template = File.join(File.expand_path(File.dirname(__FILE__)), 'templates','example-reduce.js')
rereduce_dest = File.join(app_dir,"views","example-reduce.js")
FileUtils.cp(rereduce_template, rereduce_dest)
{
"index.html" => "_attachments",
'example-map.js' => "views",
'example-reduce.js' => "views",
'bar.txt' => "foo",
}.each do |filename, targetdir|
template = File.join(File.expand_path(File.dirname(__FILE__)), 'templates',filename)
dest = File.join(app_dir,targetdir,filename)
FileUtils.cp(template, dest)
end
end
private

View file

@ -0,0 +1,11 @@
Couchapp will create a field on your document corresponding to any directories you make within the application directory, with the text of any files found as key/value pairs.
Also, any files that end in .json will be treated as json rather than text, and put in the corresponding field. Also note that file.json, file.js, or file.txt will be stored under the "file" key, so don't make collisions in the filesystem unless you want unpredictable results.
Of course you know that the views directory will be treated specially and -map and -reduce files will be mapped to the map and reduce functions. And the _attachments directory will be treated strangely as well.
doc.json is a special case, it is treated as json and its keys are applied to the document root; eg it does not result in a "doc" field on your design document. If you need a doc field on the design document, you'll have to define it with a doc.json like so: {"doc":"value for doc field"}
ps: each design document only has one language key: it will be set based on the file extensions in the views directory. CouchDB defaults to Javascript, so that's what you'll get if you don't define any views. You can override it with the doc.json file, but don't say we didn't warn you.
Oh yeah it's recommended that you delete this file.

View file

@ -7,7 +7,6 @@ describe "couchapp" do
`rm -rf #{@fixdir}`
`mkdir -p #{@fixdir}`
@run = "cd #{@fixdir} && #{@couchapp}"
end
describe "--help" do

View file

@ -37,10 +37,17 @@ describe CouchRest::FileManager, "generating an app" do
it "should create a views directory" do
Dir["#{@appdir}/*"].select{|x|x =~ /views/}.length.should == 1
end
it "should create a foo directory" do
Dir["#{@appdir}/*"].select{|x|x =~ /foo/}.length.should == 1
end
it "should create index.html" do
html = File.open("#{@appdir}/attachments/index.html").read
html = File.open("#{@appdir}/_attachments/index.html").read
html.should match(/DOCTYPE/)
end
it "should create bar.txt" do
html = File.open("#{@appdir}/foo/bar.txt").read
html.should match(/Couchapp will/)
end
it "should create an example view" do
map = File.open("#{@appdir}/views/example-map.js").read
map.should match(/function\(doc\)/)
@ -75,6 +82,27 @@ describe CouchRest::FileManager, "pushing an app" do
doc = @db.get("_design/couchapp")
doc['_attachments']['index.html']["content_type"].should == 'text/html'
end
it "should push bar.txt" do
doc = @db.get("_design/couchapp")
doc["foo"].should_not be_nil
doc["foo"]["bar"].should include("Couchapp will")
end
it "should push json as json" do
File.open("#{@appdir}/test.json",'w') do |f|
f.write("[1,2,3,4]")
end
r = @fm.push_app(@appdir, "couchapp")
doc = @db.get("_design/couchapp")
doc['test'].should == [1,2,3,4]
end
it "should apply keys from doc.json directly to the doc" do
File.open("#{@appdir}/doc.json",'w') do |f|
f.write('{"magical":"so magic"}')
end
r = @fm.push_app(@appdir, "couchapp")
doc = @db.get("_design/couchapp")
doc['magical'].should == "so magic"
end
end