keight 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +28 -8
- data/bench/benchmarker.rb +2 -2
- data/bin/k8rb +1 -1
- data/keight.gemspec +2 -1
- data/lib/keight.rb +27 -11
- data/lib/keight/skeleton/app/action.rb +13 -5
- data/lib/keight/skeleton/config.rb +7 -5
- data/test/keight_test.rb +14 -2
- data/test/oktest.rb +2 -2
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc49bd013923bbf4714db247133b1dee371519d3
|
4
|
+
data.tar.gz: f5cda960b9bd0772aae79b835ceca64ae7470c5e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32ef664b317f9c4053f1bad16e61de02616bcec598d40eb566f278fcc9e87ac35511c6f031cd91a26fae2c06a9de088b2ee8db80530b7966473878f6e613c3d7
|
7
|
+
data.tar.gz: e45639182983542961cda6d1dfc9bdb7b4e6b282a235162a66dabe74da220bd0cdd46b177d5b4d2410a67ef48fc0d0bfa60dca17bf58fdf559a17b4f65eef4d6
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Keight.rb README
|
2
2
|
================
|
3
3
|
|
4
|
-
($Release: 0.0
|
4
|
+
($Release: 0.1.0 $)
|
5
5
|
|
6
6
|
|
7
7
|
Overview
|
@@ -41,10 +41,16 @@ Quick Tutorial
|
|
41
41
|
--------------
|
42
42
|
|
43
43
|
```console
|
44
|
+
$ ruby -v # required Ruby >= 2.0
|
45
|
+
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-darwin14]
|
46
|
+
$ mkdir gems
|
47
|
+
$ export GEM_HOME=$PWD/gems
|
48
|
+
$ export PATH=$GEM_HOME/bin:$PATH
|
49
|
+
|
44
50
|
$ gem install keight
|
45
51
|
$ vi hello.rb
|
46
|
-
$ vi config.ru
|
47
|
-
$ rackup -
|
52
|
+
$ vi config.ru # != 'config.rb'
|
53
|
+
$ rackup -p 8000 config.ru
|
48
54
|
```
|
49
55
|
|
50
56
|
hello.rb:
|
@@ -82,24 +88,38 @@ config.rb:
|
|
82
88
|
require 'keight'
|
83
89
|
require './hello'
|
84
90
|
|
85
|
-
app = K8::RackApplication.new
|
91
|
+
app = K8::RackApplication.new()
|
86
92
|
app.mount '/hello', HelloAction
|
87
93
|
|
94
|
+
### or
|
95
|
+
#mapping = [
|
96
|
+
# ['/api', [
|
97
|
+
# ['/hello' , "./hello:HelloAction"],
|
98
|
+
# ]],
|
99
|
+
#]
|
100
|
+
#app = K8::RackApplication.new(mapping)
|
101
|
+
|
88
102
|
run app
|
89
103
|
```
|
90
104
|
|
91
|
-
Open http://localhost:8000/hello or http://localhost:8000/hello/123
|
105
|
+
Open http://localhost:8000/hello or http://localhost:8000/hello/123
|
106
|
+
with your browser.
|
92
107
|
|
93
108
|
Do you like it? If so, try `k8rb init myapp1` to generate project skeleton.
|
94
109
|
|
95
110
|
```console
|
96
111
|
$ k8rb init myapp1
|
97
|
-
$ cd myapp1
|
112
|
+
$ cd myapp1/
|
98
113
|
$ export APP_ENV=dev # 'dev', 'prod', or 'stg'
|
99
114
|
$ k8rb mapping
|
100
115
|
$ k8rb configs
|
101
|
-
$ rackup -
|
102
|
-
$
|
116
|
+
$ rackup -p 8000 -E production config.ru
|
117
|
+
$ open http://127.0.0.1:8000/
|
118
|
+
$ ab -n 1000 -c 10 http://127.0.0.1:8000/api/hello
|
119
|
+
## or:
|
120
|
+
$ gem install puma
|
121
|
+
$ rackup -p 8000 -E production -s puma config.ru
|
122
|
+
$ ab -n 10000 -c 100 http://localhost:8000/api/hello
|
103
123
|
```
|
104
124
|
|
105
125
|
|
data/bench/benchmarker.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
###
|
2
|
-
### $Release: 0.0
|
2
|
+
### $Release: 0.1.0 $
|
3
3
|
### $Copyright: copyright(c) 2014-2015 kuwata-lab.com all rights reserved $
|
4
4
|
### $License: MIT License $
|
5
5
|
###
|
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
module Benchmarker
|
9
9
|
|
10
|
-
VERSION = "$Release: 0.0
|
10
|
+
VERSION = "$Release: 0.1.0 $".split(/ /)[1]
|
11
11
|
|
12
12
|
def self.new(opts={}, &block)
|
13
13
|
#: creates runner object and returns it.
|
data/bin/k8rb
CHANGED
data/keight.gemspec
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |o|
|
5
5
|
o.name = "keight"
|
6
|
-
o.version = "$Release: 0.0
|
6
|
+
o.version = "$Release: 0.1.0 $".split[1]
|
7
7
|
o.author = "makoto kuwata"
|
8
8
|
o.email = "kwa(at)kuwata-lab.com"
|
9
9
|
o.platform = Gem::Platform::RUBY
|
@@ -31,6 +31,7 @@ END
|
|
31
31
|
o.test_file = "test/keight_test.rb"
|
32
32
|
|
33
33
|
o.required_ruby_version = '>= 2.0'
|
34
|
+
o.add_runtime_dependency 'rack', '~> 1.6'
|
34
35
|
o.add_runtime_dependency 'baby_erubis', '~> 2.1', '>= 2.1.1'
|
35
36
|
#o.add_development_dependency "oktest", "~> 0"
|
36
37
|
end
|
data/lib/keight.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
###
|
4
|
-
### $Release: 0.0
|
4
|
+
### $Release: 0.1.0 $
|
5
5
|
### $Copyright: copyright(c) 2014-2015 kuwata-lab.com all rights reserved $
|
6
6
|
### $License: MIT License $
|
7
7
|
###
|
@@ -432,6 +432,10 @@ module K8
|
|
432
432
|
end
|
433
433
|
|
434
434
|
|
435
|
+
class UnknownActionMethodError < BaseError
|
436
|
+
end
|
437
|
+
|
438
|
+
|
435
439
|
class UnknownContentError < BaseError
|
436
440
|
end
|
437
441
|
|
@@ -1091,12 +1095,13 @@ module K8
|
|
1091
1095
|
end
|
1092
1096
|
|
1093
1097
|
def _mount(mappings, urlpath_pattern, action_class)
|
1098
|
+
child_mappings = nil
|
1094
1099
|
#; [!4l8xl] can accept array of pairs of urlpath and action class.
|
1095
1100
|
if action_class.is_a?(Array)
|
1096
1101
|
array = action_class
|
1097
1102
|
child_mappings = []
|
1098
1103
|
array.each {|upath, klass| _mount(child_mappings, upath, klass) }
|
1099
|
-
action_class =
|
1104
|
+
action_class = nil
|
1100
1105
|
#; [!ne804] when target class name is string...
|
1101
1106
|
elsif action_class.is_a?(String)
|
1102
1107
|
str = action_class
|
@@ -1106,11 +1111,22 @@ module K8
|
|
1106
1111
|
action_class.is_a?(Class) && action_class < BaseAction or
|
1107
1112
|
raise ArgumentError.new("mount('#{urlpath_pattern}'): Action class expected but got: #{action_class.inspect}")
|
1108
1113
|
end
|
1114
|
+
#; [!30cib] raises error when action method is not defined in action class.
|
1115
|
+
_validate_action_method_existence(action_class) if action_class
|
1109
1116
|
#; [!flb11] mounts action class to urlpath.
|
1110
|
-
mappings << [urlpath_pattern, action_class]
|
1117
|
+
mappings << [urlpath_pattern, action_class || child_mappings]
|
1111
1118
|
end
|
1112
1119
|
private :_mount
|
1113
1120
|
|
1121
|
+
def _validate_action_method_existence(action_class)
|
1122
|
+
action_class._action_method_mapping.each do |_, action_methods|
|
1123
|
+
action_methods.each do |req_meth, action_method_name|
|
1124
|
+
action_class.method_defined?(action_method_name) or
|
1125
|
+
raise UnknownActionMethodError.new("#{req_meth.inspect}=>#{action_method_name.inspect}: unknown action method in #{action_class}.")
|
1126
|
+
end
|
1127
|
+
end
|
1128
|
+
end
|
1129
|
+
|
1114
1130
|
def _load_action_class(str, error)
|
1115
1131
|
#; [!9brqr] raises error when string format is invalid.
|
1116
1132
|
filepath, classname = str.split(/:/, 2)
|
@@ -1497,28 +1513,28 @@ module K8
|
|
1497
1513
|
end
|
1498
1514
|
begin
|
1499
1515
|
#; [!rz13i] returns HTTP 404 when urlpath not found.
|
1500
|
-
|
1516
|
+
tuple4 = find(req.path) or
|
1501
1517
|
raise HttpException.new(404)
|
1502
|
-
action_class, action_methods, urlpath_param_names, urlpath_param_values =
|
1518
|
+
action_class, action_methods, urlpath_param_names, urlpath_param_values = tuple4
|
1503
1519
|
#; [!rv3cf] returns HTTP 405 when urlpath found but request method not allowed.
|
1504
1520
|
action_method = action_methods[req_meth_] or
|
1505
1521
|
raise HttpException.new(405)
|
1506
1522
|
#; [!0fgbd] finds action class and invokes action method with urlpath params.
|
1507
1523
|
action_obj = action_class.new(req, resp)
|
1508
1524
|
content = action_obj.handle_action(action_method, urlpath_param_values)
|
1509
|
-
|
1525
|
+
ret = [resp.status, resp.headers, content]
|
1510
1526
|
rescue HttpException => ex
|
1511
|
-
|
1527
|
+
ret = handle_http(ex, req, resp)
|
1512
1528
|
rescue Exception => ex
|
1513
|
-
|
1529
|
+
ret = handle_error(ex, req, resp)
|
1514
1530
|
ensure
|
1515
1531
|
#; [!vdllr] clears request and response if possible.
|
1516
1532
|
req.clear() if req.respond_to?(:clear)
|
1517
1533
|
resp.clear() if resp.respond_to?(:clear)
|
1518
1534
|
end
|
1519
1535
|
#; [!9wp9z] returns empty body when request method is HEAD.
|
1520
|
-
|
1521
|
-
return
|
1536
|
+
ret[2] = [""] if req_meth == :HEAD
|
1537
|
+
return ret
|
1522
1538
|
end
|
1523
1539
|
|
1524
1540
|
def handle_http(ex, req, resp)
|
@@ -1724,7 +1740,7 @@ END
|
|
1724
1740
|
def self.set(key, value, desc=nil)
|
1725
1741
|
#; [!2yis0] raises error when not added yet.
|
1726
1742
|
self.has?(key) or
|
1727
|
-
raise K8::ConfigError.new("
|
1743
|
+
raise K8::ConfigError.new("set(#{key.inspect}, #{value.inspect}): cannot set because not added yet; use add() or put() instead.")
|
1728
1744
|
#; [!3060g] sets key, value and desc.
|
1729
1745
|
self.put(key, value, desc)
|
1730
1746
|
end
|
@@ -4,7 +4,14 @@ require 'keight'
|
|
4
4
|
require 'baby_erubis'
|
5
5
|
require 'baby_erubis/renderer'
|
6
6
|
|
7
|
-
|
7
|
+
|
8
|
+
class StrippedHtmlTemplate < BabyErubis::Html
|
9
|
+
def parse(input, *args)
|
10
|
+
## strip spaces of indentation
|
11
|
+
stripped = input.gsub(/^[ \t]+</, '<')
|
12
|
+
return super(stripped, *args)
|
13
|
+
end
|
14
|
+
end
|
8
15
|
|
9
16
|
|
10
17
|
module My
|
@@ -18,17 +25,18 @@ class My::Action < K8::Action
|
|
18
25
|
## template
|
19
26
|
##
|
20
27
|
|
21
|
-
include BabyErubis::HtmlEscaper
|
22
|
-
include BabyErubis::Renderer
|
23
|
-
|
24
28
|
ERUBY_PATH = ['app/template']
|
25
29
|
ERUBY_LAYOUT = :_layout
|
26
|
-
ERUBY_HTML
|
30
|
+
#ERUBY_HTML = BabyErubis::Html
|
31
|
+
ERUBY_HTML = StrippedHtmlTemplate
|
27
32
|
ERUBY_HTML_EXT = '.html.eruby'
|
28
33
|
ERUBY_TEXT = BabyErubis::Text
|
29
34
|
ERUBY_TEXT_EXT = '.eruby'
|
30
35
|
ERUBY_CACHE = {}
|
31
36
|
|
37
|
+
include BabyErubis::HtmlEscaper # define escape()
|
38
|
+
include BabyErubis::Renderer # define eruby_render_{html,text}()
|
39
|
+
|
32
40
|
protected
|
33
41
|
|
34
42
|
alias render_html eruby_render_html
|
@@ -21,24 +21,26 @@ if defined?(Config) # Ruby < 2.2 has obsoleted 'Config' object
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
## define Config class
|
25
25
|
require 'keight'
|
26
|
-
|
27
26
|
class Config < K8::BaseConfig
|
28
27
|
end
|
29
28
|
|
29
|
+
## load 'app.rb', 'app_xxx.rb' and 'app_xxx.private'
|
30
30
|
require_relative "config/app"
|
31
31
|
require_relative "config/app_#{app_env}"
|
32
32
|
fpath = File.join(File.dirname(__FILE__), "config", "app_#{app_env}.private")
|
33
33
|
load fpath if File.file?(fpath)
|
34
34
|
|
35
|
+
## if SECRET value is left, report error and exit.
|
35
36
|
errmsg = Config.validate_values()
|
36
37
|
if errmsg
|
37
38
|
$stderr.write(errmsg)
|
38
39
|
exit 1
|
39
40
|
end
|
40
41
|
|
41
|
-
##
|
42
|
-
ENV['K8_UPLOAD_DIR'] = $config.k8_upload_dir if $config.k8_upload_dir
|
43
|
-
|
42
|
+
## create $config object
|
44
43
|
$config = Config.new()
|
44
|
+
|
45
|
+
## temporary directory to put uploaded files
|
46
|
+
ENV['K8_UPLOAD_DIR'] = $config.k8_upload_dir if $config.k8_upload_dir
|
data/test/keight_test.rb
CHANGED
@@ -18,7 +18,7 @@ class BooksAction < K8::Action
|
|
18
18
|
#
|
19
19
|
def do_index(); "<index>"; end
|
20
20
|
def do_create(); "<create>"; end
|
21
|
-
|
21
|
+
def do_new(); "<new>"; end
|
22
22
|
def do_show(id); "<show:#{id.inspect}(#{id.class})>"; end
|
23
23
|
def do_update(id); "<update:#{id.inspect}(#{id.class})>"; end
|
24
24
|
def do_delete(id); "<delete:#{id.inspect}(#{id.class})>"; end
|
@@ -42,6 +42,7 @@ class AdminBooksAction < K8::Action
|
|
42
42
|
#
|
43
43
|
def do_index(); end
|
44
44
|
def do_create(); end
|
45
|
+
def do_new(); end
|
45
46
|
def do_show(id); end
|
46
47
|
def do_update(id); end
|
47
48
|
def do_delete(id); end
|
@@ -1653,6 +1654,17 @@ Oktest.scope do
|
|
1653
1654
|
ok {pr}.raise?(ArgumentError, "mount('/api'): Action class expected but got: String")
|
1654
1655
|
end
|
1655
1656
|
|
1657
|
+
spec "[!30cib] raises error when action method is not defined in action class." do
|
1658
|
+
|mapping|
|
1659
|
+
class ExampleAction3 < K8::Action
|
1660
|
+
mapping '', :GET=>:do_index, :POST=>:do_create
|
1661
|
+
def do_index; end
|
1662
|
+
end
|
1663
|
+
pr = proc { mapping.mount '/example3', ExampleAction3 }
|
1664
|
+
expected_msg = ":POST=>:do_create: unknown action method in ExampleAction3."
|
1665
|
+
ok {pr}.raise?(K8::UnknownActionMethodError, expected_msg)
|
1666
|
+
end
|
1667
|
+
|
1656
1668
|
spec "[!w8mee] returns self." do
|
1657
1669
|
|mapping|
|
1658
1670
|
ret = mapping.mount '/books', BooksAction
|
@@ -2731,7 +2743,7 @@ Oktest.scope do
|
|
2731
2743
|
ex = C41.instance_variable_get('@ex')
|
2732
2744
|
ok {ex} != nil
|
2733
2745
|
ok {ex}.is_a?(K8::ConfigError)
|
2734
|
-
ok {ex.message} == "
|
2746
|
+
ok {ex.message} == "set(:hom, 123): cannot set because not added yet; use add() or put() instead."
|
2735
2747
|
end
|
2736
2748
|
|
2737
2749
|
spec "[!3060g] sets key, value and desc." do
|
data/test/oktest.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
###
|
2
|
-
### $Release: 0.0
|
2
|
+
### $Release: 0.1.0 $
|
3
3
|
### $Copyright: copyright(c) 2014-2015 kuwata-lab.com all rights reserved $
|
4
4
|
### $License: MIT License $
|
5
5
|
###
|
@@ -16,7 +16,7 @@ end
|
|
16
16
|
module Oktest
|
17
17
|
|
18
18
|
|
19
|
-
VERSION = '$Release: 0.0
|
19
|
+
VERSION = '$Release: 0.1.0 $'.split(/ /)[1]
|
20
20
|
|
21
21
|
|
22
22
|
class SkipException < Exception
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: keight
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- makoto kuwata
|
@@ -9,8 +9,22 @@ autorequire:
|
|
9
9
|
bindir:
|
10
10
|
- bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-10-
|
12
|
+
date: 2015-10-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rack
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.6'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.6'
|
14
28
|
- !ruby/object:Gem::Dependency
|
15
29
|
name: baby_erubis
|
16
30
|
requirement: !ruby/object:Gem::Requirement
|