JS_FILE = 'public/javascripts/main.js'
def generate_inclusion_order(dependencies)
inclusion_order = []
nodes = {}
files = dependencies.keys
dependencies.each_pair do |file, requires|
# remove duplicate dependencies
requires.uniq!
required_paths = []
requires.each do |req|
# convert class names to file paths
class_file = "/" << req << '.js'
files.each do |f|
if f.include?(class_file)
required_paths << f
end
end
end
nodes[file] = { "requires" => required_paths, "visited" => false }
end
nodes.each_pair do |file, node|
visit(file, nodes, inclusion_order)
end
return inclusion_order
end
def visit(file, nodes, inclusion_order)
if !nodes[file]['visited']
nodes[file]['visited'] = true
nodes[file]['requires'].each do |other_file|
visit(other_file, nodes, inclusion_order)
end
end
inclusion_order << file if !inclusion_order.include?(file)
end
namespace :js do
file JS_FILE do
dependencies = {}
# read in each javascript file, and find dependencies
FILES = FileList["public/javascripts/**/*.js"]
FILES.each do |f|
file = File.new(f)
lines = file.readlines
lines.each do |line|
# check if this Implements or Extends anything
implements = line.match('Implements\s*:\s*(\w+),')
extends = line.match('.*Extends\s*:\s*(\w+)')
class_instantiations = line.match('.*new ([A-Z]\w+)')
dependencies[f] = [] if !dependencies.has_key?(f)
if implements or extends or class_instantiations
dependencies[f] << extends[1] if extends
dependencies[f] << implements[1] if implements
dependencies[f] << class_instantiations[1] if class_instantiations
end
end
end
# generate inclusion order for files to handle dependencies
inclusion_order = generate_inclusion_order(dependencies)
inclusion_order.each do |i|
puts i
end
File.open(JS_FILE, 'w') do |output|
inclusion_order.each do |f|
output.write(File.read(f))
end
end
end
desc "Merges all Javascript files into a single file keeping the dependencies in mind"
task :combine do
# delete any existing file
File.delete(JS_FILE) if File.exists?(JS_FILE)
Rake::Task[JS_FILE].invoke
end
desc "Minify all Javascript files"
task :minify => :combine do
end
file