jim 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/HISTORY +28 -0
  2. data/README.rdoc +1 -1
  3. data/Rakefile +2 -1
  4. data/jim.gemspec +67 -9
  5. data/lib/jim/bundler.rb +14 -11
  6. data/lib/jim/cli.rb +51 -9
  7. data/lib/jim/index.rb +3 -7
  8. data/lib/jim/installer.rb +140 -22
  9. data/lib/jim/templates/commands +21 -6
  10. data/lib/jim/version_parser.rb +2 -3
  11. data/lib/jim.rb +19 -2
  12. data/test/fixtures/jimfile +3 -3
  13. data/test/fixtures/sammy-0.5.0/HISTORY.md +135 -0
  14. data/test/fixtures/sammy-0.5.0/LICENSE +22 -0
  15. data/test/fixtures/sammy-0.5.0/README.md +81 -0
  16. data/test/fixtures/sammy-0.5.0/Rakefile +174 -0
  17. data/test/fixtures/sammy-0.5.0/examples/backend/README.md +23 -0
  18. data/test/fixtures/sammy-0.5.0/examples/backend/Rakefile +15 -0
  19. data/test/fixtures/sammy-0.5.0/examples/backend/app.rb +17 -0
  20. data/test/fixtures/sammy-0.5.0/examples/backend/app.ru +3 -0
  21. data/test/fixtures/sammy-0.5.0/examples/backend/public/javascripts/app.js +106 -0
  22. data/test/fixtures/sammy-0.5.0/examples/backend/public/javascripts/jquery.cloudkit.js +840 -0
  23. data/test/fixtures/sammy-0.5.0/examples/backend/public/javascripts/jquery.js +19 -0
  24. data/test/fixtures/sammy-0.5.0/examples/backend/public/javascripts/sammy.js +1013 -0
  25. data/test/fixtures/sammy-0.5.0/examples/backend/public/templates/index.html.erb +11 -0
  26. data/test/fixtures/sammy-0.5.0/examples/backend/public/templates/task.html.erb +4 -0
  27. data/test/fixtures/sammy-0.5.0/examples/backend/public/templates/task_details.html.erb +4 -0
  28. data/test/fixtures/sammy-0.5.0/examples/backend/views/app.sass +63 -0
  29. data/test/fixtures/sammy-0.5.0/examples/backend/views/index.haml +18 -0
  30. data/test/fixtures/sammy-0.5.0/examples/form_handling/files/form.html +12 -0
  31. data/test/fixtures/sammy-0.5.0/examples/form_handling/index.html +65 -0
  32. data/test/fixtures/sammy-0.5.0/examples/hello_world/index.html +50 -0
  33. data/test/fixtures/sammy-0.5.0/examples/location_override/README.md +15 -0
  34. data/test/fixtures/sammy-0.5.0/examples/location_override/data.html +110 -0
  35. data/test/fixtures/sammy-0.5.0/examples/location_override/index.html +79 -0
  36. data/test/fixtures/sammy-0.5.0/examples/location_override/test.html +121 -0
  37. data/test/fixtures/sammy-0.5.0/lib/min/sammy-0.5.0.min.js +5 -0
  38. data/test/fixtures/sammy-0.5.0/lib/min/sammy-lastest.min.js +5 -0
  39. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.cache.js +117 -0
  40. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.haml.js +539 -0
  41. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.json.js +362 -0
  42. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.mustache.js +415 -0
  43. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.nested_params.js +118 -0
  44. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.storage.js +515 -0
  45. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.template.js +117 -0
  46. data/test/fixtures/sammy-0.5.0/lib/sammy.js +1367 -0
  47. data/test/fixtures/sammy-0.5.0/test/fixtures/partial +1 -0
  48. data/test/fixtures/sammy-0.5.0/test/fixtures/partial.html +1 -0
  49. data/test/fixtures/sammy-0.5.0/test/fixtures/partial.noengine +1 -0
  50. data/test/fixtures/sammy-0.5.0/test/fixtures/partial.template +1 -0
  51. data/test/fixtures/sammy-0.5.0/test/index.html +84 -0
  52. data/test/fixtures/sammy-0.5.0/test/test_sammy_application.js +953 -0
  53. data/test/fixtures/sammy-0.5.0/test/test_sammy_event_context.js +252 -0
  54. data/test/fixtures/sammy-0.5.0/test/test_sammy_location_proxy.js +91 -0
  55. data/test/fixtures/sammy-0.5.0/test/test_sammy_plugins.js +296 -0
  56. data/test/fixtures/sammy-0.5.0/test/test_sammy_storage.js +175 -0
  57. data/test/fixtures/sammy-0.5.0/test/test_server +27 -0
  58. data/test/fixtures/sammy-0.5.0/vendor/jquery-1.4.1.js +6078 -0
  59. data/test/fixtures/sammy-0.5.0/vendor/jquery-1.4.1.min.js +152 -0
  60. data/test/fixtures/sammy-0.5.0/vendor/jsdoc/doc.haml +58 -0
  61. data/test/fixtures/sammy-0.5.0/vendor/jsdoc/jsdoc.rb +143 -0
  62. data/test/fixtures/sammy-0.5.0/vendor/jslitmus.js +670 -0
  63. data/test/fixtures/sammy-0.5.0/vendor/qunit/qunit.css +119 -0
  64. data/test/fixtures/sammy-0.5.0/vendor/qunit/qunit.js +1043 -0
  65. data/test/fixtures/sammy-0.5.0/vendor/qunit-spec.js +127 -0
  66. data/test/helper.rb +23 -3
  67. data/test/test_jim_bundler.rb +9 -8
  68. data/test/test_jim_cli.rb +21 -12
  69. data/test/test_jim_installer.rb +152 -35
  70. data/test/test_jim_version_parser.rb +4 -0
  71. metadata +117 -27
  72. data/.document +0 -5
