flatrack 1.3.3 → 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.ruby-version +1 -1
- data/.travis.yml +3 -6
- data/flatrack.gemspec +4 -3
- data/lib/custom-extensions/sprockets-sass.rb +32 -0
- data/lib/flatrack.rb +123 -11
- data/lib/flatrack/asset_extensions.rb +7 -1
- data/lib/flatrack/cli.rb +9 -1
- data/lib/flatrack/domain_parser.rb +13 -0
- data/lib/flatrack/middleware.rb +32 -0
- data/lib/flatrack/redirector.rb +63 -0
- data/lib/flatrack/request.rb +16 -2
- data/lib/flatrack/response.rb +7 -8
- data/lib/flatrack/rewriter.rb +32 -0
- data/lib/flatrack/sass/functions.rb +6 -6
- data/lib/flatrack/sass/importer.rb +7 -7
- data/lib/flatrack/sass/sass_template.rb +6 -6
- data/lib/flatrack/site.rb +2 -27
- data/lib/flatrack/template.rb +27 -8
- data/lib/flatrack/template/erubis.rb +2 -2
- data/lib/flatrack/template/html.rb +2 -2
- data/lib/flatrack/template/rb.rb +2 -2
- data/lib/flatrack/version.rb +1 -1
- data/lib/flatrack/view.rb +1 -1
- data/lib/flatrack/view/capture_helper.rb +1 -2
- data/lib/flatrack/view/link_helper.rb +8 -1
- data/lib/flatrack/view/render_helper.rb +1 -1
- data/lib/flatrack/view/request_helper.rb +23 -2
- data/lib/flatrack/view/tag_helper.rb +19 -11
- data/spec/lib/flatrack/cli_spec.rb +28 -2
- data/spec/lib/flatrack/middleware_spec.rb +55 -0
- data/spec/lib/flatrack/site_spec.rb +3 -5
- data/spec/lib/flatrack/view/render_helper_spec.rb +4 -0
- data/spec/lib/flatrack/view/set_layout_spec.rb +1 -1
- data/spec/lib/flatrack/view/tag_helper_spec.rb +9 -0
- data/spec/lib/flatrack/view_spec.rb +1 -1
- data/spec/lib/flatrack_spec.rb +73 -0
- data/spec/lib/rake/asset_tasks_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/support/fixture_helper.rb +1 -1
- data/spec/support/site_helper.rb +3 -1
- metadata +32 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d13c4d84da9f6348b2d63a2b12ba6e76f422a1a
|
4
|
+
data.tar.gz: c3d9bfc0ec684c2922edfe260e92fbfbb994a793
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 73606292ae76a830287a1b6426df26f31fb6695eccdd4ec43ab01adb322bfe210e33a08c38b23f7afc8e9301e27d10bed724a82e6d62f5d82e43ae2548082db6
|
7
|
+
data.tar.gz: f96358443ba28a52c4d8736818b7c7b9d8f26cd0d8bb6b189799438da3246568bdac01874376e3249be0914ed53dc2eb830acd733a0f822bf8a74e80b05dd6ad
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.2.0
|
data/.travis.yml
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
language: ruby
|
2
|
+
sudo: false
|
2
3
|
rvm:
|
3
4
|
- 2.0.0
|
4
|
-
- 2.1.
|
5
|
-
- 2.
|
6
|
-
- 2.1.2
|
7
|
-
- 2.2.0-preview1
|
5
|
+
- 2.1.5
|
6
|
+
- 2.2.0
|
8
7
|
cache: bundler
|
9
8
|
after_success:
|
10
9
|
- bundle exec inch
|
@@ -12,5 +11,3 @@ after_success:
|
|
12
11
|
|
13
12
|
matrix:
|
14
13
|
fast_finish: true
|
15
|
-
allow_failures:
|
16
|
-
- rvm: 2.2.0-preview1
|
data/flatrack.gemspec
CHANGED
@@ -30,14 +30,15 @@ based routing.
|
|
30
30
|
|
31
31
|
# Dependencies
|
32
32
|
spec.add_runtime_dependency 'rack', '~> 1.4'
|
33
|
+
spec.add_runtime_dependency 'rack-contrib', '~> 1.2'
|
33
34
|
spec.add_runtime_dependency 'erubis', '~> 2.7'
|
34
35
|
spec.add_runtime_dependency 'tilt', '~> 1.1'
|
35
|
-
spec.add_runtime_dependency 'activesupport', ['> 3.2', '<
|
36
|
-
spec.add_runtime_dependency 'sass', '~> 3.2
|
36
|
+
spec.add_runtime_dependency 'activesupport', ['> 3.2', '< 5.0']
|
37
|
+
spec.add_runtime_dependency 'sass', '~> 3.2'
|
37
38
|
spec.add_runtime_dependency 'sprockets-sass', '~> 1.2'
|
38
39
|
spec.add_runtime_dependency 'thor', '~> 0.18'
|
39
40
|
spec.add_runtime_dependency 'coffee-script', '~> 2.2'
|
40
|
-
spec.add_runtime_dependency 'rake', ['> 0.8.7', '< 10.
|
41
|
+
spec.add_runtime_dependency 'rake', ['> 0.8.7', '< 10.4']
|
41
42
|
|
42
43
|
# Dev Dependencies
|
43
44
|
spec.add_development_dependency 'bundler', '~> 1.5'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'sprockets'
|
2
|
+
require 'sprockets/sass/version'
|
3
|
+
require 'sprockets/sass/sass_template'
|
4
|
+
require 'sprockets/sass/scss_template'
|
5
|
+
require 'sprockets/engines'
|
6
|
+
|
7
|
+
module Sprockets
|
8
|
+
module Sass
|
9
|
+
autoload :CacheStore, 'sprockets/sass/cache_store'
|
10
|
+
autoload :Compressor, 'sprockets/sass/compressor'
|
11
|
+
autoload :Importer, 'sprockets/sass/importer'
|
12
|
+
|
13
|
+
class << self
|
14
|
+
# Global configuration for `Sass::Engine` instances.
|
15
|
+
attr_accessor :options
|
16
|
+
|
17
|
+
# When false, the asset path helpers provided by
|
18
|
+
# sprockets-helpers will not be added as Sass functions.
|
19
|
+
# `true` by default.
|
20
|
+
attr_accessor :add_sass_functions
|
21
|
+
end
|
22
|
+
|
23
|
+
@options = {}
|
24
|
+
@add_sass_functions = true
|
25
|
+
|
26
|
+
# Allow to fallback to real sass
|
27
|
+
def self.const_missing(const)
|
28
|
+
::Sass.const_get const
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
data/lib/flatrack.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'flatrack/version'
|
2
2
|
require 'active_support/all'
|
3
|
-
require 'sprockets'
|
4
|
-
require 'sprockets-sass'
|
3
|
+
require 'custom-extensions/sprockets-sass'
|
5
4
|
require 'coffee-script'
|
6
5
|
require 'sass'
|
7
6
|
require 'rack'
|
7
|
+
require 'rack/contrib'
|
8
8
|
|
9
9
|
# A static site generator with a little sprinkle of ruby magic
|
10
10
|
class Flatrack
|
@@ -17,15 +17,26 @@ class Flatrack
|
|
17
17
|
autoload :Site
|
18
18
|
autoload :AssetExtensions
|
19
19
|
autoload :CLI
|
20
|
+
autoload :Middleware
|
21
|
+
autoload :Rewriter
|
22
|
+
autoload :Redirector
|
23
|
+
autoload :DomainParser
|
24
|
+
|
25
|
+
Redirector
|
26
|
+
Rewriter
|
20
27
|
|
21
28
|
# @private
|
22
29
|
TemplateNotFound = Class.new StandardError
|
23
30
|
# @private
|
24
31
|
FileNotFound = Class.new StandardError
|
25
32
|
# @private
|
26
|
-
FORMATS
|
33
|
+
FORMATS = {}
|
34
|
+
# @private
|
35
|
+
MAPPING = { '/assets' => :assets, '/' => :site }
|
27
36
|
|
28
|
-
delegate :gem_root,
|
37
|
+
delegate :gem_root, to: self
|
38
|
+
delegate :call, to: :builder
|
39
|
+
attr_accessor :raise_errors
|
29
40
|
|
30
41
|
class << self
|
31
42
|
# The root of the flatrack gem
|
@@ -39,14 +50,20 @@ class Flatrack
|
|
39
50
|
# @!attribute [r] site_root
|
40
51
|
# @return [String]
|
41
52
|
def site_root
|
42
|
-
|
53
|
+
Dir.pwd
|
43
54
|
end
|
44
55
|
|
45
56
|
# Reset the state of flatrack and its configuration
|
57
|
+
# For testing
|
58
|
+
# @private
|
46
59
|
def reset!
|
47
60
|
@delegate_instance = nil
|
48
61
|
end
|
49
62
|
|
63
|
+
def site=(instance)
|
64
|
+
@delegate_instance = instance
|
65
|
+
end
|
66
|
+
|
50
67
|
private
|
51
68
|
|
52
69
|
def delegate_instance
|
@@ -61,9 +78,12 @@ class Flatrack
|
|
61
78
|
# Configure the flatrack instance
|
62
79
|
# @yield [Flatrack] configuration for the flatrack instance
|
63
80
|
# @return [Flatrack]
|
64
|
-
def config
|
65
|
-
yield self
|
66
|
-
|
81
|
+
def config
|
82
|
+
yield self if block_given?
|
83
|
+
OpenStruct.new(
|
84
|
+
site_root: site_root,
|
85
|
+
raise_errors: raise_errors
|
86
|
+
).freeze
|
67
87
|
end
|
68
88
|
|
69
89
|
# The flatrack sprockets environment
|
@@ -71,10 +91,13 @@ class Flatrack
|
|
71
91
|
# @return [Sprockets::Environment]
|
72
92
|
def assets
|
73
93
|
@assets ||= begin
|
94
|
+
Sass.load_paths << File.join(site_root, 'assets/stylesheets')
|
74
95
|
Sprockets::Environment.new.tap do |environment|
|
75
|
-
environment.
|
76
|
-
environment.
|
77
|
-
environment.append_path 'assets/
|
96
|
+
environment.register_engine '.sass', Sprockets::Sass::SassTemplate
|
97
|
+
environment.register_engine '.scss', Sprockets::Sass::ScssTemplate
|
98
|
+
environment.append_path File.join site_root, 'assets/images'
|
99
|
+
environment.append_path File.join site_root, 'assets/javascripts'
|
100
|
+
environment.append_path File.join site_root, 'assets/stylesheets'
|
78
101
|
environment.context_class.class_eval { include AssetExtensions }
|
79
102
|
end
|
80
103
|
end
|
@@ -88,10 +111,54 @@ class Flatrack
|
|
88
111
|
end
|
89
112
|
|
90
113
|
# The middleware stack for flatrack
|
114
|
+
# @!attribute [r] middleware
|
115
|
+
# @return [Hash]
|
91
116
|
def middleware
|
92
117
|
@middleware ||= []
|
93
118
|
end
|
94
119
|
|
120
|
+
# This is for testing
|
121
|
+
# @private
|
122
|
+
def mock_env_for(url, opts={})
|
123
|
+
env = Rack::MockRequest.env_for url, opts
|
124
|
+
env.merge! env_extensions
|
125
|
+
end
|
126
|
+
|
127
|
+
# Rewrite a path
|
128
|
+
# @param source [String]
|
129
|
+
# @param to [String]
|
130
|
+
def rewrite(source, to: nil)
|
131
|
+
unless [source, to].all? { |path| path.is_a? String }
|
132
|
+
raise ArgumentError, 'mappings must be strings'
|
133
|
+
end
|
134
|
+
rewrites.merge! source => to
|
135
|
+
end
|
136
|
+
|
137
|
+
# redirect a path
|
138
|
+
# @param source [String]
|
139
|
+
# @param to [String]
|
140
|
+
# @param type [Symbol]
|
141
|
+
def redirect(source, to: nil, type: :permanent)
|
142
|
+
unless [source, to].all? { |path| path.is_a? String }
|
143
|
+
raise ArgumentError, 'mappings must be strings'
|
144
|
+
end
|
145
|
+
redirects.merge! source => Redirector::Redirect.new(to, type)
|
146
|
+
end
|
147
|
+
|
148
|
+
# The rewrites
|
149
|
+
# @!attribute [r] rewrites
|
150
|
+
# @return [Hash]
|
151
|
+
def rewrites
|
152
|
+
@rewrites ||= {}
|
153
|
+
end
|
154
|
+
|
155
|
+
# The redirects
|
156
|
+
# @!attribute [r] redirects
|
157
|
+
# @return [Hash]
|
158
|
+
def redirects
|
159
|
+
@redirects ||= {}
|
160
|
+
end
|
161
|
+
|
95
162
|
# Insert a rack middleware at the end of the stack
|
96
163
|
# @param middleware [Class] the middleware class
|
97
164
|
# @param options [Hash] the options for the middleware
|
@@ -99,6 +166,51 @@ class Flatrack
|
|
99
166
|
self.middleware << [middleware, options].compact
|
100
167
|
end
|
101
168
|
|
169
|
+
def site_root=(path)
|
170
|
+
path = File.expand_path path
|
171
|
+
Template.register_path path
|
172
|
+
@site_root = path
|
173
|
+
end
|
174
|
+
|
175
|
+
# The site root
|
176
|
+
# @!attribute [r] site_root
|
177
|
+
# @return [String]
|
178
|
+
def site_root
|
179
|
+
@site_root || (self.site_root = self.class.site_root)
|
180
|
+
end
|
181
|
+
|
182
|
+
# Returns the site lambda
|
183
|
+
# @return [Proc]
|
184
|
+
def site
|
185
|
+
lambda { |env|
|
186
|
+
env.merge! env_extensions
|
187
|
+
Request.new(env).response
|
188
|
+
}
|
189
|
+
end
|
190
|
+
|
191
|
+
private
|
192
|
+
|
193
|
+
def builder
|
194
|
+
@builder ||= begin
|
195
|
+
this = self
|
196
|
+
Rack::Builder.app do
|
197
|
+
use Rack::Cookies
|
198
|
+
use DomainParser
|
199
|
+
use Flatrack::Rewriter, this.rewrites if this.rewrites.present?
|
200
|
+
use Flatrack::Redirector, this.redirects if this.redirects.present?
|
201
|
+
use Rack::Static,
|
202
|
+
urls: ['/favicon.ico', 'assets'],
|
203
|
+
root: File.join(this.site_root, 'public')
|
204
|
+
this.middleware.each { |mw| use *mw }
|
205
|
+
MAPPING.each { |path, app| map(path) { run this.send(app) } }
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def env_extensions
|
211
|
+
{ 'flatrack.config' => self.config }
|
212
|
+
end
|
213
|
+
|
102
214
|
# By default we know how to render 'text/html'
|
103
215
|
register_format :html, 'text/html'
|
104
216
|
|
@@ -5,7 +5,13 @@ class Flatrack
|
|
5
5
|
# @param path [String] the asset name or path
|
6
6
|
# @return [String]
|
7
7
|
def asset_path(path, _ = {})
|
8
|
-
File.join('/assets', path.to_s)
|
8
|
+
File.join('/', mount_path, 'assets', path.to_s)
|
9
|
+
end
|
10
|
+
|
11
|
+
def mount_path
|
12
|
+
a = singleton_class.ancestors
|
13
|
+
has_super = a[a.index(AssetExtensions) + 1].method_defined? __method__
|
14
|
+
has_super ? super : '/'
|
9
15
|
end
|
10
16
|
end
|
11
17
|
end
|
data/lib/flatrack/cli.rb
CHANGED
@@ -58,11 +58,19 @@ class Flatrack
|
|
58
58
|
|
59
59
|
method_option :verbose, type: :boolean, default: true, aliases: :v
|
60
60
|
method_option :port, type: :numeric, default: 5959, aliases: :p
|
61
|
+
method_option :root, default: Dir.pwd, type: :string, aliases: :r
|
61
62
|
|
62
63
|
desc 'start --port PORT', 'run the site on the given port'
|
63
64
|
# Start the app
|
64
65
|
def start
|
65
|
-
|
66
|
+
Flatrack.config do |config|
|
67
|
+
config.site_root = options[:root]
|
68
|
+
end
|
69
|
+
begin
|
70
|
+
require File.join Dir.pwd, 'boot'
|
71
|
+
rescue LoadError
|
72
|
+
nil
|
73
|
+
end
|
66
74
|
run_opts = {}
|
67
75
|
run_opts[:app] = Flatrack::Site
|
68
76
|
run_opts[:Port] = options[:port]
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Flatrack
|
2
|
+
class DomainParser < Struct.new :app
|
3
|
+
|
4
|
+
def call(env)
|
5
|
+
*subdomains, host, tld = env['SERVER_NAME'].split '.'
|
6
|
+
env['domain.sub'] = subdomains.join '.'
|
7
|
+
env['domain.host'] = host
|
8
|
+
env['domain.tld'] = tld
|
9
|
+
app.call(env)
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Flatrack
|
2
|
+
class Middleware
|
3
|
+
|
4
|
+
def initialize(app, opts = {})
|
5
|
+
@if = opts[:if] || Proc.new { true }
|
6
|
+
@unless = opts[:unless] || Proc.new { false }
|
7
|
+
@app = app
|
8
|
+
@flatrack_app = opts[:flatrack_app] || Flatrack::Site
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
Flatrack::DomainParser.new(null_app).call(env)
|
13
|
+
allow = @if.call(env) && !@unless.call(env)
|
14
|
+
return call_app env unless allow
|
15
|
+
response = @flatrack_app.call env
|
16
|
+
status, _, _ = response
|
17
|
+
response = call_app(env) if status == 404
|
18
|
+
response
|
19
|
+
rescue Flatrack::FileNotFound
|
20
|
+
call_app env
|
21
|
+
end
|
22
|
+
|
23
|
+
def call_app(env)
|
24
|
+
@app.call env
|
25
|
+
end
|
26
|
+
|
27
|
+
def null_app
|
28
|
+
->(_){}
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
class Flatrack
|
2
|
+
def Redirector(source, opts={})
|
3
|
+
to = opts.delete(:to)
|
4
|
+
type = opts.delete(:type) || :permanent
|
5
|
+
klass = Class.new(Redirector)
|
6
|
+
klass.send(:define_method, :initialize) do |app, mw_opts|
|
7
|
+
mapping = { source => Redirector::Redirect.new(to, type) }
|
8
|
+
super app, mapping, mw_opts
|
9
|
+
end
|
10
|
+
klass
|
11
|
+
end
|
12
|
+
|
13
|
+
class Redirector
|
14
|
+
|
15
|
+
def initialize(app, mapping = {}, opts = {})
|
16
|
+
@if = opts[:if] || Proc.new { true }
|
17
|
+
@unless = opts[:unless] || Proc.new { false }
|
18
|
+
@app = app
|
19
|
+
@mapping =
|
20
|
+
Hash[mapping.map { |k, v| [File.join('', k), v] }]
|
21
|
+
end
|
22
|
+
|
23
|
+
def call(env)
|
24
|
+
allow = @if.call(env) && !@unless.call(env)
|
25
|
+
if allow && @mapping.keys.include?(env['PATH_INFO'])
|
26
|
+
@mapping[env['PATH_INFO']].response
|
27
|
+
else
|
28
|
+
@app.call env
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
class Redirect
|
35
|
+
|
36
|
+
attr_reader :url, :type
|
37
|
+
|
38
|
+
def initialize(url, type = :permanent)
|
39
|
+
@url, @type = url, type
|
40
|
+
code # just to check args
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns the code for the specified type
|
44
|
+
# @returns [Fixnum]
|
45
|
+
def code
|
46
|
+
case type.to_sym
|
47
|
+
when :permanent
|
48
|
+
301
|
49
|
+
when :temporary
|
50
|
+
302
|
51
|
+
else
|
52
|
+
raise ArgumentError, 'type must be :temporary or :permanent'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def response
|
57
|
+
[code, { 'location' => url }, ["you are being redirected to: `#{url}`"]]
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|