PageRenderTime 44ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/backbone.thor

https://github.com/darthapo/thor-tasks
Unknown | 303 lines | 240 code | 63 blank | 0 comment | 0 complexity | 207d294161062b622e0d342dc95443b1 MD5 | raw file
  1. # Todo: Add Zepto support for js libs
  2. class Backbone < Thor
  3. include Thor::Actions
  4. require 'fileutils'
  5. require 'open-uri'
  6. require 'active_support/inflector'
  7. desc "new [TYPE] [NAME]", "Creates new backbone files or projects, use 'backbone:new help' for more."
  8. def new(type=nil, name=nil)
  9. type = type.nil? ? 'help' : type.downcase
  10. if name.nil? and type != 'help'
  11. unless type == 'project' or in_app?
  12. say "You need to be in a project directory to run this command."
  13. exit 0
  14. end
  15. name = ask "#{type.capitalize} name:"
  16. end
  17. case type
  18. when 'project'
  19. say "Creating project #{name}:"
  20. create_project name
  21. when 'controller'
  22. say "Creating controller #{name}:"
  23. build_controller name
  24. when 'model'
  25. say "Creating model #{name}:"
  26. build_model name
  27. when 'view'
  28. say "Creating view #{name}:"
  29. build_view name
  30. else
  31. say <<-EOS
  32. Usage:
  33. thor backbone:new TYPE NAME
  34. Types:
  35. - project
  36. - controller
  37. - model (creates a collection too)
  38. - view
  39. EOS
  40. end
  41. say "Done."
  42. end
  43. desc "update", "Updates app_scripts"
  44. def update(type='scripts')
  45. #TODO: Support type=libs -- pull latest libraries
  46. if in_app?
  47. say "Updating app_scripts:"
  48. update_scripts
  49. else
  50. say "You need to be in a project directory to run this command."
  51. exit 0
  52. end
  53. end
  54. desc "serve", "Serves this directory via WebBrick (since some browser don't handle file:// urls well)"
  55. method_options :port=>5000
  56. def serve
  57. require 'webrick'
  58. say "Launching server at 127.0.0.1:#{options.port}"
  59. server = WEBrick::HTTPServer.new(
  60. :Port => options.port,
  61. :FancyIndexing => true,
  62. :DocumentRoot => '.',
  63. :MimeTypes => {
  64. 'js' => 'text/plain',
  65. 'coffee' => 'text/plain',
  66. 'css' => 'text/plain',
  67. 'less' => 'text/plain',
  68. 'thor' => 'text/plain',
  69. 'html' => 'text/html'
  70. }
  71. )
  72. trap('INT') { server.stop }
  73. server.start
  74. end
  75. no_tasks do
  76. def update_scripts(project_name=".")
  77. File.open "#{project_name}/app/app_scripts.js", 'w' do |file|
  78. template = ERB.new APP_SCRIPTS_TEMPLATE
  79. app_scripts = []
  80. %w(controllers models views).each do |type|
  81. app_scripts << Dir["#{project_name}/app/#{type}/*.js"]
  82. end
  83. app_scripts.flatten!
  84. file.write template.result( binding )
  85. say " - #{project_name}/app/app_scripts.js"
  86. end
  87. end
  88. def build_controller(name)
  89. require 'erb'
  90. FileUtils.mkdir_p './app/controllers'
  91. File.open "./app/controllers/#{name.underscore}.js", 'w' do |file|
  92. template = ERB.new CONTROLLER_TEMPLATE
  93. name = name
  94. className = name.underscore.classify
  95. file.write template.result( binding )
  96. say " - ./app/controllers/#{name.underscore}.js"
  97. update_scripts
  98. end
  99. end
  100. def build_model(name)
  101. require 'erb'
  102. FileUtils.mkdir_p './app/models'
  103. File.open "./app/models/#{name.underscore}.js", 'w' do |file|
  104. template = ERB.new MODEL_TEMPLATE
  105. name = name
  106. className = name.underscore.classify
  107. file.write template.result( binding )
  108. say " - ./app/models/#{name.underscore}.js"
  109. update_scripts
  110. end
  111. end
  112. def build_view(name)
  113. require 'erb'
  114. FileUtils.mkdir_p './app/views'
  115. File.open "./app/views/#{name.underscore}.js", 'w' do |file|
  116. template = ERB.new VIEW_TEMPLATE
  117. name = name
  118. className = name.underscore.classify
  119. file.write template.result( binding )
  120. say " - ./app/views/#{name.underscore}.js"
  121. update_scripts
  122. end
  123. end
  124. def create_project(app_name="NewProject", libs=%w(head jquery underscore backbone))
  125. require 'erb'
  126. FileUtils.mkdir_p "./#{app_name}/app/lib"
  127. libs.each do |lib|
  128. File.open "./#{app_name}/app/lib/#{lib}.js", 'w' do |file|
  129. file.write get_latest(lib)
  130. say " - #{app_name}/app/lib/#{lib}.js"
  131. end
  132. end
  133. File.open "./#{app_name}/app/app_main.js", 'w' do |file|
  134. file.write APP_JS_TEMPLATE
  135. say " - #{app_name}/app/app_main.js"
  136. end
  137. File.open "./#{app_name}/index.html", 'w' do |file|
  138. template = ERB.new INDEX_HTML_TEMPLATE
  139. app_name = app_name
  140. app_libs = libs.reject {|lib| lib == 'head' }
  141. file.write template.result( binding )
  142. say " - #{app_name}/index.html"
  143. end
  144. File.open "./#{app_name}/Rakefile", 'w' do |file|
  145. file.write RAKEFILE_TEMPLATE
  146. say " - #{app_name}/Rakefile"
  147. end
  148. update_scripts "./#{app_name}"
  149. end
  150. def get_latest(scriptname)
  151. # TODO: Verify scriptname is actually in JS_LIBS
  152. open( JS_LIBS[scriptname] ).read
  153. end
  154. def in_app?
  155. File.exists?('./app') && File.directory?('./app')
  156. end
  157. end
  158. APP_JS_TEMPLATE =<<-EOS
  159. // You can push your own app_scripts here, example:
  160. // app_scripts.push('app/lib/my_plugin');
  161. function app_main(DEBUG) {
  162. if (app_scripts.length > 0) {
  163. head.js.apply(head, app_scripts);
  164. }
  165. head.ready(function(){
  166. // Initialize your application here.
  167. // new App();
  168. // Then:
  169. Backbone.history.start();
  170. });
  171. };
  172. EOS
  173. APP_SCRIPTS_TEMPLATE =<<-EOS
  174. // auto-generated... Add your scripts in app_main.js
  175. var app_scripts = [];
  176. <% app_scripts.each do |script| %>
  177. app_scripts.push('<%= script %>');<% end %>
  178. EOS
  179. INDEX_HTML_TEMPLATE =<<-EOS
  180. <!DOCTYPE html>
  181. <html>
  182. <head>
  183. <meta charset="utf-8" />
  184. <title><%= app_name %></title>
  185. <!-- Created by Matt McCray on <%= Time.now %> -->
  186. <script src="app/lib/head.js"></script>
  187. <script>
  188. var DEBUG = (window.location.href.indexOf('file:') == 0), app_main_src = 'app/app_main.js'+ (DEBUG ? '?'+((new Date).getTime()) : '');
  189. head.js("app/lib/<%= app_libs.join '.js", "app/lib/' %>.js", "app/app_scripts.js", app_main_src, function(){ app_main(DEBUG); });
  190. </script>
  191. </head>
  192. <body>
  193. <header></header>
  194. <nav></nav>
  195. <article>
  196. <section></section>
  197. </article>
  198. <aside></aside>
  199. <footer></footer>
  200. </body>
  201. </html>
  202. EOS
  203. CONTROLLER_TEMPLATE = <<-EOS
  204. var <%= className %> = Backbone.Controller.extend({
  205. routes: {
  206. '': 'index'
  207. },
  208. index: function() {
  209. }
  210. });
  211. EOS
  212. MODEL_TEMPLATE = <<-EOS
  213. var <%= className %> = Backbone.Model.extend({
  214. });
  215. var <%= className %>Collection = Backbone.Collection.extend({
  216. model: <%= className %>
  217. });
  218. EOS
  219. VIEW_TEMPLATE = <<-EOS
  220. var <%= className %> = Backbone.View.extend({
  221. events: {
  222. },
  223. initialize: function() {
  224. _.bindAll(this, "render");
  225. },
  226. render: function() {
  227. }
  228. });
  229. EOS
  230. RAKEFILE_TEMPLATE = <<-EOS
  231. # Your rake tasks here...
  232. #TODO: Add default tasks for: compress, create_manifest, etc...
  233. EOS
  234. JS_LIBS = {
  235. 'jquery' => 'http://code.jquery.com/jquery-1.4.4.min.js',
  236. 'backbone' => 'http://documentcloud.github.com/backbone/backbone-min.js',
  237. 'underscore' => 'http://documentcloud.github.com/underscore/underscore-min.js',
  238. 'head' => 'https://github.com/headjs/headjs/raw/master/dist/head.min.js'
  239. }
  240. end