slinky 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -3,9 +3,11 @@
3
3
  Slinky helps you write rich web applications using compiled web
4
4
  languages like SASS, HAML and CoffeeScript. The slinky server
5
5
  transparently compiles resources as they're requested, leaving you to
6
- worry about your code, not how to compile it.
6
+ worry about your code, not how to compile it. It will even proxy
7
+ AJAX requests to a backend server so you can easily develop against
8
+ REST APIs.
7
9
 
8
- Once your ready for production, the slinky builder will compile all of
10
+ Once you're ready for production the slinky builder will compile all of
9
11
  your sources and concatenate and minify your javascript and css,
10
12
  leaving you a directory that's ready to be pushed to your servers.
11
13
 
@@ -80,8 +82,65 @@ a
80
82
  color: red
81
83
  ```
82
84
 
83
- ### And coming up next...
85
+ ### Configuration
84
86
 
85
- * Support for more languages
86
- * Built in proxy-server to allow connections to web services
87
- * More control over behavior
87
+ Slinky can optionally be configured using a yaml file. By default, it
88
+ looks for a file called `slinky.yaml` in the source directory, but you
89
+ can also supply a file name on the command line using `-c`.
90
+
91
+ There are currently two directives supported:
92
+
93
+ #### Proxies
94
+
95
+ Slinky has a built-in proxy server which lets you test ajax requests
96
+ with your actual backend servers. To set it up, your slinky.yaml file
97
+ will look something like this:
98
+
99
+ ```yaml
100
+ proxy:
101
+ "/login": "http://127.0.0.1:4567/login"
102
+ "/search":
103
+ to: "http://127.0.0.1:4567/search"
104
+ lag: 2000
105
+ ```
106
+
107
+ What does this mean? We introduce the list of proxy rules using the
108
+ `proxy` key. Each rule is a key value pair. The key is a url prefix to
109
+ match against. The first rule is equivalent to the regular expression
110
+ `/\/login.*/`, and will match paths like `/login/user` and
111
+ `/login/path/to/file.html`. The value is either a url to pass the
112
+ request on to or a hash containing configuration (one of which must be
113
+ a `to` field). Currently a `lag` field is also supported. This delays
114
+ the request by the specified number of milliseconds in order to
115
+ simulate the latency associated with remote servers.
116
+
117
+ An example: we have some javascript code which makes an AJAX GET
118
+ request to `/search/widgets?q=foo`. When slinky gets the request it
119
+ will see that it has a matching proxy rule, rewrite the request
120
+ appropriately (changing paths and hosts) and send it on to the backend
121
+ server (in this case, 127.0.0.1:4567). Once it gets a response it will
122
+ wait until 2 seconds has elapsed since slinky itself received the
123
+ request and then send on the response back to the browser.
124
+
125
+ This is very convenient for developing rich web clients locally. For
126
+ example, you may have some code that shows a loading indicator while
127
+ an AJAX request is outstanding. However, when run locally the request
128
+ returns so quickly that you can't even see the loading indicator. By
129
+ adding in a lag this problem is remedied.
130
+
131
+ #### Ignores
132
+
133
+ By default slinky will include every javascript and css file it finds
134
+ into the combined scripts.js and styles.css files. However, it may be
135
+ that for some reason you want to keep some files separate and handle
136
+ them manually. The ignore directive lets you do that, by telling the
137
+ system to skip over any files or directories listed. For example:
138
+
139
+ ```yaml
140
+ ignore:
141
+ - script/vendor
142
+ - css/reset.css
143
+ ```
144
+
145
+ This will causes everything in the script/vendor directory to be
146
+ ignored by slinky, as well as the reset.css file.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.2
1
+ 0.5.0
@@ -8,7 +8,6 @@ module Slinky
8
8
  # Creates a new CompiledFile, compiling the provided source file
9
9
  # with the provided compiler class.
10
10
  def initialize source, compiler, output_ext
11
- super source
12
11
  @source = source
13
12
  @compiler = compiler
14
13
  @last_compiled = Time.new(0)
@@ -13,10 +13,10 @@ module Slinky
13
13
  end
14
14
 
15
15
  def proxies
16
- @config["proxies"]
16
+ @config["proxy"] || {}
17
17
  end
18
18
 
19
- def ignore
19
+ def ignores
20
20
  @config["ignore"] || []
21
21
  end
22
22
  end
@@ -44,7 +44,7 @@ module Slinky
44
44
  if include_ignores
45
45
  @files
46
46
  else
47
- @files.reject{|f| @config.ignore.any?{|p| f.in_tree? p}}
47
+ @files.reject{|f| @config.ignores.any?{|p| f.in_tree? p}}
48
48
  end
49
49
  end
50
50
 
@@ -64,7 +64,7 @@ module Slinky
64
64
  %Q\<script type="text/javascript" src="#{d.relative_output_path}"></script>\
65
65
  }.join("")
66
66
  else
67
- '<script type="text/javascript" src="/scripts.js"></script>'
67
+ %Q\<script type="text/javascript" src="/scripts.js?#{rand(999999999)}"></script>\
68
68
  end
69
69
  end
70
70
 
@@ -104,7 +104,7 @@ module Slinky
104
104
  %Q\<link rel="stylesheet" href="#{d.relative_output_path}" />\
105
105
  }.join("")
106
106
  else
107
- '<link rel="stylesheet" href="/styles.css" />'
107
+ %Q\<link rel="stylesheet" href="/styles.css?#{rand(999999999)}" />\
108
108
  end
109
109
  end
110
110
 
@@ -4,9 +4,10 @@ module Slinky
4
4
  HOST_MATCHER = /Host: (.+)/
5
5
 
6
6
  def self.process_proxies proxy_hash
7
- proxy_hash.map{|from, to|
7
+ proxy_hash.map{|from, h|
8
8
  begin
9
- [from, URI::parse(to)]
9
+ to, opt = h.is_a?(Hash) ? [h.delete("to"), h] : [h, {}]
10
+ a = [from, URI::parse(to), opt]
10
11
  rescue
11
12
  $stderr.puts "Invalid proxy setting: #{from} => #{to}".foreground(:red)
12
13
  end
@@ -14,13 +15,17 @@ module Slinky
14
15
  end
15
16
 
16
17
  def self.process_proxy_servers proxies
17
- proxies_servers = proxies.map{|p| [p[1].host, p[1].port]}
18
+ proxies.map{|p| [p[1].host, p[1].port]}
18
19
  end
19
20
 
20
21
  def self.find_matcher proxies, path
21
22
  proxies.find{|p| path.start_with?(p[0])}
22
23
  end
23
24
 
25
+ def self.rewrite_path path, proxy
26
+ path.gsub(/^#{proxy[0]}/, "")
27
+ end
28
+
24
29
  def self.replace_path http, old_path, new_path, addition
25
30
  # TODO: This may fail in certain, rare cases
26
31
  addition = addition[0..-2] if addition[-1] == "/"
@@ -36,6 +41,8 @@ module Slinky
36
41
  proxy_servers = process_proxy_servers proxies
37
42
 
38
43
  Proxy.start(:host => "0.0.0.0", :port => port){|conn|
44
+ proxy = nil
45
+ start_time = nil
39
46
  conn.server :slinky, :host => "127.0.0.1", :port => slinky_port
40
47
  proxy_servers.each{|p|
41
48
  conn.server p, :host => p[0], :port => p[1]
@@ -45,8 +52,9 @@ module Slinky
45
52
  begin
46
53
  _, path = data.match(ProxyServer::HTTP_MATCHER)[1..2]
47
54
  proxy = ProxyServer.find_matcher(proxies, path)
55
+ start_time = Time.now
48
56
  server = if proxy
49
- new_path = path.gsub(/^#{proxy[0]}/, "")
57
+ new_path = ProxyServer.rewrite_path path, proxy
50
58
  data = ProxyServer.replace_path(data, path, new_path, proxy[1].path)
51
59
  new_host = proxy[1].select(:host, :port).join(":")
52
60
  data = ProxyServer.replace_host(data, new_host)
@@ -62,7 +70,18 @@ module Slinky
62
70
  end
63
71
 
64
72
  conn.on_response do |server, resp|
65
- resp
73
+ opt = proxy && proxy[2]
74
+ if opt && opt["lag"]
75
+ # we want to get as close as possible to opt["lag"], so we
76
+ # take into account the lag from the backend server
77
+ so_far = Time.now - start_time
78
+ time = opt["lag"]/1000.0-so_far
79
+ EM.add_timer (time > 0 ? time : 0) do
80
+ conn.send_data resp
81
+ end
82
+ else
83
+ resp
84
+ end
66
85
  end
67
86
 
68
87
  conn.on_finish do |name|
data/lib/slinky/runner.rb CHANGED
@@ -14,7 +14,7 @@ module Slinky
14
14
  @command = @argv.shift
15
15
  @arguments = @argv
16
16
 
17
- config_path = "#{@options[:src_dir]}/slinky.yaml"
17
+ config_path = @options[:config] || "#{@options[:src_dir]}/slinky.yaml"
18
18
  @config = if File.exist?(config_path)
19
19
  ConfigReader.from_file(config_path)
20
20
  else
@@ -38,6 +38,7 @@ module Slinky
38
38
  opts.on("-p PORT", "--port PORT", "Port to run on (default: #{@options[:port]})"){|p| @options[:port] = p.to_i}
39
39
  opts.on("-s DIR", "--src-dir DIR", "Directory containing project source"){|p| @options[:src_dir] = p}
40
40
  opts.on("-n", "--no-proxy", "Don't set up proxy server"){ @options[:no_proxy] = true }
41
+ opts.on("-c FILE", "--config FILE", "Path to configuration file"){|f| @options[:config] = f}
41
42
  end
42
43
  end
43
44
 
@@ -58,8 +59,8 @@ module Slinky
58
59
  EM::run {
59
60
  Slinky::Server.dir = @options[:src_dir]
60
61
  Slinky::Server.config = @config
61
- if @config && @config.proxies && !@options[:no_proxy]
62
- server = EM::start_server "127.0.0.1", 5324, Slinky::Server
62
+ if @config && !@config.proxies.empty? && !@options[:no_proxy]
63
+ server = EM::start_server "127.0.0.1", @options[:port]+1, Slinky::Server
63
64
  ProxyServer.run(@config.proxies, @options[:port], 5324)
64
65
  else
65
66
  EM::start_server "0.0.0.0", @options[:port], Slinky::Server
data/lib/slinky.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  ROOT = File.expand_path(File.dirname(__FILE__))
2
- require "bundler/setup"
3
2
  require 'uri'
4
3
  require 'yaml'
5
4
  require 'eventmachine'
data/slinky.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{slinky}
8
- s.version = "0.4.2"
8
+ s.version = "0.5.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = [%q{mwylde}]
12
- s.date = %q{2011-09-15}
12
+ s.date = %q{2011-10-25}
13
13
  s.description = %q{A static file server for rich javascript apps that automatically compiles SASS, HAML, CoffeeScript and more}
14
14
  s.email = %q{mwylde@wesleyan.edu}
15
15
  s.executables = [%q{slinky}]
data/spec/slinky_spec.rb CHANGED
@@ -48,7 +48,8 @@ describe "Slinky" do
48
48
  end
49
49
 
50
50
  it "should produce the correct scripts string for production" do
51
- @mprod.scripts_string.should == '<script type="text/javascript" src="/scripts.js"></script>'
51
+ @mprod.scripts_string.should match \
52
+ %r!<script type="text/javascript" src="/scripts.js\?\d+"></script>!
52
53
  end
53
54
 
54
55
  it "should produce the correct scripts string for devel" do
@@ -56,7 +57,8 @@ describe "Slinky" do
56
57
  end
57
58
 
58
59
  it "should produce the correct styles string for production" do
59
- @mprod.styles_string.should == '<link rel="stylesheet" href="/styles.css" />'
60
+ @mprod.styles_string.should match \
61
+ %r!<link rel="stylesheet" href="/styles.css\?\d+" />!
60
62
  end
61
63
 
62
64
  it "should produce the correct styles string for development" do
@@ -272,7 +274,7 @@ describe "Slinky" do
272
274
  end
273
275
 
274
276
  it "should accept a port option" do
275
- port = 53453
277
+ port = 53455
276
278
  $stdout.should_receive(:puts).with(/Started static file server on port #{port}/)
277
279
  run_for 0.3 do
278
280
  Slinky::Runner.new(["start","--port", port.to_s]).run
@@ -314,4 +316,116 @@ describe "Slinky" do
314
316
  File.exists?("/build/l1/l2/test.txt").should == true
315
317
  end
316
318
  end
319
+
320
+ context "ConfigReader" do
321
+ before :each do
322
+ @config = <<eos
323
+ proxy:
324
+ "/test1": "http://127.0.0.1:8000"
325
+ "/test2": "http://127.0.0.1:7000"
326
+ ignore:
327
+ - script/vendor
328
+ - script/jquery.js
329
+ eos
330
+ File.open("/src/slinky.yaml", "w+"){|f| f.write @config}
331
+ @proxies = {
332
+ "/test1" => "http://127.0.0.1:8000",
333
+ "/test2" => "http://127.0.0.1:7000"
334
+ }
335
+ @ignores = ["script/vendor", "script/jquery.js"]
336
+ end
337
+
338
+ it "should be able to read configuration from strings" do
339
+ cr = Slinky::ConfigReader.new(@config)
340
+ cr.proxies.should == @proxies
341
+ cr.ignores.should == @ignores
342
+ end
343
+
344
+ it "should be able to read configuration from files" do
345
+ cr = Slinky::ConfigReader.from_file("/src/slinky.yaml")
346
+ cr.proxies.should == @proxies
347
+ cr.ignores.should == @ignores
348
+ end
349
+
350
+ it "should be able to create the empty config" do
351
+ Slinky::ConfigReader.empty.proxies.should == {}
352
+ Slinky::ConfigReader.empty.ignores.should == []
353
+ end
354
+ end
355
+
356
+ context "ProxyServer" do
357
+ before :each do
358
+ @config = <<eos
359
+ proxy:
360
+ "/test1": "http://127.0.0.1:8000"
361
+ "/test2/": "http://127.0.0.1:7000"
362
+ eos
363
+ @cr = Slinky::ConfigReader.new(@config)
364
+ @proxies = Slinky::ProxyServer.process_proxies(@cr.proxies)
365
+ @data = <<eos
366
+ GET /test1/something/and?q=asdf&c=E9oBiwFqZmoJam9uYXNmdXAyclkLEj0KABoMQ29ja3RhaWxJbXBsIzAFchIaA2Z0cyAAKgkaB3doaXNrZXkkS1IPd2VpZ2h0ZWRBdmFyYWdlWAJMDAsSDENvY2t0YWlsSW1wbCIGNDYtODE3DHIeGg93ZWlnaHRlZEF2YXJhZ2UgACoJIQAAAAAAAAAAggEA4AEAFA HTTP/1.1\r\nHost: 127.0.0.1:8888\nConnection: keep-alive\r\nX-Requested-With: XMLHttpRequest\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.904.0 Safari/535.7\r\nAccept: */*\r\nReferer: http://localhost:5323/\r\nAccept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\nCookie: mp_super_properties=%7B%22all%22%3A%20%7B%22%24initial_referrer%22%3A%20%22http%3A//localhost%3A5323/%22%2C%22%24initial_referring_domain%22%3A%20%22localhost%3A5323%22%7D%2C%22events%22%3A%20%7B%7D%2C%22funnels%22%3A%20%7B%7D%7D\r\n\r\n
367
+ eos
368
+ end
369
+
370
+ it "should properly process proxies" do
371
+ @proxies.map{|x|
372
+ [x[0], x[1].to_s]
373
+ }.should ==
374
+ [["/test1", URI::parse("http://127.0.0.1:8000").to_s],
375
+ ["/test2/", URI::parse("http://127.0.0.1:7000").to_s]]
376
+ end
377
+
378
+ it "should properly process proxy servers" do
379
+ Slinky::ProxyServer.process_proxy_servers(@proxies).should ==
380
+ [["127.0.0.1", 8000], ["127.0.0.1", 7000]]
381
+ end
382
+
383
+ it "should find the correct matcher for a request" do
384
+ p = Slinky::ProxyServer.find_matcher(@proxies, "/test1/this/is/another")
385
+ p[0].should == "/test1"
386
+ p[1].to_s.should == "http://127.0.0.1:8000"
387
+
388
+ p = Slinky::ProxyServer.find_matcher(@proxies, "/test2/whatsgoing.html?something=asdf")
389
+ p[0].should == "/test2/"
390
+ p[1].to_s.should == "http://127.0.0.1:7000"
391
+
392
+ Slinky::ProxyServer.find_matcher(@proxies, "/asdf/test1/asdf").should == nil
393
+ Slinky::ProxyServer.find_matcher(@proxies, "/test2x/asdf").should == nil
394
+ end
395
+
396
+ it "should properly parse out the path from a request" do
397
+ method, path = @data.match(Slinky::ProxyServer::HTTP_MATCHER)[1..2]
398
+ method.should == "GET"
399
+ path.should == "/test1/something/and?q=asdf&c=E9oBiwFqZmoJam9uYXNmdXAyclkLEj0KABoMQ29ja3RhaWxJbXBsIzAFchIaA2Z0cyAAKgkaB3doaXNrZXkkS1IPd2VpZ2h0ZWRBdmFyYWdlWAJMDAsSDENvY2t0YWlsSW1wbCIGNDYtODE3DHIeGg93ZWlnaHRlZEF2YXJhZ2UgACoJIQAAAAAAAAAAggEA4AEAFA"
400
+ Slinky::ProxyServer.find_matcher(@proxies, path)[0].should == "/test1"
401
+ end
402
+
403
+ it "should rewrite and replace paths correctly" do
404
+ path = @data.match(Slinky::ProxyServer::HTTP_MATCHER)[2]
405
+ p2 = Slinky::ProxyServer.rewrite_path(path, @proxies[0])
406
+ p2.should == "/something/and?q=asdf&c=E9oBiwFqZmoJam9uYXNmdXAyclkLEj0KABoMQ29ja3RhaWxJbXBsIzAFchIaA2Z0cyAAKgkaB3doaXNrZXkkS1IPd2VpZ2h0ZWRBdmFyYWdlWAJMDAsSDENvY2t0YWlsSW1wbCIGNDYtODE3DHIeGg93ZWlnaHRlZEF2YXJhZ2UgACoJIQAAAAAAAAAAggEA4AEAFA"
407
+
408
+ data = Slinky::ProxyServer.replace_path(@data, path, p2, @proxies[0][1].path)
409
+ data.should == "GET /something/and?q=asdf&c=E9oBiwFqZmoJam9uYXNmdXAyclkLEj0KABoMQ29ja3RhaWxJbXBsIzAFchIaA2Z0cyAAKgkaB3doaXNrZXkkS1IPd2VpZ2h0ZWRBdmFyYWdlWAJMDAsSDENvY2t0YWlsSW1wbCIGNDYtODE3DHIeGg93ZWlnaHRlZEF2YXJhZ2UgACoJIQAAAAAAAAAAggEA4AEAFA HTTP/1.1\r\nHost: 127.0.0.1:8888\nConnection: keep-alive\r\nX-Requested-With: XMLHttpRequest\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.904.0 Safari/535.7\r\nAccept: */*\r\nReferer: http://localhost:5323/\r\nAccept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\nCookie: mp_super_properties=%7B%22all%22%3A%20%7B%22%24initial_referrer%22%3A%20%22http%3A//localhost%3A5323/%22%2C%22%24initial_referring_domain%22%3A%20%22localhost%3A5323%22%7D%2C%22events%22%3A%20%7B%7D%2C%22funnels%22%3A%20%7B%7D%7D\r\n\r\n\n"
410
+
411
+ data = Slinky::ProxyServer.replace_host(data,
412
+ @proxies[0][1].select(:host, :port).join(":"))
413
+ data.should == "GET /something/and?q=asdf&c=E9oBiwFqZmoJam9uYXNmdXAyclkLEj0KABoMQ29ja3RhaWxJbXBsIzAFchIaA2Z0cyAAKgkaB3doaXNrZXkkS1IPd2VpZ2h0ZWRBdmFyYWdlWAJMDAsSDENvY2t0YWlsSW1wbCIGNDYtODE3DHIeGg93ZWlnaHRlZEF2YXJhZ2UgACoJIQAAAAAAAAAAggEA4AEAFA HTTP/1.1\r\nHost: 127.0.0.1:8000\nConnection: keep-alive\r\nX-Requested-With: XMLHttpRequest\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.904.0 Safari/535.7\r\nAccept: */*\r\nReferer: http://localhost:5323/\r\nAccept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\nCookie: mp_super_properties=%7B%22all%22%3A%20%7B%22%24initial_referrer%22%3A%20%22http%3A//localhost%3A5323/%22%2C%22%24initial_referring_domain%22%3A%20%22localhost%3A5323%22%7D%2C%22events%22%3A%20%7B%7D%2C%22funnels%22%3A%20%7B%7D%7D\r\n\r\n\n"
414
+ end
415
+
416
+ it "should support proxies with configuration" do
417
+ @config = <<eos
418
+ proxy:
419
+ "/test3":
420
+ to: "http://127.0.0.1:6000"
421
+ lag: 1000
422
+ eos
423
+ @cr = Slinky::ConfigReader.new(@config)
424
+ @proxies = Slinky::ProxyServer.process_proxies(@cr.proxies)
425
+
426
+ @proxies[0][0].should == "/test3"
427
+ @proxies[0][1].to_s.should == "http://127.0.0.1:6000"
428
+ @proxies[0][2].should == {"lag" => 1000}
429
+ end
430
+ end
317
431
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slinky
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-15 00:00:00.000000000Z
12
+ date: 2011-10-25 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
16
- requirement: &70247105720180 !ruby/object:Gem::Requirement
16
+ requirement: &70314013066900 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.12.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70247105720180
24
+ version_requirements: *70314013066900
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: eventmachine_httpserver
27
- requirement: &70247105719700 !ruby/object:Gem::Requirement
27
+ requirement: &70314013061980 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.2.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70247105719700
35
+ version_requirements: *70314013061980
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: em-proxy
38
- requirement: &70247105719220 !ruby/object:Gem::Requirement
38
+ requirement: &70314013050540 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 0.1.5
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70247105719220
46
+ version_requirements: *70314013050540
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rainbow
49
- requirement: &70247105718740 !ruby/object:Gem::Requirement
49
+ requirement: &70314013047220 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.1.1
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70247105718740
57
+ version_requirements: *70314013047220
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: haml
60
- requirement: &70247105718260 !ruby/object:Gem::Requirement
60
+ requirement: &70314013045140 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 3.0.0
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70247105718260
68
+ version_requirements: *70314013045140
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: sass
71
- requirement: &70247105717780 !ruby/object:Gem::Requirement
71
+ requirement: &70314013042780 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 3.1.1
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *70247105717780
79
+ version_requirements: *70314013042780
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: coffee-script
82
- requirement: &70247105717300 !ruby/object:Gem::Requirement
82
+ requirement: &70314013032040 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: 2.2.0
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *70247105717300
90
+ version_requirements: *70314013032040
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: mime-types
93
- requirement: &70247105733180 !ruby/object:Gem::Requirement
93
+ requirement: &70314013029780 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '1.16'
99
99
  type: :runtime
100
100
  prerelease: false
101
- version_requirements: *70247105733180
101
+ version_requirements: *70314013029780
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: yui-compressor
104
- requirement: &70247105732700 !ruby/object:Gem::Requirement
104
+ requirement: &70314013027660 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: 0.9.6
110
110
  type: :runtime
111
111
  prerelease: false
112
- version_requirements: *70247105732700
112
+ version_requirements: *70314013027660
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: rspec
115
- requirement: &70247105732220 !ruby/object:Gem::Requirement
115
+ requirement: &70314013017960 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ~>
@@ -120,10 +120,10 @@ dependencies:
120
120
  version: 2.3.0
121
121
  type: :development
122
122
  prerelease: false
123
- version_requirements: *70247105732220
123
+ version_requirements: *70314013017960
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: yard
126
- requirement: &70247105731740 !ruby/object:Gem::Requirement
126
+ requirement: &70314013016320 !ruby/object:Gem::Requirement
127
127
  none: false
128
128
  requirements:
129
129
  - - ~>
@@ -131,10 +131,10 @@ dependencies:
131
131
  version: 0.6.0
132
132
  type: :development
133
133
  prerelease: false
134
- version_requirements: *70247105731740
134
+ version_requirements: *70314013016320
135
135
  - !ruby/object:Gem::Dependency
136
136
  name: bundler
137
- requirement: &70247105731260 !ruby/object:Gem::Requirement
137
+ requirement: &70314013015020 !ruby/object:Gem::Requirement
138
138
  none: false
139
139
  requirements:
140
140
  - - ~>
@@ -142,10 +142,10 @@ dependencies:
142
142
  version: 1.0.0
143
143
  type: :development
144
144
  prerelease: false
145
- version_requirements: *70247105731260
145
+ version_requirements: *70314013015020
146
146
  - !ruby/object:Gem::Dependency
147
147
  name: jeweler
148
- requirement: &70247105730780 !ruby/object:Gem::Requirement
148
+ requirement: &70314013014020 !ruby/object:Gem::Requirement
149
149
  none: false
150
150
  requirements:
151
151
  - - ~>
@@ -153,10 +153,10 @@ dependencies:
153
153
  version: 1.5.2
154
154
  type: :development
155
155
  prerelease: false
156
- version_requirements: *70247105730780
156
+ version_requirements: *70314013014020
157
157
  - !ruby/object:Gem::Dependency
158
158
  name: cover_me
159
- requirement: &70247105730300 !ruby/object:Gem::Requirement
159
+ requirement: &70314013011880 !ruby/object:Gem::Requirement
160
160
  none: false
161
161
  requirements:
162
162
  - - ! '>='
@@ -164,10 +164,10 @@ dependencies:
164
164
  version: 1.0.0.rc6
165
165
  type: :development
166
166
  prerelease: false
167
- version_requirements: *70247105730300
167
+ version_requirements: *70314013011880
168
168
  - !ruby/object:Gem::Dependency
169
169
  name: fakefs
170
- requirement: &70247105729820 !ruby/object:Gem::Requirement
170
+ requirement: &70314013000920 !ruby/object:Gem::Requirement
171
171
  none: false
172
172
  requirements:
173
173
  - - ! '>='
@@ -175,10 +175,10 @@ dependencies:
175
175
  version: '0'
176
176
  type: :development
177
177
  prerelease: false
178
- version_requirements: *70247105729820
178
+ version_requirements: *70314013000920
179
179
  - !ruby/object:Gem::Dependency
180
180
  name: em-http-request
181
- requirement: &70247105729340 !ruby/object:Gem::Requirement
181
+ requirement: &70314012997080 !ruby/object:Gem::Requirement
182
182
  none: false
183
183
  requirements:
184
184
  - - ! '>='
@@ -186,7 +186,7 @@ dependencies:
186
186
  version: '0'
187
187
  type: :development
188
188
  prerelease: false
189
- version_requirements: *70247105729340
189
+ version_requirements: *70314012997080
190
190
  description: A static file server for rich javascript apps that automatically compiles
191
191
  SASS, HAML, CoffeeScript and more
192
192
  email: mwylde@wesleyan.edu
@@ -237,7 +237,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
237
237
  version: '0'
238
238
  segments:
239
239
  - 0
240
- hash: -2066251034160361517
240
+ hash: 1146780105758659184
241
241
  required_rubygems_version: !ruby/object:Gem::Requirement
242
242
  none: false
243
243
  requirements: