psyho_juicer 1.0.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.
- data/History.txt +58 -0
 - data/Manifest.txt +58 -0
 - data/Rakefile +96 -0
 - data/Readme.rdoc +313 -0
 - data/VERSION +1 -0
 - data/bin/juicer +6 -0
 - data/lib/juicer.rb +69 -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 +131 -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 +90 -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 +129 -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/fixtures/yui-download.html +425 -0
 - data/test/test_helper.rb +175 -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 +278 -0
 
| 
         @@ -0,0 +1,186 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'nokogiri'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'open-uri'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "juicer"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module Juicer
         
     | 
| 
      
 7 
     | 
    
         
            +
              module Install
         
     | 
| 
      
 8 
     | 
    
         
            +
                #
         
     | 
| 
      
 9 
     | 
    
         
            +
                # Installer skeleton. Provides basic functionality like figuring out where
         
     | 
| 
      
 10 
     | 
    
         
            +
                # to install, create base directories, remove unneeded directories and more
         
     | 
| 
      
 11 
     | 
    
         
            +
                # housekeeping.
         
     | 
| 
      
 12 
     | 
    
         
            +
                #
         
     | 
| 
      
 13 
     | 
    
         
            +
                class Base
         
     | 
| 
      
 14 
     | 
    
         
            +
                  attr_reader :install_dir
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  #
         
     | 
| 
      
 17 
     | 
    
         
            +
                  # Create new installer
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #
         
     | 
| 
      
 19 
     | 
    
         
            +
                  def initialize(install_dir = Juicer.home)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    @install_dir = install_dir
         
     | 
| 
      
 21 
     | 
    
         
            +
                    @path = nil
         
     | 
| 
      
 22 
     | 
    
         
            +
                    @bin_path = nil
         
     | 
| 
      
 23 
     | 
    
         
            +
                    @name = nil
         
     | 
| 
      
 24 
     | 
    
         
            +
                    @dependencies = {}
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  #
         
     | 
| 
      
 28 
     | 
    
         
            +
                  # Returns the latest available version number. Must be implemented in
         
     | 
| 
      
 29 
     | 
    
         
            +
                  # subclasses. Raises an exception when called directly.
         
     | 
| 
      
 30 
     | 
    
         
            +
                  #
         
     | 
| 
      
 31 
     | 
    
         
            +
                  def latest
         
     | 
| 
      
 32 
     | 
    
         
            +
                    raise NotImplementedError.new("Implement in subclasses")
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  # Returns the path relative to installation path this installer will
         
     | 
| 
      
 36 
     | 
    
         
            +
                  # install to
         
     | 
| 
      
 37 
     | 
    
         
            +
                  def path
         
     | 
| 
      
 38 
     | 
    
         
            +
                    return @path if @path
         
     | 
| 
      
 39 
     | 
    
         
            +
                    @path = "lib/" + self.class.to_s.split("::").pop.sub(/Installer$/, "").underscore
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  # Returns the path to search for binaries from
         
     | 
| 
      
 43 
     | 
    
         
            +
                  #
         
     | 
| 
      
 44 
     | 
    
         
            +
                  def bin_path
         
     | 
| 
      
 45 
     | 
    
         
            +
                    return @bin_path if @bin_path
         
     | 
| 
      
 46 
     | 
    
         
            +
                    @bin_path = File.join(path, "bin")
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  #
         
     | 
| 
      
 50 
     | 
    
         
            +
                  # Returns name of component. Default implementation returns class name
         
     | 
| 
      
 51 
     | 
    
         
            +
                  # with "Installer" removed
         
     | 
| 
      
 52 
     | 
    
         
            +
                  #
         
     | 
| 
      
 53 
     | 
    
         
            +
                  def name
         
     | 
| 
      
 54 
     | 
    
         
            +
                    return @name if @name
         
     | 
| 
      
 55 
     | 
    
         
            +
                    @name = File.basename(path).split("_").inject("") { |str, word| (str + " #{word.capitalize}").strip }
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  #
         
     | 
| 
      
 59 
     | 
    
         
            +
                  # Checks if the component is currently installed.
         
     | 
| 
      
 60 
     | 
    
         
            +
                  #
         
     | 
| 
      
 61 
     | 
    
         
            +
                  # If no version is provided the most recent version is assumed.
         
     | 
| 
      
 62 
     | 
    
         
            +
                  #
         
     | 
| 
      
 63 
     | 
    
         
            +
                  def installed?(version = nil)
         
     | 
