lane_groove 0.0.5 → 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.
- data/bin/lane_groove +1 -0
- data/lib/lane_groove.rb +55 -39
- data/test/lane_groove_test.rb +26 -67
- metadata +75 -68
data/bin/lane_groove
CHANGED
@@ -4,6 +4,7 @@ require 'forever'
|
|
4
4
|
|
5
5
|
WORKING_DIR = Dir.getwd
|
6
6
|
puts "Working directory is #{WORKING_DIR}"
|
7
|
+
puts "You can stop the lane_groove server with\n lane_groove stop"
|
7
8
|
puts "WARNING: Working directory is empty!" if Dir.glob(File.join(WORKING_DIR, '*.yaml')).empty?
|
8
9
|
|
9
10
|
Forever.run do
|
data/lib/lane_groove.rb
CHANGED
@@ -2,18 +2,15 @@ require 'yaml'
|
|
2
2
|
require 'json'
|
3
3
|
require 'xmlsimple'
|
4
4
|
require 'sinatra/base'
|
5
|
+
require 'sinatra/respond_with'
|
5
6
|
require 'rack/contrib'
|
6
7
|
|
8
|
+
if Dir.glob(File.join(WORKING_DIR, '*.yaml')).empty?
|
9
|
+
puts "No config file(s) found in #{WORKING_DIR}. Please put one or more YAML files in #{WORKING_DIR}."
|
10
|
+
exit
|
11
|
+
end
|
12
|
+
|
7
13
|
class Hash
|
8
|
-
def upcase_keys
|
9
|
-
inject({}){ |new_hash, key_value|
|
10
|
-
key, value = key_value
|
11
|
-
value = value.upcase_keys if value.is_a?(Hash)
|
12
|
-
new_hash[key.upcase] = value
|
13
|
-
new_hash
|
14
|
-
}
|
15
|
-
end
|
16
|
-
|
17
14
|
def recursive_values
|
18
15
|
inject([]){ |new_array, key_value|
|
19
16
|
key, value = key_value
|
@@ -37,35 +34,58 @@ class Hash
|
|
37
34
|
end
|
38
35
|
end
|
39
36
|
|
37
|
+
class Rack::Static
|
38
|
+
def initialize(app, options={})
|
39
|
+
# don't default to 'index.html' as per https://github.com/lgierth/rack/blob/5ab871f2a86ca4f943a5b1d0a3d0f32a2f9f77ef/lib/rack/static.rb
|
40
|
+
@app = app
|
41
|
+
@urls = options[:urls]
|
42
|
+
root = options[:root]
|
43
|
+
@file_server = Rack::File.new(root)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# inspired by https://github.com/crohr/rack-accept-header-updater/blob/master/lib/rack/accept_header_updater.rb
|
48
|
+
# turns file extensions into accept headers.
|
49
|
+
module Rack
|
50
|
+
class AcceptHeaderUpdater
|
51
|
+
def initialize(app)
|
52
|
+
@app = app
|
53
|
+
end
|
54
|
+
|
55
|
+
def call(env)
|
56
|
+
req = Rack::Request.new(env)
|
57
|
+
if ext = (req.path_info.match('\.') && ".#{req.path_info.split('.').last}")
|
58
|
+
if mime_type = Rack::Mime::MIME_TYPES[ext.downcase]
|
59
|
+
env['HTTP_ACCEPT'] = [mime_type, env['HTTP_ACCEPT']].join(",")
|
60
|
+
req.path_info.gsub!(/#{ext}$/, '')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
@app.call(env)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
40
68
|
class LaneGroove < Sinatra::Base
|
41
69
|
use Rack::CommonLogger
|
42
70
|
use Rack::Access, '/' => %w{ 127.0.0.1 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 }
|
43
71
|
|
44
|
-
|
72
|
+
# We're using Rack::Static instead of Sinatra static so we can put it in the Middleware stack before AcceptHeaderUpdater
|
73
|
+
if File.exists?(static_dir = File.join(WORKING_DIR, 'static'))
|
74
|
+
puts "Serving static files from #{static_dir}: #{Dir.glob File.join(static_dir, '*')}"
|
75
|
+
use Rack::Static, :urls => ['/static'], :root => WORKING_DIR
|
76
|
+
end
|
45
77
|
|
46
|
-
|
78
|
+
use Rack::AcceptHeaderUpdater
|
79
|
+
register Sinatra::RespondWith
|
47
80
|
|
48
|
-
|
49
|
-
|
50
|
-
set :static, true
|
51
|
-
set :public_folder, static_dir
|
52
|
-
end
|
81
|
+
disable :protection
|
82
|
+
set :config, nil
|
53
83
|
|
54
84
|
helpers do
|
55
85
|
def config_files
|
56
86
|
Dir.glob File.join(WORKING_DIR, '*.yaml')
|
57
87
|
end
|
58
88
|
|
59
|
-
def content_type_for(format)
|
60
|
-
{
|
61
|
-
:json => {'Content-Type' => 'application/json; charset=utf-8'},
|
62
|
-
:xml => {'Content-Type' => 'application/xml; charset=utf-8'},
|
63
|
-
:yaml => {'Content-Type' => 'application/x-yaml; charset=utf-8'},
|
64
|
-
:rb => {'Content-Type' => 'application/x-ruby; charset=utf-8'},
|
65
|
-
:line => {'Content-Type' => 'application/x-line; charset=utf-8'}
|
66
|
-
}[format]
|
67
|
-
end
|
68
|
-
|
69
89
|
def reload_yaml
|
70
90
|
self.class.config = {}
|
71
91
|
|
@@ -80,8 +100,7 @@ class LaneGroove < Sinatra::Base
|
|
80
100
|
cfg = self.class.config
|
81
101
|
|
82
102
|
path.each do |node|
|
83
|
-
cfg = cfg[node]
|
84
|
-
break if cfg.nil?
|
103
|
+
break if (cfg = cfg[node]).nil?
|
85
104
|
end
|
86
105
|
|
87
106
|
return cfg
|
@@ -100,20 +119,17 @@ class LaneGroove < Sinatra::Base
|
|
100
119
|
end
|
101
120
|
|
102
121
|
get /^(.*)\.line$/ do |paths|
|
103
|
-
|
122
|
+
content_type 'application/x-line; charset=utf-8'
|
123
|
+
paths.split(',').map{ |path| extract_values config(*parse_path(path)) }.flatten.join(params['F'] || ' ')
|
104
124
|
end
|
105
125
|
|
106
|
-
get /^(.*)
|
107
|
-
|
108
|
-
conf = config *parse_path(path)
|
126
|
+
get /^(.*)$/, :provides => [:json, :yaml, :xml] do |path|
|
127
|
+
halt 404 unless (conf = config *parse_path(path))
|
109
128
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
when :XML then [200, content_type_for(:xml), conf.remove_nil_values.upcase_keys.to_xml]
|
115
|
-
when :rb then [200, content_type_for(:rb), conf.inspect]
|
116
|
-
else ; [404, {}, "unknown format #{ext}"]
|
129
|
+
respond_to do |format|
|
130
|
+
format.json { conf.to_json }
|
131
|
+
format.yaml { conf.to_yaml }
|
132
|
+
format.xml { conf.remove_nil_values.to_xml }
|
117
133
|
end
|
118
134
|
end
|
119
135
|
|
data/test/lane_groove_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
WORKING_DIR = File.join(
|
1
|
+
WORKING_DIR = File.join(File.dirname(__FILE__), 'config_files')
|
2
2
|
|
3
|
-
|
3
|
+
require_relative '../lib/lane_groove.rb'
|
4
4
|
require 'test/unit'
|
5
5
|
require 'rack/test'
|
6
6
|
require 'fileutils'
|
@@ -41,99 +41,59 @@ class LaneGrooveTest < Test::Unit::TestCase
|
|
41
41
|
EOX
|
42
42
|
end
|
43
43
|
|
44
|
-
def config_all_XML
|
45
|
-
<<-EOX
|
46
|
-
<TEST>
|
47
|
-
<DB>
|
48
|
-
<HOST>my-db-server</HOST>
|
49
|
-
<USER>root</USER>
|
50
|
-
<PASS>none</PASS>
|
51
|
-
<BAR>1</BAR>
|
52
|
-
</DB>
|
53
|
-
<REDIS>
|
54
|
-
<HOST>my-redis-server</HOST>
|
55
|
-
</REDIS>
|
56
|
-
</TEST>
|
57
|
-
EOX
|
58
|
-
end
|
59
|
-
|
60
|
-
def config_db_XML
|
61
|
-
<<-EOX
|
62
|
-
<HOST>my-db-server</HOST>
|
63
|
-
<USER>root</USER>
|
64
|
-
<PASS>none</PASS>
|
65
|
-
<BAR>1</BAR>
|
66
|
-
EOX
|
67
|
-
end
|
68
|
-
|
69
|
-
def test_all_rb
|
70
|
-
get '/.rb'
|
71
|
-
assert_equal 200, last_response.status
|
72
|
-
assert_equal 'application/x-ruby; charset=utf-8', last_response.content_type
|
73
|
-
assert_equal config.inspect, last_response.body
|
74
|
-
end
|
75
|
-
def test_db_rb
|
76
|
-
get '/test/db.rb'
|
77
|
-
assert_equal 200, last_response.status
|
78
|
-
assert_equal 'application/x-ruby; charset=utf-8', last_response.content_type
|
79
|
-
assert_equal config["test"]["db"].inspect, last_response.body
|
80
|
-
end
|
81
|
-
|
82
44
|
def test_all_yaml
|
83
45
|
get '/.yaml'
|
84
46
|
assert_equal 200, last_response.status
|
85
|
-
assert_equal '
|
47
|
+
assert_equal 'text/yaml;charset=utf-8', last_response.content_type
|
86
48
|
assert_equal config.to_yaml, last_response.body
|
87
49
|
end
|
88
50
|
def test_db_yaml
|
89
51
|
get '/test/db.yaml'
|
90
52
|
assert_equal 200, last_response.status
|
91
|
-
assert_equal '
|
53
|
+
assert_equal 'text/yaml;charset=utf-8', last_response.content_type
|
92
54
|
assert_equal config["test"]["db"].to_yaml, last_response.body
|
93
55
|
end
|
94
56
|
|
95
57
|
def test_all_json
|
96
58
|
get '/.json'
|
97
59
|
assert_equal 200, last_response.status
|
98
|
-
assert_equal 'application/json;
|
60
|
+
assert_equal 'application/json;charset=utf-8', last_response.content_type
|
99
61
|
assert_equal config.to_json, last_response.body
|
100
62
|
end
|
101
63
|
def test_db_json
|
102
64
|
get '/test/db.json'
|
103
65
|
assert_equal 200, last_response.status
|
104
|
-
assert_equal 'application/json;
|
66
|
+
assert_equal 'application/json;charset=utf-8', last_response.content_type
|
105
67
|
assert_equal config['test']["db"].to_json, last_response.body
|
106
68
|
end
|
107
69
|
|
108
70
|
def test_all_xml
|
109
71
|
get '/.xml'
|
110
72
|
assert_equal 200, last_response.status
|
111
|
-
assert_equal 'application/xml;
|
73
|
+
assert_equal 'application/xml;charset=utf-8', last_response.content_type
|
112
74
|
assert_equal config_all_xml, last_response.body
|
113
75
|
end
|
114
76
|
def test_db_xml
|
115
77
|
get '/test/db.xml'
|
116
78
|
assert_equal 200, last_response.status
|
117
|
-
assert_equal 'application/xml;
|
79
|
+
assert_equal 'application/xml;charset=utf-8', last_response.content_type
|
118
80
|
assert_equal config_db_xml, last_response.body
|
119
81
|
end
|
120
82
|
|
121
|
-
def
|
122
|
-
get '
|
83
|
+
def test_line
|
84
|
+
get '/test/db/host,/test/db/user.line'
|
123
85
|
assert_equal 200, last_response.status
|
124
|
-
assert_equal '
|
125
|
-
assert_equal config_all_XML, last_response.body
|
86
|
+
assert_equal 'my-db-server root', last_response.body
|
126
87
|
end
|
127
|
-
def
|
128
|
-
get '/test/db.
|
88
|
+
def test_line_with_separator
|
89
|
+
get '/test/db/host,/test/db/user.line?F=,'
|
129
90
|
assert_equal 200, last_response.status
|
130
|
-
assert_equal '
|
131
|
-
assert_equal config_db_XML, last_response.body
|
91
|
+
assert_equal 'my-db-server,root', last_response.body
|
132
92
|
end
|
133
93
|
|
134
94
|
def reset_assets
|
135
|
-
FileUtils.mv('
|
136
|
-
FileUtils.mv('
|
95
|
+
FileUtils.mv(File.join(WORKING_DIR, 'more_test.yaml'), File.join(WORKING_DIR, 'test.yaml')) if File.exists?(File.join(WORKING_DIR, 'more_test.yaml'))
|
96
|
+
FileUtils.mv(File.join(WORKING_DIR, 'no_static'), File.join(WORKING_DIR, 'static')) if File.exists?(File.join(WORKING_DIR, 'no_static'))
|
137
97
|
end
|
138
98
|
|
139
99
|
def setup
|
@@ -145,16 +105,16 @@ class LaneGrooveTest < Test::Unit::TestCase
|
|
145
105
|
end
|
146
106
|
|
147
107
|
def test_reloading
|
148
|
-
get '/test/db.
|
149
|
-
assert_equal config["test"]["db"].
|
108
|
+
get '/test/db.json'
|
109
|
+
assert_equal config["test"]["db"].to_json, last_response.body
|
150
110
|
|
151
|
-
FileUtils.mv('
|
111
|
+
FileUtils.mv(File.join(WORKING_DIR, 'test.yaml'), File.join(WORKING_DIR, 'more_test.yaml'))
|
152
112
|
|
153
|
-
get '/test/db.
|
154
|
-
assert_equal config["test"]["db"].
|
113
|
+
get '/test/db.json'
|
114
|
+
assert_equal config["test"]["db"].to_json, last_response.body
|
155
115
|
|
156
|
-
get '/more_test/db.
|
157
|
-
assert_equal config["test"]["db"].
|
116
|
+
get '/more_test/db.json?reload=true'
|
117
|
+
assert_equal config["test"]["db"].to_json, last_response.body
|
158
118
|
end
|
159
119
|
|
160
120
|
def test_network_restrictions
|
@@ -164,14 +124,13 @@ class LaneGrooveTest < Test::Unit::TestCase
|
|
164
124
|
end
|
165
125
|
|
166
126
|
def test_static_files
|
167
|
-
get '/some.txt'
|
127
|
+
get '/static/some.txt'
|
168
128
|
assert_equal 'some text', last_response.body
|
169
129
|
end
|
170
130
|
def test_static_files_no_dir
|
171
|
-
FileUtils.mv('
|
172
|
-
get '/some.txt'
|
131
|
+
FileUtils.mv(File.join(WORKING_DIR, 'static'), File.join(WORKING_DIR, 'no_static'))
|
132
|
+
get '/static/some.txt'
|
173
133
|
assert_equal 404, last_response.status
|
174
|
-
assert_equal 'unknown format txt', last_response.body
|
175
134
|
end
|
176
135
|
|
177
136
|
end
|
metadata
CHANGED
@@ -1,113 +1,120 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: lane_groove
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
4
5
|
prerelease:
|
5
|
-
version: 0.0.5
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Niko
|
9
9
|
- Dittmann
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
- !ruby/object:Gem::Dependency
|
13
|
+
date: 2012-01-16 00:00:00.000000000Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
17
16
|
name: xml-simple
|
18
|
-
|
19
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
17
|
+
requirement: &70196359133860 !ruby/object:Gem::Requirement
|
20
18
|
none: false
|
21
|
-
requirements:
|
22
|
-
- -
|
23
|
-
- !ruby/object:Gem::Version
|
24
|
-
version:
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
25
23
|
type: :runtime
|
26
|
-
|
27
|
-
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *70196359133860
|
26
|
+
- !ruby/object:Gem::Dependency
|
28
27
|
name: sinatra
|
28
|
+
requirement: &70196359133420 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
29
35
|
prerelease: false
|
30
|
-
|
36
|
+
version_requirements: *70196359133420
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: sinatra-contrib
|
39
|
+
requirement: &70196359132940 !ruby/object:Gem::Requirement
|
31
40
|
none: false
|
32
|
-
requirements:
|
33
|
-
- -
|
34
|
-
- !ruby/object:Gem::Version
|
35
|
-
version:
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
36
45
|
type: :runtime
|
37
|
-
version_requirements: *id002
|
38
|
-
- !ruby/object:Gem::Dependency
|
39
|
-
name: rack-contrib
|
40
46
|
prerelease: false
|
41
|
-
|
47
|
+
version_requirements: *70196359132940
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rack-contrib
|
50
|
+
requirement: &70196359132300 !ruby/object:Gem::Requirement
|
42
51
|
none: false
|
43
|
-
requirements:
|
44
|
-
- -
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version:
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
47
56
|
type: :runtime
|
48
|
-
version_requirements: *id003
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
name: foreverb
|
51
57
|
prerelease: false
|
52
|
-
|
58
|
+
version_requirements: *70196359132300
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: foreverb
|
61
|
+
requirement: &70196359131780 !ruby/object:Gem::Requirement
|
53
62
|
none: false
|
54
|
-
requirements:
|
55
|
-
- -
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
version:
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
58
67
|
type: :runtime
|
59
|
-
version_requirements: *id004
|
60
|
-
- !ruby/object:Gem::Dependency
|
61
|
-
name: rack-test
|
62
68
|
prerelease: false
|
63
|
-
|
69
|
+
version_requirements: *70196359131780
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rack-test
|
72
|
+
requirement: &70196359131360 !ruby/object:Gem::Requirement
|
64
73
|
none: false
|
65
|
-
requirements:
|
66
|
-
- -
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version:
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
69
78
|
type: :development
|
70
|
-
|
71
|
-
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: *70196359131360
|
81
|
+
description: A small HTTP configuration server. Eats YAML, returns JSON, XML, YAML
|
82
|
+
and rb. Restricts requests to local subnet.
|
72
83
|
email: mail@niko-dittmann.com
|
73
|
-
executables:
|
84
|
+
executables:
|
74
85
|
- lane_groove
|
75
86
|
- lane_groove_test
|
76
87
|
extensions: []
|
77
|
-
|
78
88
|
extra_rdoc_files: []
|
79
|
-
|
80
|
-
files:
|
89
|
+
files:
|
81
90
|
- lib/lane_groove.rb
|
82
91
|
- test/lane_groove_test.rb
|
83
92
|
- bin/lane_groove
|
84
93
|
- bin/lane_groove_test
|
85
94
|
homepage: http://github.com/niko/lane_groove
|
86
95
|
licenses: []
|
87
|
-
|
88
96
|
post_install_message:
|
89
97
|
rdoc_options: []
|
90
|
-
|
91
|
-
require_paths:
|
98
|
+
require_paths:
|
92
99
|
- lib
|
93
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
101
|
none: false
|
95
|
-
requirements:
|
96
|
-
- -
|
97
|
-
- !ruby/object:Gem::Version
|
98
|
-
version:
|
99
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ! '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
107
|
none: false
|
101
|
-
requirements:
|
102
|
-
- -
|
103
|
-
- !ruby/object:Gem::Version
|
104
|
-
version:
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
105
112
|
requirements: []
|
106
|
-
|
107
113
|
rubyforge_project: nowarning
|
108
|
-
rubygems_version: 1.8.
|
114
|
+
rubygems_version: 1.8.10
|
109
115
|
signing_key:
|
110
116
|
specification_version: 3
|
111
|
-
summary: A small HTTP configuration server. Eats YAML, returns JSON, XML, YAML and
|
112
|
-
|
117
|
+
summary: A small HTTP configuration server. Eats YAML, returns JSON, XML, YAML and
|
118
|
+
rb. Restricts requests to local subnet.
|
119
|
+
test_files:
|
113
120
|
- test/lane_groove_test.rb
|