distil 0.10.4 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/Rakefile +2 -1
  2. data/VERSION +1 -1
  3. data/assets/distil.js +359 -0
  4. data/bin/distil +33 -10
  5. data/distil.gemspec +35 -24
  6. data/lib/distil/configurable/file-set.rb +86 -0
  7. data/lib/distil/configurable/interpolated.rb +36 -0
  8. data/lib/distil/configurable/output-path.rb +25 -0
  9. data/lib/distil/configurable/project-path.rb +25 -0
  10. data/lib/distil/configurable.rb +164 -0
  11. data/lib/distil/error-reporter.rb +63 -0
  12. data/lib/distil/product/concatenated.rb +85 -0
  13. data/lib/distil/product/css-product.rb +37 -0
  14. data/lib/distil/product/debug.rb +34 -0
  15. data/lib/distil/product/javascript-base-product.rb +35 -0
  16. data/lib/distil/product/javascript-doc-product.rb +61 -0
  17. data/lib/distil/product/javascript-product.rb +131 -0
  18. data/lib/distil/product/minified.rb +32 -0
  19. data/lib/distil/product.rb +97 -0
  20. data/lib/distil/project/distil-project.rb +99 -0
  21. data/lib/distil/project/external-project.rb +53 -0
  22. data/lib/distil/project.rb +78 -0
  23. data/lib/distil/source-file/css-file.rb +14 -0
  24. data/lib/distil/source-file/html-file.rb +14 -0
  25. data/lib/distil/source-file/javascript-file.rb +17 -0
  26. data/lib/distil/source-file/json-file.rb +16 -0
  27. data/lib/distil/source-file.rb +172 -0
  28. data/lib/distil/target.rb +235 -0
  29. data/lib/distil/task/css-dependency-task.rb +64 -0
  30. data/lib/distil/task/jsl-dependency-task.rb +49 -0
  31. data/lib/distil/task/nib-task.rb +72 -0
  32. data/lib/distil/task/validate-js-task.rb +75 -0
  33. data/lib/distil/task.rb +50 -0
  34. data/lib/distil.rb +72 -0
  35. data/lib/jsl.conf +4 -0
  36. data/vendor/jsl-0.3.0/src/Makefile.ref +16 -6
  37. data/vendor/jsl-0.3.0/src/config.mk +32 -2
  38. data/vendor/jsl-0.3.0/src/fdlibm/Makefile.ref +1 -2
  39. data/vendor/jsl-0.3.0/src/jsl.c +124 -13
  40. data/vendor/jsl-0.3.0/src/rules.mk +2 -1
  41. metadata +49 -28
  42. data/lib/bootstrap-template.js +0 -58
  43. data/lib/configurable.rb +0 -161
  44. data/lib/file-set.rb +0 -49
  45. data/lib/file-types/css-file.rb +0 -12
  46. data/lib/file-types/html-file.rb +0 -11
  47. data/lib/file-types/javascript-file.rb +0 -24
  48. data/lib/file-types/json-file.rb +0 -17
  49. data/lib/filter.rb +0 -41
  50. data/lib/filters/css-filter.rb +0 -58
  51. data/lib/filters/file-reference-filter.rb +0 -30
  52. data/lib/filters/jsl-dependency-filter.rb +0 -44
  53. data/lib/project.rb +0 -174
  54. data/lib/source-file.rb +0 -197
  55. data/lib/target.rb +0 -102
  56. data/lib/task.rb +0 -212
  57. data/lib/tasks/copy-task.rb +0 -17
  58. data/lib/tasks/css-task.rb +0 -12
  59. data/lib/tasks/javascript-task.rb +0 -206
  60. data/lib/tasks/multiple-output-task.rb +0 -140
  61. data/lib/tasks/output-task.rb +0 -76
  62. data/lib/tasks/single-output-task.rb +0 -104
  63. data/lib/tasks/test-task.rb +0 -280