| 
      
 64 
     | 
    
         
            +
                    installed = File.exists?(File.join(@install_dir, path, "#{version || latest}"))
         
     | 
| 
      
 65 
     | 
    
         
            +
                    deps = @dependencies.length == 0 || dependencies.all? { |d, v| d.installed?(v) }
         
     | 
| 
      
 66 
     | 
    
         
            +
                    installed && deps
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                  #
         
     | 
| 
      
 70 
     | 
    
         
            +
                  # Install the component. Creates basic directory structure.
         
     | 
| 
      
 71 
     | 
    
         
            +
                  #
         
     | 
| 
      
 72 
     | 
    
         
            +
                  def install(version = nil)
         
     | 
| 
      
 73 
     | 
    
         
            +
                    raise "#{name} #{version} is already installed in #{File.join(@install_dir, path)}" if installed?(version)
         
     | 
| 
      
 74 
     | 
    
         
            +
                    version ||= latest
         
     | 
| 
      
 75 
     | 
    
         
            +
                    log "Installing #{name} #{version} in #{File.join(@install_dir, path)}"
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                    if @dependencies.length > 0
         
     | 
| 
      
 78 
     | 
    
         
            +
                      log "Installing dependencies"
         
     | 
| 
      
 79 
     | 
    
         
            +
                      dependencies { |dependency, ver| dependency.install(ver) unless dependency.installed?(ver) }
         
     | 
| 
      
 80 
     | 
    
         
            +
                    end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                    # Create directories
         
     | 
| 
      
 83 
     | 
    
         
            +
                    FileUtils.mkdir_p(File.join(@install_dir, path, "bin"))
         
     | 
| 
      
 84 
     | 
    
         
            +
                    FileUtils.mkdir_p(File.join(@install_dir, path, version))
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                    # Return resolved version for subclass to use
         
     | 
| 
      
 87 
     | 
    
         
            +
                    version
         
     | 
| 
      
 88 
     | 
    
         
            +
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                  #
         
     | 
| 
      
 91 
     | 
    
         
            +
                  # Uninstalls the given version of the component.
         
     | 
| 
      
 92 
     | 
    
         
            +
                  #
         
     | 
| 
      
 93 
     | 
    
         
            +
                  # If no version is provided the most recent version is assumed.
         
     | 
| 
      
 94 
     | 
    
         
            +
                  #
         
     | 
| 
      
 95 
     | 
    
         
            +
                  # If there are no more files left in INSTALLATION_PATH/<path>, the
         
     | 
| 
      
 96 
     | 
    
         
            +
                  # whole directory is removed.
         
     | 
| 
      
 97 
     | 
    
         
            +
                  #
         
     | 
| 
      
 98 
     | 
    
         
            +
                  # This method takes a block and can be used from subclasses like so:
         
     | 
| 
      
 99 
     | 
    
         
            +
                  #
         
     | 
| 
      
 100 
     | 
    
         
            +
                  #   def self.uninstall(install_dir = nil, version = nil)
         
     | 
| 
      
 101 
     | 
    
         
            +
                  #     super do |home_dir, version|
         
     | 
| 
      
 102 
     | 
    
         
            +
                  #       # Custom uninstall logic
         
     | 
| 
      
 103 
     | 
    
         
            +
                  #     end
         
     | 
| 
      
 104 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 105 
     | 
    
         
            +
                  #
         
     | 
| 
      
 106 
     | 
    
         
            +
                  #
         
     | 
| 
      
 107 
     | 
    
         
            +
                  def uninstall(version = nil)
         
     | 
| 
      
 108 
     | 
    
         
            +
                    version ||= self.latest
         
     | 
| 
      
 109 
     | 
    
         
            +
                    install_dir = File.join(@install_dir, path, version)
         
     | 
| 
      
 110 
     | 
    
         
            +
                    raise "#{name} #{version} is not installed" if !File.exists?(install_dir)
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                    FileUtils.rm_rf(install_dir)
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                    yield(File.join(@install_dir, path), version) if block_given?
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                    files = Dir.glob(File.join(@install_dir, path, "**", "*")).find_all { |f| File.file?(f) }
         
     | 
| 
      
 117 
     | 
    
         
            +
                    FileUtils.rm_rf(File.join(@install_dir, path)) if files.length == 0
         
     | 
| 
      
 118 
     | 
    
         
            +
                  end
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
                  #
         
     | 
| 
      
 121 
     | 
    
         
            +
                  # Download a file to Juicer temporary directory. The file will be kept
         
     | 
