distil 0.13.6 → 0.14.0.b

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/Rakefile +1 -0
  2. data/VERSION +1 -1
  3. data/assets/distil.js +9 -7
  4. data/bin/distil +36 -60
  5. data/distil.gemspec +17 -32
  6. data/distil.tmproj +46 -15
  7. data/lib/distil/browser.rb +30 -26
  8. data/lib/distil/configurable.rb +64 -153
  9. data/lib/distil/error-reporter.rb +22 -20
  10. data/lib/distil/file-vendor.rb +29 -0
  11. data/lib/distil/hash-additions.rb +45 -0
  12. data/lib/distil/javascript-code.rb +12 -0
  13. data/lib/distil/{task/validate-js-task.rb → javascript-file-validator.rb} +19 -23
  14. data/lib/distil/library.rb +243 -0
  15. data/lib/distil/product/cache-manifest-product.rb +21 -0
  16. data/lib/distil/product/css-product.rb +41 -23
  17. data/lib/distil/product/html-product.rb +20 -0
  18. data/lib/distil/product/javascript-product.rb +122 -111
  19. data/lib/distil/product.rb +90 -76
  20. data/lib/distil/project.rb +370 -104
  21. data/lib/distil/recursive-http-fetcher.rb +72 -0
  22. data/lib/distil/server.rb +43 -0
  23. data/lib/distil/source-file/css-file.rb +56 -3
  24. data/lib/distil/source-file/html-file.rb +5 -6
  25. data/lib/distil/source-file/javascript-file.rb +96 -8
  26. data/lib/distil/source-file/json-file.rb +2 -4
  27. data/lib/distil/source-file/yui-minifiable-file.rb +19 -0
  28. data/lib/distil/source-file.rb +50 -92
  29. data/lib/distil/subclass-tracker.rb +13 -0
  30. data/lib/distil.rb +21 -37
  31. metadata +40 -39
  32. data/assets/mime.types +0 -1240
  33. data/lib/distil/configurable/file-set.rb +0 -85
  34. data/lib/distil/configurable/interpolated.rb +0 -36
  35. data/lib/distil/configurable/output-path.rb +0 -25
  36. data/lib/distil/configurable/project-path.rb +0 -25
  37. data/lib/distil/product/concatenated.rb +0 -83
  38. data/lib/distil/product/debug.rb +0 -32
  39. data/lib/distil/product/javascript-base-product.rb +0 -35
  40. data/lib/distil/product/javascript-doc-product.rb +0 -61
  41. data/lib/distil/product/minified.rb +0 -41
  42. data/lib/distil/product/page-product.rb +0 -27
  43. data/lib/distil/product/pdoc-product.rb +0 -42
  44. data/lib/distil/project/distil-project.rb +0 -157
  45. data/lib/distil/project/external-project.rb +0 -58
  46. data/lib/distil/project/remote-project.rb +0 -43
  47. data/lib/distil/target.rb +0 -251
  48. data/lib/distil/task/css-dependency-task.rb +0 -64
  49. data/lib/distil/task/jsl-dependency-task.rb +0 -50
  50. data/lib/distil/task/nib-task.rb +0 -72
  51. data/lib/distil/task.rb +0 -50
  52. data/lib/jsdoc.conf +0 -18
  53. data/lib/test/HtmlTestReporter.js +0 -127
  54. data/lib/test/Test.js +0 -248
  55. data/lib/test/TestReporter.js +0 -79
  56. data/lib/test/TestRunner.js +0 -132
  57. data/lib/test/browser.rb +0 -97
  58. data/lib/test/scriptwrapper.html +0 -10
  59. data/lib/test/unittest.html +0 -127
@@ -1,144 +1,410 @@
1
1
  module Distil
2
2
 
3
- class Project < Configurable
3
+ BUILD_FILE= 'Buildfile'
4
+ DEFAULT_OUTPUT_FOLDER= 'build'
5
+ DEFAULT_LANGUAGE= 'en'
4
6
 
7
+ APPLICATION_TYPE= 'application'
8
+ FRAMEWORK_TYPE= 'framework'
9
+
10
+ class Project < Configurable
5
11
  include ErrorReporter
