ktheory-juicer 1.0.0.ktheory1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +30 -0
- data/Manifest.txt +58 -0
- data/Rakefile +96 -0
- data/Readme.rdoc +312 -0
- data/VERSION +1 -0
- data/bin/juicer +8 -0
- data/lib/juicer.rb +70 -0
- data/lib/juicer/asset/path.rb +275 -0
- data/lib/juicer/asset/path_resolver.rb +79 -0
- data/lib/juicer/binary.rb +171 -0
- data/lib/juicer/cache_buster.rb +130 -0
- data/lib/juicer/chainable.rb +106 -0
- data/lib/juicer/cli.rb +56 -0
- data/lib/juicer/command/install.rb +61 -0
- data/lib/juicer/command/list.rb +57 -0
- data/lib/juicer/command/merge.rb +205 -0
- data/lib/juicer/command/util.rb +32 -0
- data/lib/juicer/command/verify.rb +60 -0
- data/lib/juicer/css_cache_buster.rb +80 -0
- data/lib/juicer/datafy/datafy.rb +20 -0
- data/lib/juicer/dependency_resolver/css_dependency_resolver.rb +29 -0
- data/lib/juicer/dependency_resolver/dependency_resolver.rb +101 -0
- data/lib/juicer/dependency_resolver/javascript_dependency_resolver.rb +23 -0
- data/lib/juicer/ext/logger.rb +5 -0
- data/lib/juicer/ext/string.rb +47 -0
- data/lib/juicer/ext/symbol.rb +15 -0
- data/lib/juicer/image_embed.rb +136 -0
- data/lib/juicer/install/base.rb +186 -0
- data/lib/juicer/install/closure_compiler_installer.rb +69 -0
- data/lib/juicer/install/jslint_installer.rb +51 -0
- data/lib/juicer/install/rhino_installer.rb +53 -0
- data/lib/juicer/install/yui_compressor_installer.rb +67 -0
- data/lib/juicer/jslint.rb +90 -0
- data/lib/juicer/merger/base.rb +74 -0
- data/lib/juicer/merger/javascript_merger.rb +29 -0
- data/lib/juicer/merger/stylesheet_merger.rb +110 -0
- data/lib/juicer/minifyer/closure_compiler.rb +90 -0
- data/lib/juicer/minifyer/java_base.rb +77 -0
- data/lib/juicer/minifyer/yui_compressor.rb +96 -0
- data/test/bin/jslint-1.0.js +523 -0
- data/test/bin/jslint.js +523 -0
- data/test/bin/rhino1_7R1.zip +0 -0
- data/test/bin/rhino1_7R2-RC1.jar +0 -0
- data/test/bin/rhino1_7R2-RC1.zip +0 -0
- data/test/bin/yuicompressor +0 -0
- data/test/bin/yuicompressor-2.3.5.zip +0 -0
- data/test/bin/yuicompressor-2.4.2.jar +0 -0
- data/test/bin/yuicompressor-2.4.2.zip +0 -0
- data/test/data/Changelog.txt +10 -0
- data/test/data/a.css +3 -0
- data/test/data/a.js +5 -0
- data/test/data/a1.css +5 -0
- data/test/data/b.css +1 -0
- data/test/data/b.js +5 -0
- data/test/data/b1.css +5 -0
- data/test/data/c1.css +3 -0
- data/test/data/css/2.gif +1 -0
- data/test/data/css/test.css +11 -0
- data/test/data/css/test2.css +1 -0
- data/test/data/d1.css +3 -0
- data/test/data/images/1.png +1 -0
- data/test/data/my_app.js +2 -0
- data/test/data/not-ok.js +2 -0
- data/test/data/ok.js +3 -0
- data/test/data/path_test.css +5 -0
- data/test/data/path_test2.css +14 -0
- data/test/data/pkg/module/moda.js +2 -0
- data/test/data/pkg/module/modb.js +3 -0
- data/test/data/pkg/pkg.js +1 -0
- data/test/test_helper.rb +169 -0
- data/test/unit/juicer/asset/path_resolver_test.rb +76 -0
- data/test/unit/juicer/asset/path_test.rb +370 -0
- data/test/unit/juicer/cache_buster_test.rb +104 -0
- data/test/unit/juicer/chainable_test.rb +94 -0
- data/test/unit/juicer/command/install_test.rb +58 -0
- data/test/unit/juicer/command/list_test.rb +81 -0
- data/test/unit/juicer/command/merge_test.rb +162 -0
- data/test/unit/juicer/command/util_test.rb +58 -0
- data/test/unit/juicer/command/verify_test.rb +48 -0
- data/test/unit/juicer/css_cache_buster_test.rb +71 -0
- data/test/unit/juicer/datafy_test.rb +37 -0
- data/test/unit/juicer/dependency_resolver/css_dependency_resolver_test.rb +36 -0
- data/test/unit/juicer/dependency_resolver/javascript_dependency_resolver_test.rb +50 -0
- data/test/unit/juicer/ext/string_test.rb +59 -0
- data/test/unit/juicer/ext/symbol_test.rb +27 -0
- data/test/unit/juicer/image_embed_test.rb +271 -0
- data/test/unit/juicer/install/installer_base_test.rb +214 -0
- data/test/unit/juicer/install/jslint_installer_test.rb +54 -0
- data/test/unit/juicer/install/rhino_installer_test.rb +57 -0
- data/test/unit/juicer/install/yui_compressor_test.rb +56 -0
- data/test/unit/juicer/jslint_test.rb +60 -0
- data/test/unit/juicer/merger/base_test.rb +122 -0
- data/test/unit/juicer/merger/javascript_merger_test.rb +74 -0
- data/test/unit/juicer/merger/stylesheet_merger_test.rb +180 -0
- data/test/unit/juicer/minifyer/closure_compressor_test.rb +107 -0
- data/test/unit/juicer/minifyer/yui_compressor_test.rb +116 -0
- data/test/unit/juicer_test.rb +1 -0
- metadata +265 -0
@@ -0,0 +1,74 @@
|
|
1
|
+
require "juicer/chainable"
|
2
|
+
|
3
|
+
# Merge several files into one single output file
|
4
|
+
module Juicer
|
5
|
+
module Merger
|
6
|
+
class Base
|
7
|
+
include Chainable
|
8
|
+
attr_accessor :dependency_resolver
|
9
|
+
attr_reader :files
|
10
|
+
|
11
|
+
def initialize(files = [], options = {})
|
12
|
+
@files = []
|
13
|
+
@root = nil
|
14
|
+
@options = options
|
15
|
+
@dependency_resolver ||= nil
|
16
|
+
self.append files
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Append contents to output. Resolves dependencies and adds
|
21
|
+
# required files recursively
|
22
|
+
# file = A file to add to merged content
|
23
|
+
#
|
24
|
+
def append(file)
|
25
|
+
return file.each { |f| self << f } if file.class == Array
|
26
|
+
return if @files.include?(file)
|
27
|
+
|
28
|
+
if !@dependency_resolver.nil?
|
29
|
+
path = File.expand_path(file)
|
30
|
+
resolve_dependencies(path)
|
31
|
+
elsif !@files.include?(file)
|
32
|
+
@files << file
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
alias_method :<<, :append
|
37
|
+
|
38
|
+
#
|
39
|
+
# Save the merged contents. If a filename is given the new file is
|
40
|
+
# written. If a stream is provided, contents are written to it.
|
41
|
+
#
|
42
|
+
def save(file_or_stream)
|
43
|
+
output = file_or_stream
|
44
|
+
|
45
|
+
if output.is_a? String
|
46
|
+
@root = Pathname.new(File.dirname(File.expand_path(output)))
|
47
|
+
output = File.open(output, 'w')
|
48
|
+
else
|
49
|
+
@root = Pathname.new(File.expand_path("."))
|
50
|
+
end
|
51
|
+
|
52
|
+
@files.each do |f|
|
53
|
+
output.puts(merge(f))
|
54
|
+
end
|
55
|
+
|
56
|
+
output.close if file_or_stream.is_a? String
|
57
|
+
end
|
58
|
+
|
59
|
+
chain_method :save
|
60
|
+
|
61
|
+
private
|
62
|
+
def resolve_dependencies(file)
|
63
|
+
@files.concat @dependency_resolver.resolve(file)
|
64
|
+
@files.uniq!
|
65
|
+
end
|
66
|
+
|
67
|
+
# Fetch contents of a single file. May be overridden in subclasses to provide
|
68
|
+
# custom content filtering
|
69
|
+
def merge(file)
|
70
|
+
IO.read(file) + "\n"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "juicer/merger/base"
|
3
|
+
require "juicer/dependency_resolver/javascript_dependency_resolver"
|
4
|
+
|
5
|
+
module Juicer
|
6
|
+
module Merger
|
7
|
+
# Merge several files into one single output file. Resolves and adds in files from @depend comments
|
8
|
+
class JavaScriptMerger < Base
|
9
|
+
|
10
|
+
# Constructor
|
11
|
+
def initialize(files = [], options = {})
|
12
|
+
@dependency_resolver = JavaScriptDependencyResolver.new
|
13
|
+
super(files, options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Run file from command line
|
20
|
+
# TODO: Refactor to testable Juicer::Merger::JavaScript::FileMerger.cli method
|
21
|
+
# or similar.
|
22
|
+
#
|
23
|
+
if $0 == __FILE__
|
24
|
+
puts("Usage: javascript_merger.rb file[...] output") and exit if $*.length < 2
|
25
|
+
|
26
|
+
fm = JavaScriptMerger.new()
|
27
|
+
fm << $*[0..-2]
|
28
|
+
fm.save($*[-1])
|
29
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "juicer/merger/base"
|
3
|
+
require "juicer/dependency_resolver/css_dependency_resolver"
|
4
|
+
require 'pathname'
|
5
|
+
|
6
|
+
module Juicer
|
7
|
+
module Merger
|
8
|
+
# Merge several files into one single output file. Resolves and adds in files
|
9
|
+
# from @import statements
|
10
|
+
#
|
11
|
+
class StylesheetMerger < Base
|
12
|
+
|
13
|
+
# Constructor
|
14
|
+
#
|
15
|
+
# Options:
|
16
|
+
# * <tt>:web_root</tt> - Path to web root if there is any @import statements
|
17
|
+
# using absolute URLs
|
18
|
+
#
|
19
|
+
def initialize(files = [], options = {})
|
20
|
+
@dependency_resolver = CssDependencyResolver.new(options)
|
21
|
+
super(files || [], options)
|
22
|
+
@hosts = options[:hosts] || []
|
23
|
+
@host_num = 0
|
24
|
+
@use_absolute = options.key?(:absolute_urls) ? options[:absolute_urls] : false
|
25
|
+
@use_relative = options.key?(:relative_urls) ? options[:relative_urls] : false
|
26
|
+
@web_root = options[:web_root]
|
27
|
+
@web_root = File.expand_path(@web_root).sub(/\/?$/, "") if @web_root # Make sure path doesn't end in a /
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
#
|
32
|
+
# Takes care of removing any import statements. This avoids importing the
|
33
|
+
# file that was just merged into the current file.
|
34
|
+
#
|
35
|
+
# +merge+ also recalculates any referenced URLs. Relative URLs are adjusted
|
36
|
+
# to be relative to the resulting merged file. Absolute URLs are left alone
|
37
|
+
# by default. If the :hosts option is set, the absolute URLs will cycle
|
38
|
+
# through these. This may help in concurrent downloads.
|
39
|
+
#
|
40
|
+
# The options hash decides how Juicer recalculates referenced URLs:
|
41
|
+
#
|
42
|
+
# options[:absolute_urls] When true, all paths are converted to absolute
|
43
|
+
# URLs. Requires options[:web_root] to define
|
44
|
+
# root directory to resolve absolute URLs from.
|
45
|
+
# options[:relative_urls] When true, all paths are converted to relative
|
46
|
+
# paths. Requires options[:web_root] to define
|
47
|
+
# root directory to resolve absolute URLs from.
|
48
|
+
#
|
49
|
+
# If none if these are set then relative URLs are recalculated to match
|
50
|
+
# location of merged target while absolute URLs are left absolute.
|
51
|
+
#
|
52
|
+
# If options[:hosts] is set to an array of hosts, then they will be cycled
|
53
|
+
# for all absolute URLs regardless of absolute/relative URL strategy.
|
54
|
+
#
|
55
|
+
def merge(file)
|
56
|
+
content = super.gsub(/^\s*\@import\s("|')(.*)("|')\;?/, '')
|
57
|
+
dir = File.expand_path(File.dirname(file))
|
58
|
+
|
59
|
+
content.scan(/url\([\s"']*([^\)"'\s]*)[\s"']*\)/m).uniq.collect do |url|
|
60
|
+
url = url.first
|
61
|
+
path = resolve_path(url, dir)
|
62
|
+
content.gsub!(/\(#{url}\)/m, "(#{path})") unless path == url
|
63
|
+
end
|
64
|
+
|
65
|
+
content
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# Resolves a path relative to a directory
|
70
|
+
#
|
71
|
+
def resolve_path(url, dir)
|
72
|
+
path = url
|
73
|
+
|
74
|
+
# Absolute URLs
|
75
|
+
if url =~ %r{^/} && @use_relative
|
76
|
+
raise ArgumentError.new("Unable to handle absolute URLs without :web_root option") if !@web_root
|
77
|
+
path = Pathname.new(File.join(@web_root, url)).relative_path_from(@root).to_s
|
78
|
+
end
|
79
|
+
|
80
|
+
# All URLs that don't start with a protocol
|
81
|
+
if url !~ %r{^/} && url !~ %r{^[a-z]+://}
|
82
|
+
if @use_absolute
|
83
|
+
raise ArgumentError.new("Unable to handle absolute URLs without :web_root option") if !@web_root
|
84
|
+
path = File.expand_path(File.join(dir, url)).sub(@web_root, "") # Make absolute
|
85
|
+
else
|
86
|
+
path = Pathname.new(File.join(dir, url)).relative_path_from(@root).to_s # ...or redefine relative ref
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Cycle hosts, if any
|
91
|
+
if url =~ %r{^/} && @hosts.length > 0
|
92
|
+
path = File.join(@hosts[@host_num % @hosts.length], url)
|
93
|
+
@host_num += 1
|
94
|
+
end
|
95
|
+
|
96
|
+
path
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Run file from command line
|
103
|
+
#
|
104
|
+
if $0 == __FILE__
|
105
|
+
puts("Usage: stylesheet_merger.rb file[...] output") and exit if $*.length < 2
|
106
|
+
|
107
|
+
fm = Juicer::Merger::StylesheetMerger.new()
|
108
|
+
fm << $*[0..-2]
|
109
|
+
fm.save($*[-1])
|
110
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'tempfile'
|
3
|
+
require 'juicer/minifyer/java_base'
|
4
|
+
require 'juicer/chainable'
|
5
|
+
|
6
|
+
module Juicer
|
7
|
+
module Minifyer
|
8
|
+
|
9
|
+
# Provides an interface to the Closure compiler library using
|
10
|
+
# Juicer::Shell::Binary. The Closure compiler library is implemented
|
11
|
+
# using Java, and as such Java is required when running this code. Also, the
|
12
|
+
# compiler jar file has to be provided.
|
13
|
+
#
|
14
|
+
# The Closure Compiler is invoked using the java binary and the compiler
|
15
|
+
# jar file.
|
16
|
+
#
|
17
|
+
# Providing the Jar file (usually compiler.jar) can be done in
|
18
|
+
# several ways. The following directories are searched (in preferred order)
|
19
|
+
#
|
20
|
+
# 1. The directory specified by the option :bin_path
|
21
|
+
# 2. The directory specified by the environment variable $CLOSUREC_HOME, if set
|
22
|
+
# 3. Current working directory
|
23
|
+
#
|
24
|
+
# For more information on how the Jar is located, see
|
25
|
+
# +Juicer::Minify::ClosureCompiler.locate_jar+
|
26
|
+
#
|
27
|
+
# Author:: Christian Johansen (christian@cjohansen.no), Pavel Valodzka (pavel@valodzka.name)
|
28
|
+
# Copyright:: Copyright (c) 2008-2009 Christian Johansen, (c) 2009 Pavel Valodzka
|
29
|
+
# License:: MIT
|
30
|
+
#
|
31
|
+
# = Usage example =
|
32
|
+
# closure = Juicer::Minifyer::ClosureCompiler.new
|
33
|
+
# closure.java = "/usr/local/bin/java" # If 'java' is not on path
|
34
|
+
# closure.path << "/home/user/java/yui_compressor/"
|
35
|
+
# closure.save("", "")
|
36
|
+
#
|
37
|
+
class ClosureCompiler
|
38
|
+
include Juicer::Minifyer::JavaBase
|
39
|
+
include Juicer::Chainable
|
40
|
+
|
41
|
+
# Compresses a file using the YUI Compressor. Note that the :bin_path
|
42
|
+
# option needs to be set in order for YuiCompressor to find and use the
|
43
|
+
# YUI jar file. Please refer to the class documentation for how to set
|
44
|
+
# this.
|
45
|
+
#
|
46
|
+
# file = The file to compress
|
47
|
+
# output = A file or stream to save the results to. If not provided the
|
48
|
+
# original file will be overwritten
|
49
|
+
# type = Either :js or :css. If this parameter is not provided, the type
|
50
|
+
# is guessed from the suffix on the input file name
|
51
|
+
def save(file, output = nil, type = nil)
|
52
|
+
type = type.nil? ? file.split('.')[-1].to_sym : type
|
53
|
+
|
54
|
+
use_tmp = unless output
|
55
|
+
output = file
|
56
|
+
file = File.join(Dir::tmpdir, File.basename(file) + '.min.tmp.' + type.to_s)
|
57
|
+
FileUtils.mkdir_p(File.dirname(file))
|
58
|
+
FileUtils.move(output, file)
|
59
|
+
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
out_dir = File.dirname(output)
|
64
|
+
FileUtils.mkdir_p(out_dir) unless File.exists?(out_dir)
|
65
|
+
result = execute(%Q{-jar "#{locate_jar}"#{jar_args} -js_output_file "#{output}" -js "#{file}"})
|
66
|
+
|
67
|
+
File.delete(file) if use_tmp
|
68
|
+
end
|
69
|
+
|
70
|
+
chain_method :save
|
71
|
+
|
72
|
+
def self.bin_base_name
|
73
|
+
"*compiler"
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.env_name
|
77
|
+
"CLOSUREC_HOME"
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
# Some class level options may be set:
|
83
|
+
# :bin_path (defaults to Dir.cwd)
|
84
|
+
# :java (Java command, defaults to 'java')
|
85
|
+
def default_options
|
86
|
+
{ }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'tempfile'
|
3
|
+
require 'juicer/binary'
|
4
|
+
|
5
|
+
module Juicer
|
6
|
+
module Minifyer
|
7
|
+
|
8
|
+
# Provides an interface to Java based compressor libraries using
|
9
|
+
# Juicer::Shell::Binary.
|
10
|
+
#
|
11
|
+
# The compressor is invoked using the java binary and the compressor jar
|
12
|
+
# file.
|
13
|
+
#
|
14
|
+
# Providing the Jar file can be done in several ways. The following
|
15
|
+
# directories are searched (in preferred order)
|
16
|
+
#
|
17
|
+
# 1. The directory specified by the option :bin_path
|
18
|
+
# 2. The directory specified by the environment variable, if set
|
19
|
+
# 3. Current working directory
|
20
|
+
#
|
21
|
+
# Name of environment variable is decided by including classes self.env_name
|
22
|
+
# constant.
|
23
|
+
#
|
24
|
+
# For more information on how the Jar is located, see
|
25
|
+
# +Juicer::Minify::JavaMinifyer.locate_jar+
|
26
|
+
#
|
27
|
+
# Author:: Christian Johansen (christian@cjohansen.no)
|
28
|
+
# Copyright:: Copyright (c) 2008-2009 Christian Johansen
|
29
|
+
# License:: MIT
|
30
|
+
#
|
31
|
+
module JavaBase
|
32
|
+
include Juicer::Binary
|
33
|
+
|
34
|
+
def initialize(options = {})
|
35
|
+
bin = options.delete(:java) || "java"
|
36
|
+
bin_path = options.delete(:bin_path) || nil
|
37
|
+
@jar = nil
|
38
|
+
@jar_args = nil
|
39
|
+
|
40
|
+
super(bin, options)
|
41
|
+
path << bin_path if bin_path
|
42
|
+
end
|
43
|
+
|
44
|
+
# Overrides set_opts called from binary class
|
45
|
+
# This avoids sending illegal options to the java binary
|
46
|
+
#
|
47
|
+
def set_opts(args)
|
48
|
+
@jar_args = " #{args}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def jar_args
|
52
|
+
@jar_args
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
# Locates the Jar file by searching directories.
|
58
|
+
# The following directories are searched (in preferred order)
|
59
|
+
#
|
60
|
+
# 1. The directory specified by the option :bin_path
|
61
|
+
# 2. The directory specified by the environment variable, if set
|
62
|
+
# 3. Current working directory
|
63
|
+
#
|
64
|
+
# If any of these folders contain one or more files named like
|
65
|
+
# [self.class.bin_base_name].jar or [self.class.bin_base_name]-x.y.z.jar
|
66
|
+
# the method willpick the last file in the list returned by
|
67
|
+
# +Dir.glob("#{dir}/[self.class.bin_base_name]*.jar").sort. This means that
|
68
|
+
# higher version numbers will be preferred with the default naming for the
|
69
|
+
# jars
|
70
|
+
#
|
71
|
+
def locate_jar
|
72
|
+
files = locate("#{self.class.bin_base_name}*.jar", self.class.env_name)
|
73
|
+
!files || files.empty? ? nil : files.sort.last
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'tempfile'
|
3
|
+
require 'juicer/minifyer/java_base'
|
4
|
+
require 'juicer/chainable'
|
5
|
+
|
6
|
+
module Juicer
|
7
|
+
module Minifyer
|
8
|
+
|
9
|
+
# Provides an interface to the YUI compressor library using
|
10
|
+
# Juicer::Shell::Binary. The YUI compressor library is implemented
|
11
|
+
# using Java, and as such Java is required when running this code. Also, the
|
12
|
+
# YUI jar file has to be provided.
|
13
|
+
#
|
14
|
+
# The YUI Compressor is invoked using the java binary and the YUI Compressor
|
15
|
+
# jar file.
|
16
|
+
#
|
17
|
+
# Providing the Jar file (usually yuicompressor-x.y.z.jar) can be done in
|
18
|
+
# several ways. The following directories are searched (in preferred order)
|
19
|
+
#
|
20
|
+
# 1. The directory specified by the option :bin_path
|
21
|
+
# 2. The directory specified by the environment variable $YUIC_HOME, if set
|
22
|
+
# 3. Current working directory
|
23
|
+
#
|
24
|
+
# For more information on how the Jar is located, see
|
25
|
+
# +Juicer::Minify::YuiCompressor.locate_jar+
|
26
|
+
#
|
27
|
+
# Author:: Christian Johansen (christian@cjohansen.no)
|
28
|
+
# Copyright:: Copyright (c) 2008-2009 Christian Johansen
|
29
|
+
# License:: MIT
|
30
|
+
#
|
31
|
+
# = Usage example =
|
32
|
+
# yuic = Juicer::Minifyer::YuiCompressor.new
|
33
|
+
# yuic.java = "/usr/local/bin/java" # If 'java' is not on path
|
34
|
+
# yuic.path << "/home/user/java/yui_compressor/"
|
35
|
+
# yuic.save("", "")
|
36
|
+
#
|
37
|
+
#
|
38
|
+
class YuiCompressor
|
39
|
+
include Juicer::Minifyer::JavaBase
|
40
|
+
include Juicer::Chainable
|
41
|
+
|
42
|
+
# Compresses a file using the YUI Compressor. Note that the :bin_path
|
43
|
+
# option needs to be set in order for YuiCompressor to find and use the
|
44
|
+
# YUI jar file. Please refer to the class documentation for how to set
|
45
|
+
# this.
|
46
|
+
#
|
47
|
+
# file = The file to compress
|
48
|
+
# output = A file or stream to save the results to. If not provided the
|
49
|
+
# original file will be overwritten
|
50
|
+
# type = Either :js or :css. If this parameter is not provided, the type
|
51
|
+
# is guessed from the suffix on the input file name
|
52
|
+
def save(file, output = nil, type = nil)
|
53
|
+
type = type.nil? ? file.split('.')[-1].to_sym : type
|
54
|
+
|
55
|
+
output ||= file
|
56
|
+
use_tmp = !output.is_a?(String)
|
57
|
+
output = File.join(Dir::tmpdir, File.basename(file) + '.min.tmp.' + type.to_s) if use_tmp
|
58
|
+
FileUtils.mkdir_p(File.dirname(output))
|
59
|
+
|
60
|
+
result = execute(%Q{-jar "#{locate_jar}"#{jar_args} -o "#{output}" "#{file}"})
|
61
|
+
|
62
|
+
if use_tmp # If no output file is provided, YUI compressor will
|
63
|
+
output.puts IO.read(output) # compress to a temp file. This file should be cleared
|
64
|
+
File.delete(output) # out after we fetch its contents.
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
chain_method :save
|
69
|
+
|
70
|
+
def self.bin_base_name
|
71
|
+
"yuicompressor"
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.env_name
|
75
|
+
"YUIC_HOME"
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
# Returns a map of options accepted by YUI Compressor, currently:
|
80
|
+
#
|
81
|
+
# :charset
|
82
|
+
# :line_break
|
83
|
+
# :no_munge (JavaScript only)
|
84
|
+
# :preserve_semi
|
85
|
+
# :disable_optimizations
|
86
|
+
#
|
87
|
+
# In addition, some class level options may be set:
|
88
|
+
# :bin_path (defaults to Dir.cwd)
|
89
|
+
# :java (Java command, defaults to 'java')
|
90
|
+
def default_options
|
91
|
+
{ :charset => nil, :line_break => nil, :nomunge => nil,
|
92
|
+
:preserve_semi => nil, :disable_optimizations => nil }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|