reins-web 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/bin/console +15 -0
- data/bin/reins +5 -0
- data/bin/setup +8 -0
- data/lib/reins/array.rb +5 -0
- data/lib/reins/cli.rb +46 -0
- data/lib/reins/controller.rb +81 -0
- data/lib/reins/dependencies.rb +13 -0
- data/lib/reins/file_model.rb +94 -0
- data/lib/reins/routing.rb +94 -0
- data/lib/reins/sqlite_model.rb +109 -0
- data/lib/reins/util.rb +9 -0
- data/lib/reins/version.rb +5 -0
- data/lib/reins/view.rb +20 -0
- data/lib/reins.rb +53 -0
- metadata +201 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 20240edf92760205c1c0c7e963b286017d07c755bee1f184eb182de326d84788
|
4
|
+
data.tar.gz: d3aa3aadaff2d9768d912324c915cf076dbb7f02aacb06354238448825c6a5dc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5b1f4dabb1f0ba43073319ce938f150de72110cef04303cf6c74581e5a456321d6580d7028696e5984bc962c7f9ea97c58c13d9f9391427fa1295b4c39de2be0
|
7
|
+
data.tar.gz: 4e78fb4c4a83c9c153d10f2fc390f28ea291ee3452b55aa2202c4df27cb191800464ee40bbdd93beb5c67febe83dcafa3d11e7599711a82d92330842ebfea694
|
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "reins"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/reins
ADDED
data/bin/setup
ADDED
data/lib/reins/array.rb
ADDED
data/lib/reins/cli.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'puma'
|
4
|
+
require 'rack'
|
5
|
+
|
6
|
+
module Reins
|
7
|
+
class Cli < Thor
|
8
|
+
desc "new", "Create a new Reins project"
|
9
|
+
def new(name)
|
10
|
+
scaffold_project(name)
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "server", "Run a local server"
|
14
|
+
def server
|
15
|
+
root = File.expand_path("#{Dir.pwd}")
|
16
|
+
config = root + "/config.ru"
|
17
|
+
|
18
|
+
app = Rack::Builder.load_file(config)
|
19
|
+
|
20
|
+
server = Puma::Server.new(app)
|
21
|
+
server.add_tcp_listener('0.0.0.0', 8000)
|
22
|
+
|
23
|
+
trap('INT') do
|
24
|
+
server.stop
|
25
|
+
puts "\nServer stopped."
|
26
|
+
exit
|
27
|
+
end
|
28
|
+
|
29
|
+
puts "Serving files from #{root} on http://localhost:8000"
|
30
|
+
server.run.join
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def scaffold_project(dir)
|
36
|
+
FileUtils.mkdir(dir)
|
37
|
+
FileUtils.mkdir(dir + "/app")
|
38
|
+
FileUtils.mkdir(dir + "/app/controllers")
|
39
|
+
FileUtils.mkdir(dir + "/app/views")
|
40
|
+
FileUtils.mkdir(dir + "/app/views/welcome")
|
41
|
+
FileUtils.mkdir(dir + "/config")
|
42
|
+
FileUtils.mkdir(dir + "/public")
|
43
|
+
FileUtils.cp(File.dirname(__FILE__) + "/../../assets/500.html", "testdir/public/500.html")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'rack'
|
2
|
+
require "reins/file_model"
|
3
|
+
require "reins/view"
|
4
|
+
|
5
|
+
module Reins
|
6
|
+
class Controller
|
7
|
+
include Reins::Model
|
8
|
+
|
9
|
+
def initialize(env)
|
10
|
+
@env = env
|
11
|
+
@routing_params = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def dispatch(action, routing_params = {})
|
15
|
+
@routing_params = routing_params
|
16
|
+
text = self.send(action)
|
17
|
+
r = get_response
|
18
|
+
if r
|
19
|
+
[r.status, r.headers, [r.body].flatten]
|
20
|
+
else
|
21
|
+
[200, {'content-type' => 'text/html'},
|
22
|
+
[text].flatten]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.action(act, rp = {})
|
27
|
+
proc { |e| self.new(e).dispatch(act, rp) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def env
|
31
|
+
@env
|
32
|
+
end
|
33
|
+
|
34
|
+
def request
|
35
|
+
@request ||= Rack::Request.new(@env)
|
36
|
+
end
|
37
|
+
|
38
|
+
def params
|
39
|
+
request.params.merge @routing_params
|
40
|
+
end
|
41
|
+
|
42
|
+
def response(text, status = 200, headers = {})
|
43
|
+
raise "Already responded!" if @response
|
44
|
+
a = [text].flatten
|
45
|
+
@response = Rack::Response.new(a, status, headers)
|
46
|
+
end
|
47
|
+
|
48
|
+
def get_response
|
49
|
+
@response
|
50
|
+
end
|
51
|
+
|
52
|
+
def controller_name
|
53
|
+
klass = self.class
|
54
|
+
klass = klass.to_s.gsub(/Controller$/, "")
|
55
|
+
Reins.to_underscore klass
|
56
|
+
end
|
57
|
+
|
58
|
+
def instance_hash
|
59
|
+
h = {}
|
60
|
+
instance_variables.each do |i|
|
61
|
+
h[i] = instance_variable_get i
|
62
|
+
end
|
63
|
+
h
|
64
|
+
end
|
65
|
+
|
66
|
+
def render(view_name, locals = {})
|
67
|
+
filename = File.join "app", "views",
|
68
|
+
controller_name, "#{view_name}.html.erb"
|
69
|
+
template = File.read filename
|
70
|
+
v = View.new
|
71
|
+
v.set_vars instance_hash
|
72
|
+
v.evaluate template
|
73
|
+
# instance_vars = instance_variables.each_with_object({}) do |var, hash|
|
74
|
+
# hash[var.to_s.delete("@").to_sym] = instance_variable_get(var)
|
75
|
+
# end
|
76
|
+
# eruby = Erubis::Eruby.new(template)
|
77
|
+
# result = eruby.result locals.merge(instance_vars) # locals.merge(:env => env)
|
78
|
+
# response(result)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Object
|
2
|
+
def self.const_missing(c)
|
3
|
+
@calling_const_missing ||= {}
|
4
|
+
return nil if @calling_const_missing[c]
|
5
|
+
|
6
|
+
@calling_const_missing[c] = true
|
7
|
+
require Reins.to_underscore(c.to_s)
|
8
|
+
klass = Object.const_get(c)
|
9
|
+
@calling_const_missing[c] = false
|
10
|
+
|
11
|
+
klass
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require "multi_json"
|
2
|
+
|
3
|
+
module Reins
|
4
|
+
module Model
|
5
|
+
class FileModel
|
6
|
+
def initialize(filename)
|
7
|
+
@filename = filename
|
8
|
+
# If filename is "dir/37.json", @id is 37
|
9
|
+
basename = File.split(filename)[-1]
|
10
|
+
@id = File.basename(basename, ".json").to_i
|
11
|
+
obj = File.read(filename)
|
12
|
+
@hash = MultiJson.load(obj)
|
13
|
+
end
|
14
|
+
|
15
|
+
def [](name)
|
16
|
+
@hash[name.to_s]
|
17
|
+
end
|
18
|
+
|
19
|
+
def []=(name, value)
|
20
|
+
@hash[name.to_s] = value
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.all
|
24
|
+
files = Dir["db/quotes/*.json"]
|
25
|
+
files.map { |f| FileModel.new f }
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.find(id)
|
29
|
+
begin
|
30
|
+
FileModel.new("db/quotes/#{id}.json")
|
31
|
+
rescue
|
32
|
+
return nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.create(attrs)
|
37
|
+
hash = {}
|
38
|
+
hash["submitter"] = attrs["submitter"] || ""
|
39
|
+
hash["quote"] = attrs["quote"] || ""
|
40
|
+
hash["attribution"] = attrs["attribution"] || ""
|
41
|
+
|
42
|
+
files = Dir["db/quotes/*.json"]
|
43
|
+
names = files.map { |f| File.split(f)[-1] }
|
44
|
+
highest = names.map { |b| b.to_i }.max
|
45
|
+
|
46
|
+
id = highest + 1
|
47
|
+
File.open("db/quotes/#{id}.json", "w") do |f|
|
48
|
+
f.write <<TEMPLATE
|
49
|
+
{
|
50
|
+
"submitter": "#{hash["submitter"]}",
|
51
|
+
"quote": "#{hash["quote"]}",
|
52
|
+
"attribution": "#{hash["attribution"]}"
|
53
|
+
}
|
54
|
+
TEMPLATE
|
55
|
+
end
|
56
|
+
|
57
|
+
FileModel.new "db/quotes/#{id}.json"
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.update(attrs)
|
61
|
+
hash = {}
|
62
|
+
hash["submitter"] = attrs["submitter"] || ""
|
63
|
+
hash["quote"] = attrs["quote"] || ""
|
64
|
+
hash["attribution"] = attrs["attribution"] || ""
|
65
|
+
|
66
|
+
id = 3
|
67
|
+
File.open("db/quotes/#{id}.json", "w") do |f|
|
68
|
+
f.write <<TEMPLATE
|
69
|
+
{
|
70
|
+
"submitter": "#{hash["submitter"]}",
|
71
|
+
"quote": "#{hash["quote"]}",
|
72
|
+
"attribution": "#{hash["attribution"]}"
|
73
|
+
}
|
74
|
+
TEMPLATE
|
75
|
+
end
|
76
|
+
|
77
|
+
FileModel.new "db/quotes/#{id}.json"
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.save
|
81
|
+
# TODO: use MultiJson.dump() to turn @hash into JSON
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.find_all_by_submitter(submitter)
|
85
|
+
files = Dir["db/quotes/*.json"]
|
86
|
+
files.map { |f| FileModel.new f }
|
87
|
+
.select { |m| m['submitter'] == submitter }
|
88
|
+
end
|
89
|
+
|
90
|
+
# TODO: Add method_missing for things that match /^find_all_by_(.*)/
|
91
|
+
# NOTE: always override respond_to_missing? if you override method_missing
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Reins
|
2
|
+
class RouteObject
|
3
|
+
def initialize
|
4
|
+
@rules = []
|
5
|
+
end
|
6
|
+
|
7
|
+
def match(url, *args)
|
8
|
+
options = {}
|
9
|
+
options = args.pop if args[-1].is_a?(Hash)
|
10
|
+
options[:default] ||= {}
|
11
|
+
|
12
|
+
dest = nil
|
13
|
+
dest = args.pop if args.size > 0
|
14
|
+
raise "Too many args!" if args.size > 0
|
15
|
+
|
16
|
+
parts = url.split("/")
|
17
|
+
parts.select! { |p| !p.empty? }
|
18
|
+
|
19
|
+
vars = []
|
20
|
+
regexp_parts = parts.map do |part|
|
21
|
+
if part[0] == ":"
|
22
|
+
vars << part[1..-1]
|
23
|
+
"([a-zA-Z0-9]+)"
|
24
|
+
elsif part[0] == "*"
|
25
|
+
vars << part[1..-1]
|
26
|
+
"(.*)"
|
27
|
+
else
|
28
|
+
part
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
regexp = regexp_parts.join("/")
|
33
|
+
@rules.push({
|
34
|
+
:regexp => Regexp.new("^/#{regexp}$"),
|
35
|
+
:vars => vars,
|
36
|
+
:dest => dest,
|
37
|
+
:options => options,
|
38
|
+
})
|
39
|
+
end
|
40
|
+
|
41
|
+
def check_url(url)
|
42
|
+
@rules.each do |r|
|
43
|
+
m = r[:regexp].match(url)
|
44
|
+
if m
|
45
|
+
options = r[:options]
|
46
|
+
params = options[:default].dup
|
47
|
+
r[:vars].each_with_index do |v, i|
|
48
|
+
params[v] = m.captures[i]
|
49
|
+
end
|
50
|
+
# TODO: remove dest = nil in GH code
|
51
|
+
if r[:dest]
|
52
|
+
return get_dest(r[:dest], params)
|
53
|
+
else
|
54
|
+
controller = params["controller"]
|
55
|
+
action = params["action"]
|
56
|
+
return get_dest("#{controller}" +
|
57
|
+
"##{action}", params)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_dest(dest, routing_params = {})
|
66
|
+
return dest if dest.respond_to?(:call)
|
67
|
+
if dest =~ /^([^#]+)#([^#]+)$/
|
68
|
+
name = $1.capitalize
|
69
|
+
con = Object.const_get("#{name}Controller")
|
70
|
+
return con.action($2, routing_params)
|
71
|
+
end
|
72
|
+
raise "No destination: #{dest.inspect}!"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class Application
|
77
|
+
def route(&block)
|
78
|
+
@route_obj ||= RouteObject.new
|
79
|
+
@route_obj.instance_eval(&block)
|
80
|
+
end
|
81
|
+
|
82
|
+
def get_rack_app(env)
|
83
|
+
raise "No routes!" unless @route_obj
|
84
|
+
@route_obj.check_url env["PATH_INFO"]
|
85
|
+
end
|
86
|
+
|
87
|
+
# def get_controller_and_action(env)
|
88
|
+
# _, cont, action, _after = env["PATH_INFO"].split('/', 4)
|
89
|
+
# cont = cont.capitalize # "People"
|
90
|
+
# cont += "Controller" # "PeopleController"
|
91
|
+
# [Object.const_get(cont), action]
|
92
|
+
# end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require "sqlite3"
|
2
|
+
require "reins/util"
|
3
|
+
|
4
|
+
DB = SQLite3::Database.new "test.db"
|
5
|
+
module Reins
|
6
|
+
module Model
|
7
|
+
class SQLite
|
8
|
+
def initialize(data = nil)
|
9
|
+
@hash = data
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.to_sql(val)
|
13
|
+
case val
|
14
|
+
when NilClass
|
15
|
+
'null'
|
16
|
+
when Numeric
|
17
|
+
val.to_s
|
18
|
+
when String
|
19
|
+
"'#{val}'"
|
20
|
+
else
|
21
|
+
raise "Can't change #{val.class} to SQL!"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.create(values)
|
26
|
+
values.delete "id"
|
27
|
+
keys = schema.keys - ["id"]
|
28
|
+
vals = keys.map do |key|
|
29
|
+
values[key] ? to_sql(values[key]) : "null"
|
30
|
+
end
|
31
|
+
DB.execute <<SQL
|
32
|
+
INSERT INTO #{table} (#{keys.join ","})
|
33
|
+
VALUES (#{vals.join ","});
|
34
|
+
SQL
|
35
|
+
raw_vals = keys.map { |k| values[k] }
|
36
|
+
data = Hash[keys.zip raw_vals]
|
37
|
+
sql = "SELECT last_insert_rowid();"
|
38
|
+
data["id"] = DB.execute(sql)[0][0]
|
39
|
+
self.new data
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.count
|
43
|
+
DB.execute(<<SQL)[0][0]
|
44
|
+
SELECT COUNT(*) FROM #{table}
|
45
|
+
SQL
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.find(id)
|
49
|
+
row = DB.execute <<SQL
|
50
|
+
select #{schema.keys.join ","} from #{table}
|
51
|
+
where id = #{id};
|
52
|
+
SQL
|
53
|
+
data = Hash[schema.keys.zip row[0]]
|
54
|
+
self.new data
|
55
|
+
end
|
56
|
+
|
57
|
+
def [](name)
|
58
|
+
@hash[name.to_s]
|
59
|
+
end
|
60
|
+
|
61
|
+
def []=(name, value)
|
62
|
+
@hash[name.to_s] = value
|
63
|
+
end
|
64
|
+
|
65
|
+
def save!
|
66
|
+
fields = @hash.map do |k, v|
|
67
|
+
"#{k}=#{self.class.to_sql(v)}"
|
68
|
+
end.join ","
|
69
|
+
DB.execute <<SQL
|
70
|
+
UPDATE #{self.class.table}
|
71
|
+
SET #{fields}
|
72
|
+
WHERE id = #{@hash["id"]}
|
73
|
+
SQL
|
74
|
+
true
|
75
|
+
end
|
76
|
+
|
77
|
+
def save
|
78
|
+
self.save! rescue false
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.table
|
82
|
+
Reins.to_underscore name
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.all
|
86
|
+
rows = DB.execute <<SQL
|
87
|
+
select #{schema.keys.join ","} from #{table};
|
88
|
+
SQL
|
89
|
+
rows.map do |r|
|
90
|
+
data = Hash[schema.keys.zip r]
|
91
|
+
self.new data
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.schema
|
96
|
+
return @schema if @schema
|
97
|
+
@schema = {}
|
98
|
+
DB.table_info(table) do |row|
|
99
|
+
@schema[row["name"]] = row["type"]
|
100
|
+
end
|
101
|
+
@schema
|
102
|
+
end
|
103
|
+
|
104
|
+
def method_missing(name)
|
105
|
+
self[name]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
data/lib/reins/util.rb
ADDED
data/lib/reins/view.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'erubis'
|
2
|
+
|
3
|
+
module Reins
|
4
|
+
class View
|
5
|
+
def set_vars(instance_vars)
|
6
|
+
instance_vars.each do |name, value|
|
7
|
+
instance_variable_set(name, value)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def evaluate(template)
|
12
|
+
eruby = Erubis:Eruby.new(template)
|
13
|
+
eval eruby.src
|
14
|
+
end
|
15
|
+
|
16
|
+
def h(str)
|
17
|
+
URI.escape str
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/reins.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "reins/cli"
|
4
|
+
require "reins/version"
|
5
|
+
require "reins/array"
|
6
|
+
require "reins/routing"
|
7
|
+
require "reins/util"
|
8
|
+
require "reins/dependencies"
|
9
|
+
require "reins/controller"
|
10
|
+
require "reins/file_model"
|
11
|
+
require "reins/sqlite_model"
|
12
|
+
|
13
|
+
module Reins
|
14
|
+
def self.framework_root
|
15
|
+
__dir__
|
16
|
+
end
|
17
|
+
|
18
|
+
class Application
|
19
|
+
def call(env)
|
20
|
+
# `echo debug > debug.txt`;
|
21
|
+
if env['PATH_INFO'] == '/favicon.ico'
|
22
|
+
return [404, {'content-type' => 'text/html'}, []]
|
23
|
+
end
|
24
|
+
|
25
|
+
begin
|
26
|
+
rack_app = get_rack_app(env)
|
27
|
+
rack_app.call(env)
|
28
|
+
rescue
|
29
|
+
return [500, {'content-type' => 'text/html'},
|
30
|
+
[File.read('public/500.html')]]
|
31
|
+
end
|
32
|
+
# klass, act = get_controller_and_action(env)
|
33
|
+
# controller = klass.new(env)
|
34
|
+
# text = controller.send(act)
|
35
|
+
# r = controller.get_response
|
36
|
+
# if r
|
37
|
+
# [r.status, r.headers, [r.body].flatten]
|
38
|
+
# else
|
39
|
+
# controller.render(act)
|
40
|
+
# r = controller.get_response
|
41
|
+
# [r.status, r.headers, [r.body].flatten]
|
42
|
+
# end
|
43
|
+
# begin
|
44
|
+
# text = controller.send(act)
|
45
|
+
# rescue
|
46
|
+
# return [500, {'content-type' => 'text/html'},
|
47
|
+
# ['Server Error']]
|
48
|
+
# end
|
49
|
+
# [200, {'content-type' => 'text/html'},
|
50
|
+
# [text]]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
metadata
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: reins-web
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ian Johnson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-04-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: erubis
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: multi_json
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: sqlite3
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: thor
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: puma
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rerun
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: listen
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rack-test
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: minitest
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
description: A Rack-based Web Framework, but with extra awesome.
|
154
|
+
email:
|
155
|
+
- tacoda@hey.com
|
156
|
+
executables:
|
157
|
+
- reins
|
158
|
+
extensions: []
|
159
|
+
extra_rdoc_files: []
|
160
|
+
files:
|
161
|
+
- bin/console
|
162
|
+
- bin/reins
|
163
|
+
- bin/setup
|
164
|
+
- lib/reins.rb
|
165
|
+
- lib/reins/array.rb
|
166
|
+
- lib/reins/cli.rb
|
167
|
+
- lib/reins/controller.rb
|
168
|
+
- lib/reins/dependencies.rb
|
169
|
+
- lib/reins/file_model.rb
|
170
|
+
- lib/reins/routing.rb
|
171
|
+
- lib/reins/sqlite_model.rb
|
172
|
+
- lib/reins/util.rb
|
173
|
+
- lib/reins/version.rb
|
174
|
+
- lib/reins/view.rb
|
175
|
+
homepage: https://www.tacoda.dev/reins/
|
176
|
+
licenses: []
|
177
|
+
metadata:
|
178
|
+
homepage_uri: https://www.tacoda.dev/reins/
|
179
|
+
source_code_uri: https://github.com/tacoda/reins
|
180
|
+
changelog_uri: https://github.com/tacoda/reins
|
181
|
+
post_install_message:
|
182
|
+
rdoc_options: []
|
183
|
+
require_paths:
|
184
|
+
- bin
|
185
|
+
- lib
|
186
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
187
|
+
requirements:
|
188
|
+
- - ">="
|
189
|
+
- !ruby/object:Gem::Version
|
190
|
+
version: 2.6.0
|
191
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
192
|
+
requirements:
|
193
|
+
- - ">="
|
194
|
+
- !ruby/object:Gem::Version
|
195
|
+
version: '0'
|
196
|
+
requirements: []
|
197
|
+
rubygems_version: 3.4.10
|
198
|
+
signing_key:
|
199
|
+
specification_version: 4
|
200
|
+
summary: A Rack-based Web Framework
|
201
|
+
test_files: []
|