12
+ include FileVendor
13
+ include JavascriptFileValidator
14
+
15
+ attr_reader :name, :path, :folder, :source_folder, :output_folder, :include_paths
16
+ attr_reader :assets, :asset_aliases
17
+ attr_reader :libraries_by_name, :libraries
18
+ attr_reader :languages, :project_type
19
+ attr_reader :source_files
20
+ attr_reader :global_export
21
+ attr_reader :additional_globals
22
+ attr_reader :subprojects
23
+ attr_reader :dependency_aliases
24
+
25
+ alias_config_key :project_type, :type
26
+
27
+ def self.find(dir=nil)
28
+ cwd= Dir.pwd
29
+ dir ||= Dir.pwd
30
+ while dir.length > 1
31
+ return from_file(File.join(dir, BUILD_FILE)) if File.exists?(File.join(dir, BUILD_FILE))
32
+
33
+ projects= Dir.glob(File.join(dir, "*.jsproj"))
34
+ return from_file(projects.first) if 1==projects.size
35
+
36
+ unless 0==projects.size
37
+ puts "More than one candidate for Project:"
38
+ projects.each { |e|
39
+ puts " #{path_relative_to_folder(e, cwd)}"
40
+ }
41
+ exit 1
42
+ end
43
+
44
+ dir= File.dirname(dir)
45
+ end
46
+
47
+ nil
48
+ end
49
+
50
+ def self.from_file(file)
51
+ yaml= YAML::load_file(file)
52
+ if File.exists?("#{file}.local")
53
+ local_yaml= YAML::load_file("#{file}.local")
54
+ yaml.deep_merge!(local_yaml)
55
+ end
56
+ new(file, yaml)
57
+ end
58
+
59
+ def initialize(path, config={}, parent=nil)
60
+ @path= path
61
+ @folder= File.dirname(@path)
62
+ @source_folder= @folder
63
+ @output_folder= DEFAULT_OUTPUT_FOLDER
64
+ @include_paths= [@folder]
65
+ @include_files= []
66
+ @asset_aliases= {}
67
+ @dependency_aliases= {}
68
+ @assets= Set.new
69
+ @source_files= Set.new
70
+ @subprojects= []
71
+ @libraries= parent ? parent.libraries : []
72
+ @libraries_by_name= parent ? parent.libraries_by_name : {}
73
+ @languages= []
74
+ @additional_globals= []
75
+ @name= File.basename(@folder, ".*")
76
+
77
+ ignore_warnings= false
78
+
79
+ child_config= config.dup
80
+ child_config.delete("targets")
81
+ child_config.delete("require")
82
+
83
+ Dir.chdir(@folder) do
84
+ configure_with config do |c|
85
+
86
+ c.with :name do |name|
87
+ @name= name
88
+ end
89
+
90
+ c.with :output_folder do |output_folder|
91
+ @output_folder= output_folder
92
+ end
93
+ FileUtils.mkdir_p output_folder
94
+
95
+ c.with :source_folder do |source_folder|
96
+ @source_folder= source_folder
97
+ end
98
+
99
+ c.with :export do |export|
100
+ export=@name.as_identifier if true==export
101
+ @global_export= export
102
+ end
103
+
104
+ c.with_each :globals do |global|
105
+ @additional_globals << global
106
+ end
107
+
108
+ c.with_each :languages do |language|
109
+ @languages << language
110
+ end
111
+
112
+ c.with_each :require do |asset|
113
+ asset= Library.new(asset, self)
114
+ @libraries << asset
115
+ @libraries_by_name[asset.name]= asset
116
+ end
117
+
118
+ c.with_each :source do |file|
119
+ include_file(file)
120
+ end
121
+
122
+ c.with_each :targets do |target|
123
+ target_config= child_config.dup
124
+ target_config.deep_merge!(target)
125
+ @subprojects << Project.new(path, target_config, self)
126
+ end
127
+
128
+ end # configure_with
129
+ end
130
+
131
+ end
132
+
133
+ def validate_files
134
+ validate_javascript_files
135
+ end
6
136
 
7
- option :output_folder, ProjectPath, "build/$(mode)", :aliases=>['output']
8
- option :source_folder, ProjectPath, ""
137
+ def compute_source_files
138
+ return if @source_files_computed
139
+ @source_files_computed= true
140
+
141
+ inspected= Set.new
142
+ ordered_files= []
9
143
 
