Class: Jim::Bundler

Inherits:
Object
  • Object
show all
Defined in:
lib/jim/bundler.rb

Overview

Bundler takes parses a Jimfile that specifies requirements as names and versions and then can bundle, compress, or copy those files into specific dirs or files.

A Jimfile has a really simple format that’s encoded as JSON. Options are specified as key value pairs and ‘bundles’ are specified under the “bundles” attribute. Each item in a bundle can be a simple string, or an array of [name, version].

{
  "bundle_dir": "test/tmp/",
  "vendor_dir": "test/tmp/public/javascripts/vendor",
  "bundles": {
    "default": [
      ["jquery", "1.4.1"],
      "myproject",
      "localfile"
    ],
    "base": [
      "jquery"
    ]
  }
}

Pre jim version 0.3 had a different simpler but proprietary and (possibly confusing) Jimfile format. Bundler can still read that format and can actually convert it into the new JSON format for you. See ‘Jim::CLI.update_jimfile`. Future versions may remove this support.

Defined Under Namespace

Classes: InvalidBundle, MissingFile

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(jimfile, index = nil, extra_options = {}) ⇒ Bundler

create a new bundler instance passing in the Jimfile as a ‘Pathname` or a string. `index` is a Jim::Index



39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/jim/bundler.rb', line 39

def initialize(jimfile, index = nil, extra_options = {})
  self.index        = index || Jim::Index.new
  self.options      = {
    :compressed_suffix => '.min'
  }
  self.bundles      = {}
  self.jimfile      = jimfile
  self.options = options.merge(extra_options)
  self.paths        = {}
  if options[:vendor_dir]
    logger.debug "adding vendor dir to index #{options[:vendor_dir]}"
    self.index.add(options[:vendor_dir])
  end
end

Instance Attribute Details

#bundle_dirObject

Returns the value of attribute bundle_dir.



35
36
37
# File 'lib/jim/bundler.rb', line 35

def bundle_dir
  @bundle_dir
end

#bundlesObject

Returns the value of attribute bundles.



34
35
36
# File 'lib/jim/bundler.rb', line 34

def bundles
  @bundles
end

#indexObject

Returns the value of attribute index.



34
35
36
# File 'lib/jim/bundler.rb', line 34

def index
  @index
end

#jimfileObject

Returns the value of attribute jimfile.



34
35
36
# File 'lib/jim/bundler.rb', line 34

def jimfile
  @jimfile
end

#optionsObject

Returns the value of attribute options.



34
35
36
# File 'lib/jim/bundler.rb', line 34

def options
  @options
end

#pathsObject

Returns the value of attribute paths.



34
35
36
# File 'lib/jim/bundler.rb', line 34

def paths
  @paths
end

Instance Method Details

#bundle!(bundle_name = false, compress = false) ⇒ Object

Concatenate all of the bundles to the dir set in ‘bundle_dir` or a specific bundle specified by bundle name. Setting `compress` to true will run the output of each bundle to the Google Closure Compiler. You can also use the YUI compressor by setting the option :compressor to ’yui’ Raises an error if there is no bundled dir or specific bundle set



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/jim/bundler.rb', line 120

def bundle!(bundle_name = false, compress = false)
  resolve! if paths.empty?
  if bundle_name
    files = self.paths[bundle_name]
    if bundle_dir
      path = path_for_bundle(bundle_name, compress)
      concatenate(files, path, compress)
      [path]
    else
      concatenate(files, "", compress)
    end
  elsif bundle_dir
    self.paths.collect do |bundle_name, files|
      path = path_for_bundle(bundle_name, compress)
      concatenate(files, path, compress)
      path
    end
  else
    raise(InvalidBundle,
      "Must set either a :bundle_dir to write files to or a specific bundle to write to STDOUT")
  end
end

#bundle_pathsObject

Returns an array of ‘Pathname`s where each of the bundles will be written



164
165
166
# File 'lib/jim/bundler.rb', line 164

def bundle_paths
  self.bundles.collect {|name, reqs|  path_for_bundle(name) }
end

#compress!(bundle_name = false) ⇒ Object

Alias to running ‘bundle!` with `compress` = `true`



144
145
146
# File 'lib/jim/bundler.rb', line 144

def compress!(bundle_name = false)
  bundle!(bundle_name, true)
end

#compress_js(uncompressed) ⇒ Object

Run the uncompressed js through a JS compressor (closure-compiler) by default. Setting options == ‘yui’ will force the YUI JS Compressor



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/jim/bundler.rb', line 170

def compress_js(uncompressed)
  if options[:compressor] == 'yui'
    begin
      require "yui/compressor"
    rescue LoadError
      raise "You must install the yui compressor gem to use the compressor\ngem install yui-compressor"
    end
    compressor = ::YUI::JavaScriptCompressor.new
  else
    begin
      require 'closure-compiler'
    rescue LoadError
      raise "You must install the closure compiler gem to use the compressor\ngem install closure-compiler"
    end
    compressor = ::Closure::Compiler.new
  end
  begin
    compressor.compress(uncompressed)
  rescue Exception => e
    logger.error e.message
  end
end

#jimfile_to_jsonObject

Output the parse Jimfile requirements and options as a Jimfile-ready JSON-encoded string



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/jim/bundler.rb', line 80

def jimfile_to_json
  h = {
    "bundle_dir" => bundle_dir
  }.merge(options)
  h['bundles'] = {}
  self.bundles.each do |bundle_name, requirements|
    h['bundles'][bundle_name] = []
    requirements.each do |name, version|
      h['bundles'][bundle_name] << if version.nil? || version.strip == ''
        name
      else
        [name, version]
      end
    end
  end
  Yajl::Encoder.encode(h, :pretty => true)
end

#resolve!Object

Resolve the requirements specified in the Jimfile for each bundle to ‘paths` Raises MissingFile error



100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/jim/bundler.rb', line 100

def resolve!
  self.bundles.each do |bundle_name, requirements|
    self.paths[bundle_name] = []
    requirements.each do |name, version|
      path = self.index.find(name, version)
      if !path
        raise(MissingFile,
        "Could not find #{name} #{version} in any of these paths #{index.directories.join(':')}")
      end
      self.paths[bundle_name] << [path, name, version]
    end
  end
  paths
end

#vendor!(dir = nil, force = false) ⇒ Object

Copy each of the requirements into the dir specified with ‘dir` or the path specified with the :vendor_dir option. Returns the dir it was vendored to.



150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/jim/bundler.rb', line 150

def vendor!(dir = nil, force = false)
  resolve! if paths.empty?
  dir ||= options[:vendor_dir]
  dir ||= 'vendor' # default
  logger.debug "Vendoring #{paths.length} files to #{dir}"
  paths.collect {|n, p| p }.flatten.each do |path, name, version|
    if index.in_jimhome?(path)
      Jim::Installer.new(path, dir, :shallow => true, :force => force).install
    end
  end
  dir
end