sinatra 2.2.4 → 3.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +99 -17
- data/CONTRIBUTING.md +11 -11
- data/Gemfile +44 -64
- data/MAINTENANCE.md +2 -2
- data/README.md +116 -414
- data/Rakefile +66 -75
- data/VERSION +1 -1
- data/examples/chat.rb +25 -12
- data/examples/rainbows.rb +3 -1
- data/examples/simple.rb +2 -0
- data/examples/stream.ru +2 -0
- data/lib/sinatra/base.rb +350 -336
- 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 +34 -26
- 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.0.6
|
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
|
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