vitrine 0.0.7 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +0 -3
- data/README.rdoc +37 -13
- data/lib/atomic_write.rb +35 -0
- data/lib/sourcemaps.rb +23 -0
- data/lib/version.rb +1 -1
- data/lib/vitrine.rb +57 -10
- data/vitrine.gemspec +6 -4
- metadata +14 -33
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ad569a8f77f0b68b74690887547a4b0b59e2de6c
|
4
|
+
data.tar.gz: eedc4cd325749f108a518be915db23b78974b39d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7b6937c1067c446acf3f187df58004da35babcc8204450812e56d2ff0baac3c382649b55c0b743690ee6af1d4d798eae3e594225cf498c7b1b53b7d463a0df97
|
7
|
+
data.tar.gz: 9cfb7408119fcf4b81d4b42d71e55ec97724ccefbeeef350751f59b9c6d0d2786cceaca70e9c71216f023ebc6470022376bac981c44e1c12410995f96490e585
|
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
@@ -1,13 +1,17 @@
|
|
1
1
|
= vitrine
|
2
2
|
|
3
3
|
Is a very small, simple web server one-liner for modern web-apps, a bit in the style of
|
4
|
-
lineman, serve and such.
|
4
|
+
lineman, serve and such. Will display your precious stuff on port 4000.
|
5
5
|
|
6
6
|
== Core idea of Vitrine
|
7
7
|
|
8
8
|
You want a server that will automatically wrap your CoffeeScript and SASS assets, and allow
|
9
9
|
some rudimentary templating. This is practically enough for putting together MVP prototypes,
|
10
|
-
especially as far as single-page apps go.
|
10
|
+
especially as far as single-page apps go. You want this server to not coerce you into a specific
|
11
|
+
SCSS framework, you don't want to scaffold anything, you don't want to have any configs defined and
|
12
|
+
you hate running wizards.
|
13
|
+
|
14
|
+
If most of the above is true, Vitrine is just what you need.
|
11
15
|
|
12
16
|
== How it works.
|
13
17
|
|
@@ -15,22 +19,40 @@ Vitrine assumes that there are two directories under the current tree:
|
|
15
19
|
* "public" - for the JS, for CSS and SCSS and in general all the static files server straight out
|
16
20
|
* "views" - for the templates
|
17
21
|
|
18
|
-
== Automatic compilation of
|
22
|
+
== Automatic compilation of SCSS
|
23
|
+
|
24
|
+
Any .scss file you shove into the "public" directory can be referenced as ".css" from your HTML code.
|
25
|
+
Vitrine will automatically compile it via SASS.
|
26
|
+
|
27
|
+
== Automatic compilation of CoffeeScript and source maps
|
28
|
+
|
29
|
+
Same thing applies to CoffeeScript - put .coffee files in "public", and reference them as .js files.
|
30
|
+
Vitrine will generate you source maps on the fly for pleasant browser debugging.
|
19
31
|
|
20
|
-
|
21
|
-
Vitrine will automatically compile it via SASS. Same thing applies to CoffeeScript - put .coffee
|
22
|
-
files in "public", and reference them as .js files.
|
32
|
+
== Fallback to precompiled files
|
23
33
|
|
24
|
-
Both
|
25
|
-
|
34
|
+
Both SCSS and JS links will fall through to the static versions if you cache them on the server or as a result of
|
35
|
+
asset compilation.
|
26
36
|
|
27
|
-
|
37
|
+
== Sensible error messages when automatic compilation fails
|
28
38
|
|
29
|
-
|
39
|
+
Vitrine will try to show you sensible errors if your SCSS or CoffeeScript fail to compile due to syntax errors and
|
40
|
+
the like.
|
30
41
|
|
31
|
-
|
42
|
+
== Do not recompile on every request
|
43
|
+
|
44
|
+
Succesfully compiled assets will be stored in your +/tmp+ to save time on next reload, and the
|
45
|
+
cache will be automatically flushed when the files are requested from the browser, but only if the modification
|
46
|
+
dates of the source files are different than before.
|
47
|
+
|
48
|
+
== Automatic Ruby template pickup
|
49
|
+
|
50
|
+
If you have the "views" directory available, Vitrine will try to pick up any usable file for any URL without extensions.
|
32
51
|
From there on, it's going to try to render it with the automatically picked template engine using the
|
33
|
-
standard Sinatra facilities.
|
52
|
+
standard Sinatra facilities. You can use HAML, LESS, Slim, ERB, Builder or anything else you like.
|
53
|
+
|
54
|
+
If you are writing an SPA, you can make a file called "catch_all.erb" which is going to be the fall-through template
|
55
|
+
for all missing URLs without extension.
|
34
56
|
|
35
57
|
== Automatic reload via Guard
|
36
58
|
|
@@ -40,7 +62,9 @@ rack-livereload, so you won't need browser extensions at all.
|
|
40
62
|
== Packaging and baking
|
41
63
|
|
42
64
|
At this point the best way to bake a Vitrine site is to crawl it externally, but we are going to implement
|
43
|
-
baking at some point.
|
65
|
+
baking at some point. The idea is that you will end up upgrading the site to either a Node app or a Ruby app
|
66
|
+
with it's own +config.ru+ - if after that point you still wish to use Vitrine, you can use it like a Rack
|
67
|
+
middleware.
|
44
68
|
|
45
69
|
== Contributing to vitrine
|
46
70
|
|
data/lib/atomic_write.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module Vitrine
|
2
|
+
# Stolen from Rails
|
3
|
+
def self.atomic_write(file_name, temp_dir = Dir.tmpdir)
|
4
|
+
require 'tempfile' unless defined?(Tempfile)
|
5
|
+
require 'fileutils' unless defined?(FileUtils)
|
6
|
+
|
7
|
+
temp_file = Tempfile.new(File.basename(file_name), temp_dir)
|
8
|
+
temp_file.binmode
|
9
|
+
yield temp_file
|
10
|
+
temp_file.close
|
11
|
+
|
12
|
+
begin
|
13
|
+
# Get original file permissions
|
14
|
+
old_stat = File.stat(file_name)
|
15
|
+
rescue Errno::ENOENT
|
16
|
+
# No old permissions, write a temp file to determine the defaults
|
17
|
+
check_name = File.join(File.dirname(file_name), ".permissions_check.#{Thread.current.object_id}.#{Process.pid}.#{rand(1000000)}")
|
18
|
+
open(check_name, "w") { }
|
19
|
+
old_stat = File.stat(check_name)
|
20
|
+
File.unlink(check_name)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Overwrite original file with temp file
|
24
|
+
FileUtils.mv(temp_file.path, file_name)
|
25
|
+
|
26
|
+
# Set correct permissions on new file
|
27
|
+
begin
|
28
|
+
File.chown(old_stat.uid, old_stat.gid, file_name)
|
29
|
+
# This operation will affect filesystem ACL's
|
30
|
+
File.chmod(old_stat.mode, file_name)
|
31
|
+
rescue Errno::EPERM
|
32
|
+
# Changing file ownership failed, moving on.
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/sourcemaps.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Vitrine
|
5
|
+
def self.build_coffeescript_source_map_body(full_coffeescript_file_path, public_dir_path)
|
6
|
+
|
7
|
+
script = File.read(full_coffeescript_file_path)
|
8
|
+
|
9
|
+
# We need to feed paths ON THE SERVER so that the browser can connect the coffee file, the map and the JS file
|
10
|
+
# - specify coffee source file explicitly (see http://coffeescript.org/documentation/docs/sourcemap.html#section-8)
|
11
|
+
# The paths need to be slash-prepended (server-absolute)
|
12
|
+
relative_path = '/' + Pathname.new(full_coffeescript_file_path).relative_path_from(Pathname.new(public_dir_path)).to_s
|
13
|
+
relative_js_path = '/' + relative_path.gsub(/\.coffee$/, '.js')
|
14
|
+
|
15
|
+
options = {sourceMap: true}
|
16
|
+
|
17
|
+
# coffee requires filename option to work with source maps (see http://coffeescript.org/documentation/docs/coffee-script.html#section-4)
|
18
|
+
options[:filename] = relative_js_path
|
19
|
+
options[:sourceFiles] = [relative_path]
|
20
|
+
|
21
|
+
CoffeeScript.compile(script, options)["v3SourceMap"]
|
22
|
+
end
|
23
|
+
end
|
data/lib/version.rb
CHANGED
data/lib/vitrine.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
require 'sinatra/base'
|
2
2
|
require 'coffee-script'
|
3
|
+
#require 'coffee-script-source'
|
3
4
|
require 'sass'
|
4
5
|
require 'pathname'
|
5
6
|
|
6
7
|
require_relative 'version'
|
8
|
+
require_relative 'atomic_write'
|
9
|
+
require_relative 'sourcemaps'
|
7
10
|
|
8
11
|
module Vitrine
|
9
12
|
DEFAULTS = { root: Dir.getwd, port: 4000, host: '127.0.0.1' }
|
13
|
+
SEED = rand
|
10
14
|
|
11
15
|
def self.check_dirs_present!
|
12
16
|
views = DEFAULTS[:root] + '/views'
|
@@ -133,18 +137,15 @@ class Vitrine::App < Sinatra::Base
|
|
133
137
|
template_engine = File.extname(template_path).gsub(/^\./, '')
|
134
138
|
render(template_engine, File.read(template_path), :layout => get_layout, :locals => locals)
|
135
139
|
end
|
136
|
-
|
137
|
-
def get_layout
|
138
|
-
layouts = Dir.glob(File.join(settings.views, 'layout.*'))
|
139
|
-
layouts.any? ? :layout : false
|
140
|
-
end
|
140
|
+
|
141
141
|
|
142
142
|
# Try to find SCSS replacement for missing CSS
|
143
143
|
get /(.+)\.css/ do | basename |
|
144
144
|
begin
|
145
145
|
content_type 'text/css', :charset => 'utf-8'
|
146
|
+
# TODO: has no handling for .sass
|
146
147
|
scss_source_path = File.join(settings.root, 'public', "#{basename}.scss")
|
147
|
-
Sass.compile_file(scss_source_path)
|
148
|
+
mtime_cache(scss_source_path) { Sass.compile_file(scss_source_path) }
|
148
149
|
rescue Errno::ENOENT # Missing SCSS
|
149
150
|
halt 404, "No such CSS or SCSS file found"
|
150
151
|
rescue Exception => e # CSS syntax error or something alike
|
@@ -154,18 +155,64 @@ class Vitrine::App < Sinatra::Base
|
|
154
155
|
end
|
155
156
|
end
|
156
157
|
|
158
|
+
# Generate a sourcemap for CoffeeScript files
|
159
|
+
get /(.+)\.js\.map$/ do | basename |
|
160
|
+
begin
|
161
|
+
coffee_source = File.join(settings.root, 'public', "#{basename}.coffee")
|
162
|
+
content_type 'application/json', :charset => 'utf-8'
|
163
|
+
mtime_cache(coffee_source) do
|
164
|
+
Vitrine.build_coffeescript_source_map_body(coffee_source, File.join(settings.root, 'public'))
|
165
|
+
end
|
166
|
+
rescue Errno::ENOENT # Missing CoffeeScript
|
167
|
+
halt 404, "No coffeescript file found to generate the map for"
|
168
|
+
rescue Exception => e # CS syntax error or something alike
|
169
|
+
# inject it into the document
|
170
|
+
'console.error(%s)' % [e.class, "\n", "--> ", e.message].join.inspect
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
157
174
|
# Try to find CoffeeScript replacement for missing JS
|
158
|
-
get /(.+)\.js
|
175
|
+
get /(.+)\.js$/ do | basename |
|
159
176
|
# If this file is not found resort back to a coffeescript
|
160
177
|
begin
|
161
|
-
coffee_source = File.
|
178
|
+
coffee_source = File.join(settings.root, 'public', "#{basename}.coffee")
|
162
179
|
content_type 'text/javascript', :charset => 'utf-8'
|
163
|
-
|
180
|
+
mtime_cache(coffee_source) do
|
181
|
+
["//# sourceMappingURL=#{basename}.js.map", CoffeeScript.compile(File.read(coffee_source))].join("\n")
|
182
|
+
end
|
164
183
|
rescue Errno::ENOENT # Missing CoffeeScript
|
165
184
|
halt 404, "No such JS file and could not find a .coffee replacement"
|
166
185
|
rescue Exception => e # CS syntax error or something alike
|
167
186
|
# inject it into the document
|
168
187
|
'console.error(%s)' % [e.class, "\n", "--> ", e.message].join.inspect
|
169
188
|
end
|
170
|
-
end
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
def mtime_cache(path, &blk)
|
193
|
+
# Mix in the request URL into the cache key so that we can hash
|
194
|
+
# .map sourcemaps and .js compiles based off of the same file path
|
195
|
+
# and mtime
|
196
|
+
|
197
|
+
key = [File.expand_path(path), File.mtime(path), request.path_info, Vitrine::SEED]
|
198
|
+
cache_sha = Digest::SHA1.hexdigest(Marshal.dump(key))
|
199
|
+
|
200
|
+
p = File.join('/tmp', cache_sha)
|
201
|
+
if File.exist?(p)
|
202
|
+
return File.read(p)
|
203
|
+
else
|
204
|
+
Vitrine.atomic_write(p) do |f|
|
205
|
+
$stderr.puts "---> Recompiling #{path}"
|
206
|
+
body = yield
|
207
|
+
f.write(body)
|
208
|
+
return body
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def get_layout
|
214
|
+
layouts = Dir.glob(File.join(settings.views, 'layout.*'))
|
215
|
+
layouts.any? ? :layout : false
|
216
|
+
end
|
217
|
+
|
171
218
|
end
|
data/vitrine.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "vitrine"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.9"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Julik Tarkhanov"]
|
12
|
-
s.date = "2013-11-
|
12
|
+
s.date = "2013-11-11"
|
13
13
|
s.description = " Serves ERB templates with live CoffeeScript and SASS "
|
14
14
|
s.email = "me@julik.nl"
|
15
15
|
s.executables = ["vitrine"]
|
@@ -24,6 +24,8 @@ Gem::Specification.new do |s|
|
|
24
24
|
"README.rdoc",
|
25
25
|
"Rakefile",
|
26
26
|
"bin/vitrine",
|
27
|
+
"lib/atomic_write.rb",
|
28
|
+
"lib/sourcemaps.rb",
|
27
29
|
"lib/version.rb",
|
28
30
|
"lib/vitrine.rb",
|
29
31
|
"test/helper.rb",
|
@@ -33,11 +35,11 @@ Gem::Specification.new do |s|
|
|
33
35
|
s.homepage = "http://github.com/julik/vitrine"
|
34
36
|
s.licenses = ["MIT"]
|
35
37
|
s.require_paths = ["lib"]
|
36
|
-
s.rubygems_version = "
|
38
|
+
s.rubygems_version = "2.0.6"
|
37
39
|
s.summary = "Quickie micro-app preview server"
|
38
40
|
|
39
41
|
if s.respond_to? :specification_version then
|
40
|
-
s.specification_version =
|
42
|
+
s.specification_version = 4
|
41
43
|
|
42
44
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
43
45
|
s.add_runtime_dependency(%q<sinatra>, ["~> 1.4"])
|
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vitrine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.9
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Julik Tarkhanov
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-11-
|
11
|
+
date: 2013-11-11 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: sinatra
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ~>
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -30,7 +27,6 @@ dependencies:
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: coffee-script
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - ~>
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - ~>
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -46,7 +41,6 @@ dependencies:
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: sass
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
45
|
- - ~>
|
52
46
|
- !ruby/object:Gem::Version
|
@@ -54,7 +48,6 @@ dependencies:
|
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
52
|
- - ~>
|
60
53
|
- !ruby/object:Gem::Version
|
@@ -62,39 +55,34 @@ dependencies:
|
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: guard
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - '>='
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: '0'
|
70
62
|
type: :runtime
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - '>='
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: '0'
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: rack-livereload
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - '>='
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: '0'
|
86
76
|
type: :runtime
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - '>='
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: '0'
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: rdoc
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
87
|
- - ~>
|
100
88
|
- !ruby/object:Gem::Version
|
@@ -102,7 +90,6 @@ dependencies:
|
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
94
|
- - ~>
|
108
95
|
- !ruby/object:Gem::Version
|
@@ -110,7 +97,6 @@ dependencies:
|
|
110
97
|
- !ruby/object:Gem::Dependency
|
111
98
|
name: bundler
|
112
99
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
100
|
requirements:
|
115
101
|
- - ~>
|
116
102
|
- !ruby/object:Gem::Version
|
@@ -118,7 +104,6 @@ dependencies:
|
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
107
|
requirements:
|
123
108
|
- - ~>
|
124
109
|
- !ruby/object:Gem::Version
|
@@ -126,7 +111,6 @@ dependencies:
|
|
126
111
|
- !ruby/object:Gem::Dependency
|
127
112
|
name: jeweler
|
128
113
|
requirement: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
114
|
requirements:
|
131
115
|
- - ~>
|
132
116
|
- !ruby/object:Gem::Version
|
@@ -134,12 +118,11 @@ dependencies:
|
|
134
118
|
type: :development
|
135
119
|
prerelease: false
|
136
120
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
121
|
requirements:
|
139
122
|
- - ~>
|
140
123
|
- !ruby/object:Gem::Version
|
141
124
|
version: 1.8.7
|
142
|
-
description:
|
125
|
+
description: ' Serves ERB templates with live CoffeeScript and SASS '
|
143
126
|
email: me@julik.nl
|
144
127
|
executables:
|
145
128
|
- vitrine
|
@@ -154,6 +137,8 @@ files:
|
|
154
137
|
- README.rdoc
|
155
138
|
- Rakefile
|
156
139
|
- bin/vitrine
|
140
|
+
- lib/atomic_write.rb
|
141
|
+
- lib/sourcemaps.rb
|
157
142
|
- lib/version.rb
|
158
143
|
- lib/vitrine.rb
|
159
144
|
- test/helper.rb
|
@@ -162,29 +147,25 @@ files:
|
|
162
147
|
homepage: http://github.com/julik/vitrine
|
163
148
|
licenses:
|
164
149
|
- MIT
|
150
|
+
metadata: {}
|
165
151
|
post_install_message:
|
166
152
|
rdoc_options: []
|
167
153
|
require_paths:
|
168
154
|
- lib
|
169
155
|
required_ruby_version: !ruby/object:Gem::Requirement
|
170
|
-
none: false
|
171
156
|
requirements:
|
172
|
-
- -
|
157
|
+
- - '>='
|
173
158
|
- !ruby/object:Gem::Version
|
174
159
|
version: '0'
|
175
|
-
segments:
|
176
|
-
- 0
|
177
|
-
hash: 3964899950062154621
|
178
160
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
|
-
none: false
|
180
161
|
requirements:
|
181
|
-
- -
|
162
|
+
- - '>='
|
182
163
|
- !ruby/object:Gem::Version
|
183
164
|
version: '0'
|
184
165
|
requirements: []
|
185
166
|
rubyforge_project:
|
186
|
-
rubygems_version:
|
167
|
+
rubygems_version: 2.0.6
|
187
168
|
signing_key:
|
188
|
-
specification_version:
|
169
|
+
specification_version: 4
|
189
170
|
summary: Quickie micro-app preview server
|
190
171
|
test_files: []
|