10
- option :path, String
11
- option :mode, DEBUG_MODE, :valid_values=>[DEBUG_MODE, RELEASE_MODE]
12
- option :force
144
+ add_file= lambda { |f|
145
+ return unless include_files.include?(f)
146
+ return if inspected.include?(f)
147
+ inspected << f
148
+
149
+ if f.respond_to? :dependencies
150
+ f.dependencies.each { |d|
151
+ add_file.call d
152
+ }
153
+ end
154
+
155
+ ordered_files << f
156
+ }
157
+
158
+ include_files.each { |f| add_file.call(f) }
159
+ ordered_files.each { |f|
160
+ next if f.is_a?(SourceFile) && f.is_asset
161
+
162
+ used= false
163
+ products.each { |p|
164
+ used= true if p.include_file(f)
165
+ }
166
+
167
+ next if !used
168
+
169
+ if !f.is_a?(Library)
170
+ @source_files << f
171
+ @assets.merge(f.assets) if f.assets
172
+ end
173
+ }
174
+ end
13
175
 
14
- def up_to_date
15
- true
176
+ def up_to_date?
177
+ products.each { |product|
178
+ return false if !product.up_to_date?
179
+ }
180
+ return true
16
181
  end
17
182
 
18
183
  def build
19
- end
184
+ subprojects.each { |subproject|
185
+ subproject.build
186
+ }
20
187
 
188
+ compute_source_files
189
+ return if up_to_date?
190
+
191
+ validate_files
192
+ build_assets
193
+
194
+ products.each { |product|
195
+ product.build
196
+ }
197
+ end
198
+
21
199
  def clean
200
+ compute_source_files
201
+ products.each { |product|
202
+ product.clean
203
+ }
22
204
  end
23
205
 
24
- def self.fetch_project_using_git(options = {})
25
- uri= options["repository"]
26
- path= options["path"]
27
-
206
+ def inspect
207
+ "<#{self.class}:0x#{object_id.to_s(16)} name=#{name}>"
208
+ end
209
+
210
+ def output_path
211
+ @output_path ||= File.join(folder, output_folder)
212
+ end
213
+
214
+ def relative_path_for(thing)
215
+ Project.path_relative_to_folder(thing.is_a?(String) ? thing : thing.full_path, path)
216
+ end
217
+
218
+ def relative_output_path_for(thing)
219
+ return nil if !thing
220
+ # puts "relative_output_path_for: #{thing} #{output_path}"
221
+ Project.path_relative_to_folder(thing.is_a?(String) ? thing : thing.output_path, output_path)
222
+ end
223
+
224
+ def notice_text
28
225
  begin
29
- `git --version 2>/dev/null`
226
+ @notice_text ||= File.read(File.join(@folder, @notice)).strip
30
227
  rescue
31
- nil
32
- end
33
- if $?.nil? || !$?.success?
34
- raise ValidationError.new("The git version control tool is required to pull this repository: #{uri}")
228
+ @notice_text ||= ""
35
229
  end
230
+ end
231
+
232
+ def products
233
+ return @products unless @products.nil?
36
234
 
37
- FileUtils.mkdir_p(path)
38
- Dir.chdir path do
39
- clone_cmd = "git clone #{uri} ."
40
- clone_cmd += " -q"
41
- clone_cmd += " -b #{options["version"]}" if options["version"]
42
- if !system(clone_cmd)
43
- raise ValidationError.new("Failed to clone external project: #{uri}")
44
- end
45
- end
235
+ @products= []
236
+ langs= languages.empty? ? [nil] : languages
237
+
238
+ Product.subclasses.each { |klass|
239
+ langs.each { |lang|
240
+ klass.variants.each { |v|
241
+ @products << klass.new(self, lang, v)
242
+ }
243
+ }
244
+ }
245
+
246
+ @products
46
247
  end
47
248
 
48
- def self.from_config(config, parent=nil)
249
+ def symlink_assets
250
+ Dir.chdir(output_path) do
251
+ folders= []
49
252
 
