distil 0.10.4 → 0.11.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 (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
data/lib/task.rb DELETED
@@ -1,212 +0,0 @@
1
- require "#{$script_dir}/filter"
2
- require "#{$script_dir}/source-file"
3
- require "#{$script_dir}/file-set"
4
- require 'set'
5
- require "#{$script_dir}/configurable"
6
-
7
- class Task < Configurable
8
- attr_reader :included_files, :assets
9
-
10
- option :remove_prefix
11
- option_alias :remove_prefix, :source_folder
12
- option :validate, true
13
-
14
- def initialize(target, settings)
15
- super(settings, target)
16
-
17
- @target= target
18
- @included_files= []
19
-
20
- @files_to_include= []
21
- @files_to_exclude= []
22
- @assets= Set.new
23
- @probed= Set.new
24
- end
25
-
26
- @@tasks= []
27
- def self.inherited(subclass)
28
- @@tasks << subclass
29
- end
30
-
31
- def self.available_tasks
32
- @@tasks
33
- end
34
-
35
- @@task_aliases= Hash.new
36
- def self.task_name_alias(name)
37
- @@task_aliases[name]= self
38
- end
39
-
40
- @@task_index= nil
41
- def self.task_index
42
- return @@task_index if @@task_index
43
- @@task_index= Hash.new
44
- @@tasks.each { |t|
45
- next if !t.task_name
46
- @@task_index[t.task_name]= t
47
- }
48
- @@task_index
49
- end
50
-
51
- def self.by_name(taskname)
52
- self.task_index[taskname] || @@task_aliases[taskname]
53
- end
54
-
55
- def self.by_product_name(productname)
56
- @@tasks.select { |t|
57
- next if !t.respond_to?(:output_type)
58
- return t if productname[/\.#{t.output_type}$/]
59
- }
60
- nil
61
- end
62
-
63
- def self.task_name
64
- s= (self.to_s)[/(.*)Task/,1]
65
- s && !s.empty? ? s.downcase : nil
66
- end
67
-
68
- def task_name
69
- self.class.task_name
70
- end
71
-
72
- def handles_file?(file)
73
- false
74
- end
75
-
76
- # Do a simple token substitution. Tokens begin and end with @.
77
- def replace_tokens(string, params)
78
- return string.gsub(/(\n[\t ]*)?@([^@ \t\r\n]*)@/) { |m|
79
- key= $2
80
- ws= $1
81
- value= params[key]||m;
82
- if (ws && ws.length)
83
- ws + value.split("\n").join(ws);
84
- else
85
- value
86
- end
87
- }
88
- end
89
-
90
- def include_file(file)
91
- return if @probed.include?(file)
92
- return if @included_files.include?(file)
93
- return if !handles_file?(file)
94
- return if !@files_to_include.include?(file)
95
- return if @files_to_exclude.include?(file)
96
-
97
- @probed << file
98
-
99
- file.dependencies.each { |d| include_file(d) }
100
- @assets.merge(file.assets)
101
- @assets << file
102
- @included_files << file
103
- end
104
-
105
- def find_files
106
- @probed= Set.new
107
- @included_files= []
108
-
109
- @files_to_include.each { |i| include_file(i) }
110
-
111
- # files= @included_files.map { |f| f.to_s }
112
- end
113
-
114
- def products
115
- []
116
- end
117
-
118
- def need_to_build
119
- return @need_to_build if !@need_to_build.nil?
120
-
121
- product_modification_times= products.map { |p|
122
- p=File.expand_path(p)
123
- return (@need_to_build=true) if !File.exists?(p)
124
- File.stat(p).mtime
125
- }
126
- oldest_product_modification_time= product_modification_times.max
127
-
128
- stat= File.stat(Project.current.project_file)
129
- return (@need_to_build=true) if stat.mtime > oldest_product_modification_time
130
-
131
- @assets.each { |a|
132
- stat= File.stat(a)
133
- return (@need_to_build=true) if stat.mtime > oldest_product_modification_time
134
- }
135
-
136
- return (@need_to_build=false)
137
- end
138
-
139
- def validate_files
140
- end
141
-
142
- def document_files
143
- end
144
-
145
- def process_files
146
- end
147
-
148
- def finish
149
- end
150
-
151
- def symlink_assets
152
- full_root_path= File.expand_path(remove_prefix||"")
153
-
154
- folders= []
155
-
156
- assets.each { |a|
157
- path= a.file_path || a.relative_to_folder(full_root_path)
158
-
159
- parts= File.dirname(path).split(File::SEPARATOR)
160
- if ('.'==parts[0])
161
- target_path= File.join(output_folder, path)
162
- FileUtils.rm target_path if File.exists? target_path
163
- File.symlink a.relative_to_folder(output_folder), target_path
164
- next
165
- end
166
-
167
- for i in (0..parts.length-1)
168
- f= parts[0..i].join(File::SEPARATOR)
169
- if !folders.include?(f)
170
- folders << f
171
- end
172
- end
173
-
174
- }
175
-
176
- folders.sort!
177
- folders.each { |f|
178
- src_folder= remove_prefix ? File.join(remove_prefix, f) : f
179
- src_folder= SourceFile.path_relative_to_folder(File.expand_path(src_folder), output_folder)
180
-
181
- target_folder= File.expand_path(File.join(output_folder, f))
182
- next if File.exists?(target_folder)
183
- File.symlink src_folder, target_folder
184
- }
185
- end
186
-
187
- def copy_assets
188
- assets.each { |a|
189
- a.copy_to(output_folder, remove_prefix)
190
- }
191
- end
192
-
193
- def build_assets
194
- FileUtils.mkdir_p(output_folder)
195
-
196
- if ("release"==mode)
197
- copy_assets
198
- else
199
- symlink_assets
200
- end
201
- end
202
-
203
- def cleanup
204
- end
205
-
206
- end
207
-
208
-
209
- # load all the other task types
210
- Dir.glob("#{$script_dir}/tasks/*-task.rb") { |file|
211
- require file
212
- }
@@ -1,17 +0,0 @@
1
- class CopyTask < Task
2
-
3
- def initialize(target, options)
4
- super(target, options)
5
- @files_to_exclude= @options.exclude.to_a
6
- @files_to_include= @options.include.to_a
7
- end
8
-
9
- def need_to_build
10
- true
11
- end
12
-
13
- def handles_file?(file_name)
14
- true
15
- end
16
-
17
- end
@@ -1,12 +0,0 @@
1
- require "#{$script_dir}/tasks/single-output-task.rb"
2
-
3
- class CssTask < SingleOutputTask
4
-
5
- output_type "css"
6
-
7
- # CssTask handles files that end in .css
8
- def handles_file?(file_name)
9
- "#{file_name}"[/\.css$/]
10
- end
11
-
12
- end
@@ -1,206 +0,0 @@
1
- require "open3"
2
- require "tempfile.rb"
3
- require "#{$script_dir}/tasks/single-output-task.rb"
4
-
5
- $lint_command= "#{$vendor_dir}/jsl-0.3.0/bin/jsl"
6
- $jsdoc_command= "#{$vendor_dir}/jsdoc-toolkit/jsrun.sh"
7
-
8
- class JavascriptTask < SingleOutputTask
9
-
10
- option :bootstrap_file, "#{$script_dir}/bootstrap-template.js"
11
- option :jsl_conf, "#{$script_dir}/jsl.conf"
12
- option :jsdoc_conf, "#{$script_dir}/jsdoc.conf"
13
- option :jsdoc_template, "#{$vendor_dir}/jsdoc-extras/templates/coherent"
14
- option :jsdoc_plugins, "#{$vendor_dir}/jsdoc-extras/plugins"
15
- option :doc_folder, "doc"
16
- option :generate_docs, false
17
- option :class_list, ""
18
- option :class_list_template, "#{$vendor_dir}/jsdoc-extras/templates/classlist"
19
-
20
- output_type "js"
21
-
22
- task_name_alias "js"
23
-
24
- def initialize(target, options)
25
- super(target, options)
26
- @concatenation_join_string = "\n/*jsl:ignore*/;/*jsl:end*/\n"
27
-
28
- if (!class_list.empty?)
29
- @products << File.join(output_folder, class_list)
30
- end
31
-
32
- if (generate_docs)
33
- @products << File.join(doc_folder, "index.html")
34
- end
35
-
36
- type= output_extension
37
- return if (!type)
38
-
39
- if (!output_name.empty?)
40
- target_name= "#{output_name}"
41
- prefix= "#{output_folder}/"
42
- else
43
- target_name= "#{target.target_name}".downcase
44
- prefix= "#{output_folder}/#{project_name}"
45
- if ("all"==target_name)
46
- target_name= ""
47
- else
48
- prefix= "#{prefix}-"
49
- end
50
- end
51
-
52
- end
53
-
54
- # JsTask handles files that end in .js
55
- def handles_file?(file_name)
56
- "#{file_name}"[/\.js$/]
57
- end
58
-
59
- def validate_files
60
-
61
- return if (!validate || !File.exists?($lint_command))
62
-
63
- tmp= Tempfile.new("jsl.conf")
64
-
65
- conf_files= [ "jsl.conf",
66
- "#{ENV['HOME']}/.jsl.conf",
67
- @options.jsl_conf
68
- ]
69
-
70
- jsl_conf= conf_files.find { |f| File.exists?(f) }
71
-
72
- tmp << File.read(jsl_conf)
73
- tmp << "\n"
74
-
75
- external_projects.each { |project|
76
- tmp << "+include #{project["include"]}\n"
77
- }
78
-
79
- @included_files.each { |f|
80
- next if "js"!=f.content_type
81
- tmp << "+process #{f}\n"
82
- }
83
-
84
- tmp.close()
85
-
86
- command= "#{$lint_command} -nologo -nofilelisting -conf #{tmp.path}"
87
-
88
- stdin, stdout, stderr= Open3.popen3(command)
89
- stdin.close
90
- output= stdout.read
91
- errors= stderr.read
92
-
93
- tmp.delete
94
-
95
- output= output.split("\n")
96
- summary= output.pop
97
- match= summary.match(/(\d+)\s+error\(s\), (\d+)\s+warning\(s\)/)
98
- if (match)
99
- @target.error_count+= match[1].to_i
100
- @target.warning_count+= match[2].to_i
101
- end
102
-
103
- output= output.join("\n")
104
-
105
- if (!output.empty?)
106
- puts output
107
- puts
108
- end
109
-
110
- end
111
-
112
- def generate_class_list()
113
- tmp= Tempfile.new("jsdoc.conf")
114
-
115
- template= File.read(@options.jsdoc_conf)
116
- doc_files= @included_files.map { |f|
117
- p= f.file_path || f.relative_to_folder(options.remove_prefix||"")
118
- "\"#{p}\""
119
- }
120
-
121
- class_list_output= File.join(output_folder, class_list)
122
-
123
- conf= replace_tokens(template, {
124
- "DOC_FILES"=>doc_files.join(",\n"),
125
- "DOC_OUTPUT_DIR"=>output_folder,
126
- "DOC_TEMPLATE_DIR"=>class_list_template,
127
- "DOC_PLUGINS_DIR"=>jsdoc_plugins
128
- })
129
-
130
- tmp << conf
131
- tmp.close()
132
-
133
- command= "#{$jsdoc_command} -c=#{tmp.path}"
134
-
135
- stdin, stdout, stderr= Open3.popen3(command)
136
- stdin.close
137
- output= stdout.read
138
- errors= stderr.read
139
-
140
- tmp.delete
141
-
142
- puts errors
143
- puts output
144
- end
145
-
146
- def document_files()
147
-
148
- generate_class_list() if (!class_list.empty?)
149
-
150
- return if (!generate_docs)
151
- return if (!File.exists?($jsdoc_command))
152
-
153
- tmp= Tempfile.new("jsdoc.conf")
154
-
155
- template= File.read(@options.jsdoc_conf)
156
- doc_files= @included_files.map { |f|
157
- p= f.file_path || f.relative_to_folder(options.remove_prefix||"")
158
- "\"#{p}\""
159
- }
160
-
161
- conf= replace_tokens(template, {
162
- "DOC_FILES"=>doc_files.join(",\n"),
163
- "DOC_OUTPUT_DIR"=>doc_folder,
164
- "DOC_TEMPLATE_DIR"=>jsdoc_template,
165
- "DOC_PLUGINS_DIR"=>jsdoc_plugins
166
- })
167
-
168
- tmp << conf
169
- tmp.close()
170
-
171
- command= "#{$jsdoc_command} -c=#{tmp.path}"
172
-
173
- stdin, stdout, stderr= Open3.popen3(command)
174
- stdin.close
175
- output= stdout.read
176
- errors= stderr.read
177
-
178
- tmp.delete
179
-
180
- puts errors
181
- puts output
182
-
183
- end
184
-
185
- def process_files
186
- super
187
- template= File.read(@options.bootstrap_file)
188
- @debug= replace_tokens(template, {
189
- "LOAD_SCRIPTS" => @debug
190
- })
191
-
192
- destination=File.expand_path(remove_prefix||"")
193
- @included_files.each { |inc|
194
- @debug << "/*jsl:import #{inc.relative_to_folder(destination)}*/\n"
195
- }
196
- end
197
-
198
- def uncompressed_preamble
199
- "/**#nocode+*/\n\n"
200
- end
201
-
202
- def uncompressed_postscript
203
- "\n\n/**#nocode-*/"
204
- end
205
-
206
- end
@@ -1,140 +0,0 @@
1
- require "#{$script_dir}/tasks/output-task.rb"
2
-
3
- class MultipleOutputTask < OutputTask
4
-
5
- def initialize(target, options)
6
- super(target, options)
7
-
8
- type= output_extension
9
- return if (!type)
10
-
11
- target_name= "#{target.target_name}".downcase
12
- if ('all'!=target_name)
13
- @options.output_folder= File.join(output_folder, target_name)
14
- end
15
-
16
- prefix= "#{output_folder}/"
17
-
18
- # if ("all"!=target_name)
19
- # prefix= "#{prefix}#{target_name}/"
20
- # end
21
-
22
- # @options.output_folder= prefix
23
- FileUtils.mkdir_p(output_folder)
24
-
25
- @concatenation_join_string= ""
26
-
27
- @prefix= prefix
28
- @concat= Hash.new
29
- @debug= Hash.new
30
- end
31
-
32
- def products
33
- @products if @products
34
-
35
- @products= []
36
-
37
- type= output_extension
38
- @included_files.each { |file|
39
- basename= file.basename("#{type}")
40
- name_concat= "#{@prefix}#{basename}-uncompressed#{type}"
41
- name_min= "#{@prefix}#{basename}#{type}"
42
- name_gz= "#{@prefix}#{basename}#{type}.gz"
43
- name_debug= "#{@prefix}#{basename}-debug#{type}"
44
- @products.concat([name_concat, name_min, name_gz, name_debug])
45
- }
46
- @products
47
- end
48
-
49
- def process_file(file)
50
- concat= ""
51
- debug= ""
52
-
53
- file.dependencies.each { |depend|
54
- next if !@files_to_include.include?(depend)
55
- next if @files_to_exclude.include?(depend)
56
-
57
- concat << depend.filtered_content(options)
58
- if (!concat.empty?)
59
- concat << @concatenation_join_string||""
60
- end
61
- debug << depend.debug_content(options)
62
- }
63
-
64
- if (!concat.empty?)
65
- concat << @concatenation_join_string||""
66
- end
67
- concat << file.filtered_content(options)
68
- debug << file.debug_content(options)
69
-
70
- @concat[file]= concat
71
- @debug[file]= debug
72
- end
73
-
74
- def process_files
75
- @included_files.each { |f|
76
- process_file(f)
77
- }
78
- end
79
-
80
- def finish_file(file)
81
- type= output_extension
82
- return if (!type)
83
-
84
- basename= file.basename("#{type}")
85
- name_concat= "#{@prefix}#{basename}-uncompressed#{type}"
86
- name_min= "#{@prefix}#{basename}#{type}"
87
- name_gz= "#{@prefix}#{basename}#{type}.gz"
88
- name_debug= "#{@prefix}#{basename}-debug#{type}"
89
-
90
- # puts "Finish: #{file}"
91
- # puts " #{name_concat}"
92
- # puts " #{name_min}"
93
- # puts " #{name_gz}"
94
- # puts " #{name_debug}"
95
- #
96
- # Clear old files
97
- [name_concat, name_min, name_gz, name_debug].each { |f|
98
- next if (!File.exists?(f))
99
- File.delete(f)
100
- }
101
-
102
- params= {
103
- "VERSION"=>version
104
- }
105
-
106
- concat= replace_tokens(@concat[file], params)
107
- return if (""==concat)
108
-
109
- File.open(name_concat, "w") { |f|
110
- f.write(notice_text)
111
- f.write(concat)
112
- }
113
-
114
- minified= minify(concat)
115
-
116
- File.open(name_min, "w") { |f|
117
- f.write(notice_text)
118
- f.write(minified)
119
- }
120
-
121
- Zlib::GzipWriter.open(name_gz) { |f|
122
- f.write(notice_text)
123
- f.write(minified)
124
- }
125
-
126
- debug= replace_tokens(@debug[file], params)
127
- return if (""==debug)
128
-
129
- File.open(name_debug, "w") { |f|
130
- f.write(notice_text)
131
- f.write(debug)
132
- }
133
- end
134
-
135
- def finish
136
- @included_files.each { |f|
137
- finish_file(f)
138
- }
139
- end
140
- end
@@ -1,76 +0,0 @@
1
- require "#{$script_dir}/task.rb"
2
- require 'zlib'
3
-
4
- $compressor = "#{$vendor_dir}/yuicompressor-2.4.2.jar"
5
-
6
- class OutputTask < Task
7
- option :notice
8
- option :output_folder, "build"
9
- option :include, FileSet
10
- option :exclude, FileSet
11
-
12
- def initialize(target, options)
13
- super(target, options)
14
- @files_to_exclude= @options.exclude.to_a
15
- @files_to_include= @options.include.to_a
16
- FileUtils.mkdir_p(output_folder)
17
- end
18
-
19
- class_attr :output_type
20
- class_attr :content_type
21
-
22
- def self.content_type(*rest)
23
- if (rest.length>0)
24
- @content_type= rest[0]
25
- else
26
- @content_type || output_type
27
- end
28
- end
29
-
30
- def output_extension
31
- output_type && ".#{output_type}"
32
- end
33
-
34
- def products
35
- @products
36
- end
37
-
38
- def minify(source)
39
- # Run the Y!UI Compressor
40
- buffer= ""
41
-
42
- IO.popen("java -jar #{$compressor} --type #{content_type}", "r+") { |pipe|
43
- pipe.puts(source)
44
- pipe.close_write
45
- buffer= pipe.read
46
- }
47
-
48
- # buffer = `java -jar #{$compressor} --type #{type} #{working_file}`
49
- if ('css'==output_type)
50
- # puts each rule on its own line, and deletes @import statements
51
- return buffer.gsub(/\}/,"}\n").gsub(/.*@import url\(\".*\"\);/,'')
52
- else
53
- return buffer
54
- end
55
- end
56
-
57
- def notice_text
58
- if (!@options.notice)
59
- return ""
60
- end
61
-
62
- if (nil==@notice_text)
63
- notice_file= @options.notice;
64
- if (!File.exists?(notice_file))
65
- @notice_text= ""
66
- else
67
- text= File.read(notice_file).strip
68
- text= " #{text}".gsub(/\n/, "\n ")
69
- @notice_text= "/*!\n#{text}\n*/\n\n"
70
- end
71
- end
72
-
73
- return @notice_text
74
- end
75
-
76
- end