PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/rb/lib/template_resolver.rb

http://asproject.googlecode.com/
Ruby | 218 lines | 175 code | 16 blank | 27 comment | 18 complexity | 56373b9aa92d0b0983dac12f77d698d5 MD5 | raw file
  1. module AsProject
  2. #######################################
  3. # TemplateResolver
  4. class TemplateResolver < Hash
  5. attr_accessor :replace_all, :ignore_all
  6. @@ASPROJECT_FILE_NAME = 'AsProject'
  7. @@RENDER_IGNORE_FILES = ['asclass_config.rb', 'SWFMillTemplate.erb']
  8. @@BINARY_EXTENSIONS = ['.jpg', '.png', '.gif', '.doc', '.xls', '.exe', '.swf', 'fla', '.psd']
  9. def initialize
  10. @replace_all = false
  11. @ignore_all = false
  12. end
  13. def copy_files(from, to, render=false)
  14. created_files = Array.new
  15. if(!File.exists? from)
  16. raise ProjectError.new('TemplateResolver attempted to copy files from (' + from + ') but it does not exist...')
  17. end
  18. if(File.directory? from)
  19. Dir.open(from).each do |filename|
  20. if(!AsProject.ignore_file? filename)
  21. fullname = File.join(from, filename)
  22. new_fullname = File.join(to, filename)
  23. cleaned_filename = clean_file_name(filename)
  24. cleaned_fullname = File.join(to, cleaned_filename)
  25. if(File.directory? fullname)
  26. Dir.mkdir(new_fullname) unless File.exists? new_fullname
  27. copy_files(fullname, new_fullname, render).each do |file|
  28. created_files << file
  29. end
  30. else
  31. file = copy_file(fullname, cleaned_fullname, render)
  32. if(file)
  33. created_files << file
  34. end
  35. end
  36. end
  37. end
  38. else
  39. raise ProjectError.new("copy_files called with a file (" + from + ") instead of a directory!")
  40. end
  41. return created_files
  42. end
  43. def b(path)
  44. (is_binary?(path)) ? 'b' : ''
  45. end
  46. def copy_file(from, to, render=false)
  47. if(write_file?(to))
  48. content = nil
  49. File.open(from, 'r' + b(from)) do |f|
  50. content = f.read
  51. end
  52. if(render && should_render?(from))
  53. begin
  54. content = ERB.new(content, nil, '>').result(binding)
  55. rescue NameError => e
  56. puts '>> Template ' + from + ' references a value that is not defined'
  57. raise e
  58. end
  59. end
  60. FileUtils.makedirs(File.dirname(to))
  61. File.open(to, 'w' + b(to)) do |f|
  62. f.write(content)
  63. end
  64. return to
  65. end
  66. return nil
  67. end
  68. =begin
  69. content = nil
  70. # content_mode = nil
  71. File.open(from, 'r') do |f|
  72. # content_mode = f.stat.mode
  73. content = f.read
  74. end
  75. parts = to.split(File::SEPARATOR)
  76. parts.pop
  77. if(render && should_render?(from))
  78. begin
  79. content = ERB.new(content, nil, '>').result(binding)
  80. rescue NameError => e
  81. puts '>> Template ' + from + ' references a value that is not defined'
  82. raise e
  83. end
  84. end
  85. File.makedirs(parts.join(File::SEPARATOR))
  86. File.open(to, 'w') do |f|
  87. f.write(content)
  88. end
  89. # FileUtils.chmod(content_mode, to)
  90. return to
  91. return nil
  92. =end
  93. def should_render?(file)
  94. if(is_binary?(file) || @@RENDER_IGNORE_FILES.index(File.basename(file)))
  95. return false
  96. end
  97. return true
  98. end
  99. def write_file?(file)
  100. if(!File.exists?(file))
  101. return true
  102. elsif(@replace_all)
  103. File.delete(file)
  104. return true
  105. elsif(@ignore_all)
  106. return false
  107. end
  108. relative = file.gsub(Dir.pwd, '')
  109. msg = <<EOF
  110. AsProject Encountered an existing file at [#{relative}], what would you like to do?
  111. (r)eplace, (i)gnore, (R)eplace all or (I)gnore all?
  112. EOF
  113. puts msg
  114. answer = gets.chomp!
  115. if(answer == 'r')
  116. return true
  117. elsif(answer == 'i')
  118. return false
  119. elsif(answer == 'R')
  120. msg = <<EOF
  121. Are you sure you want to replace ALL duplicate files?
  122. (y)es or (n)o
  123. EOF
  124. puts msg
  125. answer = gets.chomp!
  126. if(answer == 'y')
  127. @replace_all = true
  128. else
  129. write_file?(file)
  130. end
  131. elsif(answer == 'I')
  132. @ignore_all = true
  133. return false
  134. else
  135. puts "I didn't understand that response... Please choose from the following choices:\n\n"
  136. write_file?(file)
  137. end
  138. end
  139. def render_file filename
  140. file = File.open(filename, 'r')
  141. resolved = ERB.new(file.read, nil, '>').result(binding)
  142. file.close
  143. file = File.open(filename, 'w')
  144. file.write(resolved)
  145. file.close
  146. end
  147. def clean_file_name name
  148. return name.gsub(@@ASPROJECT_FILE_NAME, project_name)
  149. end
  150. # Override in subclasses!
  151. def project_name
  152. return @@ASPROJECT_FILE_NAME
  153. end
  154. #TODO: Figure out if the file is plain text or not... Possible?
  155. def is_binary? file
  156. file_extension = File.extname(file).downcase
  157. @@BINARY_EXTENSIONS.each do |ext|
  158. if(file_extension == ext)
  159. return true
  160. end
  161. end
  162. return false
  163. end
  164. =begin
  165. Found this code for binary inspection here:
  166. http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/44940
  167. it's not 100%, but better than what I'm doing with extensions.
  168. This should be tested and inserted above
  169. if it works.
  170. NON_ASCII_PRINTABLE = /[^\x20-\x7e\s]/
  171. def nonbinary?(io, forbidden, size = 1024)
  172. while buf = io.read(size)
  173. return false if forbidden =~ buf
  174. end
  175. true
  176. end
  177. # usage: ruby this_script.rb filename ...
  178. ARGV.each do |fn|
  179. begin
  180. open(fn) do |f|
  181. if nonbinary?(f, NON_ASCII_PRINTABLE)
  182. puts "#{fn}: ascii printable"
  183. else
  184. puts "#{fn}: binary"
  185. end
  186. end
  187. rescue
  188. puts "#$0: #$!"
  189. end
  190. end
  191. =end
  192. end
  193. end