diff --git a/.gitignore b/.gitignore index db3f887..ff0456f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ *~ npm-debug.log node_modules/* +.idea diff --git a/LICENSE-MIT b/LICENSE-MIT index 17416f9..5c43c07 100644 --- a/LICENSE-MIT +++ b/LICENSE-MIT @@ -1,4 +1,6 @@ -Copyright (c) 2012 Ken Elf Mathieu Sternberg +Copyright (c) +2012 Ken Elf Mathieu Sternberg +2014 Sam Hiatt Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/README.md b/README.md index f043944..ba68fa6 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,7 @@ grunt-couchapp` Then add this line to your project's `grunt.js` gruntfile: -```javascript -grunt.loadNpmTasks('grunt-couchapp'); -``` + grunt.loadNpmTasks('grunt-couchapp'); [grunt]: https://github.com/cowboy/grunt [getting_started]: https://github.com/cowboy/grunt/blob/master/docs/getting_started.md @@ -26,7 +24,10 @@ which installs a specified couchapp into the database. mkcouchdb: { demo: { - db: 'http://localhost:5984/grunt-couchapp-demo' + db: 'http://localhost:5984/grunt-couchapp-demo', + options: { + okay_if_exists: true + } } }, @@ -54,7 +55,8 @@ possible to write in your configuration file: db: 'http://localhost:5984/grunt-couchapp-demo', app: './demo/app.js', options: { - okay_if_missing: true + okay_if_missing: true, + okay_if_exists: true } } } @@ -68,8 +70,7 @@ possible to write in your configuration file: }); -Note, however, that if you call 'rmcouchdb' without a sub-argument, in -keeping with grunt's standards, it will drop *all* of your databases! +Note that if you call `rmcouchdb` without a sub-argument, it will not delete any databases. ## Demo diff --git a/package.json b/package.json index 8fb8f01..55d6745 100644 --- a/package.json +++ b/package.json @@ -1,43 +1,56 @@ { - "name": "grunt-couchapp", - "description": "A grunt plugin for building and uploading couchapps", - "version": "0.1.0", - "homepage": "https://github.com/elf/grunt-couchapp", - "author": { - "name": "Ken Elf Mathieu Sternberg", - "email": "elf.sternberg@gmail.com", - "url": "http://elfsternberg.com" + "name": "grunt-couchapp", + "description": "A grunt plugin for building and uploading couchapps", + "version": "0.2.2", + "homepage": "https://github.com/garbados/grunt-couchapp", + "author": { + "name": "Ken Elf Mathieu Sternberg", + "email": "elf.sternberg@gmail.com", + "url": "http://elfsternberg.com" + }, + "contributors": [ + { + "name": "Max Thayer", + "email": "garbados@gmail.com", + "url": "http://maxthayer.org" }, - "repository": { - "type": "git", - "url": "git://github.com/elf/grunt-couchapp.git" - }, - "bugs": { - "url": "https://github.com/elf/grunt-couchapp/issues" - }, - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/elf/grunt-couchapp/blob/master/LICENSE-MIT" - } - ], - "main": "grunt.js", - "bin": "bin/grunt-couchapp", - "engines": { - "node": "*" - }, - "scripts": { - "test": "grunt test" - }, - "dependencies": { - "couchapp": "0.9.1", - "grunt": "~0.3.12", - "nano": "3.3.0" - }, - "devDependencies": { - "grunt": "~0.3.12" - }, - "keywords": [ - "gruntplugin" - ] -} \ No newline at end of file + { + "name":"Sam Hiatt", + "email": "sam.hiatt@weather.com" + } + ], + "repository": { + "type": "git", + "url": "git://github.com/garbados/grunt-couchapp.git" + }, + "bugs": { + "url": "https://github.com/garbados/grunt-couchapp/issues" + }, + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/garbados/grunt-couchapp/blob/master/LICENSE-MIT" + } + ], + "main": "grunt.js", + "bin": "bin/grunt-couchapp", + "engines": { + "node": "*" + }, + "scripts": { + "test": "grunt test" + }, + "dependencies": { + "couchapp": "~0.11.0", + "grunt": "~0.3.12", + "nano": "3.3.0" + }, + "devDependencies": { + "grunt": "~0.3.12" + }, + "keywords": [ + "gruntplugin", + "couchdb", + "couchapp" + ] +} diff --git a/tasks/couchapp.js b/tasks/couchapp.js old mode 100644 new mode 100755 index 6b7811f..17104c4 --- a/tasks/couchapp.js +++ b/tasks/couchapp.js @@ -11,6 +11,18 @@ path = require('path'); couchapp = require('couchapp'); urls = require('url'); +var genDB = function(db) { + var parts, dbname, auth; + parts = urls.parse(db); + dbname = parts.pathname.replace(/^\//, ''); + auth = parts.auth ? (parts.auth + '@') : ''; + return { + name: dbname, + url: parts.protocol + '//' + auth + parts.host + }; +}; + + module.exports = function(grunt) { // ========================================================================== @@ -20,66 +32,103 @@ module.exports = function(grunt) { grunt.registerMultiTask("couchapp", "Install Couchapp", function() { var appobj, done; done = this.async(); - appobj = require(path.join(process.cwd(), path.normalize(this.data.app))); + if (require("fs").lstatSync(this.data.app).isDirectory()) { // if new-style (directory-based) couchapp app + appobj = couchapp.loadFiles(this.data.app); + delete appobj._attachments; + delete appobj['']; + couchapp.loadAttachments(appobj, this.data.app+"/_attachments"); + } else { // otherwise, fall back to old style. + appobj = require(path.join(process.cwd(), path.normalize(this.data.app))) + } + return couchapp.createApp(appobj, this.data.db, function(app) { return app.push(done); }); }); grunt.registerMultiTask("rmcouchdb", "Delete a Couch Database", function() { - var done, parts, nano, dbname, _this; + var done, parts, nano, dbname, _this, db; _this = this; done = this.async(); - parts = urls.parse(this.data.db); - dbname = parts.pathname.replace(/^\//, ''); + db = genDB(this.data.db); try { - nano = require('nano')(parts.protocol + '//' + parts.host); - nano.db.destroy(dbname, function(err) { - if (err) { - if (err.status_code && err.status_code === 404) { - if (_this.data.options && _this.data.options.okay_if_missing) { - grunt.log.writeln("Database " + dbname + " not present... skipping."); - return done(null, null) ; + nano = require('nano')(db.url); + if (db.name) { + nano.db.destroy(db.name, function(err) { + if (err) { + if (err.status_code && err.status_code === 404) { + if (_this.data.options && _this.data.options.okay_if_missing) { + grunt.log.writeln("Database " + db.name + " not present... skipping."); + return done(null, null) ; + } else { + throw ("Database " + db.name + " does not exist."); + } } else { - grunt.warn("Database " + dbname + " does not exist."); + throw err; } - } else { - grunt.warn(err); } - } - return done(err, null); - }); + // remove db was a success + return done(); + }); + } else { + grunt.log.writeln("No database specified... skipping."); + return done(null, null); + } } catch (e) { grunt.warn(e); - done(e, null); + return done(e, null); } + return null; }); - grunt.registerMultiTask("mkcouchdb", "Delete a Couch Database", function() { - var done, parts, nano, dbname, _this; + grunt.registerMultiTask("mkcouchdb", "Make a Couch Database", function() { + var done, parts, nano, dbname, _this, db; _this = this; + done = this.async(); parts = urls.parse(this.data.db); - dbname = parts.pathname.replace(/^\//, ''); + db = genDB(this.data.db); try { - nano = require('nano')(parts.protocol + '//' + parts.host); - nano.db.create(dbname, function(err) { - if (_this.data.options && _this.data.options.okay_if_exists) { - if (err){ - grunt.log.writeln("Database " + dbname + " exists, skipping"); + if (db.name) { + nano = require('nano')(db.url); + nano.db.create(db.name, function(err, res) { + if (err) { + if (err.error && err.error=="unauthorized") { + grunt.warn(err.reason); + throw err; + } else if (err.code && err.description) { // probably connection error + throw err; + } + else if (err.error && err.error=="file_exists") { + if (_this.data.options && _this.data.options.okay_if_exists) { + grunt.log.writeln("Database " + db.name + " exists, skipping"); + return done(null, null); + } else { + grunt.warn("Database " + db.name + " exists and okay_if_exists set to false. Aborting."); + throw err; + } + } else { + console.warn("Unrecognized error."); + throw err + } + } else if (res && res.ok==true) { + grunt.log.ok("Database " + db.name + " created."); + return done(null, null); + } else { + console.log("Unexpected response received."); + console.dir(res); + throw "Unexpected response"; } - return done(null, null); - } else { - if (err){ - grunt.warn(err); - } - return done(err, null); - } - }); + }); + } else { + var err_msg = "No database specified to create!"; + throw err_msg; + } } catch (e) { grunt.warn(e); - done(e, null); + return done(e, null); } + return null; }); };