flatrack 1.3.3 → 1.4.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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.ruby-version +1 -1
  4. data/.travis.yml +3 -6
  5. data/flatrack.gemspec +4 -3
  6. data/lib/custom-extensions/sprockets-sass.rb +32 -0
  7. data/lib/flatrack.rb +123 -11
  8. data/lib/flatrack/asset_extensions.rb +7 -1
  9. data/lib/flatrack/cli.rb +9 -1
  10. data/lib/flatrack/domain_parser.rb +13 -0
  11. data/lib/flatrack/middleware.rb +32 -0
  12. data/lib/flatrack/redirector.rb +63 -0
  13. data/lib/flatrack/request.rb +16 -2
  14. data/lib/flatrack/response.rb +7 -8
  15. data/lib/flatrack/rewriter.rb +32 -0
  16. data/lib/flatrack/sass/functions.rb +6 -6
  17. data/lib/flatrack/sass/importer.rb +7 -7
  18. data/lib/flatrack/sass/sass_template.rb +6 -6
  19. data/lib/flatrack/site.rb +2 -27
  20. data/lib/flatrack/template.rb +27 -8
  21. data/lib/flatrack/template/erubis.rb +2 -2
  22. data/lib/flatrack/template/html.rb +2 -2
  23. data/lib/flatrack/template/rb.rb +2 -2
  24. data/lib/flatrack/version.rb +1 -1
  25. data/lib/flatrack/view.rb +1 -1
  26. data/lib/flatrack/view/capture_helper.rb +1 -2
  27. data/lib/flatrack/view/link_helper.rb +8 -1
  28. data/lib/flatrack/view/render_helper.rb +1 -1
  29. data/lib/flatrack/view/request_helper.rb +23 -2
  30. data/lib/flatrack/view/tag_helper.rb +19 -11
  31. data/spec/lib/flatrack/cli_spec.rb +28 -2
  32. data/spec/lib/flatrack/middleware_spec.rb +55 -0
  33. data/spec/lib/flatrack/site_spec.rb +3 -5
  34. data/spec/lib/flatrack/view/render_helper_spec.rb +4 -0
  35. data/spec/lib/flatrack/view/set_layout_spec.rb +1 -1
  36. data/spec/lib/flatrack/view/tag_helper_spec.rb +9 -0
  37. data/spec/lib/flatrack/view_spec.rb +1 -1
  38. data/spec/lib/flatrack_spec.rb +73 -0
  39. data/spec/lib/rake/asset_tasks_spec.rb +2 -2
  40. data/spec/spec_helper.rb +1 -0
  41. data/spec/support/fixture_helper.rb +1 -1
  42. data/spec/support/site_helper.rb +3 -1
  43. metadata +32 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4712856b901f1113021c85dcd49feb181318fbc5
4
- data.tar.gz: 9234ce5891267c17e254b3953bb2219a4e4a2dfe
3
+ metadata.gz: 2d13c4d84da9f6348b2d63a2b12ba6e76f422a1a
4
+ data.tar.gz: c3d9bfc0ec684c2922edfe260e92fbfbb994a793
5
5
  SHA512:
6
- metadata.gz: 39da8a5e1fce769e1d847d74cbdeb8642d484650ffd5a533872ef56a442799ad7ffd1a7f8c24375487541967108ee5b0b7c13567664c59e7e8b3fac8c4d472af
7
- data.tar.gz: ab7fcf8c901f5613006707a6c23432f8c6723e6ed7010300c55cf503bce952cb14554d3a7442e80e694b5ce5d8936ebd6630cf350fb942ffea7dba60ea3a642b
6
+ metadata.gz: 73606292ae76a830287a1b6426df26f31fb6695eccdd4ec43ab01adb322bfe210e33a08c38b23f7afc8e9301e27d10bed724a82e6d62f5d82e43ae2548082db6
7
+ data.tar.gz: f96358443ba28a52c4d8736818b7c7b9d8f26cd0d8bb6b189799438da3246568bdac01874376e3249be0914ed53dc2eb830acd733a0f822bf8a74e80b05dd6ad
data/.gitignore CHANGED
@@ -4,6 +4,7 @@ pkg/*
4
4
  tmp
5
5
  coverage
6
6
  /.sass-cache/
7
+ .bundle
7
8
 
8
9
  /.yardoc/
9
10
 
@@ -1 +1 @@
1
- 2.1.3
1
+ 2.2.0
@@ -1,10 +1,9 @@
1
1
  language: ruby
2
+ sudo: false
2
3
  rvm:
3
4
  - 2.0.0
4
- - 2.1.1
5
- - 2.1.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
@@ -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', '< 4.2']
36
- spec.add_runtime_dependency 'sass', '~> 3.2.0'
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.2']
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
@@ -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, :site_root, to: self
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
- File.expand_path Dir.pwd
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(&block)
65
- yield self
66
- self
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.append_path 'assets/images'
76
- environment.append_path 'assets/javascripts'
77
- environment.append_path 'assets/stylesheets'
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
@@ -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
- require './boot'
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