From b62b77eee5870194f62ddb87109b1c581c6e857e Mon Sep 17 00:00:00 2001 From: Chris Anderson Date: Tue, 28 Oct 2008 09:56:42 -0700 Subject: [PATCH] new capabilities for couchapp script --- lib/couchrest/helper/file_manager.rb | 63 ++++++++++++++++----- lib/couchrest/helper/templates/bar.txt | 11 ++++ spec/couchapp_spec.rb | 1 - spec/couchrest/helpers/file_manager_spec.rb | 30 +++++++++- 4 files changed, 88 insertions(+), 17 deletions(-) create mode 100644 lib/couchrest/helper/templates/bar.txt diff --git a/lib/couchrest/helper/file_manager.rb b/lib/couchrest/helper/file_manager.rb index 4e36bef..c491dfb 100644 --- a/lib/couchrest/helper/file_manager.rb +++ b/lib/couchrest/helper/file_manager.rb @@ -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 diff --git a/lib/couchrest/helper/templates/bar.txt b/lib/couchrest/helper/templates/bar.txt new file mode 100644 index 0000000..5a8cbe4 --- /dev/null +++ b/lib/couchrest/helper/templates/bar.txt @@ -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. \ No newline at end of file diff --git a/spec/couchapp_spec.rb b/spec/couchapp_spec.rb index 6fc61d6..2ab3417 100644 --- a/spec/couchapp_spec.rb +++ b/spec/couchapp_spec.rb @@ -7,7 +7,6 @@ describe "couchapp" do `rm -rf #{@fixdir}` `mkdir -p #{@fixdir}` @run = "cd #{@fixdir} && #{@couchapp}" - end describe "--help" do diff --git a/spec/couchrest/helpers/file_manager_spec.rb b/spec/couchrest/helpers/file_manager_spec.rb index 59116f3..37bb27b 100644 --- a/spec/couchrest/helpers/file_manager_spec.rb +++ b/spec/couchrest/helpers/file_manager_spec.rb @@ -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