soca 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/HISTORY +3 -0
  4. data/LICENSE +20 -0
  5. data/README.md +89 -0
  6. data/Rakefile +58 -0
  7. data/bin/soca +5 -0
  8. data/lib/soca.rb +34 -0
  9. data/lib/soca/cli.rb +189 -0
  10. data/lib/soca/plugin.rb +31 -0
  11. data/lib/soca/plugins/compass.rb +24 -0
  12. data/lib/soca/plugins/jim.rb +19 -0
  13. data/lib/soca/pusher.rb +186 -0
  14. data/lib/soca/templates/Jimfile +12 -0
  15. data/lib/soca/templates/config.js.erb +4 -0
  16. data/lib/soca/templates/couchapprc.erb +10 -0
  17. data/lib/soca/templates/css/screen.css +1 -0
  18. data/lib/soca/templates/db/views/by_type/map.js +3 -0
  19. data/lib/soca/templates/hooks/before_build.rb +2 -0
  20. data/lib/soca/templates/index.html.erb +17 -0
  21. data/lib/soca/templates/js/app.js +12 -0
  22. data/lib/soca/templates/js/vendor/jquery-1.4.2.js +6240 -0
  23. data/lib/soca/templates/js/vendor/jquery.couch-0.11.js +668 -0
  24. data/lib/soca/templates/js/vendor/sammy-0.6.1.js +1809 -0
  25. data/lib/soca/templates/js/vendor/sammy.couch-0.1.0.js +122 -0
  26. data/lib/soca/templates/js/vendor/sha1.js +202 -0
  27. data/soca.gemspec +107 -0
  28. data/test/helper.rb +36 -0
  29. data/test/test_soca_cli.rb +120 -0
  30. data/test/test_soca_pusher.rb +79 -0
  31. data/test/testapp/.couchapprc +10 -0
  32. data/test/testapp/Jimfile +11 -0
  33. data/test/testapp/config.js +11 -0
  34. data/test/testapp/css/app.css +3 -0
  35. data/test/testapp/db/views/recent/map.js +5 -0
  36. data/test/testapp/hooks/before_build.rb +1 -0
  37. data/test/testapp/index.html +11 -0
  38. data/test/testapp/js/app.js +5 -0
  39. data/test/testapp/js/bundled.js +8544 -0
  40. data/test/testapp/js/vendor/jquery-1.4.2.js +6240 -0
  41. data/test/testapp/js/vendor/json2.js +478 -0
  42. data/test/testapp/js/vendor/sammy-0.5.4.js +1403 -0
  43. data/test/testapp/js/vendor/sammy.mustache-0.5.4.js +415 -0
  44. data/test/testapp/templates/index.mustache +1 -0
  45. metadata +205 -0
