spark_engine 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.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/CODE_OF_CONDUCT.md +49 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +34 -0
  7. data/Rakefile +2 -0
  8. data/bin/spark +99 -0
  9. data/lib/spark_engine/assets.rb +8 -0
  10. data/lib/spark_engine/command/help.rb +86 -0
  11. data/lib/spark_engine/command/npm.rb +62 -0
  12. data/lib/spark_engine/command.rb +156 -0
  13. data/lib/spark_engine/config_data.rb +29 -0
  14. data/lib/spark_engine/helpers/asset_helpers.rb +66 -0
  15. data/lib/spark_engine/helpers/layout_helpers.rb +21 -0
  16. data/lib/spark_engine/middleware.rb +72 -0
  17. data/lib/spark_engine/plugin/assets/asset.rb +163 -0
  18. data/lib/spark_engine/plugin/assets/javascripts.rb +83 -0
  19. data/lib/spark_engine/plugin/assets/stylesheets.rb +88 -0
  20. data/lib/spark_engine/plugin/assets/svgs.rb +79 -0
  21. data/lib/spark_engine/plugin.rb +191 -0
  22. data/lib/spark_engine/sass/engine.rb +21 -0
  23. data/lib/spark_engine/sass/importer.rb +103 -0
  24. data/lib/spark_engine/scaffold/gem/.gitignore +18 -0
  25. data/lib/spark_engine/scaffold/gem/app/assets/images/namespace/.keep +0 -0
  26. data/lib/spark_engine/scaffold/gem/app/assets/javascripts/namespace/engine.js +3 -0
  27. data/lib/spark_engine/scaffold/gem/app/assets/stylesheets/namespace/_index.scss +1 -0
  28. data/lib/spark_engine/scaffold/gem/app/assets/svgs/namespace/.keep +0 -0
  29. data/lib/spark_engine/scaffold/gem/app/helpers/namespace/application_helper.rb +4 -0
  30. data/lib/spark_engine/scaffold/gem/app/views/layouts/namespace/default.html.erb +18 -0
  31. data/lib/spark_engine/scaffold/gem/gem.gemspec +24 -0
  32. data/lib/spark_engine/scaffold/gem/lib/gem.rb +12 -0
  33. data/lib/spark_engine/scaffold/gem/site/app/assets/javascripts/application.js +1 -0
  34. data/lib/spark_engine/scaffold/gem/site/app/assets/stylesheets/application.scss +2 -0
  35. data/lib/spark_engine/scaffold/gem/site/app/controllers/docs_controller.rb +19 -0
  36. data/lib/spark_engine/scaffold/gem/site/app/views/docs/index.html.erb +1 -0
  37. data/lib/spark_engine/scaffold/gem/site/app/views/layouts/application.html.erb +4 -0
  38. data/lib/spark_engine/scaffold/gem/site/config/application.rb +18 -0
  39. data/lib/spark_engine/scaffold/gem/site/config/environments/development.rb +13 -0
  40. data/lib/spark_engine/scaffold/gem/site/config/routes.rb +3 -0
  41. data/lib/spark_engine/scaffold.rb +191 -0
  42. data/lib/spark_engine/version.rb +3 -0
  43. data/lib/spark_engine.rb +106 -0
  44. data/spark_engine.gemspec +31 -0
  45. metadata +234 -0