@@ -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,118 @@
1
+ (function($) {
2
+
3
+ Sammy = Sammy || {};
4
+
5
+ function parseNestedParam(field_value, field_name, params) {
6
+ var match, name, rest;
7
+
8
+ if (field_name.match(/^[^\[]+$/)) {
9
+ // basic value
10
+ params[field_name] = unescape(field_value);
11
+ } else if (match = field_name.match(/^([^\[]+)\[\](.*)$/)) {
12
+ // array
13
+ name = match[1];
14
+ rest = match[2];
15
+
16
+ if(params[name] && !$.isArray(params[name])) { throw('400 Bad Request'); }
17
+
18
+ if (rest) {
19
+ // array is not at the end of the parameter string
20
+ match = rest.match(/^\[([^\]]+)\](.*)$/);
21
+ if(!match) { throw('400 Bad Request'); }
22
+
23
+ if (params[name]) {
24
+ if(params[name][params[name].length - 1][match[1]]) {
25
+ params[name].push(parseNestedParam(field_value, match[1] + match[2], {}));
26
+ } else {
27
+ $.extend(true, params[name][params[name].length - 1], parseNestedParam(field_value, match[1] + match[2], {}));
28
+ }
29
+ } else {
30
+ params[name] = [parseNestedParam(field_value, match[1] + match[2], {})];
31
+ }
32
+ } else {
33
+ // array is at the end of the parameter string
34
+ if (params[name]) {
35
+ params[name].push(unescape(field_value));
36
+ } else {
37
+ params[name] = [unescape(field_value)];
38
+ }
39
+ }
40
+ } else if (match = field_name.match(/^([^\[]+)\[([^\[]+)\](.*)$/)) {
41
+ // hash
42
+ name = match[1];
43
+ rest = match[2] + match[3];
44
+
45
+ if (params[name] && $.isArray(params[name])) { throw('400 Bad Request'); }
46
+
47
+ if (params[name]) {
48
+ $.extend(true, params[name], parseNestedParam(field_value, rest, params[name]));
49
+ } else {
50
+ params[name] = parseNestedParam(field_value, rest, {});
51
+ }
52
+ }
53
+ return params;
54
+ };
55
+
56
+
57
+ // <tt>Sammy.NestedParams</tt> overrides the default form parsing behavior to provide
58
+ // extended functionality for parsing Rack/Rails style form name/value pairs into JS
59
+ // Objects. In fact it passes the same suite of tests as Rack's nested query parsing.
60
+ // The code and tests were ported to JavaScript/Sammy by http://github.com/endor
61
+ //
62
+ // This allows you to translate a form with properly named inputs into a JSON object.
63
+ //
64
+ // === Example
65
+ //
66
+ // Given an HTML form like so:
67
+ //
68
+ // <form action="#/parse_me" method="post">
69
+ // <input type="text" name="obj[first]" />
70
+ // <input type="text" name="obj[second]" />
71
+ // <input type="text" name="obj[hash][first]" />
72
+ // <input type="text" name="obj[hash][second]" />
73
+ // </form>
74
+ //
75
+ // And a Sammy app like:
76
+ //
77
+ // var app = $.sammy(function(app) {
78
+ // this.use(Sammy.NestedParams);
79
+ //
80
+ // this.post('#/parse_me', function(context) {
81
+ // $.log(this.params);
82
+ // });
83
+ // });
84
+ //
85
+ // If you filled out the form with some values and submitted it, you would see something
86
+ // like this in your log:
87
+ //
88
+ // {
89
+ // 'obj': {
90
+ // 'first': 'value',
91
+ // 'second': 'value',
92
+ // 'hash': {
93
+ // 'first': 'value',
94
+ // 'second': 'value'
95
+ // }
96
+ // }
97
+ // '$form': .. jQuery ..
98
+ // }
99
+ //
100
+ // It supports creating arrays with [] and other niceities. Check out the tests for
101
+ // full specs.
102
+ //
103
+ Sammy.NestedParams = function(app) {
104
+
105
+ $.extend(app, {
106
+ _parseFormParams: function($form) {
107
+ var params = {};
108
+ $.each($form.serializeArray(), function(i, field) {
109
+ $.extend(true, params, parseNestedParam(field.value, field.name, params));
110
+ });
111
+
112
+ return params;
113
+ }
114
+ });
115
+
116
+ };
117
+
118
+ })(jQuery);