@@ -0,0 +1,415 @@
1
+ (function($) {
2
+
3
+ if (!Mustache) {
4
+
5
+ /*
6
+ Shamless port of http://github.com/defunkt/mustache
7
+ by Jan Lehnardt <jan@apache.org>,
8
+ Alexander Lang <alex@upstream-berlin.com>,
9
+ Sebastian Cohnen <sebastian.cohnen@googlemail.com>
10
+
11
+ Thanks @defunkt for the awesome code.
12
+
13
+ See http://github.com/defunkt/mustache for more info.
14
+ */
15
+
16
+ var Mustache = function() {
17
+ var Renderer = function() {};
18
+
19
+ Renderer.prototype = {
20
+ otag: "{{",
21
+ ctag: "}}",
22
+ pragmas: {},
23
+ buffer: [],
24
+
25
+ render: function(template, context, partials, in_recursion) {
26
+ // fail fast
27
+ if(template.indexOf(this.otag) == -1) {
28
+ if(in_recursion) {
29
+ return template;
30
+ } else {
31
+ this.send(template);
32
+ }
33
+ }
34
+
35
+ if(!in_recursion) {
36
+ this.buffer = [];
37
+ }
38
+
39
+ template = this.render_pragmas(template);
40
+ var html = this.render_section(template, context, partials);
41
+ if(in_recursion) {
42
+ return this.render_tags(html, context, partials, in_recursion);
43
+ }
44
+
45
+ this.render_tags(html, context, partials, in_recursion);
46
+ },
47
+
48
+ /*
49
+ Sends parsed lines
50
+ */
51
+ send: function(line) {
52
+ if(line != "") {
53
+ this.buffer.push(line);
54
+ }
55
+ },
56
+
57
+ /*
58
+ Looks for %PRAGMAS
59
+ */
60
+ render_pragmas: function(template) {
61
+ // no pragmas
62
+ if(template.indexOf(this.otag + "%") == -1) {
63
+ return template;
64
+ }
65
+
66
+ var that = this;
67
+ var regex = new RegExp(this.otag + "%([\\w_-]+) ?([\\w]+=[\\w]+)?"
68
+ + this.ctag);
69
+ return template.replace(regex, function(match, pragma, options) {
70
+ that.pragmas[pragma] = {};
71
+ if(options) {
72
+ var opts = options.split("=");
73
+ that.pragmas[pragma][opts[0]] = opts[1];
74
+ }
75
+ return "";
76
+ // ignore unknown pragmas silently
77
+ });
78
+ },
79
+
80
+ /*
81
+ Tries to find a partial in the global scope and render it
82
+ */
83
+ render_partial: function(name, context, partials) {
84
+ if(typeof(context[name]) != "object") {
85
+ throw({message: "subcontext for '" + name + "' is not an object"});
86
+ }
87
+ if(!partials || !partials[name]) {
88
+ throw({message: "unknown_partial"});
89
+ }
90
+ return this.render(partials[name], context[name], partials, true);
91
+ },
92
+
93
+ /*
94
+ Renders boolean and enumerable sections
95
+ */
96
+ render_section: function(template, context, partials) {
97
+ if(template.indexOf(this.otag + "#") == -1) {
98
+ return template;
99
+ }
100
+ var that = this;
101
+ // CSW - Added "+?" so it finds the tighest bound, not the widest
102
+ var regex = new RegExp(this.otag + "\\#(.+)" + this.ctag +
103
+ "\\s*([\\s\\S]+?)" + this.otag + "\\/\\1" + this.ctag + "\\s*", "mg");
104
+
105
+ // for each {{#foo}}{{/foo}} section do...
106
+ return template.replace(regex, function(match, name, content) {
107
+ var value = that.find(name, context);
108
+ if(that.is_array(value)) { // Enumerable, Let's loop!
109
+ return that.map(value, function(row) {
110
+ return that.render(content, that.merge(context,
111
+ that.create_context(row)), partials, true);
112
+ }).join("");
113
+ } else if(value) { // boolean section
114
+ return that.render(content, context, partials, true);
115
+ } else {
116
+ return "";
117
+ }
118
+ });
119
+ },
120
+
121
+ /*
122
+ Replace {{foo}} and friends with values from our view
123
+ */
124
+ render_tags: function(template, context, partials, in_recursion) {
125
+ // tit for tat
126
+ var that = this;
127
+
128
+ var new_regex = function() {
129
+ return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\/#]+?)\\1?" +
130
+ that.ctag + "+", "g");
131
+ };
132
+
133
+ var regex = new_regex();
134
+ var lines = template.split("\n");
135
+ for (var i=0; i < lines.length; i++) {
136
+ lines[i] = lines[i].replace(regex, function(match, operator, name) {
137
+ switch(operator) {
138
+ case "!": // ignore comments
139
+ return match;
140
+ case "=": // set new delimiters, rebuild the replace regexp
141
+ that.set_delimiters(name);
142
+ regex = new_regex();
143
+ return "";
144
+ case ">": // render partial
145
+ return that.render_partial(name, context, partials);
146
+ case "{": // the triple mustache is unescaped
147
+ return that.find(name, context);
148
+ default: // escape the value
149
+ return that.escape(that.find(name, context));
150
+ }
151
+ }, this);
152
+ if(!in_recursion) {
153
+ this.send(lines[i]);
154
+ }
155
+ }
156
+ return lines.join("\n");
157
+ },
158
+
159
+ set_delimiters: function(delimiters) {
160
+ var dels = delimiters.split(" ");
161
+ this.otag = this.escape_regex(dels[0]);
162
+ this.ctag = this.escape_regex(dels[1]);
163
+ },
164
+
165
+ escape_regex: function(text) {
166
+ // thank you Simon Willison
167
+ if(!arguments.callee.sRE) {
168
+ var specials = [
169
+ '/', '.', '*', '+', '?', '|',
170
+ '(', ')', '[', ']', '{', '}', '\\'
171
+ ];
172
+ arguments.callee.sRE = new RegExp(
173
+ '(\\' + specials.join('|\\') + ')', 'g'
174
+ );
175
+ }
176
+ return text.replace(arguments.callee.sRE, '\\$1');
177
+ },
178
+
179
+ /*
180
+ find `name` in current `context`. That is find me a value
181
+ from the view object
182
+ */
183
+ find: function(name, context) {
184
+ name = this.trim(name);
185
+ if(typeof context[name] === "function") {
186
+ return context[name].apply(context);
187
+ }
188
+ if(context[name] !== undefined) {
189
+ return context[name];
190
+ }
191
+ // silently ignore unkown variables
192
+ return "";
193
+ },
194
+
195
+ // Utility methods
196
+
197
+ /*
198
+ Does away with nasty characters
199
+ */
200
+ escape: function(s) {
201
+ return s.toString().replace(/[&"<>\\]/g, function(s) {
202
+ switch(s) {
203
+ case "&": return "&amp;";
204
+ case "\\": return "\\\\";;
205
+ case '"': return '\"';;
206
+ case "<": return "&lt;";
207
+ case ">": return "&gt;";
208
+ default: return s;
209
+ }
210
+ });
211
+ },
212
+
213
+ /*
214
+ Merges all properties of object `b` into object `a`.
215
+ `b.property` overwrites a.property`
216
+ */
217
+ merge: function(a, b) {
218
+ var _new = {};
219
+ for(var name in a) {
220
+ if(a.hasOwnProperty(name)) {
221
+ _new[name] = a[name];
222
+ }
223
+ };
224
+ for(var name in b) {
225
+ if(b.hasOwnProperty(name)) {
226
+ _new[name] = b[name];
227
+ }
228
+ };
229
+ return _new;
230
+ },
231
+
232
+ // by @langalex, support for arrays of strings
233
+ create_context: function(_context) {
234
+ if(this.is_object(_context)) {
235
+ return _context;
236
+ } else if(this.pragmas["IMPLICIT-ITERATOR"]) {
237
+ var iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator || ".";
238
+ var ctx = {};
239
+ ctx[iterator] = _context
240
+ return ctx;
241
+ }
242
+ },
243
+
244
+ is_object: function(a) {
245
+ return a && typeof a == "object"
246
+ },
247
+
248
+ /*
249
+ Thanks Doug Crockford
250
+ JavaScript — The Good Parts lists an alternative that works better with
251
+ frames. Frames can suck it, we use the simple version.
252
+ */
253
+ is_array: function(a) {
254
+ return (a &&
255
+ typeof a === "object" &&
256
+ a.constructor === Array);
257
+ },
258
+
259
+ /*
260
+ Gets rid of leading and trailing whitespace
261
+ */
262
+ trim: function(s) {
263
+ return s.replace(/^\s*|\s*$/g, "");
264
+ },
265
+
266
+ /*
267
+ Why, why, why? Because IE. Cry, cry cry.
268
+ */
269
+ map: function(array, fn) {
270
+ if (typeof array.map == "function") {
271
+ return array.map(fn)
272
+ } else {
273
+ var r = [];
274
+ var l = array.length;
275
+ for(i=0;i<l;i++) {
276
+ r.push(fn(array[i]));
277
+ }
278
+ return r;
279
+ }
280
+ }
281
+ };
282
+
283
+ return({
284
+ name: "mustache.js",
285
+ version: "0.2.2",
286
+
287
+ /*
288
+ Turns a template and view into HTML
289
+ */
290
+ to_html: function(template, view, partials, send_fun) {
291
+ var renderer = new Renderer();
292
+ if(send_fun) {
293
+ renderer.send = send_fun;
294
+ }
295
+ renderer.render(template, view, partials);
296
+ return renderer.buffer.join("\n");
297
+ }
298
+ });
299
+ }();
300
+
301
+ } // Ensure Mustache
302
+
303
+ Sammy = Sammy || {};
304
+
305
+ // <tt>Sammy.Mustache</tt> provides a quick way of using mustache style templates in your app.
306
+ // The plugin itself includes the awesome mustache.js lib created and maintained by Jan Lehnardt
307
+ // at http://github.com/janl/mustache.js
308
+ //
309
+ // Mustache is a clever templating system that relys on double brackets {{}} for interpolation.
310
+ // For full details on syntax check out the original Ruby implementation created by Chris Wanstrath at
311
+ // http://github.com/defunkt/mustache
312
+ //
313
+ // By default using Sammy.Mustache in your app adds the <tt>mustache()</tt> method to the EventContext
314
+ // prototype. However, just like <tt>Sammy.Template</tt> you can change the default name of the method
315
+ // by passing a second argument (e.g. you could use the ms() as the method alias so that all the template
316
+ // files could be in the form file.ms instead of file.mustache)
317
+ //
318
+ // ### Example #1
319
+ //
320
+ // The template (mytemplate.ms):
321
+ //
322
+ // <h1>\{\{title\}\}<h1>
323
+ //
324
+ // Hey, {{name}}! Welcome to Mustache!
325
+ //
326
+ // The app:
327
+ //
328
+ // var $.app = $.sammy(function() {
329
+ // // include the plugin and alias mustache() to ms()
330
+ // this.use(Sammy.Mustache, 'ms');
331
+ //
332
+ // this.get('#/hello/:name', function() {
333
+ // // set local vars
334
+ // this.title = 'Hello!'
335
+ // this.name = this.params.name;
336
+ // // render the template and pass it through mustache
337
+ // this.partial('mytemplate.ms');
338
+ // });
339
+ //
340
+ // });
341
+ //
342
+ // If I go to #/hello/AQ in the browser, Sammy will render this to the <tt>body</tt>:
343
+ //
344
+ // <h1>Hello!</h1>
345
+ //
346
+ // Hey, AQ! Welcome to Mustache!
347
+ //
348
+ //
349
+ // ### Example #2 - Mustache partials
350
+ //
351
+ // The template (mytemplate.ms)
352
+ //
353
+ // Hey, {{name}}! {{>hello_friend}}
354
+ //
355
+ //
356
+ // The partial (mypartial.ms)
357
+ //
358
+ // Say hello to your friend {{friend}}!
359
+ //
360
+ // The app:
361
+ //
362
+ // var $.app = $.sammy(function() {
363
+ // // include the plugin and alias mustache() to ms()
364
+ // this.use(Sammy.Mustache, 'ms');
365
+ //
366
+ // this.get('#/hello/:name/to/:friend', function() {
367
+ // var context = this;
368
+ //
369
+ // // fetch mustache-partial first
370
+ // $.get('mypartial.ms', function(response){
371
+ // context.partials = response;
372
+ //
373
+ // // set local vars
374
+ // context.name = this.params.name;
375
+ // context.hello_friend = {name: this.params.friend};
376
+ //
377
+ // // render the template and pass it through mustache
378
+ // context.partial('mytemplate.ms');
379
+ // });
380
+ // });
381
+ //
382
+ // });
383
+ //
384
+ // If I go to #/hello/AQ/to/dP in the browser, Sammy will render this to the <tt>body</tt>:
385
+ //
386
+ // Hey, AQ! Say hello to your friend dP!
387
+ //
388
+ // Note: You dont have to include the mustache.js file on top of the plugin as the plugin
389
+ // includes the full source.
390
+ //
391
+ Sammy.Mustache = function(app, method_alias) {
392
+
393
+ // *Helper* Uses Mustache.js to parse a template and interpolate and work with the passed data
394
+ //
395
+ // ### Arguments
396
+ //
397
+ // * `template` A String template. {{}} Tags are evaluated and interpolated by Mustache.js
398
+ // * `data` An Object containing the replacement values for the template.
399
+ // data is extended with the <tt>EventContext</tt> allowing you to call its methods within the template.
400
+ // * `partials` An Object containing one or more partials (String templates
401
+ // that are called from the main template).
402
+ //
403
+ var mustache = function(template, data, partials) {
404
+ data = $.extend({}, this, data);
405
+ partials = $.extend({}, data.partials, partials);
406
+ return Mustache.to_html(template, data, partials);
407
+ };
408
+
409
+ // set the default method name/extension
410
+ if (!method_alias) method_alias = 'mustache';
411
+ app.helper(method_alias, mustache);
412
+
413
+ };
414
+
415
+ })(jQuery);
@@ -0,0 +1 @@
1
+ <h1>{{name}}</h1>
metadata ADDED
@@ -0,0 +1,205 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: soca
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Aaron Quint
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-09-26 00:00:00 +02:00
19
+ default_executable: soca
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: json
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 11
30
+ segments:
31
+ - 1
32
+ - 4
33
+ - 6
34
+ version: 1.4.6
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: typhoeus
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 37
46
+ segments:
47
+ - 0
48
+ - 1
49
+ - 31
50
+ version: 0.1.31
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: jim
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ hash: 17
62
+ segments:
63
+ - 0
64
+ - 2
65
+ - 3
66
+ version: 0.2.3
67
+ type: :runtime
68
+ version_requirements: *id003
69
+ - !ruby/object:Gem::Dependency
70
+ name: compass
71
+ prerelease: false
72
+ requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ hash: 61
78
+ segments:
79
+ - 0
80
+ - 10
81
+ - 5
82
+ version: 0.10.5
83
+ type: :runtime
84
+ version_requirements: *id004
85
+ - !ruby/object:Gem::Dependency
86
+ name: shoulda
87
+ prerelease: false
88
+ requirement: &id005 !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ hash: 3
94
+ segments:
95
+ - 0
96
+ version: "0"
97
+ type: :development
98
+ version_requirements: *id005
99
+ - !ruby/object:Gem::Dependency
100
+ name: yard
101
+ prerelease: false
102
+ requirement: &id006 !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ hash: 3
108
+ segments:
109
+ - 0
110
+ version: "0"
111
+ type: :development
112
+ version_requirements: *id006
113
+ description: soca is a different way of writing apps for CouchDB. The structure is up to you.
114
+ email: aaron@quirkey.com
115
+ executables:
116
+ - soca
117
+ extensions: []
118
+
119
+ extra_rdoc_files:
120
+ - LICENSE
121
+ - README.md
122
+ files:
123
+ - .document
124
+ - .gitignore
125
+ - HISTORY
126
+ - LICENSE
127
+ - README.md
128
+ - Rakefile
129
+ - bin/soca
130
+ - lib/soca.rb
131
+ - lib/soca/cli.rb
132
+ - lib/soca/plugin.rb
133
+ - lib/soca/plugins/compass.rb
134
+ - lib/soca/plugins/jim.rb
135
+ - lib/soca/pusher.rb
136
+ - lib/soca/templates/Jimfile
137
+ - lib/soca/templates/config.js.erb
138
+ - lib/soca/templates/couchapprc.erb
139
+ - lib/soca/templates/css/screen.css
140
+ - lib/soca/templates/db/views/by_type/map.js
141
+ - lib/soca/templates/hooks/before_build.rb
142
+ - lib/soca/templates/index.html.erb
143
+ - lib/soca/templates/js/app.js
144
+ - lib/soca/templates/js/vendor/jquery-1.4.2.js
145
+ - lib/soca/templates/js/vendor/jquery.couch-0.11.js
146
+ - lib/soca/templates/js/vendor/sammy-0.6.1.js
147
+ - lib/soca/templates/js/vendor/sammy.couch-0.1.0.js
148
+ - lib/soca/templates/js/vendor/sha1.js
149
+ - soca.gemspec
150
+ - test/helper.rb
151
+ - test/test_soca_cli.rb
152
+ - test/test_soca_pusher.rb
153
+ - test/testapp/.couchapprc
154
+ - test/testapp/Jimfile
155
+ - test/testapp/config.js
156
+ - test/testapp/css/app.css
157
+ - test/testapp/db/views/recent/map.js
158
+ - test/testapp/hooks/before_build.rb
159
+ - test/testapp/index.html
160
+ - test/testapp/js/app.js
161
+ - test/testapp/js/bundled.js
162
+ - test/testapp/js/vendor/jquery-1.4.2.js
163
+ - test/testapp/js/vendor/json2.js
164
+ - test/testapp/js/vendor/sammy-0.5.4.js
165
+ - test/testapp/js/vendor/sammy.mustache-0.5.4.js
166
+ - test/testapp/templates/index.mustache
167
+ has_rdoc: true
168
+ homepage: http://github.com/quirkey/soca
169
+ licenses: []
170
+
171
+ post_install_message:
172
+ rdoc_options:
173
+ - --charset=UTF-8
174
+ require_paths:
175
+ - lib
176
+ required_ruby_version: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ hash: 3
182
+ segments:
183
+ - 0
184
+ version: "0"
185
+ required_rubygems_version: !ruby/object:Gem::Requirement
186
+ none: false
187
+ requirements:
188
+ - - ">="
189
+ - !ruby/object:Gem::Version
190
+ hash: 3
191
+ segments:
192
+ - 0
193
+ version: "0"
194
+ requirements: []
195
+
196
+ rubyforge_project:
197
+ rubygems_version: 1.3.7
198
+ signing_key:
199
+ specification_version: 3
200
+ summary: Sammy on CouchApp
201
+ test_files:
202
+ - test/helper.rb
203
+ - test/test_soca_cli.rb
204
+ - test/test_soca_pusher.rb
205
+ - test/testapp/hooks/before_build.rb