| 
      
 122 
     | 
    
         
            +
                  # until #purge is called to wipe it. If the installer receives a request
         
     | 
| 
      
 123 
     | 
    
         
            +
                  # to download the same file again, the disk cache will be used unless the
         
     | 
| 
      
 124 
     | 
    
         
            +
                  # force argument is true (default false)
         
     | 
| 
      
 125 
     | 
    
         
            +
                  #
         
     | 
| 
      
 126 
     | 
    
         
            +
                  def download(url, force = false)
         
     | 
| 
      
 127 
     | 
    
         
            +
                    filename = File.join(@install_dir, "download", path.sub("lib/", ""), File.basename(url))
         
     | 
| 
      
 128 
     | 
    
         
            +
                    return filename if File.exists?(filename) && !force
         
     | 
| 
      
 129 
     | 
    
         
            +
                    FileUtils.mkdir_p(File.dirname(filename))
         
     | 
| 
      
 130 
     | 
    
         
            +
                    File.delete(filename) if File.exists?(filename) && force
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                    log "Downloading #{url}"
         
     | 
| 
      
 133 
     | 
    
         
            +
                    File.open(filename, "wb") do |file|
         
     | 
| 
      
 134 
     | 
    
         
            +
                      webpage = open(url)
         
     | 
| 
      
 135 
     | 
    
         
            +
                      file.write(webpage.read)
         
     | 
| 
      
 136 
     | 
    
         
            +
                      webpage.close
         
     | 
| 
      
 137 
     | 
    
         
            +
                    end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                    filename
         
     | 
| 
      
 140 
     | 
    
         
            +
                  end
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                  #
         
     | 
| 
      
 143 
     | 
    
         
            +
                  # Display a message to the user through Juicer::LOGGER
         
     | 
| 
      
 144 
     | 
    
         
            +
                  #
         
     | 
| 
      
 145 
     | 
    
         
            +
                  def log(str)
         
     | 
| 
      
 146 
     | 
    
         
            +
                    Juicer::LOGGER.info str
         
     | 
| 
      
 147 
     | 
    
         
            +
                  end
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
                  #
         
     | 
| 
      
 150 
     | 
    
         
            +
                  # Add a dependency. Dependency should be a Juicer::Install::Base installer
         
     | 
| 
      
 151 
     | 
    
         
            +
                  # class (not instance) OR a symbol/string like :rhino/"rhino" (which will
         
     | 
| 
      
 152 
     | 
    
         
            +
                  # be expanded unto Juicer::Install::RhinoInstaller). Version is optional
         
     | 
| 
      
 153 
     | 
    
         
            +
                  # and defaults to latest and greatest.
         
     | 
| 
      
 154 
     | 
    
         
            +
                  #
         
     | 
| 
      
 155 
     | 
    
         
            +
                  def dependency(dependency, version = nil)
         
     | 
| 
      
 156 
     | 
    
         
            +
                    dependency = Juicer::Install.get(dependency) if [String, Symbol].include?(dependency.class)
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                    @dependencies[dependency.to_s + (version || "")] = [dependency, version]
         
     | 
| 
      
 159 
     | 
    
         
            +
                  end
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
                  #
         
     | 
| 
      
 162 
     | 
    
         
            +
                  # Yields depencies one at a time: class and version and returns an array
         
     | 
| 
      
 163 
     | 
    
         
            +
                  # of arrays: [dependency, version] where dependency is an instance and
         
     | 
| 
      
 164 
     | 
    
         
            +
                  # version a string.
         
     | 
| 
      
 165 
     | 
    
         
            +
                  #
         
     | 
| 
      
 166 
     | 
    
         
            +
                  def dependencies(&block)
         
     | 
| 
      
 167 
     | 
    
         
            +
                    @dependencies.collect do |name, dependency|
         
     | 
| 
      
 168 
     | 
    
         
            +
                      version = dependency[1]
         
     | 
| 
      
 169 
     | 
    
         
            +
                      dependency = dependency[0].new(@install_dir)
         
     | 
| 
      
 170 
     | 
    
         
            +
                      block.call(dependency, version) if block
         
     | 
| 
      
 171 
     | 
    
         
            +
                      [dependency, version]
         
     | 
| 
      
 172 
     | 
    
         
            +
                    end
         
     | 
| 
      
 173 
     | 
    
         
            +
                  end
         
     | 
| 
      
 174 
     | 
    
         
            +
                end
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                #
         
     | 
| 
      
 177 
     | 
    
         
            +
                # Returns the installer. Accepts installer classes (which are returned
         
     | 
