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
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