1. JS_FILE = 'public/javascripts/main.js'
  2.  
  3. def generate_inclusion_order(dependencies)
  4. inclusion_order = []
  5. nodes = {}
  6. files = dependencies.keys
  7.  
  8. dependencies.each_pair do |file, requires|
  9. # remove duplicate dependencies
  10. requires.uniq!
  11. required_paths = []
  12. requires.each do |req|
  13. # convert class names to file paths
  14. class_file = "/" << req << '.js'
  15. files.each do |f|
  16. if f.include?(class_file)
  17. required_paths << f
  18. end
  19. end
  20. end
  21. nodes[file] = { "requires" => required_paths, "visited" => false }
  22. end
  23.  
  24. nodes.each_pair do |file, node|
  25. visit(file, nodes, inclusion_order)
  26. end
  27.  
  28. return inclusion_order
  29. end
  30.  
  31. def visit(file, nodes, inclusion_order)
  32. if !nodes[file]['visited']
  33. nodes[file]['visited'] = true
  34. nodes[file]['requires'].each do |other_file|
  35. visit(other_file, nodes, inclusion_order)
  36. end
  37. end
  38.  
  39. inclusion_order << file if !inclusion_order.include?(file)
  40. end
  41.  
  42. namespace :js do
  43.  
  44. file JS_FILE do
  45. dependencies = {}
  46.  
  47. # read in each javascript file, and find dependencies
  48. FILES = FileList["public/javascripts/**/*.js"]
  49.  
  50. FILES.each do |f|
  51. file = File.new(f)
  52. lines = file.readlines
  53. lines.each do |line|
  54. # check if this Implements or Extends anything
  55. implements = line.match('Implements\s*:\s*(\w+),')
  56. extends = line.match('.*Extends\s*:\s*(\w+)')
  57. class_instantiations = line.match('.*new ([A-Z]\w+)')
  58. dependencies[f] = [] if !dependencies.has_key?(f)
  59.  
  60. if implements or extends or class_instantiations
  61. dependencies[f] << extends[1] if extends
  62. dependencies[f] << implements[1] if implements
  63. dependencies[f] << class_instantiations[1] if class_instantiations
  64. end
  65. end
  66. end
  67.  
  68. # generate inclusion order for files to handle dependencies
  69. inclusion_order = generate_inclusion_order(dependencies)
  70. inclusion_order.each do |i|
  71. puts i
  72. end
  73.  
  74. File.open(JS_FILE, 'w') do |output|
  75. inclusion_order.each do |f|
  76. output.write(File.read(f))
  77. end
  78. end
  79. end
  80.  
  81. desc "Merges all Javascript files into a single file keeping the dependencies in mind"
  82. task :combine do
  83. # delete any existing file
  84. File.delete(JS_FILE) if File.exists?(JS_FILE)
  85. Rake::Task[JS_FILE].invoke
  86. end
  87.  
  88. desc "Minify all Javascript files"
  89. task :minify => :combine do
  90.  
  91. end
  92.  
  93. file