require 'barber' require 'coffee-script' require 'fileutils' require 'sass' # Public: Define an Asset. # # Examples # # Asset.new(file: "#{@working_dir}/#{args[:src]}", # build_dir: @build_dir, # working_dir: @working_dir, # helper_args: args) module Pyro class Asset attr_accessor :file, :build_dir, :working_dir, :helper_args # Public: Set args to attrs on new(). # # Examples # # Asset.new(file: "#{@working_dir}/#{args[:src]}", # build_dir: @build_dir, # working_dir: @working_dir, # helper_args: args) # # Returns an Asset instance. def initialize(args) args.each { |k, v| instance_variable_set("@#{k}", v) } end # Public: Map File methods to an Asset. # # * Maybe Asset should inheret from File? # # Examples # # @asset.mtime # # * See the File class for more info. def mtime File.mtime file end def basename File.basename file end def dirname File.dirname file end def extname File.extname file end # Public: Strip the extension from the basename. # # Examples # # @asset.name # # Retunrs a String of the basename without the extension. # ('my_file.rb' -> 'myfile') def name basename.sub(extname, '') end # Public: Format the mtime as a timestamp String. # # Examples # # @asset.timestamp # # Returns a String. def timestamp mtime.strftime "%Y%m%d%H%M%S" end # Public: Find the relative target path of an Asset. # # Examples # # @asset.relative_dir # # Returns a path as a String. def relative_dir dirname.sub("#{working_dir}/", '') end # Public: Find the relative target file path of an Asset. # # Examples # # @asset.relative_file # # Returns a filepath as a String. def relative_file if helper_args[:target] helper_args[:target] else "#{relative_dir}/#{name}#{compiled_ext}" end end # Public: Determine the target extension of an Asset. # # Examples # # @asset.compiled_ext # # Returns a String. def compiled_ext case extname when '.coffee', '.hbs', '.handlebars' '.js' when '.scss' '.css' else extname end end # Public: Compile the contents of an Asset. # # Examples # # @asset.contents # # Returns the compiled contents. def contents contents = File.read file case extname when '.coffee' contents = CoffeeScript.compile(contents, bare: true) when '.scss' contents = Sass::Engine.new(contents, { syntax: :scss }).render when '.hbs', '.handlebars' contents = Barber::Ember::FilePrecompiler.call(contents) contents = "Ember.TEMPLATES['#{template_name}'] = #{contents}" end contents end # Public: Find the name to use for a Handlebars template. # # * Use the name: arg in the template() helper to override the default. # # Examples # # @asset.template_name # # Returns the relative template path and filename unless told otherwise. def template_name if helper_args[:name] helper_args[:name] elsif helper_args[:src] name elsif helper_args[:dir] file.sub("#{working_dir}/#{helper_args[:dir]}/", '').sub(extname, '') else 'name-not-found' end end # Public: Generate a compiled Asset. # # Examples # # @asset.generate_file # # Generates a compiled Asset file into a target file. def generate_file FileUtils.mkdir_p "#{build_dir}/#{relative_dir}" File.open("#{build_dir}/#{relative_file}", 'a+') { |f| f.write contents } end # Public: Generate link to a generated Asset. # # Examples # # @asset.generate_link # # Retunrs a \n" when '.css' "\n" end end end end