nyara 0.1.pre.0 → 0.1.pre.1
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 +4 -4
- data/bin/nyara +2 -14
- data/changes +3 -0
- data/example/factorial.rb +19 -0
- data/example/hello.rb +5 -0
- data/example/project.rb +11 -0
- data/example/stream.rb +14 -0
- data/ext/extconf.rb +19 -0
- data/ext/hashes.c +160 -57
- data/ext/inc/ary_intern.h +36 -0
- data/ext/route.cc +2 -1
- data/ext/url_encoded.c +1 -0
- data/lib/nyara.rb +1 -0
- data/lib/nyara/command.rb +60 -79
- data/lib/nyara/config.rb +19 -1
- data/lib/nyara/controller.rb +64 -7
- data/lib/nyara/hashes/config_hash.rb +3 -20
- data/lib/nyara/hashes/header_hash.rb +2 -2
- data/lib/nyara/hashes/param_hash.rb +1 -0
- data/lib/nyara/nyara.rb +45 -37
- data/lib/nyara/part.rb +2 -2
- data/lib/nyara/reload.rb +63 -64
- data/lib/nyara/route.rb +7 -6
- data/lib/nyara/session.rb +4 -0
- data/lib/nyara/templates/{Gemfile → Gemfile.tt} +4 -0
- data/lib/nyara/templates/Linnerfile +28 -0
- data/lib/nyara/templates/Rakefile +16 -2
- data/lib/nyara/templates/app/assets/files/favicon.ico +1 -0
- data/lib/nyara/templates/app/assets/files/robots.txt +5 -0
- data/lib/nyara/templates/app/assets/scripts/app.coffee +4 -0
- data/lib/nyara/templates/app/assets/scripts/module-example.coffee +4 -0
- data/lib/nyara/templates/app/assets/styles/app.scss +2 -0
- data/lib/nyara/templates/app/controllers/application_controller.rb +8 -0
- data/lib/nyara/templates/app/views/layouts/application.erb.tt +12 -0
- data/lib/nyara/templates/config/application.rb +4 -0
- data/lib/nyara/templates/config/{database.yml → database.yml.tt} +3 -3
- data/lib/nyara/templates/config/production.rb +2 -0
- data/lib/nyara/view.rb +6 -2
- data/nyara.gemspec +3 -1
- data/rakefile +7 -26
- data/spec/apps/reload.rb +35 -0
- data/spec/command_spec.rb +24 -10
- data/spec/config_spec.rb +19 -8
- data/spec/controller_spec.rb +14 -0
- data/spec/evented_io_spec.rb +3 -1
- data/spec/ext_route_spec.rb +25 -3
- data/spec/hashes_spec.rb +45 -21
- data/spec/integration_spec.rb +28 -2
- data/spec/path_helper_spec.rb +7 -0
- data/spec/performance_spec.rb +1 -1
- data/spec/public/test.css +1 -0
- data/{lib/nyara/templates/public/robot.txt → spec/public/test.jpg} +0 -0
- data/spec/public/test.js +1 -0
- data/spec/reload_spec.rb +50 -0
- data/spec/route_spec.rb +4 -4
- data/spec/spec_helper.rb +15 -9
- data/spec/url_encoded_spec.rb +5 -0
- data/spec/view_spec.rb +7 -0
- data/spec/views/_partial.slim +1 -1
- data/tools/bug.rb +53 -0
- data/tools/hello.rb +49 -0
- data/tools/memcheck.rb +33 -0
- metadata +73 -41
- data/ext/inc/status_codes.inc +0 -64
- data/lib/nyara/templates/app/views/layouts/application.erb +0 -12
- data/lib/nyara/templates/public/css/app.css +0 -1
- data/lib/nyara/templates/public/js/app.js +0 -1
@@ -8,14 +8,14 @@ module Nyara
|
|
8
8
|
CONTENT_TYPE = 'Content-Type'.freeze
|
9
9
|
|
10
10
|
def aref_content_type
|
11
|
-
|
11
|
+
_aref CONTENT_TYPE
|
12
12
|
end
|
13
13
|
|
14
14
|
def aset_content_type value
|
15
15
|
unless value.index 'charset'
|
16
16
|
value = "#{value}; charset=UTF-8"
|
17
17
|
end
|
18
|
-
|
18
|
+
_aset CONTENT_TYPE, value
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
data/lib/nyara/nyara.rb
CHANGED
@@ -26,7 +26,6 @@ require_relative "route"
|
|
26
26
|
require_relative "view"
|
27
27
|
require_relative "cpu_counter"
|
28
28
|
require_relative "part"
|
29
|
-
require_relative "command"
|
30
29
|
|
31
30
|
module Nyara
|
32
31
|
HTTP_STATUS_FIRST_LINES = Hash[HTTP_STATUS_CODES.map{|k,v|[k, "HTTP/1.1 #{k} #{v}\r\n".freeze]}].freeze
|
@@ -61,7 +60,7 @@ module Nyara
|
|
61
60
|
Config
|
62
61
|
end
|
63
62
|
|
64
|
-
%w[logger env production? test? development? project_path views_path public_path].each do |m|
|
63
|
+
%w[logger env production? test? development? project_path assets_path views_path public_path].each do |m|
|
65
64
|
eval <<-RUBY
|
66
65
|
def #{m} *xs
|
67
66
|
Config.#{m} *xs
|
@@ -77,42 +76,49 @@ module Nyara
|
|
77
76
|
View.init
|
78
77
|
end
|
79
78
|
|
79
|
+
# load with Config['app_files']
|
80
80
|
def load_app
|
81
|
+
app_files = Config['app_files']
|
82
|
+
return unless app_files
|
83
|
+
|
81
84
|
Dir.chdir Config.root do
|
85
|
+
# NOTE app_files can be an array
|
86
|
+
Dir.glob Config['app_files'] do |file|
|
87
|
+
require Config.project_path file
|
88
|
+
end
|
82
89
|
if Config.development?
|
83
90
|
require_relative "reload"
|
84
|
-
Reload.
|
85
|
-
|
86
|
-
Dir.glob(Config['app_files']).uniq.each do |file|
|
87
|
-
Reload.load_file Config.project_path file
|
88
|
-
end
|
89
|
-
end
|
90
|
-
else
|
91
|
-
Dir.glob Config['app_files'] do |file|
|
92
|
-
require Config.project_path file
|
93
|
-
end
|
91
|
+
Reload.listen
|
92
|
+
@reload = Reload
|
94
93
|
end
|
95
94
|
end
|
96
95
|
end
|
97
96
|
|
98
97
|
def start_server
|
99
|
-
port = Config[
|
98
|
+
port = Config['port']
|
99
|
+
env = Config['env']
|
100
100
|
|
101
101
|
if l = logger
|
102
|
-
l.info "starting #{
|
102
|
+
l.info "starting #{env} server at 0.0.0.0:#{port}"
|
103
103
|
end
|
104
|
-
case
|
104
|
+
case env.to_s
|
105
105
|
when 'production'
|
106
|
-
patch_tcp_socket
|
107
106
|
start_production_server port
|
108
107
|
when 'test'
|
109
108
|
# don't
|
110
109
|
else
|
111
|
-
|
110
|
+
start_watch_assets
|
112
111
|
start_development_server port
|
113
112
|
end
|
114
113
|
end
|
115
114
|
|
115
|
+
def start_watch_assets
|
116
|
+
return if Config[:assets].blank?
|
117
|
+
Process.fork do
|
118
|
+
exec 'bundle exec linner watch'
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
116
122
|
def patch_tcp_socket
|
117
123
|
if l = logger
|
118
124
|
l.info "patching TCPSocket"
|
@@ -121,17 +127,14 @@ module Nyara
|
|
121
127
|
end
|
122
128
|
|
123
129
|
def start_development_server port
|
124
|
-
|
125
|
-
|
126
|
-
|
130
|
+
create_tcp_server port
|
131
|
+
@workers = []
|
132
|
+
incr_workers nil
|
127
133
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
Ext.run_queue server.fileno
|
133
|
-
end
|
134
|
-
t.join
|
134
|
+
trap :INT, &method(:kill_all)
|
135
|
+
trap :QUIT, &method(:kill_all)
|
136
|
+
trap :TERM, &method(:kill_all)
|
137
|
+
Process.waitall
|
135
138
|
end
|
136
139
|
|
137
140
|
# Signals:
|
@@ -161,16 +164,7 @@ module Nyara
|
|
161
164
|
workers = Config[:workers]
|
162
165
|
|
163
166
|
puts "workers: #{workers}"
|
164
|
-
|
165
|
-
if (server_fd = ENV['NYARA_FD'].to_i) > 0
|
166
|
-
puts "inheriting server fd #{server_fd}"
|
167
|
-
@server = TCPServer.for_fd server_fd
|
168
|
-
end
|
169
|
-
unless @server
|
170
|
-
@server = TCPServer.new '0.0.0.0', port
|
171
|
-
@server.listen 1000
|
172
|
-
ENV['NYARA_FD'] = @server.fileno.to_s
|
173
|
-
end
|
167
|
+
create_tcp_server port
|
174
168
|
|
175
169
|
GC.start
|
176
170
|
@workers = []
|
@@ -198,11 +192,24 @@ module Nyara
|
|
198
192
|
|
199
193
|
private
|
200
194
|
|
195
|
+
def create_tcp_server port
|
196
|
+
if (server_fd = ENV['NYARA_FD'].to_i) > 0
|
197
|
+
puts "inheriting server fd #{server_fd}"
|
198
|
+
@server = TCPServer.for_fd server_fd
|
199
|
+
end
|
200
|
+
unless @server
|
201
|
+
@server = TCPServer.new '0.0.0.0', port
|
202
|
+
@server.listen 1000
|
203
|
+
ENV['NYARA_FD'] = @server.fileno.to_s
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
201
207
|
# Kill all workers and exit
|
202
208
|
def kill_all sig
|
203
209
|
@workers.each do |w|
|
204
210
|
Process.kill :KILL, w
|
205
211
|
end
|
212
|
+
@reload.stop if @reload
|
206
213
|
exit!
|
207
214
|
end
|
208
215
|
|
@@ -254,6 +261,7 @@ module Nyara
|
|
254
261
|
def incr_workers sig
|
255
262
|
Config['before_fork'].call if Config['before_fork']
|
256
263
|
pid = fork {
|
264
|
+
patch_tcp_socket
|
257
265
|
$0 = "(nyara:worker) ruby #{$0}"
|
258
266
|
Config['after_fork'].call if Config['after_fork']
|
259
267
|
|
data/lib/nyara/part.rb
CHANGED
@@ -103,11 +103,11 @@ module Nyara
|
|
103
103
|
keys = ParamHash.split_name(name)
|
104
104
|
|
105
105
|
if self['filename']
|
106
|
-
params.nested_aset keys, self
|
106
|
+
params.send :nested_aset, keys, self
|
107
107
|
elsif self['type']
|
108
108
|
warn "looks like bad part: #{self['header'].inspect}"
|
109
109
|
else
|
110
|
-
params.nested_aset keys, CGI.unescape(self['data'])
|
110
|
+
params.send :nested_aset, keys, CGI.unescape(self['data'])
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
data/lib/nyara/reload.rb
CHANGED
@@ -2,84 +2,83 @@ require "listen"
|
|
2
2
|
|
3
3
|
module Nyara
|
4
4
|
# listen to fs events and reload code / views
|
5
|
-
# todo add to development env: require 'nyara/reload'; Reload.listen
|
6
5
|
module Reload
|
7
|
-
# init, should require all files that needs to be reloaded in the given block
|
8
|
-
def self.init
|
9
|
-
@new_classes = []
|
10
|
-
@trace_point = TracePoint.new :class do |tp|
|
11
|
-
@new_classes << tp.self.to_s.to_sym
|
12
|
-
end
|
13
|
-
@file_list = {}
|
14
|
-
@first_load = true
|
15
|
-
yield
|
16
|
-
@first_load = false
|
17
|
-
end
|
18
6
|
|
19
|
-
|
20
|
-
def self.load_file file
|
21
|
-
if consts = @file_list[file]
|
22
|
-
consts.reverse_each do |const|
|
23
|
-
Object.send :remove_const, const
|
24
|
-
end
|
25
|
-
end
|
7
|
+
extend self
|
26
8
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
9
|
+
# NOTE file should end with '.rb'<br>
|
10
|
+
# returns last error
|
11
|
+
def load_file file
|
12
|
+
verbose = $VERBOSE
|
13
|
+
$VERBOSE = nil
|
14
|
+
begin
|
15
|
+
load file
|
16
|
+
@last_error = nil
|
17
|
+
rescue Exception
|
18
|
+
@last_error = $!
|
19
|
+
ensure
|
20
|
+
$VERBOSE = verbose
|
21
|
+
end
|
22
|
+
if l = Nyara.logger
|
23
|
+
if @last_error
|
24
|
+
l.error @last_error
|
40
25
|
end
|
41
26
|
end
|
42
|
-
@trace_point.disable
|
43
|
-
added_consts = Object.send(:constants) - old_consts
|
44
|
-
|
45
|
-
added_consts.concat @new_classes
|
46
|
-
@new_classes.clear
|
47
|
-
added_consts.uniq!
|
48
|
-
added_consts.sort!
|
49
|
-
|
50
|
-
@file_list[file] = added_consts
|
51
|
-
@last_error
|
52
27
|
end
|
28
|
+
attr_reader :last_error
|
53
29
|
|
54
30
|
# start listening
|
55
|
-
def
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
View.on_modified file
|
64
|
-
end
|
65
|
-
removed.each do |file|
|
66
|
-
View.on_removed file
|
67
|
-
end
|
31
|
+
def listen
|
32
|
+
@port = Config['port']
|
33
|
+
app_path = Config['root']
|
34
|
+
views_path = Config.views_path('/', false)
|
35
|
+
if l = Nyara.logger
|
36
|
+
l.info "watching app and view changes under #{app_path}"
|
37
|
+
unless views_path.start_with?(app_path)
|
38
|
+
l.warn "views not under project dir, changes not watched"
|
68
39
|
end
|
69
40
|
end
|
41
|
+
@app_listener = hook_app_reload app_path
|
42
|
+
@views_listener = hook_views_reload views_path
|
43
|
+
end
|
70
44
|
|
71
|
-
|
72
|
-
|
73
|
-
|
45
|
+
# cleanup workers
|
46
|
+
def stop
|
47
|
+
if @app_listener.adapter.worker
|
48
|
+
@app_listener.adapter.worker.stop
|
74
49
|
end
|
75
|
-
|
76
|
-
|
77
|
-
load_file file
|
78
|
-
end
|
79
|
-
# (1.0) todo send notification on bad files
|
50
|
+
if @views_listener.adapter.worker
|
51
|
+
@views_listener.adapter.worker.stop
|
80
52
|
end
|
81
53
|
end
|
82
54
|
|
83
|
-
#
|
55
|
+
# ---
|
56
|
+
# private
|
57
|
+
# +++
|
58
|
+
|
59
|
+
def hook_app_reload app_path
|
60
|
+
l = Listen.to(app_path).relative_paths(false).filter(/\.rb$/).change do |modified, added, removed|
|
61
|
+
notify 'app-modified', (added + modified).uniq
|
62
|
+
end
|
63
|
+
l.start
|
64
|
+
l
|
65
|
+
end
|
66
|
+
|
67
|
+
def hook_views_reload views_path
|
68
|
+
l = Listen.to(views_path).relative_paths(true).change do |modified, added, removed|
|
69
|
+
notify 'views-modified', (added + modified).uniq
|
70
|
+
notify 'views-removed', removed
|
71
|
+
end
|
72
|
+
l.start
|
73
|
+
l
|
74
|
+
end
|
75
|
+
|
76
|
+
def notify leader, files
|
77
|
+
return if files.empty?
|
78
|
+
data = files.to_query('files')
|
79
|
+
s = TCPSocket.new 'localhost', @port
|
80
|
+
s << "POST /reload:#{leader}\r\nContent-Length: #{data.bytesize}\r\n\r\n" << data
|
81
|
+
s.close
|
82
|
+
end
|
84
83
|
end
|
85
84
|
end
|
data/lib/nyara/route.rb
CHANGED
@@ -158,8 +158,6 @@ module Nyara
|
|
158
158
|
def analyse_path path
|
159
159
|
raise 'path must contain no new line' if path.index "\n"
|
160
160
|
raise 'path must start with /' unless path.start_with? '/'
|
161
|
-
path = path.sub(/\/$/, '') if path != '/'
|
162
|
-
|
163
161
|
path.split(FORWARD_SPLIT, 2)
|
164
162
|
end
|
165
163
|
end
|
@@ -240,12 +238,15 @@ module Nyara
|
|
240
238
|
end
|
241
239
|
|
242
240
|
def print_routes
|
243
|
-
puts "
|
241
|
+
puts "All routes:"
|
244
242
|
Nyara::Route.routes.each do |route|
|
245
|
-
|
243
|
+
cname = route.controller.to_s
|
244
|
+
cname.gsub!("Controller", "")
|
245
|
+
cname.downcase!
|
246
|
+
print "#{cname}#{route.id}".rjust(30), " "
|
246
247
|
print route.http_method_to_s.ljust(6), " "
|
247
|
-
print route.
|
248
|
-
puts
|
248
|
+
print route.path_template
|
249
|
+
puts
|
249
250
|
end
|
250
251
|
end
|
251
252
|
|
data/lib/nyara/session.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
paths:
|
2
|
+
app: "app/assets"
|
3
|
+
public: "public"
|
4
|
+
groups:
|
5
|
+
scripts:
|
6
|
+
paths:
|
7
|
+
- app/assets/scripts
|
8
|
+
concat:
|
9
|
+
"/assets/app.js": "app/assets/**/*.{js,coffee}"
|
10
|
+
order:
|
11
|
+
- "..."
|
12
|
+
- app/assets/scripts/app.coffee
|
13
|
+
styles:
|
14
|
+
paths:
|
15
|
+
- app/assets/styles
|
16
|
+
concat:
|
17
|
+
"/assets/app.css": "app/assets/**/[a-z]*.{css,scss,sass}"
|
18
|
+
files:
|
19
|
+
paths:
|
20
|
+
- app/assets/files
|
21
|
+
copy:
|
22
|
+
"/": "app/assets/**/*.{ico,txt}"
|
23
|
+
modules:
|
24
|
+
wrapper: "cmd"
|
25
|
+
ignored: "{vendor/**/*,app/assets/scripts/app.{js,coffee}}"
|
26
|
+
definition: "/assets/app.js"
|
27
|
+
revision: true
|
28
|
+
notification: true
|
@@ -1,6 +1,20 @@
|
|
1
|
-
|
1
|
+
require "rake"
|
2
|
+
|
3
|
+
desc "print all routes"
|
2
4
|
task :routes do
|
3
|
-
require_relative
|
5
|
+
require_relative "config/application"
|
4
6
|
Nyara.setup
|
5
7
|
Nyara::Route.print_routes
|
6
8
|
end
|
9
|
+
|
10
|
+
namespace :assets do
|
11
|
+
desc "compile assets into public"
|
12
|
+
task :build do
|
13
|
+
sh 'bundle exec linner build'
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "clean assets in public"
|
17
|
+
task :clean do
|
18
|
+
sh 'bundle exec linner clean'
|
19
|
+
end
|
20
|
+
end
|