| 
      
 178 
     | 
    
         
            +
                # directly), strings or symbols. Strings and symbols may be on the form
         
     | 
| 
      
 179 
     | 
    
         
            +
                # :my_module which is expanded to Juicer::Install::MyModuleInstaller
         
     | 
| 
      
 180 
     | 
    
         
            +
                #
         
     | 
| 
      
 181 
     | 
    
         
            +
                def self.get(nameOrClass)
         
     | 
| 
      
 182 
     | 
    
         
            +
                  return nameOrClass if nameOrClass.is_a? Class
         
     | 
| 
      
 183 
     | 
    
         
            +
                  (nameOrClass.to_s + "_installer").classify(Juicer::Install)
         
     | 
| 
      
 184 
     | 
    
         
            +
                end
         
     | 
| 
      
 185 
     | 
    
         
            +
              end
         
     | 
| 
      
 186 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,69 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "juicer"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "juicer/install/base"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "zip/zip"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Juicer
         
     | 
| 
      
 6 
     | 
    
         
            +
              module Install
         
     | 
| 
      
 7 
     | 
    
         
            +
                #
         
     | 
| 
      
 8 
     | 
    
         
            +
                # Install and uninstall routines for the Google Closure Compiler.
         
     | 
| 
      
 9 
     | 
    
         
            +
                # Installation downloads the Closure Compiler distribution, unzips it and
         
     | 
| 
      
 10 
     | 
    
         
            +
                # storesthe jar file on disk along with the README.
         
     | 
| 
      
 11 
     | 
    
         
            +
                #
         
     | 
| 
      
 12 
     | 
    
         
            +
                class ClosureCompilerInstaller < Base
         
     | 
| 
      
 13 
     | 
    
         
            +
                  def initialize(install_dir = Juicer.home)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    super(install_dir)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @latest = nil
         
     | 
| 
      
 16 
     | 
    
         
            +
                    @website = "http://code.google.com/p/closure-compiler/downloads/list"
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @download_link = "http://closure-compiler.googlecode.com/files/compiler-%s.zip"
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  #
         
     | 
| 
      
 21 
     | 
    
         
            +
                  # Install the Closure Compiler. Downloads the distribution and keeps the jar
         
     | 
| 
      
 22 
     | 
    
         
            +
                  # file inside PATH/closure_compiler/bin and the README in
         
     | 
| 
      
 23 
     | 
    
         
            +
                  # PATH/closere_compiler/yyyymmdd/ where yyyymmdd is the version, most recent if
         
     | 
| 
      
 24 
     | 
    
         
            +
                  # not specified otherwise.
         
     | 
| 
      
 25 
     | 
    
         
            +
                  #
         
     | 
| 
      
 26 
     | 
    
         
            +
                  # Path defaults to environment variable $JUICER_HOME or default Juicer
         
     | 
| 
      
 27 
     | 
    
         
            +
                  # home
         
     | 
| 
      
 28 
     | 
    
         
            +
                  #
         
     | 
| 
      
 29 
     | 
    
         
            +
                  def install(version = nil)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    version = super(version)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    base = "closure-compiler-#{version}"
         
     | 
| 
      
 32 
     | 
    
         
            +
                    filename = download(@download_link % version)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    target = File.join(@install_dir, path)
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                    Zip::ZipFile.open(filename) do |file|
         
     | 
| 
      
 36 
     | 
    
         
            +
                      file.extract("README", File.join(target, version, "README"))
         
     | 
| 
      
 37 
     | 
    
         
            +
                      file.extract("compiler.jar", File.join(target, "bin", "#{base}.jar"))
         
     | 
| 
      
 38 
     | 
    
         
            +
                    end
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  #
         
     | 
| 
      
 42 
     | 
    
         
            +
                  # Uninstalls the given version of Closure Compiler. If no location is
         
     | 
| 
      
 43 
     | 
    
         
            +
                  # provided the environment variable $JUICER_HOME or Juicers default home
         
     | 
| 
      
 44 
     | 
    
         
            +
                  # directory is used.
         
     | 
| 
      
 45 
     | 
    
         
            +
                  #
         
     | 
| 
      
 46 
     | 
    
         
            +
                  # If no version is provided the most recent version is assumed.
         
     | 
| 
      
 47 
     | 
    
         
            +
                  #
         
     | 
| 
      
 48 
     | 
    
         
            +
                  # If there are no more files left in INSTALLATION_PATH/closure_compiler, the
         
     | 
| 
      
 49 
     | 
    
         
            +
                  # whole directory is removed.
         
     | 