50
- if config.is_a?(String)
51
- string= config
52
- uri= URI.parse(string)
53
-
54
- config= { "name" => File.basename(config, ".*") }
55
-
56
- case
57
- when ['.js', '.css'].include?(File.extname(uri.path))
58
- config["href"]= uri.to_s
59
- when uri.scheme
60
- config["repository"]= uri.to_s
61
- else
62
- config["path"]= uri.to_s
63
-
64
- full_path= File.expand_path(config["path"])
65
-
66
- if File.exist?(full_path) && File.file?(full_path)
67
- config["path"]= File.dirname(full_path)
68
- else
69
- config["path"]= full_path
253
+ files= assets+source_files
254
+ files.each { |a|
255
+ next if (a.full_path).starts_with?(output_path)
256
+
257
+ path= relative_output_path_for(a)
258
+
259
+ parts= File.dirname(path).split(File::SEPARATOR)
260
+ if ('.'==parts[0])
261
+ product_path= File.join(output_folder, path)
262
+ FileUtils.rm product_path if File.exists? product_path
263
+ File.symlink path, product_path
264
+ next
70
265
  end
71
- end
72
- end
73
266
 
74
- if !config["name"]
75
- case when config["repository"]
76
- uri= URI.parse(config["repository"])
77
- config["name"]= File.basename(uri.path, ".*")
78
- when config["path"]
79
- config["name"]= File.basename(config["path"], ".*")
80
- else
81
- raise ValidationError.new("External project has neither name, path nor repository")
82
- end
83
- end
267
+ folders << parts[0] if !folders.include?(parts[0])
268
+ }
269
+
270
+ folders.each { |f|
271
+ target= f
272
+ source= relative_output_path_for(File.join(source_folder, f))
84
273
 
85
- if config["href"]
86
- return RemoteProject.new(config, parent)
274
+ FileUtils.rm target if File.symlink?(target)
275
+ next if File.directory?(target)
276
+ File.symlink source, target
277
+ }
87
278
  end
88
-
89
- config["path"]||= "ext/#{config["name"]}"
90
-
91
- if config["repository"] && !File.directory?(config["path"])
92
- fetch_project_using_git(config)
279
+ end
280
+
281
+ def copy_assets
282
+ assets.each { |a|
283
+ a.copy_to(output_folder, source_folder)
284
+ }
285
+ end
286
+
287
+ def build_assets
288
+ symlink_assets
289
+ # if (RELEASE_MODE==mode)
290
+ # copy_assets
291
+ # else
292
+ # symlink_assets
293
+ # end
294
+ end
295
+
296
+ def add_alias_for_asset(alias_name, asset)
297
+ if asset_aliases.include?(alias_name)
298
+ error "Attempt to register asset with the same alias as another asset: #{alias_name}"
299
+ return
93
300
  end
301
+ asset_aliases[asset]= alias_name
302
+ end
303
+
304
+ def include_files
305
+ @include_files
306
+ end
307
+
308
+ def include_file(file)
309
+ return if file.nil?
94
310
 
95
- config["mode"]||= parent.mode if parent
96
-
97
- path= config["path"]
98
- if !path
99
- ErrorReporter.error "No path for project: #{config["name"]}"
100
- return nil
311
+ asset= @libraries_by_name[file]
312
+ if (asset)
313
+ @include_files << asset unless @include_files.include?(asset)
314
+ return
101
315
  end
102
316
 
103
- if !File.directory?(path)
104
- ErrorReporter.error "Path is not valid for project: #{config["name"]}"
105
- return nil
317
+ matches= glob(file)
318
+ matches= glob(File.join(source_folder, file)) if matches.empty?
319
+
320
+ if (matches.empty?)
321
+ error("No matching files found for: #{file}")
322
+ return
106
323
  end
107
324
 
108
- basename= File.basename(path)
109
-
110
- case
111
- when exist?(path, "#{basename}.jsproj")
112
- project_file= File.join(path, "#{basename}.jsproj")
113
- project_info= YAML.load_file(project_file)
114
- project_info.merge!(config)
115
- project_info["path"]= path
116
- project= ExternalProject.new(project_info, parent)
117
- if parent
118
- project.build_command ||= "distil --mode=#{parent.mode} --force=#{parent.force}"
325
+ matches.each { |m|
326
+ if File.directory?(m)
327
+ include_file(File.join(m, "**/*"))
119
328
  else
120
- project.build_command ||= "distil"
329
+ f= file_from_path(m)
330
+ unless @include_files.include?(f)
331
+ @include_files << f
332
+ # determine language
333
+ f.language= languages.find { |l| File.fnmatch?("**/#{l}/**", f.full_path) }
334
+ end
121
335
  end
122
- when exist?(path, "Makefile") || exist?(path, "makefile")
123
- project= ExternalProject.new(config, parent)
124
- project.build_command ||= "make"
125
- when exist?(path, "Rakefile") || exist?(path, "rakefile")
126
- project= ExternalProject.new(config, parent)
127
- project.build_command ||= "rake"
128
- when exist?(path, "Jakefile") || exist?(path, "jakefile")
129
- project= ExternalProject.new(config, parent)
130
- project.build_command ||= "jake"
131
- else
132
- ErrorReporter.error "Could not determine type for project: #{config["name"]}"
336
+ }
337
+ end
338
+
339
+ def glob(path)
340
+ return path if File.exists?(path)
341
+
342
+ files= []
343
+
344
+ parts= path.split(File::SEPARATOR)
345
+ asset_name= parts[0]
346
+ file_path= File.join(parts.slice(1..-1))
347
+
348
+ if (@libraries_by_name.include?(asset_name))
349
+ asset= @libraries_by_name[asset_name]
350
+ return Dir.glob(File.join(asset.output_path, file_path))
133
351
  end
