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