Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: fb37104530
Fetching contributors…

Cannot retrieve contributors at this time

file 101 lines (86 sloc) 3.728 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
module Jake
  # A +Buildable+ represents a group of files that may be merged to form a single
  # build file. There are two subtypes of +Buildable+; a +Package+ takes several
  # source files and produces a build file, and a +Bundle+ takes several +Package+
  # build files to produce another build file. This class should be considered
  # abstract as some of its methods must be filled in by subtypes.
  class Buildable
    
    attr_reader :name
    
    # Create a new +Buildable+ using a +Build+ container, a name and a configuration
    # hash, typically a subsection of jake.yml.
    def initialize(build, name, config)
      @build, @name = build, name
      @config = case config
      when Hash then config
      when String then {:files => [config]}
      when Array then {:files => config}
      end
      @code = {}
    end
    
    # Returns the parent +Buildable+ set using the +extends+ option, or +nil+ if
    # there is no parent.
    def parent
      return nil unless @config[:extends]
      @parent ||= @build.package(@config[:extends])
    end
    
    # Returns the source directory for this package.
    def directory
      dir = @config[:directory]
      return parent.directory if parent && !dir
      Jake.path(@build.source_directory, @config[:directory])
    end
    
    # Returns the path to the output file from this package for the given build name.
    def build_path(build_name)
      suffix = @build.use_suffix?(build_name) ? "-#{ build_name }" : ""
      @build.layout == 'together' ?
          Jake.path(@build.build_directory, "#{ @name }#{ suffix }.js") :
          Jake.path(@build.build_directory, build_name, "#{ @name }.js")
    end
    
    # Returns +true+ if the build file for the given build name is out of date and
    # should be regenerated.
    def build_needed?(name)
      return true if @build.forced?
      path = build_path(name)
      return true unless File.file?(path)
      build_time = File.mtime(path)
      files.any? { |path| File.mtime(path) > build_time }
    end
    
    # Returns the header string being used for this package.
    def header
      content = @config[:header] ?
          Jake.read(Jake.path( directory, @config[:header])) :
          (parent ? parent.header : @build.header)
      
      header = Jake.erb(content).result(@build.helper.scope).strip
      return nil if header == ''
      header << "\n"
    end
    
    # Returns the Packr settings to use for this package during the given build.
    def packer_settings(build_name)
      global = @build.packer_settings(build_name)
      local = @config[:packer]
      return parent.packer_settings(build_name) if parent && !local
      return false if global == false or local == false
      {}.merge(global || {}).merge(local || {})
    end
    
    # Returns a hash containing any metadata attached to the package in the config.
    def meta
      @config[:meta] || {}
    end
    
    # Generates all the build files for this package by looping over all the
    # required builds and compressing the source code using each set of minification
    # options. Files are only generated if they are out of date or the build has
    # been forced.
    def write!
      @build.each do |name, settings|
        path = build_path(name)
        @build.fire(:file_not_changed, self, name, path) and next unless build_needed?(name)
        
        @build.helper.build = name.to_s
        FileUtils.mkdir_p(File.dirname(path))
        File.open(path, 'wb') { |f| f.write(code(name).strip) }
        
        @build.fire(:file_created, self, name, path)
        
        size = (File.size(path)/1024.0).ceil
        path = path.sub(@build.build_directory, '')
      end
    end
    
  end
end
Something went wrong with that request. Please try again.