| 
      
 50 
     | 
    
         
            +
                  #
         
     | 
| 
      
 51 
     | 
    
         
            +
                  def uninstall(version = nil)
         
     | 
| 
      
 52 
     | 
    
         
            +
                    super(version) do |dir, version|
         
     | 
| 
      
 53 
     | 
    
         
            +
                      File.delete(File.join(dir, "bin/closure-compiler-#{version}.jar"))
         
     | 
| 
      
 54 
     | 
    
         
            +
                    end
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  #
         
     | 
| 
      
 58 
     | 
    
         
            +
                  # Check which version is the most recent
         
     | 
| 
      
 59 
     | 
    
         
            +
                  #
         
     | 
| 
      
 60 
     | 
    
         
            +
                  def latest
         
     | 
| 
      
 61 
     | 
    
         
            +
                    return @latest if @latest
         
     | 
| 
      
 62 
     | 
    
         
            +
                    webpage = Nokogiri::HTML(open(@website))
         
     | 
| 
      
 63 
     | 
    
         
            +
                    @latest = (webpage / "//table[@id='resultstable']//td/a[contains(@href, 'compiler')]").map{|link|
         
     | 
| 
      
 64 
     | 
    
         
            +
                      link.get_attribute('href')[/\d{8}/].to_i
         
     | 
| 
      
 65 
     | 
    
         
            +
                    }.sort.last.to_s
         
     | 
| 
      
 66 
     | 
    
         
            +
                  end
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
              end
         
     | 
| 
      
 69 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,51 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "juicer"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "juicer/install/base"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "zip/zip"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Juicer
         
     | 
| 
      
 6 
     | 
    
         
            +
              module Install
         
     | 
| 
      
 7 
     | 
    
         
            +
                #
         
     | 
| 
      
 8 
     | 
    
         
            +
                # Install and uninstall routines for the JSLint library by Douglas Crockford.
         
     | 
| 
      
 9 
     | 
    
         
            +
                # Installation downloads the jslintfull.js and rhino.js files and stores
         
     | 
| 
      
 10 
     | 
    
         
            +
                # them in the Juicer installation directory.
         
     | 
| 
      
 11 
     | 
    
         
            +
                #
         
     | 
| 
      
 12 
     | 
    
         
            +
                class JSLintInstaller < Base
         
     | 
| 
      
 13 
     | 
    
         
            +
                  attr_reader :latest
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  def initialize(install_dir = Juicer.home)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    super(install_dir)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @latest = "1.0"
         
     | 
| 
      
 18 
     | 
    
         
            +
                    @website = "http://www.jslint.com/"
         
     | 
| 
      
 19 
     | 
    
         
            +
                    @path = "lib/jslint"
         
     | 
| 
      
 20 
     | 
    
         
            +
                    @name = "JsLint"
         
     | 
| 
      
 21 
     | 
    
         
            +
                    dependency :rhino
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  #
         
     | 
| 
      
 25 
     | 
    
         
            +
                  # Install JSLint. Downloads the two js files and stores them in the
         
     | 
| 
      
 26 
     | 
    
         
            +
                  # installation directory.
         
     | 
| 
      
 27 
     | 
    
         
            +
                  #
         
     | 
| 
      
 28 
     | 
    
         
            +
                  def install(version = nil)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    version = super(version)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    filename = download(File.join(@website, "rhino/jslint.js"))
         
     | 
| 
      
 31 
     | 
    
         
            +
                    FileUtils.copy(filename, File.join(@install_dir, path, "bin", "jslint-#{version}.js"))
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  #
         
     | 
| 
      
 35 
     | 
    
         
            +
                  # Uninstalls JSLint
         
     | 
| 
      
 36 
     | 
    
         
            +
                  #
         
     | 
| 
      
 37 
     | 
    
         
            +
                  def uninstall(version = nil)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    super(version) do |dir, version|
         
     | 
| 
      
 39 
     | 
    
         
            +
                      File.delete(File.join(dir, "bin", "jslint-#{version}.js"))
         
     | 
| 
      
 40 
     | 
    
         
            +
                    end
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                #
         
     | 
| 
      
 45 
     | 
    
         
            +
                # This class makes it possible to do Juicer.install("jslint") instead of
         
     | 
| 
      
 46 
     | 
    
         
            +
                # Juicer.install("j_s_lint"). Sugar, sugar...
         
     | 
| 
      
 47 
     | 
    
         
            +
                #
         
     | 
