class Fones::Builder
Public Class Methods
new(project)
click to toggle source
# File lib/fones/builder.rb, line 8 def initialize(project) @project = project @task = project.task @templates_path = @project.templates_path @assets_path = @project.assets_path @functions_path = @project.functions_path @includes_path = @project.includes_path @package_path = @project.package_path init_sprockets end
Public Instance Methods
build()
click to toggle source
Runs all the methods necessary to build a completed project
# File lib/fones/builder.rb, line 21 def build clean_build_directory copy_templates copy_functions copy_includes build_assets end
build_assets()
click to toggle source
# File lib/fones/builder.rb, line 143 def build_assets [['style.css'], ['css', 'ie.css'], ['css', 'login.css'], ['js', 'theme.js'], ['js', 'admin.js']].each do |asset| destination = File.join(@project.build_path, asset) sprocket = @sprockets.find_asset(asset.last) # Catch any sprockets errors and continue the process begin @task.shell.mute do FileUtils.mkdir_p(File.dirname(destination)) unless File.directory?(File.dirname(destination)) sprocket.write_to(destination) unless sprocket.nil? if @project.config[:compress_js] && destination.end_with?('.js') require "yui/compressor" # Grab the initial sprockets output sprockets_output = File.open(destination, 'r').read # Re-write the file, minified File.open(destination, 'w') do |file| file.write(YUI::JavaScriptCompressor.new.compress(sprockets_output)) end end end rescue Exception => e @task.say "Error while building #{asset.last}:" @task.say e.message, Thor::Shell::Color::RED File.open(destination, 'w') do |file| file.puts(e.message) end # Re-initializing sprockets to prevent further errors # TODO: This is done for lack of a better solution init_sprockets end end # Copy the images directory over FileUtils.cp_r(File.join(@assets_path, 'img'), @project.build_path) if File.exists?(File.join(@assets_path, 'img')) # Check for screenshot and move it into main build directory Dir.glob(File.join(@project.build_path, 'img', '*')).each do |filename| if filename.index(/(screenshot|favicon)\.(png|jpg|jpeg|gif|ico)/) FileUtils.mv(filename, @project.build_path + File::SEPARATOR ) end end end
clean_build_directory()
click to toggle source
Empty out the build directory
# File lib/fones/builder.rb, line 65 def clean_build_directory FileUtils.rm_rf Dir.glob(File.join(@project.build_path, '*')) end
clean_functions()
click to toggle source
# File lib/fones/builder.rb, line 93 def clean_functions FileUtils.rm File.join(@project.build_path, 'functions.php') FileUtils.rm_rf File.join(@project.build_path, 'library') end
clean_images()
click to toggle source
# File lib/fones/builder.rb, line 139 def clean_images FileUtils.rm_rf File.join(@project.build_path, 'img') end
clean_includes()
click to toggle source
# File lib/fones/builder.rb, line 124 def clean_includes FileUtils.rm_rf File.join(@project.build_path, 'includes') end
clean_templates()
click to toggle source
# File lib/fones/builder.rb, line 69 def clean_templates # TODO: cleaner way of removing templates only? Dir.glob(File.join(@project.build_path, '*.php')).each do |path| FileUtils.rm path unless path.include?('functions.php') end end
copy_functions()
click to toggle source
# File lib/fones/builder.rb, line 98 def copy_functions functions_erb_path = File.join(@functions_path, 'functions.php.erb') functions_php_path = File.join(@functions_path, 'functions.php') if File.exists?(functions_erb_path) destination = File.join(@project.build_path, 'functions.php') write_erb(functions_erb_path, destination) elsif File.exists?(functions_php_path) FileUtils.cp functions_php_path, @project.build_path end library_paths = Dir.glob(File.join(@functions_path, '*')).reject do |filename| [functions_erb_path, functions_php_path].include?(filename) end unless library_paths.empty? # Iterate over all files in source/library, skipping the actual functions.php file paths = Dir.glob(File.join(@functions_path, '**', '*')).reject do |filename| [functions_erb_path, functions_php_path].include?(filename) end copy_paths_with_erb(paths, @functions_path, @project.build_path) end end
copy_includes()
click to toggle source
# File lib/fones/builder.rb, line 128 def copy_includes unless Dir.glob(File.join(@includes_path, '*')).empty? # Create the includes folder in the build directory FileUtils.mkdir(File.join(@project.build_path, 'includes')) # Iterate over all files in source/includes, so we can exclude if necessary paths = Dir.glob(File.join(@includes_path, '**', '*')) copy_paths_with_erb(paths, @includes_path, File.join(@project.build_path, 'includes')) end end
copy_templates()
click to toggle source
# File lib/fones/builder.rb, line 76 def copy_templates template_paths.each do |template_path| # Skip directories next if File.directory?(template_path) if template_path.end_with?('.erb') # Chop the .erb extension off the filename destination = File.join(@project.build_path, File.basename(template_path).slice(0..-5)) write_erb(template_path, destination) else # Regular old copy of PHP-only files FileUtils.cp template_path, @project.build_path end end end
zip(filename=nil)
click to toggle source
Use the rubyzip library to build a zip from the generated source
# File lib/fones/builder.rb, line 30 def zip(filename=nil) filename = filename || File.basename(@project.root) project_base = File.basename(@project.root) zip_filename = File.join(File.basename(@package_path), "#{filename}.zip") # Create a temporary file for RubyZip to write to temp_filename = "#{zip_filename}.tmp" File.delete(temp_filename) if File.exists?(temp_filename) # Wrapping the zip creation in Thor's create_file to get "overwrite" prompts # Note: I could be overcomplicating this @task.create_file(zip_filename) do Zip::ZipFile.open(temp_filename, Zip::ZipFile::CREATE) do |zip| # Get all filenames in the build directory recursively filenames = Dir[File.join(@project.build_path, '**', '*')] # Remove the build directory path from the filename filenames.collect! {|path| path.gsub(/#{@project.build_path}\//, '')} # Add each file in the build directory to the zip file filenames.each do |filename| zip.add File.join(project_base, filename), File.join(@project.build_path, filename) end end # Give Thor contents of zip file for "overwrite" prompt File.open(temp_filename, 'rb') { |f| f.read } end # Clean up the temp file File.delete(temp_filename) end
Protected Instance Methods
write_erb(source, destination)
click to toggle source
Write an .erb from source to destination, catching and reporting errors along the way
# File lib/fones/builder.rb, line 253 def write_erb(source, destination) begin @task.shell.mute do @task.create_file(destination) do @project.parse_erb(source) end end rescue Exception => e @task.say "Error while building #{File.basename(source)}:" @task.say e.message + "\n", Thor::Shell::Color::RED exit end end
Private Instance Methods
copy_paths_with_erb(paths, source_dir, destination_dir)
click to toggle source
# File lib/fones/builder.rb, line 193 def copy_paths_with_erb(paths, source_dir, destination_dir) paths.each do |path| # Remove source directory from full file path to get the relative path relative_path = path.gsub(source_dir, '') destination = File.join(destination_dir, relative_path) if destination.end_with?('.erb') # Remove the .erb extension if the path was an erb file destination = destination.slice(0..-5) # And process it as an erb write_erb(path, destination) else # Otherwise, we simply move the file over FileUtils.mkdir_p(destination) if File.directory?(path) FileUtils.cp path, destination unless File.directory?(path) end end end
get_output_filename(basename)
click to toggle source
Generate a unique filename for the zip output
# File lib/fones/builder.rb, line 237 def get_output_filename(basename) package_path_base = File.basename(@package_path) filename = File.join(package_path_base, "#{basename}.zip") i = 1 while File.exists?(filename) filename = File.join(package_path_base, "#{basename}(#{i}).zip") i += 1 end filename end
init_sprockets()
click to toggle source
# File lib/fones/builder.rb, line 213 def init_sprockets @sprockets = Sprockets::Environment.new ['js', 'css', 'lib'].each do |dir| @sprockets.append_path File.join(@assets_path, dir) end # Add assets/styleshets to load path for Less Engine # Tilt::LessTemplateWithPaths.load_path = File.join(@assets_path, 'css') # Passing the @project instance variable to the Sprockets::Context instance # used for processing the asset ERB files. Ruby meta-programming, FTW. @sprockets.context_class.instance_exec(@project) do |project| define_method :config do project.config end end end
template_paths()
click to toggle source
# File lib/fones/builder.rb, line 232 def template_paths Dir.glob(File.join(@templates_path, '**', '*')) end