module Slinky # Stores information about compiled files, including location, # source file and last modified time class CompiledFile attr_accessor :source, :print_name, :output_path attr_reader :last_compiled, :output_ext # Creates a new CompiledFile, compiling the provided source file # with the provided compiler class. def initialize source, compiler, output_ext @source = source @compiler = compiler @last_compiled = Time.at(0) @output_ext = output_ext end def build path compiler_compile path, EM::DefaultDeferrable end # Compiles the source file to a temporary location def compile &cb path = @output_path || tmp_path @last_compiled = Time.now if @compiler.respond_to? :compile compiler_compile path, cb else compile_failed Exception.new("invalid compiler") cb.call @output_path, nil, nil, "invalid compiler" # compiler_command path, cb end end def compiler_compile path, cb begin out = File.open @source do |f| @compiler.compile f.read, @source end compile_succeeded File.open(path, "w+") do |f| f.write out end rescue Exception compile_failed $! path = nil end cb.call((path ? path.to_s : nil), nil, nil, $!) end # def compiler_command path, cb # #NOTE: This currently won't strip out compiler directives, so # #use at own risk. Ideally all compilers would have ruby version # #so we don't have to use this # command = @compiler.command @source, path # EM.system3 command do |stdout, stderr, status| # if status.exitstatus != 0 # compile_failed stderr.strip # else # compile_succeeded # @output_path = path # end # cb.call(@output_path, status, stdout, stderr) # end # end def name @print_name || @source end def compile_succeeded $stdout.puts "Compiled #{name}".foreground(:green) end def compile_failed e SlinkyError.raise BuildFailedError, "Compilation failed on #{name}: #{e}" end # Calls the supplied callback with the path of the compiled file, # compiling the source file first if necessary. def file &cb #if needs_update? compile &cb #else # cb.call @output_path, nil, nil, nil #end end # Returns whether the source file has changed since it was last # compiled. def needs_update? return true if @compiler.to_s.match "SassCompiler" File.new(source).mtime > @last_compiled rescue true end private def tmp_path Tempfile.new("slinky").path + "." + @output_ext end end end