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,58 +0,0 @@
1
- module Distil
2
-
3
- class ExternalProject < Project
4
-
5
- option :name, String
6
- option :repository
7
- option :build_command, String, :aliases=>['build']
8
- option :linkage, WEAK_LINKAGE, :valid_values=> [WEAK_LINKAGE, STRONG_LINKAGE, LAZY_LINKAGE]
9
-
10
- option :import_name, OutputPath, "$(name)-debug.$(extension)", :aliases=>['import']
11
- option :concatenated_name, OutputPath, "$(name)-uncompressed.$(extension)", :aliases=>['concatenated']
12
- option :debug_name, OutputPath, "$(name)-debug.$(extension)", :aliases=>['debug']
13
- option :minified_name, OutputPath, "$(name).$(extension)", :aliases=>['minified']
14
- option :compressed_name, OutputPath, "$(name).$(extension).gz", :aliases=>['compressed']
15
-
16
- def initialize(config, parent=nil)
17
- if !config.has_key?("source_folder")
18
- config["source_folder"]= "build/$(mode)"
19
- end
20
- super(config, parent)
21
-
22
- self.output_folder= File.join(parent.output_folder, name)
23
- end
24
-
25
- def product_name(product_type, extension)
26
- info= Struct.new(:extension).new(extension)
27
- name= self.send("#{product_type.to_s}_name")
28
- Interpolated.value_of(name, info)
29
- end
30
-
31
- def up_to_date
32
- build
33
- true
34
- end
35
-
36
- def build
37
- wd= Dir.getwd
38
- Dir.chdir(path)
39
- system build_command
40
- Dir.chdir(wd)
41
-
42
- # external projects aren't included in the output when weak linked,
43
- # they are just expected to be there, somehow. Like magic.
44
- return if WEAK_LINKAGE==linkage
45
-
46
- FileUtils.rm_r(output_folder) if File.directory?(output_folder)
47
- FileUtils.rm(output_folder) if File.symlink?(output_folder)
48
-
49
- if DEBUG_MODE==mode
50
- FileUtils.symlink(SourceFile.path_relative_to_folder(File.expand_path(source_folder), File.dirname(output_folder)), output_folder)
51
- else
52
- FileUtils.cp_r(File.expand_path(source_folder), output_folder)
53
- end
54
- end
55
-
56
- end
57
-
58
- end
@@ -1,43 +0,0 @@
1
- module Distil
2
-
3
- class RemoteProject < Project
4
-
5
- option :name, String
6
- option :href, URI
7
- option :linkage, WEAK_LINKAGE, :valid_values=> [WEAK_LINKAGE, STRONG_LINKAGE, LAZY_LINKAGE]
8
-
9
- def initialize(config, parent=nil)
10
-
11
- super(config, parent)
12
-
13
- if !href.respond_to?(:read)
14
- raise ValidationError, "Cannot read from project source url: #{source}"
15
- end
16
-
17
- @source_path= File.join(parent.output_folder, href.host, href.path)
18
- self.source_folder= File.dirname(@source_path)
19
-
20
- if !File.exist?(@source_path)
21
- FileUtils.mkdir_p(source_folder)
22
- begin
23
- text= href.read
24
- rescue OpenURI::HTTPError => http_error
25
- raise ValidationError, "Unable to fetch remote project: status=#{http_error.io.status[0]} url=#{href}"
26
- end
27
- File.open(@source_path, "w") { |output|
28
- output.write text
29
- }
30
- end
31
-
32
- end
33
-
34
- def product_name(product_type, extension)
35
- File.join(File.dirname(@source_path), "#{File.basename(@source_path, ".*")}.#{extension}")
36
- end
37
-
38
- def build
39
- end
40
-
41
- end
42
-
43
- end
data/lib/distil/target.rb DELETED
@@ -1,251 +0,0 @@
1
- module Distil
2
-
3
- class Target < Configurable
4
- include ErrorReporter
5
-
6
- attr_accessor :project, :assets, :file_aliases
7
-
8
- option :version, String
9
- option :name, String
10
- option :notice_file, ProjectPath, "$(source_folder)/NOTICE", :aliases=>['notice']
11
- option :target_type, String, FRAMEWORK_TYPE, :aliases=>['type'], :valid_values=>[FRAMEWORK_TYPE, APP_TYPE]
12
-
13
- option :include_files, FileSet, :aliases=>['source']
14
- option :exclude_files, FileSet, :aliases=>['exclude']
15
-
16
- option :include_projects, [], :aliases=>['include']
17
-
18
- option :validate, true
19
- option :generate_docs, nil
20
-
21
- option :minify, true
22
- option :compress, true
23
-
24
- option :global_export, :aliases=>['export']
25
-
26
- def initialize(settings, project)
27
- @project=project
28
-
29
- super(settings, project)
30
-
31
- @assets= Set.new
32
- @probed= Set.new
33
- @contents= {}
34
- @asset_aliases= {}
35
- @file_aliases= {}
36
-
37
- if !include_files
38
- self.include_files= FileSet.new
39
- end
40
-
41
- if !exclude_files
42
- self.exclude_files= FileSet.new
43
- end
44
-
45
- @options.global_export=name.as_identifier if true==global_export
46
-
47
- projects= []
48
- include_projects.each { |name|
49
- ext= project.external_project_with_name(name)
50
- if (!ext)
51
- raise ValidationError, "External project not found: #{name}"
52
- end
53
-
54
- ext.linkage= STRONG_LINKAGE
55
- projects << ext
56
- }
57
- self.include_projects= projects
58
- end
59
-
60
- def source_folder
61
- project.source_folder
62
- end
63
-
64
- def tasks
65
- @tasks ||= Task.tasks.map { |task| task.new(@extras.clone, self) }
66
- end
67
-
68
- def products
69
- return @products if @products
70
-
71
- product_types= [CssProduct, CssDebugProduct, JavascriptProduct, JavascriptDebugProduct]
72
- if minify
73
- product_types << CssMinifiedProduct
74
- product_types << JavascriptMinifiedProduct
75
- end
76
-
77
- if generate_docs
78
- if ('pdoc'==generate_docs)
79
- product_types << PDocProduct
80
- else
81
- product_types << JavascriptDocProduct
82
- end
83
- end
84
-
85
- @products=[]
86
- product_types.each { |t|
87
- product= t.new(@extras.clone, self)
88
- product.files= files
89
- @products << product if !product.files.empty?
90
- }
91
-
92
- if APP_TYPE==target_type
93
- product= PageProduct.new(@extras.clone, self)
94
- product.files= files
95
- @products << product if !product.files.empty?
96
- end
97
-
98
- @products
99
- end
100
-
101
- def notice_text
102
- @notice_text if @notice_text
103
-
104
- if (nil==@notice_text)
105
- if (!File.exists?(notice_file))
106
- @notice_text= ""
107
- else
108
- text= File.read(notice_file).strip
109
- text= " #{text}".gsub(/\n/, "\n ")
110
- @notice_text= "/*!\n#{text}\n*/\n\n"
111
- end
112
- end
113
- end
114
-
115
- def include_file(file)
116
- return if @probed.include?(file)
117
- return if @files.include?(file)
118
- return if !include_files.include?(file)
119
- return if exclude_files.include?(file)
120
-
121
- @probed << file
122
-
123
- tasks.each { |t| t.include_file(file) }
124
- file.dependencies.each { |d| include_file(d) }
125
- @assets.merge(file.assets)
126
- @assets << file
127
- @files << file
128
- end
129
-
130
- def files
131
- return @files if @files
132
-
133
- @probed= Set.new
134
- @files= []
135
-
136
- tasks.each { |t|
137
- extra_files= t.find_files
138
- extra_files.each { |f| include_files.include_file(f) }
139
- }
140
-
141
- include_files.each { |i| include_file(i) }
142
-
143
- @files
144
- end
145
-
146
- def add_file_alias(original, full_path)
147
- @file_aliases[original]= full_path
148
- end
149
-
150
- def symlink_assets
151
- folders= []
152
-
153
- assets.each { |a|
154
-
155
- next if (a.full_path).starts_with?(project.output_folder)
156
-
157
- path= a.file_path || a.relative_to_folder(source_folder)
158
- parts= File.dirname(path).split(File::SEPARATOR)
159
- if ('.'==parts[0])
160
- product_path= File.join(project.output_folder, path)
161
- FileUtils.rm product_path if File.exists? product_path
162
- File.symlink a.relative_to_folder(project.output_folder), product_path
163
- next
164
- end
165
-
166
- folders << parts[0] if !folders.include?(parts[0])
167
- }
168
-
169
- folders.each { |f|
170
- src_folder= File.join(source_folder, f)
171
- product_folder= File.join(project.output_folder, f)
172
-
173
- relative_folder= SourceFile.path_relative_to_folder(src_folder, project.output_folder)
174
-
175
- FileUtils.rm product_folder if File.symlink?(product_folder)
176
- next if File.directory?(product_folder)
177
-
178
- File.symlink relative_folder, product_folder
179
- }
180
- end
181
-
182
- def copy_assets
183
- assets.each { |a|
184
- a.copy_to(project.output_folder, source_folder)
185
- }
186
- end
187
-
188
- def build_assets
189
- if (RELEASE_MODE==project.mode)
190
- copy_assets
191
- else
192
- symlink_assets
193
- end
194
- end
195
-
196
- def add_asset(asset)
197
- @assets << asset
198
- end
199
-
200
- def set_alias_for_asset(asset_alias, asset_file)
201
- @assets << asset_file
202
- @asset_aliases[asset_file.to_s]= asset_alias
203
- end
204
-
205
- def alias_for_asset(asset_file)
206
- full_path= asset_file.to_s
207
- @asset_aliases[full_path] || asset_file.relative_to_folder(source_folder)
208
- end
209
-
210
- def up_to_date
211
- products.all? { |p| p.up_to_date }
212
- end
213
-
214
- def clean
215
- puts "\n#{name}:\n\n"
216
- products.each { |p| p.clean }
217
- end
218
-
219
- def build
220
- puts "\n#{name}:\n\n"
221
-
222
- if !up_to_date
223
- tasks.each { |t| t.process_files(files) }
224
- products.each { |p| p.write_output }
225
- build_assets
226
- end
227
-
228
- report
229
- end
230
-
231
- def find_file(file, source_file=nil)
232
- project.find_file(file, source_file)
233
- end
234
-
235
- def get_content_for_file(file)
236
- file=SourceFile.from_path(file) if !file.is_a?(SourceFile)
237
- @contents[file.to_s] ||= file.content
238
- end
239
-
240
- def set_content_for_file(file, content)
241
- @contents[file.to_s] = content
242
- end
243
-
244
- end
245
-
246
- end
247
-
248
- # load all the other target types
249
- # Dir.glob("#{File.dirname(__FILE__)}/target/*-target.rb") { |file|
250
- # require file
251
- # }
@@ -1,64 +0,0 @@
1
- module Distil
2
-
3
- CSS_IMPORT_REGEX = /@import\s+url\("?(.*\.css)"?\)/
4
-
5
- class CssDependencyTask < Task
6
-
7
- def handles_file(file)
8
- return ["css"].include?(file.content_type)
9
- end
10
-
11
- def include_file(file)
12
- return if !handles_file(file)
13
-
14
- content= target.get_content_for_file(file)
15
-
16
- # Replace all ' (single quotes) with " (double quotes)
17
- content.gsub!(/\'/,'"')
18
- # Force a newline after a rule terminating ; (semi-colon)
19
- content.gsub!(/;(\n|\r)*/, ";\n")
20
-
21
- source_folder= get_option("source_folder")
22
-
23
- # Rewrites the 'url("...")' rules to a relative path
24
- # based on the location of the new concatenated CSS file.
25
- line_num=0
26
-
27
- lines= content.split("\n")
28
-
29
- lines.each { |line|
30
-
31
- line_num+=1
32
-
33
- line.gsub!(CSS_IMPORT_REGEX) { |match|
34
- css_file= File.join(file.parent_folder, $1)
35
-
36
- if (!File.exists?(css_file))
37
- file.error "Imported CSS file not found: #{$1}", line_num
38
- # leave the @import rule in place
39
- match
40
- else
41
- file.add_dependency(SourceFile.from_path(css_file))
42
- end
43
- }
44
-
45
- line.gsub!(/url\("?(.*\.(jpg|png|gif))"?\)/) { |match|
46
- image_file= File.join(file.parent_folder, $1)
47
-
48
- if (!File.exists?(image_file))
49
- file.warning "Resource not found: #{$1} (#{image_file})", line_num
50
- "url(\"#{$1}\")"
51
- else
52
- asset= SourceFile.from_path(image_file)
53
- file.add_asset(asset)
54
- "url(\"#{asset.relative_to_folder(source_folder)}\")"
55
- end
56
- }
57
- }
58
-
59
- target.set_content_for_file(file, lines.join("\n"))
60
- end
61
-
62
- end
63
-
64
- end
@@ -1,50 +0,0 @@
1
- module Distil
2
-
3
- JSL_IMPORT_REGEX= /\/\*jsl:import\s+([^\*]*)\*\//
4
-
5
- class JslDependencyTask < Task
6
-
7
- def handles_file(file)
8
- return ["js"].include?(file.content_type)
9
- end
10
-
11
- def include_file(file)
12
- return if !handles_file(file)
13
-
14
- content= target.get_content_for_file(file).split("\n")
15
-
16
- line_num=0
17
-
18
- content.each { |line|
19
-
20
- line_num+=1
21
-
22
- # handle dependencies
23
- line.gsub!(JSL_IMPORT_REGEX) { |match|
24
-
25
- import_file= File.expand_path(File.join(file.parent_folder, $1))
26
- if (File.exists?(import_file))
27
- file.add_dependency SourceFile.from_path(import_file)
28
- else
29
- dependency= target.find_file($1, file)
30
- if (dependency)
31
- target.add_file_alias($1, dependency.full_path)
32
- file.add_dependency dependency
33
- else
34
- file.error "Missing import file: #{$1}", line_num
35
- end
36
- end
37
-
38
- # replace jsl import with empty string
39
- ""
40
-
41
- }
42
-
43
- }
44
-
45
- target.set_content_for_file(file, content.join("\n"))
46
- end
47
-
48
- end
49
-
50
- end
@@ -1,72 +0,0 @@
1
- module Distil
2
-
3
- NIB_ASSET_REGEX= /(NIB\.asset(?:Url)?)\(['"]([^)]+)['"]\)/
4
-
5
- class NibTask < Task
6
- include ErrorReporter
7
-
8
- def handles_file(file)
9
- return ["js"].include?(file.content_type)
10
- end
11
-
12
- def preprocess_file(nib_name, nib_folder, file)
13
- return if !handles_file(file)
14
-
15
- content= target.get_content_for_file(file).split("\n")
16
-
17
- line_num=0
18
-
19
- content.each { |line|
20
-
21
- line_num+=1
22
-
23
- # handle dependencies
24
- line.gsub!(NIB_ASSET_REGEX) { |match|
25
- asset_file= File.expand_path(File.join(file.parent_folder, $2))
26
- asset_file= SourceFile.from_path(asset_file)
27
- if (!File.exists?(asset_file))
28
- file.warning "Asset not found: #{$2} (#{asset_file})", line_num
29
- "#{$0}"
30
- else
31
- "#{$1}(\"#{asset_file.relative_to_folder(target.source_folder)}\")"
32
- # "#{$1}(\"#{nib_name}##{asset_file.relative_to_folder(nib_folder)}\")"
33
- end
34
- }
35
-
36
- }
37
-
38
- target.set_content_for_file(file, content.join("\n"))
39
- end
40
-
41
- def include_file(file)
42
-
43
- return if !File.fnmatch("**/*.jsnib/*.js", file)
44
- # puts "Nib asset: #{file}"
45
- match= file.to_s.match(/([^\.\/]+).jsnib\/(.*)\.js/)
46
- return if match[1]!=match[2]
47
-
48
- nib_name= match[1]
49
- nib_folder= File.dirname(file)
50
-
51
- preprocess_file(nib_name, nib_folder, file)
52
-
53
-
54
- # Found main js file inside the JSNib add assets for all the other files
55
- target.set_alias_for_asset("#{match[1]}##{match[2]}", file)
56
- Dir.glob("#{File.dirname(file)}/**/*") { |asset|
57
- next if File.directory?(asset) || asset.to_s==file.to_s
58
-
59
- asset= SourceFile.from_path(asset)
60
- preprocess_file(nib_name, nib_folder, asset)
61
- file.add_asset(asset)
62
-
63
- if 'html'==asset.content_type
64
- target.set_alias_for_asset("#{nib_name}##{asset.relative_to_folder(nib_folder)}", asset)
65
- end
66
- }
67
-
68
- end
69
-
70
- end
71
-
72
- end
data/lib/distil/task.rb DELETED
@@ -1,50 +0,0 @@
1
- require 'set'
2
-
3
- module Distil
4
-
5
- class Task < Configurable
6
-
7
- def initialize(options, target)
8
- @target= target
9
- super(options, target)
10
- end
11
-
12
- def project
13
- target.project
14
- end
15
-
16
- def target
17
- @target
18
- end
19
-
20
- @@tasks= []
21
- def self.inherited(subclass)
22
- @@tasks << subclass
23
- end
24
-
25
- def self.tasks
26
- @@tasks
27
- end
28
-
29
- def handles_file?(file)
30
- false
31
- end
32
-
33
- def find_files
34
- []
35
- end
36
-
37
- def include_file(file)
38
- end
39
-
40
- def process_files(files)
41
- end
42
-
43
- end
44
-
45
- end
46
-
47
- # load all the other task types
48
- Dir.glob("#{Distil::LIB_DIR}/distil/task/*-task.rb") { |file|
49
- require file
50
- }
data/lib/jsdoc.conf DELETED
@@ -1,18 +0,0 @@
1
- {
2
- // source files to use
3
- _: [@DOC_FILES@],
4
-
5
- // document all functions, even uncommented ones
6
- a: true,
7
-
8
- // including those marked @private
9
- p: true,
10
-
11
- // use this directory as the output directory
12
- d: "@DOC_OUTPUT_DIR@",
13
-
14
- // use this template
15
- t: "@DOC_TEMPLATE_DIR@",
16
-
17
- plugins: "@DOC_PLUGINS_DIR@"
18
- }