134
- return project
135
352
 
353
+ files.concat(Dir.glob(path));
354
+
355
+ include_paths.each { |i|
356
+ files.concat(Dir.glob(File.join(i, path)))
357
+ }
358
+ return files
359
+ end
360
+
361
+ def add_alias_for_file(alias_name, file)
362
+ @dependency_aliases[alias_name]= file
363
+ end
364
+
365
+ def find_file(path, content_type=nil, mode=nil)
366
+ return path if File.exists?(path)
367
+
368
+ include_paths.each { |i|
369
+ f= File.join(i, path)
370
+ return f if File.exists?(f)
371
+ }
372
+
373
+ # Check remote assets
374
+ parts= path.split(File::SEPARATOR)
375
+ asset_name= parts[0]
376
+ file_path= File.join(parts.slice(1..-1))
377
+
378
+ return nil unless @libraries_by_name.include?(asset_name)
379
+ asset= @libraries_by_name[asset_name]
380
+
381
+ return asset.file_for(content_type, nil, mode) if 1==parts.length
382
+
383
+ f= File.join(asset.output_path, file_path)
384
+ return f if File.exists?(f)
385
+
386
+ nil
387
+ end
388
+
389
+ def self.path_relative_to_folder(path, folder)
390
+ path= File.expand_path(path)
391
+ outputFolder= File.expand_path(folder).to_s
392
+
393
+ # Remove leading slash and split into parts
394
+ file_parts= path.slice(1..-1).split('/');
395
+ output_parts= outputFolder.slice(1..-1).split('/');
396
+
397
+ common_prefix_length= 0
398
+
399
+ file_parts.each_index { |i|
400
+ common_prefix_length= i
401
+ break if file_parts[i]!=output_parts[i]
402
+ }
403
+
404
+ return '../'*(output_parts.length-common_prefix_length) + file_parts[common_prefix_length..-1].join('/')
136
405
  end
137
406
 
138
407
  end
139
408
 
409
+
140
410
  end
