sinatra-rack-3-commonlit 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
Binary file
@@ -0,0 +1,206 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sinatra
4
+ # A poor man's ActiveSupport::HashWithIndifferentAccess, with all the Rails-y
5
+ # stuff removed.
6
+ #
7
+ # Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are
8
+ # considered to be the same.
9
+ #
10
+ # rgb = Sinatra::IndifferentHash.new
11
+ #
12
+ # rgb[:black] = '#000000' # symbol assignment
13
+ # rgb[:black] # => '#000000' # symbol retrieval
14
+ # rgb['black'] # => '#000000' # string retrieval
15
+ #
16
+ # rgb['white'] = '#FFFFFF' # string assignment
17
+ # rgb[:white] # => '#FFFFFF' # symbol retrieval
18
+ # rgb['white'] # => '#FFFFFF' # string retrieval
19
+ #
20
+ # Internally, symbols are mapped to strings when used as keys in the entire
21
+ # writing interface (calling e.g. <tt>[]=</tt>, <tt>merge</tt>). This mapping
22
+ # belongs to the public interface. For example, given:
23
+ #
24
+ # hash = Sinatra::IndifferentHash.new(:a=>1)
25
+ #
26
+ # You are guaranteed that the key is returned as a string:
27
+ #
28
+ # hash.keys # => ["a"]
29
+ #
30
+ # Technically other types of keys are accepted:
31
+ #
32
+ # hash = Sinatra::IndifferentHash.new(:a=>1)
33
+ # hash[0] = 0
34
+ # hash # => { "a"=>1, 0=>0 }
35
+ #
36
+ # But this class is intended for use cases where strings or symbols are the
37
+ # expected keys and it is convenient to understand both as the same. For
38
+ # example the +params+ hash in Sinatra.
39
+ class IndifferentHash < Hash
40
+ def self.[](*args)
41
+ new.merge!(Hash[*args])
42
+ end
43
+
44
+ def initialize(*args)
45
+ args.map!(&method(:convert_value))
46
+
47
+ super(*args)
48
+ end
49
+
50
+ def default(*args)
51
+ args.map!(&method(:convert_key))
52
+
53
+ super(*args)
54
+ end
55
+
56
+ def default=(value)
57
+ super(convert_value(value))
58
+ end
59
+
60
+ def assoc(key)
61
+ super(convert_key(key))
62
+ end
63
+
64
+ def rassoc(value)
65
+ super(convert_value(value))
66
+ end
67
+
68
+ def fetch(key, *args)
69
+ args.map!(&method(:convert_value))
70
+
71
+ super(convert_key(key), *args)
72
+ end
73
+
74
+ def [](key)
75
+ super(convert_key(key))
76
+ end
77
+
78
+ def []=(key, value)
79
+ super(convert_key(key), convert_value(value))
80
+ end
81
+
82
+ alias store []=
83
+
84
+ def key(value)
85
+ super(convert_value(value))
86
+ end
87
+
88
+ def key?(key)
89
+ super(convert_key(key))
90
+ end
91
+
92
+ alias has_key? key?
93
+ alias include? key?
94
+ alias member? key?
95
+
96
+ def value?(value)
97
+ super(convert_value(value))
98
+ end
99
+
100
+ alias has_value? value?
101
+
102
+ def delete(key)
103
+ super(convert_key(key))
104
+ end
105
+
106
+ # Added in Ruby 2.3
107
+ def dig(key, *other_keys)
108
+ super(convert_key(key), *other_keys)
109
+ end
110
+
111
+ def fetch_values(*keys)
112
+ keys.map!(&method(:convert_key))
113
+
114
+ super(*keys)
115
+ end
116
+
117
+ def slice(*keys)
118
+ keys.map!(&method(:convert_key))
119
+
120
+ self.class[super(*keys)]
121
+ end
122
+
123
+ def values_at(*keys)
124
+ keys.map!(&method(:convert_key))
125
+
126
+ super(*keys)
127
+ end
128
+
129
+ def merge!(*other_hashes)
130
+ other_hashes.each do |other_hash|
131
+ if other_hash.is_a?(self.class)
132
+ super(other_hash)
133
+ else
134
+ other_hash.each_pair do |key, value|
135
+ key = convert_key(key)
136
+ value = yield(key, self[key], value) if block_given? && key?(key)
137
+ self[key] = convert_value(value)
138
+ end
139
+ end
140
+ end
141
+
142
+ self
143
+ end
144
+
145
+ alias update merge!
146
+
147
+ def merge(*other_hashes, &block)
148
+ dup.merge!(*other_hashes, &block)
149
+ end
150
+
151
+ def replace(other_hash)
152
+ super(other_hash.is_a?(self.class) ? other_hash : self.class[other_hash])
153
+ end
154
+
155
+ def transform_values(&block)
156
+ dup.transform_values!(&block)
157
+ end
158
+
159
+ def transform_values!
160
+ super
161
+ super(&method(:convert_value))
162
+ end
163
+
164
+ def transform_keys(&block)
165
+ dup.transform_keys!(&block)
166
+ end
167
+
168
+ def transform_keys!
169
+ super
170
+ super(&method(:convert_key))
171
+ end
172
+
173
+ def select(*args, &block)
174
+ return to_enum(:select) unless block_given?
175
+
176
+ dup.tap { |hash| hash.select!(*args, &block) }
177
+ end
178
+
179
+ def reject(*args, &block)
180
+ return to_enum(:reject) unless block_given?
181
+
182
+ dup.tap { |hash| hash.reject!(*args, &block) }
183
+ end
184
+
185
+ def compact
186
+ dup.tap(&:compact!)
187
+ end
188
+
189
+ private
190
+
191
+ def convert_key(key)
192
+ key.is_a?(Symbol) ? key.to_s : key
193
+ end
194
+
195
+ def convert_value(value)
196
+ case value
197
+ when Hash
198
+ value.is_a?(self.class) ? value : self.class[value]
199
+ when Array
200
+ value.map(&method(:convert_value))
201
+ else
202
+ value
203
+ end
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sinatra
4
+ PARAMS_CONFIG = {}
5
+
6
+ if ARGV.any?
7
+ require 'optparse'
8
+ parser = OptionParser.new do |op|
9
+ op.on('-p port', 'set the port (default is 4567)') { |val| PARAMS_CONFIG[:port] = Integer(val) }
10
+ op.on('-s server', 'specify rack server/handler') { |val| PARAMS_CONFIG[:server] = val }
11
+ op.on('-q', 'turn on quiet mode (default is off)') { PARAMS_CONFIG[:quiet] = true }
12
+ op.on('-x', 'turn on the mutex lock (default is off)') { PARAMS_CONFIG[:lock] = true }
13
+ op.on('-e env', 'set the environment (default is development)') do |val|
14
+ ENV['RACK_ENV'] = val
15
+ PARAMS_CONFIG[:environment] = val.to_sym
16
+ end
17
+ op.on('-o addr', "set the host (default is (env == 'development' ? 'localhost' : '0.0.0.0'))") do |val|
18
+ PARAMS_CONFIG[:bind] = val
19
+ end
20
+ end
21
+ begin
22
+ parser.parse!(ARGV.dup)
23
+ rescue StandardError => e
24
+ PARAMS_CONFIG[:optparse_error] = e
25
+ end
26
+ end
27
+
28
+ require 'sinatra/base'
29
+
30
+ class Application < Base
31
+ # we assume that the first file that requires 'sinatra' is the
32
+ # app_file. all other path related options are calculated based
33
+ # on this path by default.
34
+ set :app_file, caller_files.first || $0
35
+
36
+ set :run, proc { File.expand_path($0) == File.expand_path(app_file) }
37
+
38
+ if run? && ARGV.any?
39
+ error = PARAMS_CONFIG.delete(:optparse_error)
40
+ raise error if error
41
+
42
+ PARAMS_CONFIG.each { |k, v| set k, v }
43
+ end
44
+ end
45
+
46
+ remove_const(:PARAMS_CONFIG)
47
+ at_exit { Application.run! if $!.nil? && Application.run? }
48
+ end
49
+
50
+ # include would include the module in Object
51
+ # extend only extends the `main` object
52
+ extend Sinatra::Delegator
53
+
54
+ class Rack::Builder
55
+ include Sinatra::Delegator
56
+ end
@@ -0,0 +1,364 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rack/show_exceptions'
4
+
5
+ module Sinatra
6
+ # Sinatra::ShowExceptions catches all exceptions raised from the app it
7
+ # wraps. It shows a useful backtrace with the sourcefile and clickable
8
+ # context, the whole Rack environment and the request data.
9
+ #
10
+ # Be careful when you use this on public-facing sites as it could reveal
11
+ # information helpful to attackers.
12
+ class ShowExceptions < Rack::ShowExceptions
13
+ @@eats_errors = Object.new
14
+ def @@eats_errors.flush(*) end
15
+
16
+ def @@eats_errors.puts(*) end
17
+
18
+ def initialize(app)
19
+ @app = app
20
+ end
21
+
22
+ def call(env)
23
+ @app.call(env)
24
+ rescue Exception => e
25
+ errors = env['rack.errors']
26
+ env['rack.errors'] = @@eats_errors
27
+
28
+ if prefers_plain_text?(env)
29
+ content_type = 'text/plain'
30
+ body = dump_exception(e)
31
+ else
32
+ content_type = 'text/html'
33
+ body = pretty(env, e)
34
+ end
35
+
36
+ env['rack.errors'] = errors
37
+
38
+ [
39
+ 500,
40
+ {
41
+ 'content-type' => content_type,
42
+ 'content-length' => body.bytesize.to_s
43
+ },
44
+ [body]
45
+ ]
46
+ end
47
+
48
+ def template
49
+ TEMPLATE
50
+ end
51
+
52
+ private
53
+
54
+ def bad_request?(exception)
55
+ Sinatra::BadRequest === exception
56
+ end
57
+
58
+ def prefers_plain_text?(env)
59
+ Request.new(env).preferred_type('text/plain', 'text/html') != 'text/html' &&
60
+ [/curl/].index { |item| item =~ env['HTTP_USER_AGENT'] }
61
+ end
62
+
63
+ def frame_class(frame)
64
+ if frame.filename =~ %r{lib/sinatra.*\.rb}
65
+ 'framework'
66
+ elsif (defined?(Gem) && frame.filename.include?(Gem.dir)) ||
67
+ frame.filename =~ %r{/bin/(\w+)\z}
68
+ 'system'
69
+ else
70
+ 'app'
71
+ end
72
+ end
73
+
74
+ TEMPLATE = ERB.new <<-HTML # :nodoc:
75
+ <!DOCTYPE html>
76
+ <html>
77
+ <head>
78
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
79
+ <title><%=h exception.class %> at <%=h path %></title>
80
+
81
+ <script type="text/javascript">
82
+ //<!--
83
+ function toggle(id) {
84
+ var pre = document.getElementById("pre-" + id);
85
+ var post = document.getElementById("post-" + id);
86
+ var context = document.getElementById("context-" + id);
87
+
88
+ if (pre.style.display == 'block') {
89
+ pre.style.display = 'none';
90
+ post.style.display = 'none';
91
+ context.style.background = "none";
92
+ } else {
93
+ pre.style.display = 'block';
94
+ post.style.display = 'block';
95
+ context.style.background = "#fffed9";
96
+ }
97
+ }
98
+
99
+ function toggleBacktrace(){
100
+ var bt = document.getElementById("backtrace");
101
+ var toggler = document.getElementById("expando");
102
+
103
+ if (bt.className == 'condensed') {
104
+ bt.className = 'expanded';
105
+ toggler.innerHTML = "(condense)";
106
+ } else {
107
+ bt.className = 'condensed';
108
+ toggler.innerHTML = "(expand)";
109
+ }
110
+ }
111
+ //-->
112
+ </script>
113
+
114
+ <style type="text/css" media="screen">
115
+ * {margin: 0; padding: 0; border: 0; outline: 0;}
116
+ div.clear {clear: both;}
117
+ body {background: #EEEEEE; margin: 0; padding: 0;
118
+ font-family: 'Lucida Grande', 'Lucida Sans Unicode',
119
+ 'Garuda';}
120
+ code {font-family: 'Lucida Console', monospace;
121
+ font-size: 12px;}
122
+ li {height: 18px;}
123
+ ul {list-style: none; margin: 0; padding: 0;}
124
+ ol:hover {cursor: pointer;}
125
+ ol li {white-space: pre;}
126
+ #explanation {font-size: 12px; color: #666666;
127
+ margin: 20px 0 0 100px;}
128
+ /* WRAP */
129
+ #wrap {width: 1000px; background: #FFFFFF; margin: 0 auto;
130
+ padding: 30px 50px 20px 50px;
131
+ border-left: 1px solid #DDDDDD;
132
+ border-right: 1px solid #DDDDDD;}
133
+ /* HEADER */
134
+ #header {margin: 0 auto 25px auto;}
135
+ #header img {float: left;}
136
+ #header #summary {float: left; margin: 12px 0 0 20px; width:660px;
137
+ font-family: 'Lucida Grande', 'Lucida Sans Unicode';}
138
+ h1 {margin: 0; font-size: 36px; color: #981919;}
139
+ h2 {margin: 0; font-size: 22px; color: #333333;}
140
+ #header ul {margin: 0; font-size: 12px; color: #666666;}
141
+ #header ul li strong{color: #444444;}
142
+ #header ul li {display: inline; padding: 0 10px;}
143
+ #header ul li.first {padding-left: 0;}
144
+ #header ul li.last {border: 0; padding-right: 0;}
145
+ /* BODY */
146
+ #backtrace,
147
+ #get,
148
+ #post,
149
+ #cookies,
150
+ #rack {width: 980px; margin: 0 auto 10px auto;}
151
+ p#nav {float: right; font-size: 14px;}
152
+ /* BACKTRACE */
153
+ a#expando {float: left; padding-left: 5px; color: #666666;
154
+ font-size: 14px; text-decoration: none; cursor: pointer;}
155
+ a#expando:hover {text-decoration: underline;}
156
+ h3 {float: left; width: 100px; margin-bottom: 10px;
157
+ color: #981919; font-size: 14px; font-weight: bold;}
158
+ #nav a {color: #666666; text-decoration: none; padding: 0 5px;}
159
+ #backtrace li.frame-info {background: #f7f7f7; padding-left: 10px;
160
+ font-size: 12px; color: #333333;}
161
+ #backtrace ul {list-style-position: outside; border: 1px solid #E9E9E9;
162
+ border-bottom: 0;}
163
+ #backtrace ol {width: 920px; margin-left: 50px;
164
+ font: 10px 'Lucida Console', monospace; color: #666666;}
165
+ #backtrace ol li {border: 0; border-left: 1px solid #E9E9E9;
166
+ padding: 2px 0;}
167
+ #backtrace ol code {font-size: 10px; color: #555555; padding-left: 5px;}
168
+ #backtrace-ul li {border-bottom: 1px solid #E9E9E9; height: auto;
169
+ padding: 3px 0;}
170
+ #backtrace-ul .code {padding: 6px 0 4px 0;}
171
+ #backtrace.condensed .system,
172
+ #backtrace.condensed .framework {display:none;}
173
+ /* REQUEST DATA */
174
+ p.no-data {padding-top: 2px; font-size: 12px; color: #666666;}
175
+ table.req {width: 980px; text-align: left; font-size: 12px;
176
+ color: #666666; padding: 0; border-spacing: 0;
177
+ border: 1px solid #EEEEEE; border-bottom: 0;
178
+ border-left: 0;
179
+ clear:both}
180
+ table.req tr th {padding: 2px 10px; font-weight: bold;
181
+ background: #F7F7F7; border-bottom: 1px solid #EEEEEE;
182
+ border-left: 1px solid #EEEEEE;}
183
+ table.req tr td {padding: 2px 20px 2px 10px;
184
+ border-bottom: 1px solid #EEEEEE;
185
+ border-left: 1px solid #EEEEEE;}
186
+ /* HIDE PRE/POST CODE AT START */
187
+ .pre-context,
188
+ .post-context {display: none;}
189
+
190
+ table td.code {width:750px}
191
+ table td.code div {width:750px;overflow:hidden}
192
+ </style>
193
+ </head>
194
+ <body>
195
+ <div id="wrap">
196
+ <div id="header">
197
+ <img src="<%= env['SCRIPT_NAME'] %>/__sinatra__/500.png" alt="application error" height="161" width="313" />
198
+ <div id="summary">
199
+ <h1><strong><%=h exception.class %></strong> at <strong><%=h path %>
200
+ </strong></h1>
201
+ <h2><%=h exception.message %></h2>
202
+ <ul>
203
+ <li class="first"><strong>file:</strong> <code>
204
+ <%=h frames.first.filename.split("/").last %></code></li>
205
+ <li><strong>location:</strong> <code><%=h frames.first.function %>
206
+ </code></li>
207
+ <li class="last"><strong>line:
208
+ </strong> <%=h frames.first.lineno %></li>
209
+ </ul>
210
+ </div>
211
+ <div class="clear"></div>
212
+ </div>
213
+
214
+ <div id="backtrace" class='condensed'>
215
+ <h3>BACKTRACE</h3>
216
+ <p><a href="#" id="expando"
217
+ onclick="toggleBacktrace(); return false">(expand)</a></p>
218
+ <p id="nav"><strong>JUMP TO:</strong>
219
+ <% unless bad_request?(exception) %>
220
+ <a href="#get-info">GET</a>
221
+ <a href="#post-info">POST</a>
222
+ <% end %>
223
+ <a href="#cookie-info">COOKIES</a>
224
+ <a href="#env-info">ENV</a>
225
+ </p>
226
+ <div class="clear"></div>
227
+
228
+ <ul id="backtrace-ul">
229
+
230
+ <% id = 1 %>
231
+ <% frames.each do |frame| %>
232
+ <% if frame.context_line && frame.context_line != "#" %>
233
+
234
+ <li class="frame-info <%= frame_class(frame) %>">
235
+ <code><%=h frame.filename %></code> in
236
+ <code><strong><%=h frame.function %></strong></code>
237
+ </li>
238
+
239
+ <li class="code <%= frame_class(frame) %>">
240
+ <% if frame.pre_context %>
241
+ <ol start="<%=h frame.pre_context_lineno + 1 %>"
242
+ class="pre-context" id="pre-<%= id %>"
243
+ onclick="toggle(<%= id %>);">
244
+ <% frame.pre_context.each do |line| %>
245
+ <li class="pre-context-line"><code><%=h line %></code></li>
246
+ <% end %>
247
+ </ol>
248
+ <% end %>
249
+
250
+ <ol start="<%= frame.lineno %>" class="context" id="<%= id %>"
251
+ onclick="toggle(<%= id %>);">
252
+ <li class="context-line" id="context-<%= id %>"><code><%=
253
+ h frame.context_line %></code></li>
254
+ </ol>
255
+
256
+ <% if frame.post_context %>
257
+ <ol start="<%=h frame.lineno + 1 %>" class="post-context"
258
+ id="post-<%= id %>" onclick="toggle(<%= id %>);">
259
+ <% frame.post_context.each do |line| %>
260
+ <li class="post-context-line"><code><%=h line %></code></li>
261
+ <% end %>
262
+ </ol>
263
+ <% end %>
264
+ <div class="clear"></div>
265
+ </li>
266
+
267
+ <% end %>
268
+
269
+ <% id += 1 %>
270
+ <% end %>
271
+
272
+ </ul>
273
+ </div> <!-- /BACKTRACE -->
274
+
275
+ <% unless bad_request?(exception) %>
276
+ <div id="get">
277
+ <h3 id="get-info">GET</h3>
278
+ <% if req.GET and not req.GET.empty? %>
279
+ <table class="req">
280
+ <tr>
281
+ <th>Variable</th>
282
+ <th>Value</th>
283
+ </tr>
284
+ <% req.GET.sort_by { |k, v| k.to_s }.each { |key, val| %>
285
+ <tr>
286
+ <td><%=h key %></td>
287
+ <td class="code"><div><%=h val.inspect %></div></td>
288
+ </tr>
289
+ <% } %>
290
+ </table>
291
+ <% else %>
292
+ <p class="no-data">No GET data.</p>
293
+ <% end %>
294
+ <div class="clear"></div>
295
+ </div> <!-- /GET -->
296
+
297
+ <div id="post">
298
+ <h3 id="post-info">POST</h3>
299
+ <% if req.POST and not req.POST.empty? %>
300
+ <table class="req">
301
+ <tr>
302
+ <th>Variable</th>
303
+ <th>Value</th>
304
+ </tr>
305
+ <% req.POST.sort_by { |k, v| k.to_s }.each { |key, val| %>
306
+ <tr>
307
+ <td><%=h key %></td>
308
+ <td class="code"><div><%=h val.inspect %></div></td>
309
+ </tr>
310
+ <% } %>
311
+ </table>
312
+ <% else %>
313
+ <p class="no-data">No POST data.</p>
314
+ <% end %>
315
+ <div class="clear"></div>
316
+ </div> <!-- /POST -->
317
+ <% end %>
318
+
319
+ <div id="cookies">
320
+ <h3 id="cookie-info">COOKIES</h3>
321
+ <% unless req.cookies.empty? %>
322
+ <table class="req">
323
+ <tr>
324
+ <th>Variable</th>
325
+ <th>Value</th>
326
+ </tr>
327
+ <% req.cookies.each { |key, val| %>
328
+ <tr>
329
+ <td><%=h key %></td>
330
+ <td class="code"><div><%=h val.inspect %></div></td>
331
+ </tr>
332
+ <% } %>
333
+ </table>
334
+ <% else %>
335
+ <p class="no-data">No cookie data.</p>
336
+ <% end %>
337
+ <div class="clear"></div>
338
+ </div> <!-- /COOKIES -->
339
+
340
+ <div id="rack">
341
+ <h3 id="env-info">Rack ENV</h3>
342
+ <table class="req">
343
+ <tr>
344
+ <th>Variable</th>
345
+ <th>Value</th>
346
+ </tr>
347
+ <% env.sort_by { |k, v| k.to_s }.each { |key, val| %>
348
+ <tr>
349
+ <td><%=h key %></td>
350
+ <td class="code"><div><%=h val %></div></td>
351
+ </tr>
352
+ <% } %>
353
+ </table>
354
+ <div class="clear"></div>
355
+ </div> <!-- /RACK ENV -->
356
+
357
+ <p id="explanation">You're seeing this error because you have
358
+ enabled the <code>show_exceptions</code> setting.</p>
359
+ </div> <!-- /WRAP -->
360
+ </body>
361
+ </html>
362
+ HTML
363
+ end
364
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sinatra
4
+ VERSION = '4.0.0.alpha'
5
+ end
data/lib/sinatra.rb ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sinatra/main'
4
+
5
+ enable :inline_templates
data/sinatra.gemspec ADDED
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ version = File.read(File.expand_path('VERSION', __dir__)).strip
4
+
5
+ Gem::Specification.new 'sinatra-rack-3-commonlit', version do |s|
6
+ s.description = 'Sinatra is a DSL for quickly creating web applications in Ruby with minimal effort.'
7
+ s.summary = 'Classy web-development dressed in a DSL'
8
+ s.authors = ['Blake Mizerany', 'Ryan Tomayko', 'Simon Rozet', 'Konstantin Haase']
9
+ s.email = 'sinatrarb@googlegroups.com'
10
+ s.homepage = 'http://sinatrarb.com/'
11
+ s.license = 'MIT'
12
+ s.files = Dir['README*.md', 'lib/**/*', 'examples/*'] + [
13
+ '.yardopts',
14
+ 'AUTHORS.md',
15
+ 'CHANGELOG.md',
16
+ 'CONTRIBUTING.md',
17
+ 'Gemfile',
18
+ 'LICENSE',
19
+ 'MAINTENANCE.md',
20
+ 'Rakefile',
21
+ 'SECURITY.md',
22
+ 'sinatra.gemspec',
23
+ 'VERSION'
24
+ ]
25
+ s.extra_rdoc_files = %w[README.md LICENSE]
26
+ s.rdoc_options = %w[--line-numbers --title Sinatra --main README.rdoc --encoding=UTF-8]
27
+
28
+ unless s.respond_to?(:metadata)
29
+ raise <<-WARN
30
+ RubyGems 2.0 or newer is required to protect against public gem pushes. You can update your rubygems version by running:
31
+ gem install rubygems-update
32
+ update_rubygems:
33
+ gem update --system
34
+ WARN
35
+ end
36
+
37
+ s.metadata = {
38
+ 'source_code_uri' => 'https://github.com/sinatra/sinatra',
39
+ 'changelog_uri' => 'https://github.com/sinatra/sinatra/blob/main/CHANGELOG.md',
40
+ 'homepage_uri' => 'http://sinatrarb.com/',
41
+ 'bug_tracker_uri' => 'https://github.com/sinatra/sinatra/issues',
42
+ 'mailing_list_uri' => 'http://groups.google.com/group/sinatrarb',
43
+ 'documentation_uri' => 'https://www.rubydoc.info/gems/sinatra'
44
+ }
45
+
46
+ s.required_ruby_version = '>= 2.6.0'
47
+
48
+ s.add_dependency 'mustermann', '~> 3.0'
49
+ s.add_dependency 'rack', '>= 3.0.0.beta1', '< 4'
50
+ s.add_dependency 'rackup', '>= 2.0.0', '< 3'
51
+ s.add_dependency 'rack-session', '>= 2.0.0', '< 3'
52
+ s.add_dependency 'rack-protection', version
53
+ s.add_dependency 'tilt', '~> 2.0'
54
+
55
+ s.add_development_dependency 'rack-test', '~> 2'
56
+ end