stir_fry 0.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +9 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/Gemfile +16 -0
- data/LICENSE +21 -0
- data/README.md +99 -0
- data/Rakefile +40 -0
- data/lib/stir_fry/app.rb +290 -0
- data/lib/stir_fry/component.rb +80 -0
- data/lib/stir_fry/middleware/logger.rb +88 -0
- data/lib/stir_fry/middleware.rb +8 -0
- data/lib/stir_fry/pages/error_page.rb +68 -0
- data/lib/stir_fry/pages/layout.rb +15 -0
- data/lib/stir_fry/pages/not_found_page.rb +31 -0
- data/lib/stir_fry/pages/routes_page.rb +21 -0
- data/lib/stir_fry/pages.rb +10 -0
- data/lib/stir_fry/request.rb +43 -0
- data/lib/stir_fry/response.rb +351 -0
- data/lib/stir_fry/static/stir_fry.css +64 -0
- data/lib/stir_fry/version.rb +6 -0
- data/lib/stir_fry.rb +180 -0
- data/stir_fry.gemspec +45 -0
- metadata +180 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--ruby-red: #cc342d;
|
|
3
|
+
--ruby-green: #2e8b57;
|
|
4
|
+
--ink: #2b2b2b;
|
|
5
|
+
--muted: #6b6b6b;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
* {
|
|
9
|
+
box-sizing: border-box;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
body {
|
|
13
|
+
margin: 0;
|
|
14
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
|
15
|
+
color: var(--ink);
|
|
16
|
+
background: #fafafa;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
section {
|
|
20
|
+
max-width: 640px;
|
|
21
|
+
margin: 0 auto;
|
|
22
|
+
padding: 2rem 1.5rem;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
header h1 {
|
|
26
|
+
display: inline-block;
|
|
27
|
+
color: var(--ruby-red);
|
|
28
|
+
border-bottom: 3px solid var(--ruby-green);
|
|
29
|
+
padding-bottom: 0.5rem;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.error-page {
|
|
33
|
+
text-align: center;
|
|
34
|
+
padding: 4rem 1.5rem;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.error-page__code {
|
|
38
|
+
margin: 0;
|
|
39
|
+
color: var(--ruby-red);
|
|
40
|
+
font-size: 4rem;
|
|
41
|
+
font-weight: 700;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.error-page__path {
|
|
45
|
+
display: inline-block;
|
|
46
|
+
margin: 0 0 1rem;
|
|
47
|
+
padding: 0.35rem 0.75rem;
|
|
48
|
+
border: 1px solid var(--ruby-green);
|
|
49
|
+
border-radius: 4px;
|
|
50
|
+
background: #eef6f0;
|
|
51
|
+
color: var(--ink);
|
|
52
|
+
font-family: Menlo, Consolas, "Liberation Mono", monospace;
|
|
53
|
+
font-size: 0.9rem;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.error-page__message {
|
|
57
|
+
color: var(--muted);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
ul.error-page__backtrace {
|
|
61
|
+
color: var(--muted);
|
|
62
|
+
text-align: left;
|
|
63
|
+
list-style-type: none;
|
|
64
|
+
}
|
data/lib/stir_fry.rb
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "semantic_logger"
|
|
4
|
+
require "rbx"
|
|
5
|
+
require "rackup"
|
|
6
|
+
require "logger"
|
|
7
|
+
|
|
8
|
+
##
|
|
9
|
+
# StirFry as a module provides an entrypoint to starting your app. It is also the
|
|
10
|
+
# namespace that contains the server library that will render the rbx templates.
|
|
11
|
+
module StirFry
|
|
12
|
+
# Error is the main root error for most errors raised by the library. Most of these
|
|
13
|
+
# errors are raised to bail out of a request cycle early and return early.
|
|
14
|
+
class Error < StandardError; end
|
|
15
|
+
# Okay represents a http 200 response.
|
|
16
|
+
class OKAY < Error; end
|
|
17
|
+
# Found represents a http 302 response.
|
|
18
|
+
class Found < Error; end
|
|
19
|
+
# NotModified represents a http 304 response.
|
|
20
|
+
class NotModified < Error; end
|
|
21
|
+
# BadRequest represents a http 400 response.
|
|
22
|
+
class BadRequest < Error; end
|
|
23
|
+
# Unauthorized represents a http 401 response.
|
|
24
|
+
class Unauthorized < Error; end
|
|
25
|
+
# NotFound represents a http 404 response.
|
|
26
|
+
class NotFound < Error; end
|
|
27
|
+
# PreconditionFailed represents a http 412 response.
|
|
28
|
+
class PreconditionFailed < Error; end
|
|
29
|
+
# InternalError represents a http 500 response.
|
|
30
|
+
class InternalError < Error; end
|
|
31
|
+
|
|
32
|
+
autoload :App, "stir_fry/app"
|
|
33
|
+
autoload :Component, "stir_fry/component"
|
|
34
|
+
autoload :Pages, "stir_fry/pages"
|
|
35
|
+
autoload :Request, "stir_fry/request"
|
|
36
|
+
autoload :Response, "stir_fry/response"
|
|
37
|
+
autoload :Middleware, "stir_fry/middleware"
|
|
38
|
+
autoload :Version, "stir_fry/version"
|
|
39
|
+
|
|
40
|
+
SIGNALS = %i[INT TERM].freeze # :nodoc:
|
|
41
|
+
|
|
42
|
+
class << self
|
|
43
|
+
attr_reader :running_server # :nodoc:
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# Start the application server for an App.
|
|
47
|
+
#
|
|
48
|
+
# Example:
|
|
49
|
+
#
|
|
50
|
+
# ```ruby
|
|
51
|
+
# class App < StirFry::App
|
|
52
|
+
# get "/" { |request:, response:| response.text("Hello world") }
|
|
53
|
+
# end
|
|
54
|
+
#
|
|
55
|
+
# StirFry.run!(App)
|
|
56
|
+
# ```
|
|
57
|
+
#
|
|
58
|
+
# Options:
|
|
59
|
+
#
|
|
60
|
+
# - port [int] port to listen on for the server.
|
|
61
|
+
# Defaults to 8080 in development and 80 in production.
|
|
62
|
+
# - host [string] host to bind on.
|
|
63
|
+
# Default to `localhost` in development and `0.0.0.0` in production
|
|
64
|
+
# - logger [Logger] logger to output requests and app messages to.
|
|
65
|
+
# Defaults to new semantic logger.
|
|
66
|
+
# - log_level [Symbol] the log level or limit output of the log.
|
|
67
|
+
# options: (:trace, :debug, :info, :warn, :error, :fatal)
|
|
68
|
+
# default: :trace in development and :info in production.
|
|
69
|
+
# - log_format [Symbol] the output format of the semantic logger.
|
|
70
|
+
# options: (:default, :color, :json, :logfmt)
|
|
71
|
+
# - log_stdout disable stdout logging.
|
|
72
|
+
# default: true
|
|
73
|
+
# - log_file set a filepath to output logs to.
|
|
74
|
+
# default: nil, only outputs to stdout.
|
|
75
|
+
#
|
|
76
|
+
def run!(app_klass, **options)
|
|
77
|
+
return unless running_server.nil?
|
|
78
|
+
|
|
79
|
+
Rackup::Handler.default.run(app_klass, **extract_options(app_klass, **options)) do |server|
|
|
80
|
+
at_exit { quit! }
|
|
81
|
+
SIGNALS.each { |signal| chain_trap(signal) { quit! } }
|
|
82
|
+
@logger.info("Server started", **server_info(server))
|
|
83
|
+
server.threaded = true if server.respond_to? :threaded=
|
|
84
|
+
@running_server = server
|
|
85
|
+
end
|
|
86
|
+
ensure
|
|
87
|
+
quit!
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
##
|
|
91
|
+
# Returns the running status of the server. If `run!` has not already been called
|
|
92
|
+
# then this will return false.
|
|
93
|
+
def running? = !running_server.nil?
|
|
94
|
+
|
|
95
|
+
# Is the set environment setting evaluated from environment variables APP_ENV,
|
|
96
|
+
# RACK_ENV or ENV. It defaults to :development.
|
|
97
|
+
def app_env = @app_env ||= (ENV["APP_ENV"] || ENV["RACK_ENV"] || ENV["ENV"] || :development).to_sym
|
|
98
|
+
|
|
99
|
+
# is the app running in development.
|
|
100
|
+
def development? = app_env == :development
|
|
101
|
+
|
|
102
|
+
# is the app running in test.
|
|
103
|
+
def test? = app_env == :test
|
|
104
|
+
|
|
105
|
+
# is the app running in production
|
|
106
|
+
def production? = app_end == :production
|
|
107
|
+
|
|
108
|
+
# Logger is the app wide logger for any app messages.
|
|
109
|
+
def logger = @logger ||= default_logger(App)
|
|
110
|
+
|
|
111
|
+
##
|
|
112
|
+
# Stops the running server if it is running. If it is not running then this is
|
|
113
|
+
# a no-op
|
|
114
|
+
def quit!
|
|
115
|
+
return if running_server.nil?
|
|
116
|
+
|
|
117
|
+
running_server.respond_to?(:stop!) ? running_server.stop! : running_server.stop
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
private
|
|
121
|
+
|
|
122
|
+
def extract_options(klass, **options)
|
|
123
|
+
@port = options.fetch(:Port, options.fetch(:port, default_port)) || default_port
|
|
124
|
+
@host = options.fetch(:Host, options.fetch(:host, default_host)) || default_host
|
|
125
|
+
@logger = options.delete(:logger) || default_logger(klass, options)
|
|
126
|
+
dev_null = Logger.new(File.open(File::NULL, "w"))
|
|
127
|
+
{
|
|
128
|
+
# Set the capitalized options in case the downcased options are set.
|
|
129
|
+
Port: @port,
|
|
130
|
+
Host: @host,
|
|
131
|
+
# Disable Rack logging
|
|
132
|
+
Logger: dev_null,
|
|
133
|
+
AccessLog: dev_null
|
|
134
|
+
}.merge(options)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def server_info(server)
|
|
138
|
+
{
|
|
139
|
+
port: @port,
|
|
140
|
+
host: @host,
|
|
141
|
+
app_env: @app_env,
|
|
142
|
+
threaded: server.respond_to?(:threaded=),
|
|
143
|
+
server: Rackup::Handler.default.name
|
|
144
|
+
}
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def default_logger(klass, options = {})
|
|
148
|
+
log_format = options.fetch(:log_format, :color) || :color
|
|
149
|
+
log_stdout = options.fetch(:log_silence, false)
|
|
150
|
+
log_file = options.fetch(:log_file, nil)
|
|
151
|
+
|
|
152
|
+
SemanticLogger.add_signal_handler
|
|
153
|
+
SemanticLogger.application = klass.name.to_s
|
|
154
|
+
SemanticLogger.environment = @app_env
|
|
155
|
+
SemanticLogger.default_level = options.fetch(:log_level, default_log_level) || default_log_level
|
|
156
|
+
SemanticLogger.add_appender(io: $stdout, formatter: log_format) unless log_stdout
|
|
157
|
+
SemanticLogger.add_appender(filename: log_file, formatter: log_format) unless log_file.nil?
|
|
158
|
+
SemanticLogger[klass.name.to_s]
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def default_port
|
|
162
|
+
development? ? "8080" : "80"
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def default_host
|
|
166
|
+
development? ? "localhost" : "0.0.0.0"
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def default_log_level
|
|
170
|
+
development? ? :trace : :info
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def chain_trap(sig, &)
|
|
174
|
+
prev = Signal.trap(sig) do
|
|
175
|
+
yield
|
|
176
|
+
prev.call if prev.respond_to?(:call)
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
data/stir_fry.gemspec
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/stir_fry/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "stir_fry"
|
|
7
|
+
spec.version = StirFry::VERSION
|
|
8
|
+
spec.authors = ["Tim Anema"]
|
|
9
|
+
spec.email = ["timanema@gmail.com"]
|
|
10
|
+
spec.summary = "Small simple ruby web framework that feels familiar."
|
|
11
|
+
spec.description = <<~DESC
|
|
12
|
+
Small simple ruby web framework that feels familiar.
|
|
13
|
+
It leverages a JSX like templating language, simple routing definitions
|
|
14
|
+
similar to sinatra and usage of ruby that will make it feel easy and understandable.
|
|
15
|
+
DESC
|
|
16
|
+
spec.homepage = "https://github.com/tanema/stir_fry"
|
|
17
|
+
spec.license = "MIT"
|
|
18
|
+
spec.required_ruby_version = ">= 3.1"
|
|
19
|
+
spec.require_paths = ["lib"]
|
|
20
|
+
spec.metadata = {
|
|
21
|
+
"source_code_uri" => "https://github.com/tanema/stir_fry",
|
|
22
|
+
"changelog_uri" => "https://github.com/tanema/stir_fry/blob/main/CHANGELOG.md",
|
|
23
|
+
"homepage_uri" => spec.homepage,
|
|
24
|
+
"bug_tracker_uri" => "https://github.com/tanema/stir_fry/issues",
|
|
25
|
+
"documentation_uri" => "https://github.com/tanema/stir_fry",
|
|
26
|
+
"rubygems_mfa_required" => "true"
|
|
27
|
+
}
|
|
28
|
+
spec.files = Dir["lib/**/*"] + [
|
|
29
|
+
"README.md",
|
|
30
|
+
"CHANGELOG.md",
|
|
31
|
+
"CODE_OF_CONDUCT.md",
|
|
32
|
+
"Gemfile",
|
|
33
|
+
"LICENSE",
|
|
34
|
+
"Rakefile",
|
|
35
|
+
"stir_fry.gemspec"
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
spec.add_dependency "mustermann", "~> 3.0"
|
|
39
|
+
spec.add_dependency "rack", ">= 3.0.0", "< 4"
|
|
40
|
+
spec.add_dependency "rack-protection", ">= 3.1"
|
|
41
|
+
spec.add_dependency "rack-session", ">= 2.0.0", "< 3"
|
|
42
|
+
spec.add_dependency "rackup", ">= 2.1"
|
|
43
|
+
spec.add_dependency "rbxrb", ">= 0.1"
|
|
44
|
+
spec.add_dependency "semantic_logger", ">= 5.1"
|
|
45
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: stir_fry
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Tim Anema
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: mustermann
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '3.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '3.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: rack
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 3.0.0
|
|
33
|
+
- - "<"
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: '4'
|
|
36
|
+
type: :runtime
|
|
37
|
+
prerelease: false
|
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: 3.0.0
|
|
43
|
+
- - "<"
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '4'
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: rack-protection
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
requirements:
|
|
50
|
+
- - ">="
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: '3.1'
|
|
53
|
+
type: :runtime
|
|
54
|
+
prerelease: false
|
|
55
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
56
|
+
requirements:
|
|
57
|
+
- - ">="
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: '3.1'
|
|
60
|
+
- !ruby/object:Gem::Dependency
|
|
61
|
+
name: rack-session
|
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - ">="
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: 2.0.0
|
|
67
|
+
- - "<"
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '3'
|
|
70
|
+
type: :runtime
|
|
71
|
+
prerelease: false
|
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
requirements:
|
|
74
|
+
- - ">="
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: 2.0.0
|
|
77
|
+
- - "<"
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '3'
|
|
80
|
+
- !ruby/object:Gem::Dependency
|
|
81
|
+
name: rackup
|
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
|
83
|
+
requirements:
|
|
84
|
+
- - ">="
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
86
|
+
version: '2.1'
|
|
87
|
+
type: :runtime
|
|
88
|
+
prerelease: false
|
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
90
|
+
requirements:
|
|
91
|
+
- - ">="
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '2.1'
|
|
94
|
+
- !ruby/object:Gem::Dependency
|
|
95
|
+
name: rbxrb
|
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
|
97
|
+
requirements:
|
|
98
|
+
- - ">="
|
|
99
|
+
- !ruby/object:Gem::Version
|
|
100
|
+
version: '0.1'
|
|
101
|
+
type: :runtime
|
|
102
|
+
prerelease: false
|
|
103
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
104
|
+
requirements:
|
|
105
|
+
- - ">="
|
|
106
|
+
- !ruby/object:Gem::Version
|
|
107
|
+
version: '0.1'
|
|
108
|
+
- !ruby/object:Gem::Dependency
|
|
109
|
+
name: semantic_logger
|
|
110
|
+
requirement: !ruby/object:Gem::Requirement
|
|
111
|
+
requirements:
|
|
112
|
+
- - ">="
|
|
113
|
+
- !ruby/object:Gem::Version
|
|
114
|
+
version: '5.1'
|
|
115
|
+
type: :runtime
|
|
116
|
+
prerelease: false
|
|
117
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
118
|
+
requirements:
|
|
119
|
+
- - ">="
|
|
120
|
+
- !ruby/object:Gem::Version
|
|
121
|
+
version: '5.1'
|
|
122
|
+
description: |
|
|
123
|
+
Small simple ruby web framework that feels familiar.
|
|
124
|
+
It leverages a JSX like templating language, simple routing definitions
|
|
125
|
+
similar to sinatra and usage of ruby that will make it feel easy and understandable.
|
|
126
|
+
email:
|
|
127
|
+
- timanema@gmail.com
|
|
128
|
+
executables: []
|
|
129
|
+
extensions: []
|
|
130
|
+
extra_rdoc_files: []
|
|
131
|
+
files:
|
|
132
|
+
- CHANGELOG.md
|
|
133
|
+
- CODE_OF_CONDUCT.md
|
|
134
|
+
- Gemfile
|
|
135
|
+
- LICENSE
|
|
136
|
+
- README.md
|
|
137
|
+
- Rakefile
|
|
138
|
+
- lib/stir_fry.rb
|
|
139
|
+
- lib/stir_fry/app.rb
|
|
140
|
+
- lib/stir_fry/component.rb
|
|
141
|
+
- lib/stir_fry/middleware.rb
|
|
142
|
+
- lib/stir_fry/middleware/logger.rb
|
|
143
|
+
- lib/stir_fry/pages.rb
|
|
144
|
+
- lib/stir_fry/pages/error_page.rb
|
|
145
|
+
- lib/stir_fry/pages/layout.rb
|
|
146
|
+
- lib/stir_fry/pages/not_found_page.rb
|
|
147
|
+
- lib/stir_fry/pages/routes_page.rb
|
|
148
|
+
- lib/stir_fry/request.rb
|
|
149
|
+
- lib/stir_fry/response.rb
|
|
150
|
+
- lib/stir_fry/static/stir_fry.css
|
|
151
|
+
- lib/stir_fry/version.rb
|
|
152
|
+
- stir_fry.gemspec
|
|
153
|
+
homepage: https://github.com/tanema/stir_fry
|
|
154
|
+
licenses:
|
|
155
|
+
- MIT
|
|
156
|
+
metadata:
|
|
157
|
+
source_code_uri: https://github.com/tanema/stir_fry
|
|
158
|
+
changelog_uri: https://github.com/tanema/stir_fry/blob/main/CHANGELOG.md
|
|
159
|
+
homepage_uri: https://github.com/tanema/stir_fry
|
|
160
|
+
bug_tracker_uri: https://github.com/tanema/stir_fry/issues
|
|
161
|
+
documentation_uri: https://github.com/tanema/stir_fry
|
|
162
|
+
rubygems_mfa_required: 'true'
|
|
163
|
+
rdoc_options: []
|
|
164
|
+
require_paths:
|
|
165
|
+
- lib
|
|
166
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
167
|
+
requirements:
|
|
168
|
+
- - ">="
|
|
169
|
+
- !ruby/object:Gem::Version
|
|
170
|
+
version: '3.1'
|
|
171
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
172
|
+
requirements:
|
|
173
|
+
- - ">="
|
|
174
|
+
- !ruby/object:Gem::Version
|
|
175
|
+
version: '0'
|
|
176
|
+
requirements: []
|
|
177
|
+
rubygems_version: 3.6.9
|
|
178
|
+
specification_version: 4
|
|
179
|
+
summary: Small simple ruby web framework that feels familiar.
|
|
180
|
+
test_files: []
|