sinatra 2.2.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sinatra might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +133 -16
- data/CONTRIBUTING.md +11 -11
- data/Gemfile +48 -62
- data/MAINTENANCE.md +2 -2
- data/README.md +199 -386
- data/Rakefile +66 -75
- data/VERSION +1 -1
- data/examples/chat.rb +25 -12
- data/examples/lifecycle_events.rb +20 -0
- data/examples/rainbows.rb +3 -1
- data/examples/simple.rb +2 -0
- data/examples/stream.ru +2 -1
- data/lib/sinatra/base.rb +420 -338
- data/lib/sinatra/indifferent_hash.rb +25 -33
- data/lib/sinatra/main.rb +18 -16
- data/lib/sinatra/show_exceptions.rb +17 -15
- data/lib/sinatra/version.rb +3 -1
- data/lib/sinatra.rb +2 -0
- data/sinatra.gemspec +38 -33
- metadata +40 -30
- data/README.de.md +0 -3239
- data/README.es.md +0 -3231
- data/README.fr.md +0 -3111
- data/README.hu.md +0 -728
- data/README.ja.md +0 -2844
- data/README.ko.md +0 -2967
- data/README.malayalam.md +0 -3141
- data/README.pt-br.md +0 -3787
- data/README.pt-pt.md +0 -791
- data/README.ru.md +0 -3207
- data/README.zh.md +0 -2934
data/Rakefile
CHANGED
@@ -1,15 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rake/clean'
|
2
|
-
require '
|
4
|
+
require 'minitest/test_task'
|
3
5
|
require 'fileutils'
|
4
6
|
require 'date'
|
5
7
|
|
6
|
-
task :
|
7
|
-
task :spec => :test
|
8
|
-
|
9
|
-
CLEAN.include "**/*.rbc"
|
8
|
+
task default: :test
|
10
9
|
|
11
10
|
def source_version
|
12
|
-
@source_version ||= File.read(File.expand_path(
|
11
|
+
@source_version ||= File.read(File.expand_path('VERSION', __dir__)).strip
|
13
12
|
end
|
14
13
|
|
15
14
|
def prev_feature
|
@@ -17,69 +16,59 @@ def prev_feature
|
|
17
16
|
end
|
18
17
|
|
19
18
|
def prev_version
|
20
|
-
return prev_feature
|
21
|
-
source_version.gsub(/\d+$/) { |s| s.to_i - 1 }
|
22
|
-
end
|
19
|
+
return "#{prev_feature}.0" if source_version.end_with? '.0'
|
23
20
|
|
24
|
-
|
25
|
-
|
26
|
-
task :test do
|
27
|
-
ENV['LANG'] = 'C'
|
28
|
-
ENV.delete 'LC_CTYPE'
|
21
|
+
source_version.gsub(/\d+$/) { |s| s.to_i - 1 }
|
29
22
|
end
|
30
23
|
|
31
|
-
|
32
|
-
t.test_files = FileList['test/*_test.rb']
|
33
|
-
t.ruby_opts = ['-r rubygems'] if defined? Gem
|
34
|
-
t.ruby_opts << '-I.'
|
35
|
-
t.warning = true
|
36
|
-
end
|
24
|
+
# Tests ===============================================================
|
37
25
|
|
38
|
-
|
39
|
-
|
40
|
-
helpers mapped_error middleware radius rdoc
|
41
|
-
readme request response result route_added_hook
|
42
|
-
routing server settings sinatra static templates]
|
43
|
-
t.test_files = core_tests.map {|n| "test/#{n}_test.rb"}
|
44
|
-
t.ruby_opts = ["-r rubygems"] if defined? Gem
|
45
|
-
t.ruby_opts << "-I."
|
26
|
+
Minitest::TestTask.create # Default `test` task
|
27
|
+
Minitest::TestTask.create(:'test:core') do |t|
|
46
28
|
t.warning = true
|
29
|
+
t.test_globs = %w[
|
30
|
+
base delegator encoding extensions filter
|
31
|
+
helpers mapped_error middleware rdoc
|
32
|
+
readme request response result route_added_hook
|
33
|
+
routing server settings sinatra static templates
|
34
|
+
].map { |n| "test/#{n}_test.rb" }
|
47
35
|
end
|
48
36
|
|
49
|
-
#
|
37
|
+
# Test code coverage ==================================================
|
50
38
|
|
51
39
|
namespace :test do
|
52
40
|
desc 'Measures test coverage'
|
53
41
|
task :coverage do
|
54
|
-
rm_f
|
42
|
+
rm_f 'coverage'
|
55
43
|
ENV['COVERAGE'] = '1'
|
56
44
|
Rake::Task['test'].invoke
|
57
45
|
end
|
58
46
|
end
|
47
|
+
CLEAN.include('coverage')
|
59
48
|
|
60
49
|
# Website =============================================================
|
61
50
|
|
62
51
|
desc 'Generate RDoc under doc/api'
|
63
|
-
task 'doc'
|
64
|
-
task('doc:api') { sh
|
52
|
+
task 'doc' => ['doc:api']
|
53
|
+
task('doc:api') { sh 'yardoc -o doc/api' }
|
65
54
|
CLEAN.include 'doc/api'
|
66
55
|
|
67
56
|
# README ===============================================================
|
68
57
|
|
69
|
-
task :add_template, [:name] do |
|
58
|
+
task :add_template, [:name] do |_t, args|
|
70
59
|
Dir.glob('README.*') do |file|
|
71
60
|
code = File.read(file)
|
72
61
|
if code =~ /^===.*#{args.name.capitalize}/
|
73
62
|
puts "Already covered in #{file}"
|
74
63
|
else
|
75
|
-
template = code[
|
76
|
-
if
|
77
|
-
puts "Liquid not found in #{file}"
|
78
|
-
else
|
64
|
+
template = code[%r{===[^\n]*Liquid.*index\.liquid</tt>[^\n]*}m]
|
65
|
+
if template
|
79
66
|
puts "Adding section to #{file}"
|
80
67
|
template = template.gsub(/Liquid/, args.name.capitalize).gsub(/liquid/, args.name.downcase)
|
81
68
|
code.gsub! /^(\s*===.*CoffeeScript)/, "\n" << template << "\n\\1"
|
82
|
-
File.open(file,
|
69
|
+
File.open(file, 'w') { |f| f << code }
|
70
|
+
else
|
71
|
+
puts "Liquid not found in #{file}"
|
83
72
|
end
|
84
73
|
end
|
85
74
|
end
|
@@ -87,29 +76,31 @@ end
|
|
87
76
|
|
88
77
|
# Thanks in announcement ===============================================
|
89
78
|
|
90
|
-
team = [
|
91
|
-
desc
|
92
|
-
task :thanks, ['release:all', :backports] do |
|
93
|
-
a.with_defaults :
|
94
|
-
|
79
|
+
team = ['Ryan Tomayko', 'Blake Mizerany', 'Simon Rozet', 'Konstantin Haase', 'Zachary Scott']
|
80
|
+
desc 'list of contributors'
|
81
|
+
task :thanks, ['release:all', :backports] do |_t, a|
|
82
|
+
a.with_defaults release: "#{prev_version}..HEAD",
|
83
|
+
backports: "#{prev_feature}.0..#{prev_feature}.x"
|
84
|
+
|
95
85
|
included = `git log --format=format:"%aN\t%s" #{a.release}`.lines.map { |l| l.force_encoding('binary') }
|
96
86
|
excluded = `git log --format=format:"%aN\t%s" #{a.backports}`.lines.map { |l| l.force_encoding('binary') }
|
97
87
|
commits = (included - excluded).group_by { |c| c[/^[^\t]+/] }
|
98
88
|
authors = commits.keys.sort_by { |n| - commits[n].size } - team
|
99
|
-
puts authors[0..-2].join(', ') <<
|
100
|
-
|
89
|
+
puts authors[0..-2].join(', ') << ' and ' << authors.last,
|
90
|
+
"(based on commits included in #{a.release}, but not in #{a.backports})"
|
101
91
|
end
|
102
92
|
|
103
|
-
desc
|
104
|
-
task :authors, [:commit_range, :format, :sep] do |
|
105
|
-
a.with_defaults :
|
93
|
+
desc 'list of authors'
|
94
|
+
task :authors, [:commit_range, :format, :sep] do |_t, a|
|
95
|
+
a.with_defaults format: '%s (%d)', sep: ', ', commit_range: '--all'
|
106
96
|
authors = Hash.new(0)
|
107
|
-
blake =
|
97
|
+
blake = 'Blake Mizerany'
|
108
98
|
overall = 0
|
109
99
|
mapping = {
|
110
|
-
|
111
|
-
|
112
|
-
|
100
|
+
'blake.mizerany@gmail.com' => blake, 'bmizerany' => blake,
|
101
|
+
'a_user@mac.com' => blake, 'ichverstehe' => 'Harry Vangberg',
|
102
|
+
'Wu Jiang (nouse)' => 'Wu Jiang'
|
103
|
+
}
|
113
104
|
`git shortlog -s #{a.commit_range}`.lines.map do |line|
|
114
105
|
line = line.force_encoding 'binary' if line.respond_to? :force_encoding
|
115
106
|
num, name = line.split("\t", 2).map(&:strip)
|
@@ -117,18 +108,18 @@ task :authors, [:commit_range, :format, :sep] do |t, a|
|
|
117
108
|
overall += num.to_i
|
118
109
|
end
|
119
110
|
puts "#{overall} commits by #{authors.count} authors:"
|
120
|
-
puts authors.sort_by { |
|
111
|
+
puts authors.sort_by { |_n, c| -c }.map { |e| a.format % e }.join(a.sep)
|
121
112
|
end
|
122
113
|
|
123
|
-
desc
|
124
|
-
task :toc, [:readme] do |
|
125
|
-
a.with_defaults :
|
114
|
+
desc 'generates TOC'
|
115
|
+
task :toc, [:readme] do |_t, a|
|
116
|
+
a.with_defaults readme: 'README.md'
|
126
117
|
|
127
118
|
def self.link(title)
|
128
119
|
title.downcase.gsub(/(?!-)\W /, '-').gsub(' ', '-').gsub(/(?!-)\W/, '')
|
129
120
|
end
|
130
121
|
|
131
|
-
puts
|
122
|
+
puts '* [Sinatra](#sinatra)'
|
132
123
|
title = Regexp.new('(?<=\* )(.*)') # so Ruby 1.8 doesn't complain
|
133
124
|
File.binread(a.readme).scan(/^##.*/) do |line|
|
134
125
|
puts line.gsub(/#(?=#)/, ' ').gsub('#', '*').gsub(title) { "[#{$1}](##{link($1)})" }
|
@@ -139,12 +130,12 @@ end
|
|
139
130
|
|
140
131
|
if defined?(Gem)
|
141
132
|
GEMS_AND_ROOT_DIRECTORIES = {
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
}
|
133
|
+
'sinatra' => '.',
|
134
|
+
'sinatra-contrib' => './sinatra-contrib',
|
135
|
+
'rack-protection' => './rack-protection'
|
136
|
+
}.freeze
|
146
137
|
|
147
|
-
def package(gem, ext='')
|
138
|
+
def package(gem, ext = '')
|
148
139
|
"pkg/#{gem}-#{source_version}" + ext
|
149
140
|
end
|
150
141
|
|
@@ -152,12 +143,12 @@ if defined?(Gem)
|
|
152
143
|
CLOBBER.include('pkg')
|
153
144
|
|
154
145
|
GEMS_AND_ROOT_DIRECTORIES.each do |gem, directory|
|
155
|
-
file package(gem, '.gem') => [
|
146
|
+
file package(gem, '.gem') => ['pkg/', "#{"#{directory}/#{gem}"}.gemspec"] do |f|
|
156
147
|
sh "cd #{directory} && gem build #{gem}.gemspec"
|
157
|
-
mv directory
|
148
|
+
mv "#{directory}/#{File.basename(f.name)}", f.name
|
158
149
|
end
|
159
150
|
|
160
|
-
file package(gem, '.tar.gz') => [
|
151
|
+
file package(gem, '.tar.gz') => ['pkg/'] do |f|
|
161
152
|
sh <<-SH
|
162
153
|
git archive \
|
163
154
|
--prefix=#{gem}-#{source_version}/ \
|
@@ -168,29 +159,29 @@ if defined?(Gem)
|
|
168
159
|
end
|
169
160
|
|
170
161
|
namespace :package do
|
171
|
-
GEMS_AND_ROOT_DIRECTORIES.each do |gem,
|
162
|
+
GEMS_AND_ROOT_DIRECTORIES.each do |gem, _directory|
|
172
163
|
desc "Build #{gem} packages"
|
173
164
|
task gem => %w[.gem .tar.gz].map { |e| package(gem, e) }
|
174
165
|
end
|
175
166
|
|
176
|
-
desc
|
177
|
-
task :
|
167
|
+
desc 'Build all packages'
|
168
|
+
task all: GEMS_AND_ROOT_DIRECTORIES.keys
|
178
169
|
end
|
179
170
|
|
180
171
|
namespace :install do
|
181
|
-
GEMS_AND_ROOT_DIRECTORIES.each do |gem,
|
172
|
+
GEMS_AND_ROOT_DIRECTORIES.each do |gem, _directory|
|
182
173
|
desc "Build and install #{gem} as local gem"
|
183
174
|
task gem => package(gem, '.gem') do
|
184
175
|
sh "gem install #{package(gem, '.gem')}"
|
185
176
|
end
|
186
177
|
end
|
187
178
|
|
188
|
-
desc
|
189
|
-
task :
|
179
|
+
desc 'Build and install all of the gems as local gems'
|
180
|
+
task all: GEMS_AND_ROOT_DIRECTORIES.keys
|
190
181
|
end
|
191
182
|
|
192
183
|
namespace :release do
|
193
|
-
GEMS_AND_ROOT_DIRECTORIES.each do |gem,
|
184
|
+
GEMS_AND_ROOT_DIRECTORIES.each do |gem, _directory|
|
194
185
|
desc "Release #{gem} as a package"
|
195
186
|
task gem => "package:#{gem}" do
|
196
187
|
sh <<-SH
|
@@ -200,7 +191,7 @@ if defined?(Gem)
|
|
200
191
|
end
|
201
192
|
end
|
202
193
|
|
203
|
-
desc
|
194
|
+
desc 'Commits the version to github repository'
|
204
195
|
task :commit_version do
|
205
196
|
%w[
|
206
197
|
lib/sinatra
|
@@ -219,7 +210,7 @@ if defined?(Gem)
|
|
219
210
|
SH
|
220
211
|
end
|
221
212
|
|
222
|
-
desc
|
223
|
-
task :
|
213
|
+
desc 'Release all gems as packages'
|
214
|
+
task all: %i[test commit_version] + GEMS_AND_ROOT_DIRECTORIES.keys
|
224
215
|
end
|
225
216
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.1.0
|
data/examples/chat.rb
CHANGED
@@ -1,24 +1,37 @@
|
|
1
1
|
#!/usr/bin/env ruby -I ../lib -I lib
|
2
|
-
#
|
3
|
-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# This example does *not* work properly with WEBrick or other
|
5
|
+
# servers that buffer output. To shut down the server, close any
|
6
|
+
# open browser tabs that are connected to the chat server.
|
7
|
+
|
4
8
|
require 'sinatra'
|
5
|
-
set :server, :
|
6
|
-
connections =
|
9
|
+
set :server, :puma
|
10
|
+
connections = Set.new
|
7
11
|
|
8
12
|
get '/' do
|
9
13
|
halt erb(:login) unless params[:user]
|
10
|
-
erb :chat, :
|
14
|
+
erb :chat, locals: { user: params[:user].gsub(/\W/, '') }
|
11
15
|
end
|
12
16
|
|
13
|
-
get '/stream', :
|
17
|
+
get '/stream', provides: 'text/event-stream' do
|
14
18
|
stream :keep_open do |out|
|
15
|
-
connections
|
16
|
-
|
19
|
+
if connections.add?(out)
|
20
|
+
out.callback { connections.delete(out) }
|
21
|
+
end
|
22
|
+
out << "heartbeat:\n"
|
23
|
+
sleep 1
|
24
|
+
rescue
|
25
|
+
out.close
|
17
26
|
end
|
18
27
|
end
|
19
28
|
|
20
29
|
post '/' do
|
21
|
-
connections.each
|
30
|
+
connections.each do |out|
|
31
|
+
out << "data: #{params[:msg]}\n\n"
|
32
|
+
rescue
|
33
|
+
out.close
|
34
|
+
end
|
22
35
|
204 # response without entity body
|
23
36
|
end
|
24
37
|
|
@@ -35,10 +48,10 @@ __END__
|
|
35
48
|
</html>
|
36
49
|
|
37
50
|
@@ login
|
38
|
-
<form action=
|
51
|
+
<form action="/">
|
39
52
|
<label for='user'>User Name:</label>
|
40
|
-
<input name=
|
41
|
-
<input type=
|
53
|
+
<input name="user" value="" />
|
54
|
+
<input type="submit" value="GO!" />
|
42
55
|
</form>
|
43
56
|
|
44
57
|
@@ chat
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby -I ../lib -I lib
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'sinatra'
|
5
|
+
|
6
|
+
get('/') do
|
7
|
+
'This shows how lifecycle events work'
|
8
|
+
end
|
9
|
+
|
10
|
+
on_start do
|
11
|
+
puts "=============="
|
12
|
+
puts " Booting up"
|
13
|
+
puts "=============="
|
14
|
+
end
|
15
|
+
|
16
|
+
on_stop do
|
17
|
+
puts "================="
|
18
|
+
puts " Shutting down"
|
19
|
+
puts "================="
|
20
|
+
end
|
data/examples/rainbows.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rainbows'
|
2
4
|
|
3
5
|
module Rack
|
@@ -8,7 +10,7 @@ module Rack
|
|
8
10
|
listeners: ["#{options[:Host]}:#{options[:Port]}"],
|
9
11
|
worker_processes: 1,
|
10
12
|
timeout: 30,
|
11
|
-
config_file: ::File.expand_path('rainbows.conf', __dir__)
|
13
|
+
config_file: ::File.expand_path('rainbows.conf', __dir__)
|
12
14
|
}
|
13
15
|
|
14
16
|
::Rainbows::HttpServer.new(app, rainbows_options).start.join
|
data/examples/simple.rb
CHANGED
data/examples/stream.ru
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# this example does *not* work properly with WEBrick
|
2
4
|
#
|
3
5
|
# run *one* of these:
|
4
6
|
#
|
5
|
-
# rackup -s mongrel stream.ru # gem install mongrel
|
6
7
|
# unicorn stream.ru # gem install unicorn
|
7
8
|
# puma stream.ru # gem install puma
|
8
9
|
# rainbows -c rainbows.conf stream.ru # gem install rainbows eventmachine
|