| 
      
 48 
     | 
    
         
            +
                class JslintInstaller < JSLintInstaller
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,53 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "juicer"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "juicer/install/base"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "zip/zip"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Juicer
         
     | 
| 
      
 6 
     | 
    
         
            +
              module Install
         
     | 
| 
      
 7 
     | 
    
         
            +
                #
         
     | 
| 
      
 8 
     | 
    
         
            +
                # Install and uninstall routines for the Mozilla Rhino jar.
         
     | 
| 
      
 9 
     | 
    
         
            +
                #
         
     | 
| 
      
 10 
     | 
    
         
            +
                class RhinoInstaller < Base
         
     | 
| 
      
 11 
     | 
    
         
            +
                  attr_reader :latest
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  def initialize(install_dir = Juicer.home)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    super(install_dir)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @latest = "1_7R2-RC1"
         
     | 
| 
      
 16 
     | 
    
         
            +
                    @website = "http://ftp.mozilla.org/pub/mozilla.org/js/"
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  #
         
     | 
| 
      
 20 
     | 
    
         
            +
                  # Install Rhino. Downloads the jar file and stores it in the installation
         
     | 
| 
      
 21 
     | 
    
         
            +
                  # directory along with the License text.
         
     | 
| 
      
 22 
     | 
    
         
            +
                  #
         
     | 
| 
      
 23 
     | 
    
         
            +
                  def install(version = nil)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    version = super((version || latest).gsub(/\./, "_"))
         
     | 
| 
      
 25 
     | 
    
         
            +
                    base = "rhino#{version}"
         
     | 
| 
      
 26 
     | 
    
         
            +
                    filename = download(File.join(@website, "#{base}.zip"))
         
     | 
| 
      
 27 
     | 
    
         
            +
                    target = File.join(@install_dir, path)
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                    Zip::ZipFile.open(filename) do |file|
         
     | 
| 
      
 30 
     | 
    
         
            +
                      FileUtils.mkdir_p(File.join(target, version))
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 33 
     | 
    
         
            +
                        file.extract("#{base.sub(/-RC\d/, "")}/LICENSE.txt", File.join(target, version, "LICENSE.txt"))
         
     | 
| 
      
 34 
     | 
    
         
            +
                      rescue Exception
         
     | 
| 
      
 35 
     | 
    
         
            +
                        # Fail silently, some releases don't carry the license
         
     | 
| 
      
 36 
     | 
    
         
            +
                      end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                      file.extract("#{base.sub(/-RC\d/, "")}/js.jar", File.join(target, "bin", "#{base}.jar"))
         
     | 
| 
      
 39 
     | 
    
         
            +
                    end
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  #
         
     | 
| 
      
 43 
     | 
    
         
            +
                  # Uninstalls Rhino
         
     | 
| 
      
 44 
     | 
    
         
            +
                  #
         
     | 
| 
      
 45 
     | 
    
         
            +
                  def uninstall(version = nil)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    super((version || latest).gsub(/\./, "_")) do |dir, version|
         
     | 
| 
      
 47 
     | 
    
         
            +
                      base = "rhino#{version}"
         
     | 
| 
      
 48 
     | 
    
         
            +
                      File.delete(File.join(dir, "bin/", "#{base}.jar"))
         
     | 
| 
      
 49 
     | 
    
         
            +
                    end
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,67 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "juicer"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "juicer/install/base"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "zip/zip"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Juicer
         
     | 
| 
      
 6 
     | 
    
         
            +
              module Install
         
     | 
| 
      
 7 
     | 
    
         
            +
                #
         
     | 
| 
      
 8 
     | 
    
         
            +
                # Install and uninstall routines for the YUI Compressor.
         
     | 
| 
      
 9 
     | 
    
         
            +
                # Installation downloads the YUI Compressor distribution, unzips it and
         
     | 
| 
      
 10 
     | 
    
         
            +
                # storesthe jar file on disk along with the license.
         
     | 
| 
      
 11 
     | 
    
         
            +
                #
         
     | 
| 
      
 12 
     | 
    
         
            +
                class YuiCompressorInstaller < Base
         
     | 
| 
      
 13 
     | 
    
         
            +
                  def initialize(install_dir = Juicer.home)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    super(install_dir)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @latest = nil
         
     | 
| 
      
 16 
     | 
    
         
            +
                    @website = "http://yuilibrary.com/downloads/"
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  #
         
     | 
| 
      
 20 
     | 
    
         
            +
                  # Install the Yui Compressor. Downloads the distribution and keeps the jar
         
     | 
