flatrack 1.0.0.alpha5 → 1.0.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 +4 -4
- data/.gitignore +4 -1
- data/.rubocop.yml +6 -0
- data/.ruby-version +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +1 -3
- data/Guardfile +11 -0
- data/README.md +41 -10
- data/Rakefile +8 -1
- data/bin/flatrack +1 -1
- data/flatrack.gemspec +30 -20
- data/lib/flatrack.rb +50 -7
- data/lib/flatrack/asset_extensions.rb +2 -4
- data/lib/flatrack/cli.rb +71 -20
- data/lib/flatrack/renderer.rb +18 -7
- data/lib/flatrack/renderer/base.rb +2 -4
- data/lib/flatrack/request.rb +6 -14
- data/lib/flatrack/response.rb +19 -32
- data/lib/flatrack/response/view_context.rb +27 -40
- data/lib/flatrack/site.rb +27 -9
- data/lib/flatrack/version.rb +2 -2
- data/lib/rake/asset_tasks.rb +12 -12
- data/logo.png +0 -0
- data/public/assets/manifest-6d7e78baa6d2c0670a82be957315fcbc.json +1 -0
- data/renderers/erb.rb +1 -3
- data/renderers/html.rb +1 -3
- data/renderers/rb.rb +11 -9
- data/spec/fixtures/assets/application.js.coffee +2 -0
- data/spec/lib/flatrack/asset_extensions_spec.rb +13 -0
- data/spec/lib/flatrack/cli_spec.rb +58 -0
- data/spec/lib/flatrack/renderer/base_spec.rb +4 -0
- data/spec/lib/flatrack/renderer_spec.rb +4 -0
- data/spec/lib/flatrack/request_spec.rb +22 -0
- data/spec/lib/flatrack/response/view_context_spec.rb +76 -0
- data/spec/lib/flatrack/response_spec.rb +22 -0
- data/spec/lib/flatrack/site_spec.rb +39 -0
- data/spec/lib/flatrack_spec.rb +28 -0
- data/spec/lib/rake/asset_tasks_spec.rb +55 -0
- data/spec/renderers/erb_spec.rb +21 -0
- data/spec/renderers/html_spec.rb +21 -0
- data/spec/renderers/rb_spec.rb +21 -0
- data/spec/spec_helper.rb +14 -2
- data/spec/support/site_helper.rb +52 -0
- data/templates/.gitignore +2 -1
- data/{spec/rake/asset_tasks_spec.rb → templates/.keep} +0 -0
- data/templates/404.html +1 -0
- data/templates/500.html +1 -0
- data/templates/Rakefile +1 -1
- data/templates/boot.rb +3 -1
- data/templates/javascript.js.coffee +2 -0
- data/templates/layout.html.erb +5 -3
- data/templates/stylesheet.css.scss +2 -0
- metadata +163 -54
data/lib/flatrack/request.rb
CHANGED
@@ -1,24 +1,16 @@
|
|
1
|
-
|
1
|
+
class Flatrack
|
2
2
|
class Request
|
3
|
-
|
4
3
|
DEFAULT_FORMAT = 'html'
|
5
4
|
|
6
5
|
attr_reader :env, :rack_request
|
7
6
|
|
8
7
|
def initialize(env)
|
9
8
|
@rack_request = Rack::Request.new(env)
|
10
|
-
@env
|
9
|
+
@env = env
|
11
10
|
end
|
12
11
|
|
13
12
|
def path
|
14
|
-
env['
|
15
|
-
end
|
16
|
-
|
17
|
-
def headers
|
18
|
-
env.reduce({}) do |hash, (key, value)|
|
19
|
-
next hash unless /^HTTP_(?<name>.+)/ =~ key
|
20
|
-
hash.merge name.downcase.to_sym => value
|
21
|
-
end
|
13
|
+
env['PATH_INFO']
|
22
14
|
end
|
23
15
|
|
24
16
|
def params
|
@@ -42,8 +34,8 @@ module Flatrack
|
|
42
34
|
def respond_with_error(code)
|
43
35
|
Response.new(self).render(file: "#{code}.html", status: code)
|
44
36
|
rescue FileNotFound
|
45
|
-
|
37
|
+
file = File.join Flatrack.gem_root, '../templates', "#{code}.html"
|
38
|
+
Response.new(self).render(file: file, status: code)
|
46
39
|
end
|
47
|
-
|
48
40
|
end
|
49
|
-
end
|
41
|
+
end
|
data/lib/flatrack/response.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
|
1
|
+
class Flatrack
|
2
2
|
class Response
|
3
|
-
|
4
3
|
autoload :ViewContext, 'flatrack/response/view_context'
|
5
4
|
|
6
|
-
DEFAULT_FILE
|
5
|
+
DEFAULT_FILE = 'index'
|
7
6
|
CONTENT_TYPES = {
|
8
7
|
html: 'text/html',
|
9
8
|
rb: 'text/html'
|
@@ -15,17 +14,6 @@ module Flatrack
|
|
15
14
|
@request = request
|
16
15
|
end
|
17
16
|
|
18
|
-
def render(options={})
|
19
|
-
file, text, status, layout = options.values_at(:file, :text, :status, :layout)
|
20
|
-
set_content_type
|
21
|
-
status ||= 200
|
22
|
-
if text
|
23
|
-
render_text text, status: status
|
24
|
-
else
|
25
|
-
render_file file, status: status, layout: layout
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
17
|
def headers
|
30
18
|
@headers ||= {}
|
31
19
|
end
|
@@ -34,29 +22,29 @@ module Flatrack
|
|
34
22
|
@body ||= []
|
35
23
|
end
|
36
24
|
|
25
|
+
def render(file: file_for(request.path), status: 200, layout: :layout)
|
26
|
+
page_content = proc { renderer_for(file).render(view_context) }
|
27
|
+
set_content_type
|
28
|
+
body << begin
|
29
|
+
layout_for(layout).render(view_context, &page_content)
|
30
|
+
rescue Flatrack::FileNotFound
|
31
|
+
page_content.call
|
32
|
+
end
|
33
|
+
[status, headers, body]
|
34
|
+
end
|
35
|
+
|
37
36
|
def set_content_type
|
38
37
|
headers['Content-Type'] = CONTENT_TYPES[request.format.to_sym]
|
39
38
|
end
|
40
39
|
|
41
40
|
private
|
42
41
|
|
43
|
-
def render_file(file = nil, options={})
|
44
|
-
status, layout = options.values_at(:status, :layout)
|
45
|
-
layout ||= :layout
|
46
|
-
file ||= file_for(request.path)
|
47
|
-
contents = renderer_for(file).render(view_context)
|
48
|
-
contents = layout_for(layout).render(view_context){ contents } if layout
|
49
|
-
self.body << contents
|
50
|
-
[status, headers, body]
|
51
|
-
end
|
52
|
-
|
53
|
-
def render_text(text = '', options={})
|
54
|
-
status = options[:status]
|
55
|
-
[status, headers, [text.to_s]]
|
56
|
-
end
|
57
|
-
|
58
42
|
def file_for(path)
|
59
|
-
File.directory?(File.join 'pages', path)
|
43
|
+
if File.directory?(File.join 'pages', path)
|
44
|
+
File.join(path, DEFAULT_FILE)
|
45
|
+
else
|
46
|
+
path
|
47
|
+
end
|
60
48
|
end
|
61
49
|
|
62
50
|
def renderer_for(file)
|
@@ -70,6 +58,5 @@ module Flatrack
|
|
70
58
|
def view_context
|
71
59
|
@view_context ||= ViewContext.new(self)
|
72
60
|
end
|
73
|
-
|
74
61
|
end
|
75
|
-
end
|
62
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
class Flatrack
|
2
2
|
class Response
|
3
3
|
class ViewContext
|
4
4
|
include AssetExtensions
|
@@ -11,64 +11,51 @@ module Flatrack
|
|
11
11
|
binding(&block)
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
def params
|
19
|
-
@response.request.params
|
20
|
-
end
|
21
|
-
|
22
|
-
def files
|
23
|
-
Dir.glob(File.join 'pages', path, '*').map do |file|
|
24
|
-
File.basename File.basename(file, '.*'), '.*'
|
25
|
-
end - [DEFAULT_FILE]
|
14
|
+
def html_tag(tag, options = {}, &block)
|
15
|
+
meta = options.map { |k, v| "#{k}=\"#{v}\"" }
|
16
|
+
prefix = [tag, *meta].join(' ')
|
17
|
+
"<#{prefix}" + (block_given? ? ">#{yield}</#{tag}>" : '/>')
|
26
18
|
end
|
27
19
|
|
28
20
|
def image_tag(uri, options = {})
|
29
|
-
uri =
|
21
|
+
uri = asset_path(uri)
|
30
22
|
html_tag(:img, { src: uri }.merge(options))
|
31
23
|
end
|
32
24
|
|
33
25
|
def javascript_tag(uri)
|
34
|
-
uri =
|
35
|
-
html_tag(:script, src: uri){ nil }
|
26
|
+
uri = asset_path(uri) + '.js' if uri.is_a? Symbol
|
27
|
+
html_tag(:script, src: uri) { nil }
|
36
28
|
end
|
37
29
|
|
38
|
-
def
|
39
|
-
|
40
|
-
|
30
|
+
def link_to(link_or_name, link_or_options=nil, options={})
|
31
|
+
name = link_or_name
|
32
|
+
link, options = if link_or_options.is_a?(Hash)
|
33
|
+
[name, link_or_options]
|
34
|
+
else
|
35
|
+
[link_or_options, options]
|
36
|
+
end
|
37
|
+
|
38
|
+
html_tag(:a, link_to_options(link, options)) { name }
|
41
39
|
end
|
42
40
|
|
43
|
-
def
|
44
|
-
|
45
|
-
base_path = File.join File.dirname(file), File.basename(file, '.*')
|
46
|
-
stylesheet_tag base_path if stylesheet_exists?(base_path)
|
41
|
+
def params
|
42
|
+
@response.request.params
|
47
43
|
end
|
48
44
|
|
49
|
-
def
|
50
|
-
|
51
|
-
html_tag(:a, { href: link }.merge(options) ){ name }
|
45
|
+
def path
|
46
|
+
@response.request.path
|
52
47
|
end
|
53
48
|
|
54
|
-
def
|
55
|
-
|
56
|
-
|
57
|
-
if block_given?
|
58
|
-
lines << yield
|
59
|
-
lines << "</#{tag}>"
|
60
|
-
end
|
61
|
-
end.compact.join("\n")
|
49
|
+
def stylesheet_tag(uri)
|
50
|
+
uri = asset_path(uri) + '.css' if uri.is_a? Symbol
|
51
|
+
html_tag(:link, rel: 'stylesheet', type: 'text/css', href: uri)
|
62
52
|
end
|
63
53
|
|
64
54
|
private
|
65
55
|
|
66
|
-
def
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
def javascript_exists?(name)
|
71
|
-
Flatrack.assets[name]
|
56
|
+
def link_to_options(link, opts={})
|
57
|
+
link << '?' + opts.delete(:params).to_param if opts[:params].present?
|
58
|
+
{ href: link }.merge(opts)
|
72
59
|
end
|
73
60
|
|
74
61
|
end
|
data/lib/flatrack/site.rb
CHANGED
@@ -1,15 +1,33 @@
|
|
1
|
-
|
1
|
+
require 'rack/server'
|
2
2
|
|
3
|
-
|
3
|
+
class Flatrack
|
4
|
+
module Site
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
run Flatrack.assets
|
6
|
+
def self.call(env)
|
7
|
+
builder.call(env)
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
private
|
11
|
+
|
12
|
+
def self.builder
|
13
|
+
mapping = self.mapping
|
14
|
+
Rack::Builder.app do
|
15
|
+
use Rack::Static, urls: ['/favicon.ico', 'assets'], root: 'public'
|
16
|
+
Flatrack.middleware.each { |mw| use(*mw) }
|
17
|
+
mapping.each { |path, app| map(path) { run app } }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.site
|
22
|
+
->(env) { Request.new(env).response }
|
13
23
|
end
|
24
|
+
|
25
|
+
def self.mapping
|
26
|
+
{
|
27
|
+
'/assets' => Flatrack.assets,
|
28
|
+
'/' => site
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
14
32
|
end
|
15
|
-
end
|
33
|
+
end
|
data/lib/flatrack/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION =
|
1
|
+
class Flatrack
|
2
|
+
VERSION = '1.0.0'
|
3
3
|
end
|
data/lib/rake/asset_tasks.rb
CHANGED
@@ -9,11 +9,10 @@ module Rake
|
|
9
9
|
# Rake::AssetTasks.new
|
10
10
|
#
|
11
11
|
class AssetTasks < Rake::TaskLib
|
12
|
-
|
13
|
-
|
12
|
+
attr_accessor :output
|
13
|
+
attr_accessor :environment
|
14
14
|
attr_reader :index
|
15
15
|
attr_reader :manifest
|
16
|
-
attr_reader :output
|
17
16
|
attr_reader :keep
|
18
17
|
|
19
18
|
# Number of old assets to keep.
|
@@ -46,8 +45,9 @@ module Rake
|
|
46
45
|
@environment = Flatrack.assets
|
47
46
|
@logger = Logger.new($stderr)
|
48
47
|
@logger.level = Logger::INFO
|
48
|
+
@output = './public/assets'
|
49
|
+
yield self
|
49
50
|
@index = environment.index
|
50
|
-
@output = "./public/assets"
|
51
51
|
@manifest = Sprockets::Manifest.new(index, output)
|
52
52
|
@keep = 2
|
53
53
|
define
|
@@ -56,8 +56,9 @@ module Rake
|
|
56
56
|
def assets
|
57
57
|
Dir['assets/**/*.*'].map do |file|
|
58
58
|
file_basename = File.basename file
|
59
|
-
|
60
|
-
|
59
|
+
parts = file_basename.split('.').size
|
60
|
+
file = file.split('.').tap(&:pop).join('.') if parts > 2
|
61
|
+
File.expand_path(file).sub(/(#{environment.paths.join('|')})\//, '')
|
61
62
|
end
|
62
63
|
end
|
63
64
|
|
@@ -71,20 +72,19 @@ module Rake
|
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
74
|
-
desc
|
75
|
+
desc 'Remove all assets'
|
75
76
|
task :clobber do
|
76
77
|
with_logger do
|
77
78
|
manifest.clobber
|
78
79
|
end
|
79
80
|
end
|
80
81
|
|
81
|
-
desc
|
82
|
+
desc 'Clean old assets'
|
82
83
|
task :clean do
|
83
84
|
with_logger do
|
84
85
|
manifest.clean(keep)
|
85
86
|
end
|
86
87
|
end
|
87
|
-
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
@@ -93,7 +93,8 @@ module Rake
|
|
93
93
|
# Sub out environment logger with our rake task logger that
|
94
94
|
# writes to stderr.
|
95
95
|
def with_logger
|
96
|
-
|
96
|
+
env = manifest.environment
|
97
|
+
if env
|
97
98
|
old_logger = env.logger
|
98
99
|
env.logger = @logger
|
99
100
|
end
|
@@ -101,6 +102,5 @@ module Rake
|
|
101
102
|
ensure
|
102
103
|
env.logger = old_logger if env
|
103
104
|
end
|
104
|
-
|
105
105
|
end
|
106
|
-
end
|
106
|
+
end
|
data/logo.png
ADDED
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
{}
|
data/renderers/erb.rb
CHANGED
data/renderers/html.rb
CHANGED
data/renderers/rb.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
require 'flatrack/renderer/base'
|
2
2
|
|
3
3
|
class Flatrack::Renderer::Rb < Flatrack::Renderer::Base
|
4
|
-
|
5
4
|
renders :rb
|
6
5
|
|
7
6
|
def render(context)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
7
|
+
eval <<-RUBY, context.get_binding
|
8
|
+
r = nil
|
9
|
+
evaluator = Thread.start do
|
10
|
+
$SAFE = 3
|
11
|
+
r = begin
|
12
|
+
#{contents}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
nil while evaluator.alive?
|
16
|
+
r
|
17
|
+
RUBY
|
15
18
|
end
|
16
|
-
|
17
19
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Flatrack::AssetExtensions do
|
4
|
+
|
5
|
+
subject(:instance){ double.extend described_class }
|
6
|
+
|
7
|
+
describe '#asset_path' do
|
8
|
+
it 'should be a path to the asset' do
|
9
|
+
expect(instance.asset_path :foo).to eq '/assets/foo'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Flatrack::CLI do
|
4
|
+
extend FileUtils
|
5
|
+
include SiteHelper
|
6
|
+
|
7
|
+
describe '#new' do
|
8
|
+
it 'should create a new site' do
|
9
|
+
in_temp_sites do
|
10
|
+
sha = SecureRandom.hex
|
11
|
+
Flatrack::CLI.start(['new', sha, '--verbose', 'false'])
|
12
|
+
expect(File.directory? sha).to be true
|
13
|
+
cleanup(sha)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#start' do
|
19
|
+
it 'should start the rack server' do
|
20
|
+
expect do
|
21
|
+
site do
|
22
|
+
thread = Thread.new do
|
23
|
+
Flatrack::CLI.start(['start', '--verbose', 'false'])
|
24
|
+
end
|
25
|
+
retries = 0
|
26
|
+
begin
|
27
|
+
Net::HTTP.get URI.parse 'http://localhost:5959'
|
28
|
+
thread.kill
|
29
|
+
rescue Errno::ECONNREFUSED => error
|
30
|
+
retries += 1
|
31
|
+
sleep 0.1 and retry unless retries > 100
|
32
|
+
raise error
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end.to_not raise_error
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should start a server on a custom port' do
|
39
|
+
expect do
|
40
|
+
site do
|
41
|
+
thread = Thread.new do
|
42
|
+
Flatrack::CLI.start(['start', '--port', '8282', '--verbose', 'false'])
|
43
|
+
end
|
44
|
+
retries = 0
|
45
|
+
begin
|
46
|
+
Net::HTTP.get URI.parse 'http://localhost:8282'
|
47
|
+
thread.kill
|
48
|
+
rescue Errno::ECONNREFUSED => error
|
49
|
+
retries += 1
|
50
|
+
sleep 0.1 and retry unless retries > 100
|
51
|
+
raise error
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end.to_not raise_error
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|