141
-
142
- require 'distil/project/remote-project'
143
- require 'distil/project/external-project'
144
- require 'distil/project/distil-project'
@@ -0,0 +1,72 @@
1
+ module Distil
2
+
3
+ class RecursiveHTTPFetcher
4
+ attr_accessor :quiet
5
+
6
+ def initialize(urls_to_fetch, level = 1, cwd = ".")
7
+ @level = level
8
+ @cwd = cwd
9
+ @urls_to_fetch = RUBY_VERSION >= '1.9' ? urls_to_fetch.to_s.lines : urls_to_fetch.to_s.to_a
10
+ @quiet = true
11
+ end
12
+
13
+ def ls
14
+ @urls_to_fetch.collect do |url|
15
+ if url =~ /^svn(\+ssh)?:\/\/.*/ || url =~ /\/svn\//
16
+ `svn ls #{url}`.split("\n").map {|entry| "/#{entry}"} rescue nil
17
+ else
18
+ open(url) do |stream|
19
+ links("", stream.read)
20
+ end rescue nil
21
+ end
22
+ end.flatten
23
+ end
24
+
25
+ def push_d(dir)
26
+ @cwd = File.join(@cwd, dir)
27
+ FileUtils.mkdir_p(@cwd)
28
+ end
29
+
30
+ def pop_d
31
+ @cwd = File.dirname(@cwd)
32
+ end
33
+
34
+ def links(base_url, contents)
35
+ links = []
36
+ contents.scan(/href\s*=\s*\"*[^\">]*/i) do |link|
37
+ link = link.sub(/href="/i, "")
38
+ next if link =~ /svnindex.xsl$/
39
+ next if link =~ /^(\w*:|)\/\// || link =~ /^\./
40
+ links << File.join(base_url, link)
41
+ end
42
+ links
43
+ end
44
+
45
+ def download(link)
46
+ puts "+ #{File.join(@cwd, File.basename(link))}" unless @quiet
47
+ open(link) do |stream|
48
+ File.open(File.join(@cwd, File.basename(link)), "wb") do |file|
49
+ file.write(stream.read)
50
+ end
51
+ end
52
+ end
53
+
54
+ def fetch(links = @urls_to_fetch)
55
+ links.each do |l|
56
+ (l =~ /\/$/ || links == @urls_to_fetch) ? fetch_dir(l) : download(l)
57
+ end
58
+ end
59
+
60
+ def fetch_dir(url)
61
+ @level += 1
62
+ push_d(File.basename(url)) if @level > 0
63
+ open(url) do |stream|
64
+ contents = stream.read
65
+ fetch(links(url, contents))
66
+ end
67
+ pop_d if @level > 0
68
+ @level -= 1
69
+ end
70
+ end
71
+
72
+ end
@@ -0,0 +1,43 @@
1
+ module Distil
2
+
3
+ def self.start_server(project, options)
4
+ require 'webrick'
5
+ require 'directory_watcher'
6
+
7
+ port= options['server_port'] || 8888;
8
+ path= options['url']
9
+ config= {
10
+ :Port => port
11
+ }
12
+
13
+ server= WEBrick::HTTPServer.new(config)
14
+ server.mount(path || '/', WEBrick::HTTPServlet::FileHandler, project.output_folder)
15
+
16
+ ['INT', 'TERM'].each { |signal|
17
+ trap(signal){ server.shutdown }
18
+ }
19
+
20
+ puts "watching #{project.folder}"
21
+ dw = DirectoryWatcher.new(project.folder, {
22
+ :glob=>"**/*",
23
+ :pre_load => true,
24
+ :interval => 1
25
+ })
26
+ dw.add_observer { |*args|
27
+ args.each { |event|
28
+ puts event
29
+ if :modified==event.type
30
+ puts event.path
31
+ end
32
+ }
33
+ }
34
+
35
+ dw.start
36
+ gets
37
+ # b= Browser.new
38
+ # b.open("http://localhost:#{port}/#{path}")
39
+ # server.start
40
+ dw.stop
41
+ end
42
+
43
+ end
@@ -1,14 +1,67 @@
1
1
  module Distil
2
2
 
3
+ CSS_IMPORT_REGEX = /@import\s+url\("?(.*\.css)"?\)/
4
+ CSS_IMAGE_URL_REGEX= /url\("?(.*\.(jpg|png|gif))"?\)/
5
+
3
6
  class CssFile < SourceFile
4
-
7
+ include YuiMinifiableFile
8
+
5
9
  extension "css"
6
10
  content_type "css"
7
11
 
8
- def minified_content(source)
9
- super(source).gsub(/\}/,"}\n").gsub(/.*@import url\(\".*\"\);/,'')
12
+ def content
13
+ return @content unless @content.nil?
14
+ @content= File.read(full_path)
15
+ # Replace all ' (single quotes) with " (double quotes)
16
+ @content.gsub!(/\'/,'"')
17
+ # Force a newline after a rule terminating ; (semi-colon)
18
+ @content.gsub!(/;(\n|\r)*/, ";\n")
19
+ @content
10
20
  end
11
21
 
22
+ def rewrite_content_relative_to_path(path)
23
+ content.gsub(CSS_IMAGE_URL_REGEX) { |match|
24
+ image_file= File.join(dirname, $1)
25
+
26
+ if (!File.exists?(image_file))
27
+ match
28
+ else
29
+ asset= project.file_from_path(image_file)
30
+ "url(\"#{asset.relative_path}\")"
31
+ end
32
+ }
33
+ end
34
+
35
+ def dependencies
36
+ @dependencies unless @dependencies.nil?
37
+
38
+ line_num=0
39
+ content.each_line { |line|
40
+ line_num+=1
41
+
42
+ line.scan(CSS_IMPORT_REGEX) { |match|
43
+ css_file= File.join(dirname, $1)
44
+
45
+ if (!File.exists?(css_file))
46
+ error "Imported CSS file not found: #{$1}", line_num
47
+ else
48
+ add_dependency(project.file_from_path(css_file))
49
+ end
50
+ }
51
+
52
+ line.scan(CSS_IMAGE_URL_REGEX) { |match|
53
+ image_file= File.join(dirname, $1)
54
+
55
+ if (!File.exists?(image_file))
56
+ warning "Resource not found: #{$1}", line_num
57
+ else
58
+ asset= project.file_from_path(image_file)
59
+ add_asset(asset)
60
+ end
61
+ }
62
+ }
63
+ end
64
+
12
65
  end
13
66
 
14
67
  end