| 
      
 21 
     | 
    
         
            +
                  # file inside PATH/yui_compressor/bin and the README and CHANGELOG in
         
     | 
| 
      
 22 
     | 
    
         
            +
                  # PATH/yui_compressor/x.y.z/ where x.y.z is the version, most recent if
         
     | 
| 
      
 23 
     | 
    
         
            +
                  # not specified otherwise.
         
     | 
| 
      
 24 
     | 
    
         
            +
                  #
         
     | 
| 
      
 25 
     | 
    
         
            +
                  # Path defaults to environment variable $JUICER_HOME or default Juicer
         
     | 
| 
      
 26 
     | 
    
         
            +
                  # home
         
     | 
| 
      
 27 
     | 
    
         
            +
                  #
         
     | 
| 
      
 28 
     | 
    
         
            +
                  def install(version = nil)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    version = super(version)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    base = "yuicompressor-#{version}"
         
     | 
| 
      
 31 
     | 
    
         
            +
                    filename = download(File.join(@website, "yuicompressor", "#{base}.zip"))
         
     | 
| 
      
 32 
     | 
    
         
            +
                    target = File.join(@install_dir, path)
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                    Zip::ZipFile.open(filename) do |file|
         
     | 
| 
      
 35 
     | 
    
         
            +
                      file.extract("#{base}/doc/README", File.join(target, version, "README"))
         
     | 
| 
      
 36 
     | 
    
         
            +
                      file.extract("#{base}/doc/CHANGELOG", File.join(target, version, "CHANGELOG"))
         
     | 
| 
      
 37 
     | 
    
         
            +
                      file.extract("#{base}/build/#{base}.jar", File.join(target, "bin", "#{base}.jar"))
         
     | 
| 
      
 38 
     | 
    
         
            +
                    end
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  #
         
     | 
| 
      
 42 
     | 
    
         
            +
                  # Uninstalls the given version of YUI Compressor. If no location is
         
     | 
| 
      
 43 
     | 
    
         
            +
                  # provided the environment variable $JUICER_HOME or Juicers default home
         
     | 
| 
      
 44 
     | 
    
         
            +
                  # directory is used.
         
     | 
| 
      
 45 
     | 
    
         
            +
                  #
         
     | 
| 
      
 46 
     | 
    
         
            +
                  # If no version is provided the most recent version is assumed.
         
     | 
| 
      
 47 
     | 
    
         
            +
                  #
         
     | 
| 
      
 48 
     | 
    
         
            +
                  # If there are no more files left in INSTALLATION_PATH/yui_compressor, the
         
     | 
| 
      
 49 
     | 
    
         
            +
                  # whole directory is removed.
         
     | 
| 
      
 50 
     | 
    
         
            +
                  #
         
     | 
| 
      
 51 
     | 
    
         
            +
                  def uninstall(version = nil)
         
     | 
| 
      
 52 
     | 
    
         
            +
                    super(version) do |dir, version|
         
     | 
| 
      
 53 
     | 
    
         
            +
                      File.delete(File.join(dir, "bin/yuicompressor-#{version}.jar"))
         
     | 
| 
      
 54 
     | 
    
         
            +
                    end
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  #
         
     | 
| 
      
 58 
     | 
    
         
            +
                  # Check which version is the most recent
         
     | 
| 
      
 59 
     | 
    
         
            +
                  #
         
     | 
| 
      
 60 
     | 
    
         
            +
                  def latest
         
     | 
| 
      
 61 
     | 
    
         
            +
                    return @latest if @latest
         
     | 
| 
      
 62 
     | 
    
         
            +
                    webpage = Nokogiri::HTML(open(@website))
         
     | 
| 
      
 63 
     | 
    
         
            +
                    @latest = (webpage / "//h2[@id='yuicompressor']/../../../..//a")[0].get_attribute("href").match(/(\d\.\d\.\d)/)[1]
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,90 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "juicer/binary"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Juicer
         
     | 
| 
      
 4 
     | 
    
         
            +
              #
         
     | 
| 
      
 5 
     | 
    
         
            +
              # A Ruby API to Douglas Crockfords genious JsLint program
         
     | 
| 
      
 6 
     | 
    
         
            +
              # http://www.jslint.com/
         
     | 
| 
      
 7 
     | 
    
         
            +
              #
         
     | 
| 
      
 8 
     | 
    
         
            +
              # JsLint parses JavaScript code and identifies (potential) problems.
         
     | 
| 
      
 9 
     | 
    
         
            +
              # Effectively, JsLint defines a subset of JavaScript which is safe to use, and
         
     | 
