class StitchPlus

Attributes

deleted[RW]
options[RW]

Public Class Methods

new(options={}) click to toggle source
# File lib/stitch-plus.rb, line 9
def initialize(options={})

  @options = {
    :dependencies   => nil,
    :paths          => nil,
    :output         => 'all.js',
    :fingerprint    => false,
    :cleanup        => true,
    :uglify         => false,
    :uglify_options => {},
    :config         => nil
  }
  @deleted = []

  set_options(options)

  begin
    require 'coffee-script'
    @has_coffee = true
  rescue LoadError
  end

end

Public Instance Methods

all_files(options=nil) click to toggle source

Get a list of all files to be stitched

# File lib/stitch-plus.rb, line 138
def all_files(options=nil)
  temp_options(options) if options
  files = []
  files << dependencies if @options[:dependencies]
  files << Dir.glob(File.join(@options[:paths], '**/*')) if @options[:paths]
  reset_options if options
  files.flatten.uniq
end
compile() click to toggle source

Compile javascripts, uglifying if necessary

# File lib/stitch-plus.rb, line 58
def compile

  if all_files.join().match(/\.coffee/) and !@has_coffee
    error "Cannot compile coffeescript".red
    error "Add ".white + "gem 'coffee-script'".yellow + " to your Gemfile."
  end

  if @options[:uglify] and !@uglifier
    error "Cannot uglify javascript".red
    error "Add ".white + "gem 'uglifier'".yellow + " to your Gemfile."
  end

  begin
    js = Stitch::Package.new(:dependencies => dependencies, :paths => @options[:paths]).compile
    js = @uglifier.compile(js) if @uglifier
    js
  rescue StandardError => e
    error "Stitch failed to compile".red
    error e
    false
  end
end
file_fingerprint(options=nil) click to toggle source

Get and MD5 hash of files including order of dependencies

# File lib/stitch-plus.rb, line 148
def file_fingerprint(options=nil)
  temp_options(options) if options
  fingerprint = Digest::MD5.hexdigest(all_files.map! { |path| "#{File.mtime(path).to_i}" }.join + @options.to_s)
  reset_options if options
  fingerprint
end
last_write() click to toggle source

Return the path for the last file written This exists because it's more performant than calling output_file unnecessarily

# File lib/stitch-plus.rb, line 133
def last_write
  @file
end
output_file(options=nil) click to toggle source

return the compiled js path including fingerprint if enabled

# File lib/stitch-plus.rb, line 115
def output_file(options=nil)
  temp_options(options) if options
  file = @options[:output]

  if @options[:fingerprint]
    @fingerprint ||= file_fingerprint
    basename = File.basename(file).split(/(\..+)$/).join("-#{@fingerprint}")
    dir = File.dirname(file)
    file = File.join(dir, basename)
  end

  reset_options if options
  file
end
set_options(options={}, temporary=false) click to toggle source

Set or temporarily set options

# File lib/stitch-plus.rb, line 34
def set_options(options={}, temporary=false)
  @old_options = @options if temporary

  # If options is a file path, read options from yaml
  options = { :config => options } if options.class == String
  options = load_options(options)

  @options = @options.merge symbolize_keys(options)

  if @options[:uglify]
    begin
      require 'uglifier'
      @uglifier = Uglifier.new(@options[:uglify_options])
    rescue LoadError
    end
  end

end
temp_options(options) click to toggle source
# File lib/stitch-plus.rb, line 53
def temp_options(options)
  set_options(options, true)
end
write(options=nil) click to toggle source

Write compiled javascripts to disk

# File lib/stitch-plus.rb, line 82
def write(options=nil)
  temp_options(options) if options

  @fingerprint = file_fingerprint
  @file = output_file

  js = "/* Build fingerprint: #{@fingerprint} */\n" + compile

  if has_fingerprint(@file, @fingerprint)
    info "Stitch " + "identical ".green + @file.sub("#{Dir.pwd}/", '')
    reset_options if options
    true
  else
    begin
      write_msg = (File.exists?(@file) ? "overwrite " : "created ").yellow + @file.sub("#{Dir.pwd}/", '')
      cleanup(@file) if @options[:cleanup]

      FileUtils.mkdir_p(File.dirname(@file))
      File.open(@file, 'w') { |f| f.write js }

      info "Stitch " + write_msg
      true
    rescue StandardError => e
      error "Stitch failed to write #{@file.sub("#{Dir.pwd}/", '')}".red
      error e
      reset_options if options
      false
    end
  end

end

Private Instance Methods

cleanup(file) click to toggle source

Remove existing generated files with the same options name

# File lib/stitch-plus.rb, line 158
def cleanup(file)
  Dir.glob(@options[:output].sub(/\./, '*')).each do |item|
    if File.basename(item) != File.basename(file)
      info "Stitch " + "deleted ".red + item.sub("#{Dir.pwd}/", '')
      FileUtils.rm(item)
      @deleted << item
    end
  end
end
dependencies() click to toggle source

Return all files included as dependencies, globbing as necessary

# File lib/stitch-plus.rb, line 175
def dependencies
  if @options[:dependencies]
    deps = [] << @options[:dependencies]
    deps.flatten.collect { |item|
      item = File.join(item,'**/*') if File.directory?(item)
      Dir.glob item
    }.flatten.uniq.collect { |item|
      File.directory?(item) ? nil : item
    }.compact
  else
    false
  end
end
error(message) click to toggle source
# File lib/stitch-plus.rb, line 197
def error(message)
  if defined?(Guard::UI)
    Guard::UI.error message
  else
    puts message
  end
end
has_fingerprint(file, fingerprint) click to toggle source

Determine if the file has a fingerprint

# File lib/stitch-plus.rb, line 170
def has_fingerprint(file, fingerprint)
  File.size?(file) && File.open(file) {|f| f.readline} =~ /#{fingerprint}/
end
info(message) click to toggle source
# File lib/stitch-plus.rb, line 189
def info(message)
  if defined?(Guard::UI)
    Guard::UI.info message
  else
    puts message
  end
end
load_options(options) click to toggle source
# File lib/stitch-plus.rb, line 212
def load_options(options)
  if options[:config] and File.exist? options[:config]
    config = YAML::load(File.open(options[:config]))
    config = config['stitch'] unless config['stitch'].nil?
    options = options.merge config
  end
  options
end
reset_options() click to toggle source
# File lib/stitch-plus.rb, line 205
def reset_options
  if @old_options
    @options = @old_options
    @old_options = nil
  end
end
symbolize_keys(hash) click to toggle source
# File lib/stitch-plus.rb, line 221
def symbolize_keys(hash)
  hash.inject({}){|result, (key, value)|
    new_key = case key
              when String then key.to_sym
              else key
              end
  new_value = case value
              when Hash then symbolize_keys(value)
              else value
              end
  result[new_key] = new_value
  result
  }
end