@@ -1,24 +0,0 @@
1
- $jsl_import_regex= /\/\*jsl:import\s+([^\*]*)\*\//
2
- $include_regex= /NIB\.asset\(['"]([^)]+)['"]\)/
3
-
4
- class JavascriptFile < SourceFile
5
-
6
- def self.extension
7
- ".js"
8
- end
9
-
10
- def can_embed_as_content(file)
11
- [".css", ".html", ".json"].include?(file.extension)
12
- end
13
-
14
- def escape_embeded_content(content)
15
- content.gsub("\\", "\\\\").gsub("\n", "\\n").gsub("\"", "\\\"").gsub("'", "\\\\'")
16
- end
17
-
18
- def debug_content(options)
19
- destination= File.expand_path(options.remove_prefix||"")
20
- path= @file_path ? @file_path : self.relative_to_folder(destination)
21
- "loadScript(\"#{path}\");\n"
22
- end
23
-
24
- end
@@ -1,17 +0,0 @@
1
- require "#{$script_dir}/file-types/javascript-file.rb"
2
-
3
- class JsonFile < JavascriptFile
4
-
5
- def self.extension
6
- ".json"
7
- end
8
-
9
- def content_type
10
- "js"
11
- end
12
-
13
- def minify_content(source)
14
- super("(#{source})")[1..-3]
15
- end
16
-
17
- end
data/lib/filter.rb DELETED
@@ -1,41 +0,0 @@
1
- # require "#{$script_dir}/configurable"
2
-
3
- class Filter
4
-
5
- @@filters= []
6
- def self.inherited(subclass)
7
- @@filters << subclass.new
8
- end
9
-
10
- def self.abstract
11
- false
12
- end
13
-
14
- def self.each
15
- @@filters.each { |f|
16
- yield f
17
- }
18
- end
19
-
20
- def self.defined
21
- @@filters
22
- end
23
-
24
- def handles_file(file)
25
- false
26
- end
27
-
28
- def preprocess_content(file, content)
29
- content
30
- end
31
-
32
- def filter_content(file, content, options={})
33
- content
34
- end
35
-
36
- end
37
-
38
- # load all the other file types
39
- Dir.glob("#{$script_dir}/filters/*-filter.rb") { |file|
40
- require file
41
- }
@@ -1,58 +0,0 @@
1
- require "#{$script_dir}/filters/file-reference-filter"
2
-
3
- $jsl_import_regex= /\/\*jsl:import\s+([^\*]*)\*\//
4
-
5
- class CssDependencyFilter < FileReferenceFilter
6
-
7
- def handles_file(file)
8
- return ["css"].include?(file.content_type)
9
- end
10
-
11
- def preprocess_content(file, content)
12
- # Replace all ' (single quotes) with " (double quotes) in
13
- # order to fix a problem with the background url regexp
14
- content.gsub!(/\'/,'"')
15
- # Force a newline after a rule terminating ; (semi-colon)
16
- # in order to fix a problem with the background url regexp
17
- content.gsub!(/;(\n|\r)*/, ";\n")
18
-
19
- # Rewrites the 'url("...")' rules to a relative path
20
- # based on the location of the new concatenated CSS file.
21
- line_num=0
22
-
23
- lines= content.split("\n")
24
-
25
- lines.each { |line|
26
-
27
- line_num+=1
28
-
29
- line.gsub!(/@import\s+url\("?(.*\.css)"?\)/) { |match|
30
- css_file= File.join(file.parent_folder, $1)
31
-
32
- if (!File.exists?(css_file))
33
- file.error "imported CSS file not found: #{$1}", line_num
34
- # leave the @import rule in place
35
- match
36
- else
37
- file.add_dependency(SourceFile.from_path(css_file))
38
- end
39
- }
40
-
41
- line.gsub!(/url\("?(.*\.(jpg|png|gif))"?\)/) { |match|
42
- image_file= File.join(file.parent_folder, $1)
43
-
44
- if (!File.exists?(image_file))
45
- file.warning "resource not found: #{$1} (#{image_file})", line_num
46
- "url(\"#{$1}\")"
47
- else
48
- asset= SourceFile.from_path(image_file)
49
- file.add_asset(asset)
50
- "url(\"#{file_reference(asset)}\")"
51
- end
52
- }
53
- }
54
-
55
- lines.join("\n")
56
- end
57
-
58
- end
@@ -1,30 +0,0 @@
1
- class FileReferenceFilter < Filter
2
-
3
- def file_reference(file)
4
- "{{FILEREF(#{file})}}"
5
- end
6
-
7
- def content_reference(file)
8
- "{{CONTENTREF(#{file})}}"
9
- end
10
-
11
- def filter_content(file, content, options)
12
- destination= File.expand_path(options.remove_prefix||"")
13
-
14
- content.gsub!(/\{\{FILEREF\(([^)]*)\)\}\}/) { |match|
15
- include_file= SourceFile.from_path($1)
16
- include_file.relative_to_folder(destination)
17
- }
18
-
19
- content.gsub!(/\{\{CONTENTREF\(([^)]*)\)\}\}/) { |match|
20
- include_file= SourceFile.from_path($1)
21
- included_content= include_file.filtered_content(options)
22
- included_content= include_file.minify_content(included_content)
23
- file.escape_embeded_content(included_content)
24
- }
25
-
26
- content
27
- end
28
-
29
-
30
- end
@@ -1,44 +0,0 @@
1
- $jsl_import_regex= /\/\*jsl:import\s+([^\*]*)\*\//
2
-
3
- class JslDependencyFilter < Filter
4
-
5
- def handles_file(file)
6
- return ["js"].include?(file.content_type)
7
- end
8
-
9
- def preprocess_content(file, content)
10
-
11
- content= content.split("\n")
12
-
13
- line_num=0
14
-
15
- content.each { |line|
16
-
17
- line_num+=1
18
-
19
- # handle dependencies
20
- line.gsub!($jsl_import_regex) { |match|
21
-
22
- import_file= File.expand_path(File.join(file.parent_folder, $1))
23
- if (File.exists?(import_file))
24
- file.add_dependency SourceFile.from_path(import_file)
25
- else
26
- dependency= Project.current.find_file($1)
27
- if (dependency)
28
- file.add_dependency dependency
29
- else
30
- file.error "Missing import file: #{$1}", line_num
31
- end
32
- end
33
-
34
- # replace jsl import with empty string
35
- ""
36
-
37
- }
38
-
39
- }
40
-
41
- content.join("\n")
42
- end
43
-
44
- end
data/lib/project.rb DELETED
@@ -1,174 +0,0 @@
1
- require "#{$script_dir}/target"
2
-
3
- require 'yaml'
4
-
5
- class Project < Configurable
6
- attr_reader :project_file
7
-
8
- option :tasks, Array
9
- option_alias :tasks, :task
10
-
11
- option :version, String
12
- option :project_name, String
13
- option_alias :project_name, :name
14
-
15
- option :targets, Array
16
- option_alias :targets, :target
17
-
18
- option :mode
19
- option :ignore_warnings, false
20
-
21
- option :external_projects
22
-
23
- option :distileries, Array
24
- option_alias :distileries, :distilleries
25
- option_alias :distileries, :distilery
26
- option_alias :distileries, :distillery
27
-
28
-
29
- def initialize(project_file, settings)
30
- @@current= self
31
- @project_file= File.expand_path(project_file)
32
- Dir.chdir(File.dirname(@project_file))
33
-
34
- project_info= YAML.load_file(@project_file)
35
- settings.merge!(project_info)
36
- super(settings)
37
- end
38
-
39
- @@current=nil
40
- def self.current
41
- @@current
42
- end
43
-
44
- def find_file(file)
45
- return nil if external_projects.nil?
46
-
47
- external_projects.each { |project|
48
- path= File.expand_path(File.join(project["include"], file))
49
- if (File.exists?(path))
50
- source_file= SourceFile.from_path(path)
51
- source_file.file_path= file
52
- return source_file
53
- end
54
- }
55
- nil
56
- end
57
-
58
- def build
59
- load_distileries
60
- build_external_projects
61
- build_targets
62
- end
63
-
64
- def load_distileries
65
- return if distileries.nil?
66
-
67
- distileries.each { |d|
68
- if (File.exists?(d))
69
- require d
70
- next
71
- end
72
- path= Gem.required_location(d, 'distilery.rb')
73
- if (path.nil?)
74
- puts "Missing distilery: #{d}"
75
- end
76
- next if path.nil?
77
- require path
78
- }
79
- end
80
-
81
- def build_external_projects
82
- projects= external_projects
83
- if (projects.nil?)
84
- @options.external_projects= []
85
- return
86
- end
87
-
88
- # Handle external projects
89
- if (projects.is_a?(String))
90
- projects= projects.split(/\s*,\s*/)
91
- end
92
-
93
- if (projects.is_a?(Array))
94
- projects= projects.map { |folder|
95
- {
96
- "folder"=>folder
97
- }
98
- }
99
- else
100
- projects= projects.map { |folder, project|
101
-
102
- if project.is_a?(String)
103
- project= {
104
- "url"=>project
105
- }
106
- end
107
-
108
- defaults= {
109
- "folder"=>folder,
110
- "build"=>"distil",
111
- "include"=>File.join(folder, "build")
112
- }
113
-
114
- defaults.merge(project)
115
- }
116
- end
117
-
118
- # build or get each project
119
- projects.each { |project|
120
-
121
- if (project.key?("folder") && !File.directory?(project["folder"]) && !File.symlink?(project["folder"]))
122
- if (project["url"])
123
- url= project["url"]
124
- system "svn co #{url} #{project["folder"]}"
125
- else
126
- puts "#{@project_file}: external project folder missing: #{project["folder"]}"
127
- exit
128
- end
129
- end
130
-
131
- if (!project.key?("include"))
132
- project["include"]= File.join(project["folder"], "build")
133
- end
134
-
135
- build= project["build"] || "distil"
136
- wd= Dir.pwd
137
- Dir.chdir(project["folder"]||project["include"])
138
- # pass along mode flag to sub-projects
139
- if (mode)
140
- build= "#{build} -mode=#{mode}"
141
- end
142
- system(build)
143
- Dir.chdir(wd)
144
- }
145
-
146
- @options.external_projects= projects
147
- end
148
-
149
- def build_targets
150
-
151
- @extras.each { |section, value|
152
-
153
- next if (options.targets && !options.targets.include?(section))
154
- next if ((!options.targets || !options.targets.include?(section)) &&
155
- value.is_a?(Hash) && value.has_key?("enabled") && !value["enabled"])
156
-
157
- puts
158
- puts "#{project_name}/#{section}:"
159
- puts
160
-
161
- task= Task.by_name(section) || Task.by_product_name(section)
162
- if (task)
163
- new_value= Hash.new
164
- new_value[section]= value
165
- value= new_value
166
- section= "all"
167
- end
168
-
169
- target= Target.new(section, value, self)
170
- target.process_files
171
- target.finish
172
- }
173
- end
174
- end
data/lib/source-file.rb DELETED
@@ -1,197 +0,0 @@
1
- require 'fileutils'
2
-
3
- $compressor = "#{$script_dir}/yuicompressor-2.4.2.jar"
4
-
5
- class SourceFile
6
- attr_accessor :parent_folder, :full_path
7
-
8
- def initialize(filepath)
9
- @full_path= File.expand_path(filepath)
10
-
11
- @parent_folder= File.dirname(@full_path)
12
- @dependencies= []
13
- @assets= []
14
-
15
- @@file_cache[@full_path]= self
16
- end
17
-
18
- def self.extension
19
- end
20
-
21
- def extension
22
- self.class.extension
23
- end
24
-
25
- def can_embed_as_content(file)
26
- false
27
- end
28
-
29
- def content_type
30
- ext= self.extension
31
- return if !ext
32
- ext[1..-1]
33
- end
34
-
35
- @@file_types= []
36
- def self.inherited(subclass)
37
- @@file_types << subclass
38
- end
39
-
40
- def self.file_types
41
- @@file_types
42
- end
43
-
44
- @@file_cache= Hash.new
45
- def self.from_path(filepath)
46
- full_path= File.expand_path(filepath)
47
- file= @@file_cache[full_path]
48
- return file if file
49
-
50
- extension= File.extname(filepath)
51
-
52
- @@file_types.each { |handler|
53
- next if (handler.extension != extension)
54
-
55
- return handler.new(filepath)
56
- }
57
-
58
- return SourceFile.new(filepath)
59
- end
60
-
61
- def to_s
62
- @full_path
63
- end
64
-
65
- def to_str
66
- @full_path
67
- end
68
-
69
- def error(message, line_number=0)
70
- Target.current.error(message, self, line_number)
71
- end
72
-
73
- def warning(message, line_number=0)
74
- Target.current.warning(message, self, line_number)
75
- end
76
-
77
- def basename(suffix="")
78
- File.basename(@full_path, suffix)
79
- end
80
-
81
- def file_path
82
- @file_path
83
- end
84
-
85
- def file_path=(path)
86
- @file_path=path
87
- end
88
-
89
- def load_content
90
- content= File.read(@full_path)
91
- Filter.each { |f|
92
- next if !f.handles_file(self)
93
- content= f.preprocess_content(self, content)
94
- }
95
- content
96
- end
97
-
98
- def escape_embeded_content(content)
99
- content
100
- end
101
-
102
- def content
103
- @content ||= load_content
104
- end
105
-
106
- def filtered_content(options)
107
- c= content || ""
108
- Filter.each { |f|
109
- next if !f.handles_file(self)
110
- c= f.filter_content(self, c, options)
111
- }
112
- c
113
- end
114
-
115
- def debug_content(options)
116
- self.filtered_content(options)
117
- end
118
-
119
- def minify_content(source)
120
- # Run the Y!UI Compressor
121
- return source if !content_type
122
- buffer= ""
123
-
124
- IO.popen("java -jar #{$compressor} --type #{content_type}", "r+") { |pipe|
125
- pipe.puts(source)
126
- pipe.close_write
127
- buffer= pipe.read
128
- }
129
-
130
- # buffer = `java -jar #{$compressor} --type #{type} #{working_file}`
131
- if ('css'==content_type)
132
- # puts each rule on its own line, and deletes @import statements
133
- return buffer.gsub(/\}/,"}\n").gsub(/.*@import url\(\".*\"\);/,'')
134
- else
135
- return buffer
136
- end
137
- end
138
-
139
- def self.path_relative_to_folder(path, folder)
140
- outputFolder= File.expand_path(folder).to_s
141
-
142
- # Remove leading slash and split into parts
143
- file_parts= path.slice(1..-1).split('/');
144
- output_parts= outputFolder.slice(1..-1).split('/');
145
-
146
- common_prefix_length= 0
147
-
148
- file_parts.each_index { |i|
149
- common_prefix_length= i
150
- break if file_parts[i]!=output_parts[i]
151
- }
152
-
153
- return '../'*(output_parts.length-common_prefix_length) + file_parts[common_prefix_length..-1].join('/')
154
- end
155
-
156
- def relative_to_folder(output_folder)
157
- self.class.path_relative_to_folder(@full_path, output_folder)
158
- end
159
-
160
- def relative_to_file(source_file)
161
- folder= File.dirname(File.expand_path(source_file))
162
- self.relative_to_folder(folder)
163
- end
164
-
165
- def dependencies
166
- content
167
- @dependencies
168
- end
169
-
170
- def add_dependency(file)
171
- return if @dependencies.include?(file)
172
- @dependencies << file
173
- end
174
-
175
- def assets
176
- content
177
- @assets
178
- end
179
-
180
- def add_asset(file)
181
- @assets << file
182
- end
183
-
184
- def copy_to(folder, prefix)
185
- file_path= self.file_path || relative_to_folder(prefix||"")
186
- final_target_folder= File.join(folder, File.dirname(file_path))
187
- FileUtils.mkdir_p final_target_folder
188
- FileUtils.cp self.full_path, final_target_folder
189
- File.join(final_target_folder, File.basename(file_path))
190
- end
191
-
192
- end
193
-
194
- # load all the other file types
195
- Dir.glob("#{$script_dir}/file-types/*-file.rb") { |file|
196
- require file
197
- }
data/lib/target.rb DELETED
@@ -1,102 +0,0 @@
1
- require "#{$script_dir}/task"
2
- require "set"
3
-
4
- class Target < Configurable
5
- attr_accessor :target_name, :warning_count, :error_count
6
-
7
- option :tasks, Array
8
-
9
- def initialize(name, settings, project)
10
- super(settings, project)
11
-
12
- @@current= self
13
- @project= project
14
- @target_name= name
15
-
16
- @warning_count=0
17
- @error_count=0
18
-
19
- @tasks= []
20
-
21
- @extras.each { |task_name, task_settings|
22
- next if (tasks && !tasks.include?(task_name))
23
-
24
- if (task_settings.is_a?(Array) || task_settings.is_a?(String))
25
- task_settings= { "include"=>task_settings }
26
- end
27
-
28
- t= Task.by_name(task_name)
29
- if (!t.nil?)
30
- @tasks << t.new(self, task_settings)
31
- next
32
- end
33
-
34
- t= Task.by_product_name(task_name)
35
- if (!t.nil?)
36
- task_settings["output_name"]= task_name[/(.*)\.#{t.output_type}$/,1]
37
- @tasks << t.new(self, task_settings)
38
- next
39
- end
40
-
41
- error("Unknown task: #{task_name}")
42
- }
43
- end
44
-
45
- @@current=nil
46
- def self.current
47
- @@current
48
- end
49
-
50
- def error(message, file="", line_number=0)
51
- @error_count+=1
52
- if (file && line_number)
53
- printf("%s:%d: error: %s\n", file, line_number, message)
54
- else
55
- printf("error: %s\n", message)
56
- end
57
- end
58
-
59
- def warning(message, file="", line_number=0)
60
- @warning_count+=1
61
- return if (ignore_warnings)
62
- if (file && line_number)
63
- printf("%s:%d: warning: %s\n", file, line_number, message)
64
- else
65
- printf("warning: %s\n", message)
66
- end
67
- end
68
-
69
- def products
70
- products= []
71
- @tasks.each { |task|
72
- products.concat(task.products)
73
- }
74
- products
75
- end
76
-
77
- def process_files
78
- @tasks.each { |t|
79
- t.find_files
80
-
81
- next if !t.need_to_build
82
-
83
- t.validate_files
84
- t.document_files
85
- t.process_files
86
- }
87
- end
88
-
89
- def finish
90
- @tasks.each { |t|
91
- t.finish if t.need_to_build
92
- t.build_assets
93
- }
94
-
95
- @tasks.each { |t|
96
- t.cleanup
97
- }
98
-
99
- puts "#{@error_count} error(s), #{@warning_count} warning(s)#{ignore_warnings ? " ignored" : ""}"
100
- end
101
-
102
- end