| 
      
 10 
     | 
    
         
            +
              # among other things make code minification a substantially less dangerous
         
     | 
| 
      
 11 
     | 
    
         
            +
              # task.
         
     | 
| 
      
 12 
     | 
    
         
            +
              #
         
     | 
| 
      
 13 
     | 
    
         
            +
              class JsLint
         
     | 
| 
      
 14 
     | 
    
         
            +
                include Juicer::Binary
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def initialize(options = {})
         
     | 
| 
      
 17 
     | 
    
         
            +
                  super(options[:java] || "java")
         
     | 
| 
      
 18 
     | 
    
         
            +
                  path << options[:bin_path] if options[:bin_path]
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                #
         
     | 
| 
      
 22 
     | 
    
         
            +
                # Checks if a files has problems. Also includes experimental support for CSS
         
     | 
| 
      
 23 
     | 
    
         
            +
                # files. CSS files should begin with the line @charset "UTF-8";
         
     | 
| 
      
 24 
     | 
    
         
            +
                #
         
     | 
| 
      
 25 
     | 
    
         
            +
                # Returns a Juicer::JsLint::Report object
         
     | 
| 
      
 26 
     | 
    
         
            +
                #
         
     | 
| 
      
 27 
     | 
    
         
            +
                def check(file)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  rhino_jar = rhino
         
     | 
| 
      
 29 
     | 
    
         
            +
                  js_file = locate_lib
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  raise FileNotFoundError.new("Unable to locate Rhino jar '#{rhino_jar}'") if !rhino_jar || !File.exists?(rhino_jar)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  raise FileNotFoundError.new("Unable to locate JsLint '#{js_file}'") if !js_file || !File.exists?(js_file)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  raise FileNotFoundError.new("Unable to locate input file '#{file}'") unless File.exists?(file)
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  lines = execute(%Q{-jar "#{rhino}" "#{locate_lib}" "#{file}"}).split("\n")
         
     | 
| 
      
 36 
     | 
    
         
            +
                  return Report.new if lines.length == 1 && lines[0] =~ /jslint: No problems/
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  report = Report.new
         
     | 
| 
      
 39 
     | 
    
         
            +
                  lines = lines.reject { |line| !line || "#{line}".strip == "" }
         
     | 
| 
      
 40 
     | 
    
         
            +
                  report.add_error(lines.shift, lines.shift) while lines.length > 0
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  return report
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                def rhino
         
     | 
| 
      
 46 
     | 
    
         
            +
                  files = locate("**/rhino*.jar", "RHINO_HOME")
         
     | 
| 
      
 47 
     | 
    
         
            +
                  !files || files.empty? ? nil : files.sort.last
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                def locate_lib
         
     | 
| 
      
 51 
     | 
    
         
            +
                  files = locate("**/jslint-*.js", "JSLINT_HOME")
         
     | 
| 
      
 52 
     | 
    
         
            +
                  !files || files.empty? ? nil : files.sort.last
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                #
         
     | 
| 
      
 56 
     | 
    
         
            +
                # Represents the results of a JsLint run
         
     | 
| 
      
 57 
     | 
    
         
            +
                #
         
     | 
| 
      
 58 
     | 
    
         
            +
                class Report
         
     | 
| 
      
 59 
     | 
    
         
            +
                  attr_accessor :errors
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                  def initialize(errors = [])
         
     | 
| 
      
 62 
     | 
    
         
            +
                    @errors = errors
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  def add_error(message, code)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    @errors << JsLint::Error.new(message, code)
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                  def ok?
         
     | 
| 
      
 70 
     | 
    
         
            +
                    @errors.nil? || @errors.length == 0
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                #
         
     | 
| 
      
 75 
     | 
    
         
            +
                # A JsLint error
         
     | 
| 
      
 76 
     | 
    
         
            +
                #
         
     | 
| 
      
 77 
     | 
    
         
            +
                class Error
         
     | 
| 
      
 78 
     | 
    
         
            +
                  attr_accessor :message, :code
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                  def initialize(message, code)
         
     | 
| 
      
 81 
     | 
    
         
            +
                    @message = message
         
     | 
| 
      
 82 
     | 
    
         
            +
                    @code = code
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                  def to_s
         
     | 
| 
      
 86 
     | 
    
         
            +
                    "#@message\n#@code"
         
     | 
| 
      
 87 
     | 
    
         
            +
                  end
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
              end
         
     | 
| 
      
 90 
     | 
    
         
            +
            end
         
     |