@@ -0,0 +1,72 @@
1
+ require 'action_dispatch/middleware/static'
2
+
3
+ module SparkEngine
4
+ class Application < Rails::Application
5
+ initializer "static assets" do |app|
6
+ app.middleware.insert_before(::ActionDispatch::Static, ::ActionDispatch::Static, "#{root}/public")
7
+ end
8
+ end
9
+
10
+ class StaticAssets
11
+
12
+ # Rails 5 middleware patch
13
+ if SparkEngine.rails5?
14
+
15
+ def initialize(app, path, index: 'index', headers: {}, engine_name: nil)
16
+ @app = app
17
+ @engine_name = engine_name
18
+ @file_handler = ActionDispatch::FileHandler.new(path, index: index, headers: headers)
19
+ end
20
+
21
+ def call(env)
22
+ req = Rack::Request.new env
23
+ prefix = File.join Application.config.assets.prefix, @engine_name
24
+
25
+ if req.get? || req.head?
26
+ path = req.path_info.chomp('/'.freeze)
27
+
28
+ if path.start_with? prefix
29
+ path = path.remove /\A#{prefix}\//
30
+
31
+ if match = @file_handler.match?(path)
32
+ req.path_info = match
33
+ return @file_handler.serve(req)
34
+ end
35
+ end
36
+ end
37
+
38
+ @app.call(req.env)
39
+ end
40
+
41
+ # Rails 4 middleware patch
42
+ else
43
+
44
+ def initialize(app, path, cache_control=nil, engine_name: nil)
45
+ @app = app
46
+ @engine_name = engine_name
47
+ @file_handler = ::ActionDispatch::FileHandler.new(path, cache_control)
48
+ end
49
+
50
+ def call(env)
51
+ prefix = File.join Application.config.assets.prefix, @engine_name
52
+
53
+ case env['REQUEST_METHOD']
54
+ when 'GET', 'HEAD'
55
+ path = env['PATH_INFO'].chomp('/')
56
+
57
+ if path.start_with? prefix
58
+ path = path.remove /\A#{prefix}\//
59
+
60
+ if match = @file_handler.match?(path)
61
+ env["PATH_INFO"] = match
62
+ return @file_handler.call(env)
63
+ end
64
+ end
65
+ end
66
+
67
+ @app.call(env)
68
+ end
69
+ end
70
+ end
71
+
72
+ end
@@ -0,0 +1,163 @@
1
+ module SparkEngine
2
+ module Assets
3
+ class AssetType
4
+ attr_reader :plugin, :base
5
+
6
+ def initialize(plugin, base)
7
+ @base = base
8
+ @plugin = plugin
9
+ end
10
+
11
+ def find_files
12
+ if @files
13
+ @files
14
+ else
15
+ files = Dir[File.join(base, "*.#{ext}")].reject do |f|
16
+ # Filter out partials
17
+ File.basename(f).start_with?('_')
18
+ end
19
+
20
+ @files = files if SparkEngine.production?
21
+ files
22
+ end
23
+ end
24
+
25
+ def filter_files(names)
26
+
27
+ # Filter names based on asset file locations
28
+ find_files.select do |f|
29
+ names.include? File.basename(f).sub(/(\..+)$/,'')
30
+ end
31
+ end
32
+
33
+ def versioned(path)
34
+ File.basename(path).sub(/(\.\w+)$/, '-'+plugin.version+'\1')
35
+ end
36
+
37
+ def local_path(file)
38
+ destination(file).sub(plugin.root+'/','')
39
+ end
40
+
41
+ def build_success(file)
42
+ log_success "Built: #{local_path(file)}"
43
+ end
44
+
45
+ def build_failure(file)
46
+ msg = "\nFAILED TO BUILD"
47
+ msg += ": #{local_path(file)}" if file
48
+ log_error msg
49
+ end
50
+
51
+ def log_success( msg )
52
+ STDOUT.puts msg.to_s.colorize(:green)
53
+ end
54
+
55
+ def log_error( msg )
56
+ STDERR.puts msg.to_s.colorize(:red)
57
+ end
58
+
59
+ # Determine if an NPM module is installed by checking paths with `npm bin`
60
+ # Returns path to binary if installed
61
+ def find_node_module(cmd)
62
+ require 'open3'
63
+ (@modules ||= {})[cmd] ||= begin
64
+
65
+ local = "$(npm bin)/#{cmd}"
66
+ global = "$(npm -g bin)/#{cmd}"
67
+
68
+ if Open3.capture3(local)[2].success?
69
+ local
70
+ elsif Open3.capture3(global)[2].success?
71
+ global
72
+ end
73
+
74
+ end
75
+ end
76
+
77
+ def npm_command(cmd)
78
+ cmd = cmd.split(' ')
79
+ if path = find_node_module(cmd.shift)
80
+ system "#{path} #{cmd.join(' ')}"
81
+ end
82
+ end
83
+
84
+ def destination(path)
85
+ plugin.asset_path(versioned(path))
86
+ end
87
+
88
+ def url(path)
89
+ plugin.asset_url(versioned(path))
90
+ end
91
+
92
+ def urls(names=nil)
93
+ # If names are passed, look at the basename minus
94
+ # the extension as build files may have
95
+ # different extensions than sources
96
+ names = [names].flatten.compact.map do |n|
97
+ File.basename(n).sub(/(\..+)$/,'')
98
+ end
99
+
100
+ # Return all asset urls if none were specifically chosen
101
+ if names.empty?
102
+ find_files.map{ |file| url(file) }
103
+
104
+ # Filter files based on name
105
+ else
106
+ filter_files(names).map{ |file| url(file) }
107
+ end
108
+ end
109
+
110
+ def watch
111
+
112
+ @throttle = 4
113
+ @last_build = 0
114
+
115
+ puts "Watching for changes to #{base.sub(plugin.root+'/', '')}...".colorize(:light_yellow)
116
+
117
+ Thread.new {
118
+ listener = Listen.to(base) do |modified, added, removed|
119
+ change(modified, added, removed)
120
+ end
121
+
122
+ listener.start # not blocking
123
+ sleep
124
+ }
125
+ end
126
+
127
+ def change(modified, added, removed)
128
+ return if (Time.now.to_i - @last_build) < @throttle
129
+
130
+ puts "Added: #{file_event(added)}".colorize(:light_green) unless added.empty?
131
+ puts "Removed: #{file_event(removed)}".colorize(:light_red) unless removed.empty?
132
+ puts "Modified: #{file_event(modified)}".colorize(:light_yellow) unless modified.empty?
133
+
134
+ build
135
+ @last_build = Time.now.to_i
136
+ end
137
+
138
+ def file_event(files)
139
+ list = files.flat_map { |f| f.sub(base+'/', '') }.join(" \n")
140
+ list = " \n#{files}" if 1 < files.size
141
+
142
+ list
143
+ end
144
+
145
+ def compress(file)
146
+ return unless SparkEngine.production?
147
+
148
+ mtime = File.mtime(file)
149
+ gz_file = "#{file}.gz"
150
+ return if File.exist?(gz_file) && File.mtime(gz_file) >= mtime
151
+
152
+ File.open(gz_file, "wb") do |dest|
153
+ gz = Zlib::GzipWriter.new(dest, Zlib::BEST_COMPRESSION)
154
+ gz.mtime = mtime.to_i
155
+ IO.copy_stream(open(file), gz)
156
+ gz.close
157
+ end
158
+
159
+ File.utime(mtime, mtime, gz_file)
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,83 @@
1
+ module SparkEngine
2
+ module Assets
3
+ class Javascripts < AssetType
4
+ def ext
5
+ "js"
6
+ end
7
+
8
+ def asset_tag(*args)
9
+ javascript_include_tag(args)
10
+ end
11
+
12
+ def cache_file(name=nil)
13
+ SparkEngine.rails_path("tmp/cache/assets/.browserify-cache-#{name}.json")
14
+ end
15
+
16
+ # Find all asset files matching array of names
17
+ def filter_files(names)
18
+ [find_files, plugin.svgs.build_paths].flatten.select do |f|
19
+ names.include? File.basename(f).sub(/(\..+)$/,'')
20
+ end
21
+ end
22
+
23
+ def build
24
+ files = find_files
25
+ FileUtils.mkdir_p(File.dirname(cache_file)) if !files.empty?
26
+
27
+ if Open3.capture3("npm ls browserify-incremental")[1].empty?
28
+ files.each do |file|
29
+
30
+ dest = destination(file)
31
+
32
+ FileUtils.rm(dest) if File.exists?(dest)
33
+
34
+ response = Open3.capture3(build_command(file))
35
+
36
+ # If the file exists and is not empty (a failed build is empty)
37
+ if File.exist?(dest) && !File.read(dest).strip.empty?
38
+ compress(dest) if SparkEngine.production?
39
+ build_success file
40
+ else
41
+ build_failure file
42
+
43
+ response = response.map { |l| l.to_s.split("\n") }.flatten
44
+
45
+ response.each do |line|
46
+ if !line.empty? && # Don't print empty lines
47
+ !line.match(/node_modules/i) && # Ignore stack traces from installed modules
48
+ !line.match(/pid (\d+?) exit/i) && # Ignore pid exit stack line
49
+ !line.match(/\[BABEL\] Note:/i) # Notices from Bable are noisy
50
+ log_error line.gsub(plugin.root+'/','')
51
+ end
52
+ end
53
+
54
+ puts ""
55
+ end
56
+ end
57
+ else
58
+ log_error "JS BUILD FAILED: browserifyinc NPM module not found.\n" << "Please add browserifyinc to your package.json and run `npm install`"
59
+ abort
60
+ end
61
+ end
62
+
63
+ def npm_path( cmd )
64
+ File.join SparkEngine.gem_path, "node_modules/.bin", cmd
65
+ end
66
+
67
+ def build_command(file)
68
+ dest = destination(file).sub(/\.js$/,'')
69
+ options = "--standalone #{plugin.name} -o #{dest}.js -d"
70
+
71
+ cmd = if SparkEngine.production?
72
+ npm_path "browserify #{file} #{options} -t"
73
+ else
74
+ npm_path "browserifyinc --cachefile #{cache_file(File.basename(dest))} #{file} #{options}"
75
+ end
76
+ puts "Running: #{cmd}"
77
+
78
+ cmd
79
+
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,88 @@
1
+ require 'sass'
2
+ require "autoprefixer-rails"
3
+
4
+ module SparkEngine
5
+ module Assets
6
+ class Stylesheets < AssetType
7
+
8
+ def ext
9
+ "*[ca]ss"
10
+ end
11
+
12
+ def asset_tag(*args)
13
+ stylesheet_link_tag(args)
14
+ end
15
+
16
+ def build(ext=nil)
17
+ files = find_files
18
+ files = files.reject {|f| !f.match(/\.#{ext}/) } if ext
19
+
20
+ files.each do |file|
21
+
22
+ begin
23
+ if File.extname(file).match(/\.css/)
24
+ build_css(file)
25
+ elsif File.extname(file).match(/\.s[ca]ss/)
26
+ build_sass(file)
27
+ end
28
+
29
+ puts build_success(file)
30
+
31
+ rescue Exception => e
32
+ build_failure file
33
+
34
+ if e.backtrace.is_a? Array
35
+ log_error "Error in file: #{local_path(e.backtrace[0])}"
36
+ end
37
+
38
+ log_error " #{e.message}\n" if e.message
39
+ end
40
+ end
41
+ end
42
+
43
+ def build_css(file)
44
+ css = AutoprefixerRails.process(File.read(file)).css
45
+ File.open(destination(file), 'w') { |io| io.write(css) }
46
+
47
+ compress(destination(file))
48
+ end
49
+
50
+ def build_sass(file)
51
+ style = SparkEngine.production? ? "compressed" : 'nested'
52
+ dest = destination(file)
53
+
54
+ Sass.logger.log_level = :error if SparkEngine.production?
55
+
56
+ css = Sass.compile_file(file, style: style)
57
+ css = AutoprefixerRails.process(css).css
58
+
59
+ File.open(dest, 'w') { |io| io.write(css) }
60
+
61
+ compress(dest)
62
+ end
63
+
64
+ def data
65
+ if @data
66
+ @data
67
+ else
68
+ data = {}
69
+
70
+ Dir[File.join(base, "**/*.yml")].each do |file|
71
+ key = file.sub(base+"/", '').sub(/^_/,'').sub('.yml','')
72
+
73
+ data[key] = SassParser.parse(file)
74
+ end
75
+
76
+ @data = data if SparkEngine.production?
77
+ data
78
+ end
79
+ end
80
+
81
+ # Convert extension
82
+ def versioned(file)
83
+ super(file.sub(/(\.css)?\.s[ca]ss$/i,'.css'))
84
+ end
85
+ end
86
+ end
87
+ end
88
+
@@ -0,0 +1,79 @@
1
+ module SparkEngine
2
+ module Assets
3
+ class Svgs < AssetType
4
+
5
+ def initialize(plugin, path)
6
+
7
+ require 'esvg'
8
+
9
+ @plugin = plugin
10
+ @base = path
11
+ @svg = esvg
12
+ end
13
+
14
+ def esvg
15
+ @svg || Esvg.new({
16
+ config_file: File.join(plugin.root, 'config', 'esvg.yml'),
17
+ source: @base,
18
+ assets: plugin.paths[:javascripts],
19
+ version: plugin.version,
20
+ build: plugin.destination,
21
+ temp: SparkEngine.rails_path('tmp/cache/assets'),
22
+ filename: '_icons.js',
23
+ compress: SparkEngine.production?,
24
+ optimize: true,
25
+ print: false
26
+ })
27
+ end
28
+
29
+ def ext
30
+ "svg"
31
+ end
32
+
33
+ def local_path(path)
34
+ path = File.expand_path(path)
35
+
36
+ # Strip all irrelevant sections of the path
37
+ path.sub(plugin.paths[:javascripts]+'/', '') # written to assets dir
38
+ .sub(plugin.root+'/','') # writtent to public dir
39
+ end
40
+
41
+ def use(*args)
42
+ esvg.use(*args)
43
+ end
44
+
45
+ def build_paths
46
+ esvg.build_paths.map { |file| file.sub("-#{plugin.version}",'') }
47
+ end
48
+
49
+ def build
50
+ begin
51
+ esvg.load_files
52
+
53
+ return if esvg.symbols.empty?
54
+
55
+ if files = esvg.build
56
+ files.each do |file|
57
+ puts build_success(file)
58
+ end
59
+ else
60
+ log_error "FAILED TO BUILD SVGs"
61
+ end
62
+ rescue Exception => e
63
+ log_error "\nFAILED TO BUILD SVGs"
64
+
65
+ if e.backtrace && e.backtrace.is_a?(Array)
66
+ log_error "Error in file: #{local_path(e.backtrace.shift)}"
67
+
68
+ e.backtrace.each do |line|
69
+ log_error local_path(line)
70
+ end
71
+ end
72
+
73
+ log_error(" #{e.message}\n") if e.message
74
+
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,191 @@
1
+ module SparkEngine
2
+ class Plugin
3
+ attr_reader :name, :gem, :engine,
4
+ :stylesheets, :javascripts, :svgs, :destination
5
+
6
+ def initialize(options)
7
+ @name = options.delete(:engine).downcase
8
+ @gem = Gem.loaded_specs[options.delete(:gem)]
9
+ config(options)
10
+ expand_asset_paths
11
+
12
+ # Store the gem path for access later when overriding root
13
+ parent_module.instance_variable_set(:@gem_path, root)
14
+ parent_module.instance_variable_set(:@spark_plugin_name, name)
15
+ add_assets
16
+ end
17
+
18
+ def engine_name
19
+ @engine.name.sub(/::Engine/,'')
20
+ end
21
+
22
+ def create_engine(&block)
23
+ # Create a new Rails::Engine
24
+ @engine = parent_module.const_set('Engine', Class.new(Rails::Engine) do
25
+
26
+ def spark_plugin_path
27
+ parent = Object.const_get(self.class.name.sub(/::Engine/,''))
28
+ Pathname.new parent.instance_variable_get("@gem_path")
29
+ end
30
+
31
+ def config
32
+ @config ||= Rails::Engine::Configuration.new(spark_plugin_path)
33
+ end
34
+
35
+ engine_name SparkEngine.plugin.name
36
+
37
+ require 'spark_engine/middleware'
38
+
39
+ initializer "#{name}.static_assets" do |app|
40
+ if !SparkEngine.rails5? || app.config.public_file_server.enabled
41
+ app.middleware.insert_after ::ActionDispatch::Static, SparkEngine::StaticAssets, "#{root}/public", engine_name: SparkEngine.plugin.name
42
+ app.middleware.insert_before ::ActionDispatch::Static, Rack::Deflater
43
+ end
44
+ end
45
+
46
+ end)
47
+
48
+ @engine.instance_eval(&block) if block_given?
49
+ end
50
+
51
+ def parent_module
52
+ mods = self.class.to_s.split('::')
53
+ mods.pop
54
+ Object.const_get(mods.join('::'))
55
+ end
56
+
57
+ def add_assets
58
+ @javascripts = Assets::Javascripts.new(self, paths[:javascripts])
59
+ @stylesheets = Assets::Stylesheets.new(self, paths[:stylesheets])
60
+ @svgs = Assets::Svgs.new(self, paths[:svgs])
61
+ end
62
+
63
+ def assets(options={})
64
+ assets = []
65
+ if options[:select_assets]
66
+ assets.push @svgs if options[:svg]
67
+ assets.push @stylesheets if options[:css]
68
+ assets.push @javascripts if options[:js]
69
+ else
70
+ assets = [@svgs, @stylesheets, @javascripts]
71
+ end
72
+
73
+ assets
74
+ end
75
+
76
+ def svgs?
77
+ @svgs.icons.nil?
78
+ end
79
+
80
+ def build(options={})
81
+ FileUtils.mkdir_p(asset_path)
82
+ assets(options).each do |asset|
83
+ asset.build
84
+ end
85
+
86
+ end
87
+
88
+ def watch(options)
89
+ assets(options).map(&:watch)
90
+ end
91
+
92
+ def asset_root
93
+ asset_prefix = Rails.application.config.assets.prefix || '/assets'
94
+ File.join asset_prefix, name
95
+ end
96
+
97
+ def production_root
98
+ @production_asset_root ||= asset_root
99
+ end
100
+
101
+ def config(options)
102
+
103
+ options = {
104
+ production_asset_root: nil,
105
+ destination: "public/",
106
+ root: @gem.full_gem_path,
107
+ version: @gem.version.to_s,
108
+ gem_name: @gem.name,
109
+ paths: {
110
+ stylesheets: "app/assets/stylesheets/#{name}",
111
+ javascripts: "app/assets/javascripts/#{name}",
112
+ images: "app/assets/images/#{name}",
113
+ svgs: "app/assets/svgs/#{name}",
114
+ }
115
+ }.merge(options)
116
+
117
+ options.each do |k,v|
118
+ set_instance(k.to_s,v)
119
+ end
120
+ end
121
+
122
+ def expand_asset_paths
123
+ @paths.each do |type, path|
124
+ @paths[type] = File.join(root, path)
125
+ end
126
+ @destination = File.join(root, @destination)
127
+ end
128
+
129
+ def asset_path(file=nil)
130
+ dest = destination
131
+ dest = File.join(dest, file) if file
132
+ dest
133
+ end
134
+
135
+ def asset_url(file=nil)
136
+
137
+ path = if SparkEngine.production? && !ENV[name.upcase + '_FORCE_LOCAL_ASSETS']
138
+ production_root
139
+ else
140
+ asset_root
141
+ end
142
+
143
+ path = File.join(path, file) if file
144
+ path
145
+ end
146
+
147
+ private
148
+
149
+ def asset_ext(klass)
150
+ klass.name.split('::').last.downcase
151
+ end
152
+
153
+ # Find files based on class type and
154
+ # return an array of Classes for each file
155
+ def add_files(klass)
156
+ ext = asset_ext klass
157
+ find_files(ext).map do |path|
158
+ klass.new(self, path)
159
+ end
160
+ end
161
+
162
+ # Find files by class type and extension
163
+ def find_files(ext)
164
+ files = Dir[File.join(paths[ext.to_sym], asset_glob(ext))]
165
+
166
+ # Filter out partials
167
+ files.reject { |f| File.basename(f).start_with?('_') }
168
+ end
169
+
170
+ def asset_glob(type)
171
+ case type
172
+ when "sass"
173
+ "*.s[ca]ss"
174
+ else
175
+ "*.#{type}"
176
+ end
177
+ end
178
+
179
+ # Convert configuration into instance variables
180
+ def set_instance(name, value)
181
+ instance_variable_set("@#{name}", value)
182
+
183
+ instance_eval(<<-EOS, __FILE__, __LINE__ + 1)
184
+ def #{name}
185
+ @#{name}
186
+ end
187
+ EOS
188
+ end
189
+
190
+ end
191
+ end
@@ -0,0 +1,21 @@
1
+ require 'spark_engine/sass/importer'
2
+
3
+ # Taken from https://github.com/chriseppstein/sass-css-importer/blob/master/lib/sass/css_importer/monkey_patches.rb
4
+ # TODO: This feels wrong, surely there must be a better way to handle this
5
+
6
+ class Sass::Engine
7
+ alias initialize_without_yaml_importer initialize
8
+
9
+ def initialize(template, options={})
10
+ initialize_without_yaml_importer(template, options)
11
+
12
+ yaml_importer = self.options[:load_paths].find {|lp| lp.is_a?(SparkEngine::Importer) }
13
+
14
+ unless yaml_importer
15
+ root = File.dirname(options[:filename] || ".")
16
+ plugin_root = SparkEngine.plugin.stylesheets.base
17
+ self.options[:load_paths] << SparkEngine::Importer.new(root)
18
+ self.options[:load_paths] << SparkEngine::Importer.new(plugin_root)
19
+ end
20
+ end
21
+ end