bowline 0.1.6 → 0.3.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/README.txt +26 -23
  2. data/Rakefile +18 -23
  3. data/VERSION +1 -0
  4. data/assets/jquery.bowline.js +51 -29
  5. data/assets/jquery.js +2122 -1295
  6. data/bin/bowline-gen +1 -1
  7. data/bowline.gemspec +94 -17
  8. data/examples/twitter.html +18 -18
  9. data/lib/bowline.rb +10 -14
  10. data/lib/bowline/async.rb +29 -0
  11. data/lib/bowline/binders.rb +11 -40
  12. data/lib/bowline/binders/collection.rb +11 -8
  13. data/lib/bowline/binders/singleton.rb +9 -6
  14. data/lib/bowline/commands/run.rb +4 -11
  15. data/lib/bowline/dependencies/FAQ.markdown +6 -0
  16. data/lib/bowline/dependencies/MIT-LICENSE +20 -0
  17. data/lib/bowline/dependencies/README.markdown +51 -0
  18. data/lib/bowline/dependencies/Rakefile +10 -0
  19. data/lib/bowline/dependencies/TODO.markdown +4 -0
  20. data/lib/bowline/dependencies/init.rb +41 -0
  21. data/lib/bowline/dependencies/lib/dependencies.rb +9 -0
  22. data/lib/bowline/dependencies/lib/dependencies/dependency.rb +12 -0
  23. data/lib/bowline/dependencies/lib/dependencies/reader.rb +30 -0
  24. data/lib/bowline/dependencies/lib/dependencies/repository.rb +64 -0
  25. data/lib/bowline/dependencies/lib/ext/rubygems.rb +125 -0
  26. data/lib/bowline/dependencies/lib/template/app_script.rb +31 -0
  27. data/lib/bowline/dependencies/spec/spec.opts +4 -0
  28. data/lib/bowline/dependencies/tasks/dependencies.rake +164 -0
  29. data/lib/bowline/ext/array.rb +1 -1
  30. data/lib/bowline/generators.rb +1 -0
  31. data/lib/bowline/generators/application.rb +7 -2
  32. data/lib/bowline/generators/helper.rb +28 -0
  33. data/lib/bowline/helpers.rb +7 -0
  34. data/lib/bowline/initializer.rb +75 -41
  35. data/lib/bowline/observer.rb +42 -19
  36. data/lib/bowline/tasks/app.rake +143 -77
  37. data/lib/bowline/tasks/gems.rake +34 -0
  38. data/lib/bowline/tasks/{misk.rake → misc.rake} +0 -0
  39. data/lib/bowline/version.rb +11 -0
  40. data/lib/bowline/window.rb +19 -0
  41. data/templates/config/boot.rb +4 -3
  42. data/templates/config/environment.rb +8 -4
  43. data/templates/gitignore +0 -2
  44. data/templates/helper.rb +2 -0
  45. data/templates/public/icon.png +0 -0
  46. data/templates/public/index.html +8 -10
  47. metadata +38 -41
  48. data/Manifest.txt +0 -58
  49. data/lib/bowline/gem_dependency.rb +0 -42
  50. data/templates/config/manifest +0 -18
  51. data/templates/config/tiapp.xml +0 -24
@@ -1,5 +1,5 @@
1
1
  class Array
2
2
  def to_js(opts = {})
3
- collect {|i| i.to_js(opts) }
3
+ map {|i| i.to_js(opts) }
4
4
  end
5
5
  end
@@ -56,4 +56,5 @@ end
56
56
  require "bowline/generators/application"
57
57
  require "bowline/generators/binder"
58
58
  require "bowline/generators/model"
59
+ require "bowline/generators/helper"
59
60
  require "bowline/generators/migration"
@@ -31,7 +31,10 @@ module Bowline::Generators
31
31
  file :gitignore, "gitignore", ".gitignore"
32
32
 
33
33
  empty_directory :public, "public"
34
+
34
35
  template :index, "public/index.html", "public/index.html"
36
+ file :logo, "public/icon.png", "public/icon.png"
37
+
35
38
  glob! "public/javascripts"
36
39
  glob! "public/stylesheets"
37
40
 
@@ -44,14 +47,16 @@ module Bowline::Generators
44
47
  empty_directory :app, "app"
45
48
  empty_directory :models, "app/models"
46
49
  empty_directory :binders, "app/binders"
50
+ empty_directory :binders, "app/helpers"
47
51
  empty_directory :config, "config"
48
52
 
49
53
  template :environment, "config/environment.rb", "config/environment.rb"
50
- template :tiapp, "config/tiapp.xml", "config/tiapp.xml"
51
- ["application.yml", "database.yml", "manifest", "boot.rb"].each {|action|
54
+ ["application.yml", "database.yml", "boot.rb"].each {|action|
52
55
  action = File.join('config', action)
53
56
  file(action.downcase.gsub(/[^a-z0-9]+/, '_').to_sym, action, action)
54
57
  }
58
+
59
+ empty_directory :initializers, "config/initializers"
55
60
  end
56
61
 
57
62
  add :app, ApplicationGenerator
@@ -0,0 +1,28 @@
1
+ module Bowline::Generators
2
+ class HelperGenerator < NamedGenerator
3
+ desc <<-DESC
4
+ Generates a new helper.
5
+ DESC
6
+
7
+ def modules
8
+ []
9
+ end
10
+
11
+ def module_name
12
+ "#{self.name.camel_case}Helper"
13
+ end
14
+
15
+ def file_name
16
+ "#{name}_helper"
17
+ end
18
+
19
+ first_argument :name, :required => true, :desc => "helper name"
20
+
21
+ template :helper do |template|
22
+ template.source = "helper.rb"
23
+ template.destination = "app/helpers/#{file_name}.rb"
24
+ end
25
+ end
26
+
27
+ add :helper, HelperGenerator
28
+ end
@@ -0,0 +1,7 @@
1
+ module Bowline
2
+ module Helpers
3
+ def self.init
4
+ Bowline.js.send("bowline_helper=", method(:send))
5
+ end
6
+ end
7
+ end
@@ -65,7 +65,7 @@ module Bowline
65
65
  end
66
66
 
67
67
  def set_load_path
68
- load_paths = configuration.load_paths + configuration.framework_paths
68
+ load_paths = configuration.load_paths
69
69
  load_paths.reverse_each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) }
70
70
  $LOAD_PATH.uniq!
71
71
  end
@@ -172,25 +172,27 @@ module Bowline
172
172
  end
173
173
  end
174
174
 
175
- def initialize_rubygems
176
- # todo - use custom rubygems on deployment
177
- # $LOAD_PATH << File.join(root, 'ruby', 'rubygems')
178
- # ::GEM_DIR = File.join(root, 'ruby', 'gems')
179
- # $LOAD_PATH << GEM_DIR
180
- # ENV['GEM_HOME'] = GEM_DIR
181
- # require 'rubygems'
182
- # Gem.use_paths(GEM_DIR, [GEM_DIR])
183
- # Gem.source_index.refresh!
184
- end
185
-
186
- def add_gem_load_paths
187
- unless configuration.gems.empty?
188
- configuration.gems.each { |gem| gem.add_load_paths }
189
- end
175
+ def initialize_gems
176
+ require 'rubygems'
177
+ Gem.clear_paths
178
+ Gem.path.unshift(configuration.gem_path)
190
179
  end
191
180
 
192
181
  def load_gems
193
- configuration.gems.each { |gem| gem.load }
182
+ configuration.gems.each do |dep|
183
+ options = {
184
+ :lib => dep.name
185
+ }.merge(dep.options)
186
+
187
+ next unless options[:lib]
188
+ begin
189
+ gem(dep.name, *dep.versions)
190
+ require(options[:lib])
191
+ rescue LoadError => e
192
+ puts "was unable to require #{dep.name} as '#{options[:lib]}'
193
+ Reason: #{e.class.name} error raised with message: #{e.message}"
194
+ end
195
+ end
194
196
  end
195
197
 
196
198
  def load_plugins
@@ -212,6 +214,13 @@ module Bowline
212
214
  end
213
215
  end
214
216
 
217
+ def load_application_helpers
218
+ helpers = configuration.helpers
219
+ helpers = helpers.map(&:constantize)
220
+ helpers.each {|h| Helpers.module_eval { extend h } }
221
+ Helpers.init
222
+ end
223
+
215
224
  def load_application_classes
216
225
  if configuration.cache_classes
217
226
  configuration.eager_load_paths.each do |load_path|
@@ -252,12 +261,15 @@ module Bowline
252
261
  })
253
262
  end
254
263
 
264
+ def initialize_js
265
+ Bowline.js.bowline_loaded
266
+ end
267
+
255
268
  def process
256
269
  Bowline.configuration = configuration
257
270
 
258
271
  set_load_path
259
- initialize_rubygems
260
- add_gem_load_paths
272
+ initialize_gems
261
273
 
262
274
  require_frameworks
263
275
  set_autoload_paths
@@ -286,6 +298,9 @@ module Bowline
286
298
  after_initialize
287
299
 
288
300
  load_application_classes
301
+ load_application_helpers
302
+
303
+ initialize_js
289
304
 
290
305
  Bowline.initialized = true
291
306
  end
@@ -317,8 +332,6 @@ module Bowline
317
332
  attr_accessor :bowline
318
333
 
319
334
  attr_accessor :frameworks
320
-
321
- attr_accessor :framework_paths
322
335
 
323
336
  # Whether or not classes should be cached (set to false if you want
324
337
  # application classes to be reloaded on each request)
@@ -371,7 +384,7 @@ module Bowline
371
384
  # An array of gems that this Bowline application depends on. Bowline will automatically load
372
385
  # these gems during installation, and allow you to install any missing gems with:
373
386
  #
374
- # rake gems:install
387
+ # rake gems:sync
375
388
  #
376
389
  # You can add gems with the #gem method.
377
390
  attr_accessor :gems
@@ -387,11 +400,12 @@ module Bowline
387
400
  # To require a library be installed, but not attempt to load it, pass :lib => false
388
401
  #
389
402
  # config.gem 'qrp', :version => '0.4.1', :lib => false
390
- def gem(name, options = {})
391
- # todo
392
- @gems << Bowline::GemDependency.new(name, options)
403
+ def gem(*args)
404
+ @gems << Dependencies::Dependency.new(*args)
393
405
  end
394
406
 
407
+ attr_accessor :gem_path
408
+
395
409
  # Sets the default +time_zone+. Setting this will enable +time_zone+
396
410
  # awareness for Active Record models and set the Active Record default
397
411
  # timezone to <tt>:utc</tt>.
@@ -399,17 +413,25 @@ module Bowline
399
413
 
400
414
  attr_accessor :plugin_glob
401
415
 
416
+ attr_accessor :helper_glob
417
+
402
418
  attr_accessor :initializer_glob
403
419
 
404
420
  attr_accessor :name
405
-
406
- # Create a new Configuration instance, initialized with the default
407
- # values.
421
+ attr_accessor :id
422
+ attr_accessor :version
423
+ attr_accessor :description
424
+ attr_accessor :publisher
425
+ attr_accessor :url
426
+ attr_accessor :icon
427
+ attr_accessor :sdk
428
+ attr_accessor :copyright
429
+
430
+ # Create a new Configuration instance, initialized with the default values.
408
431
  def initialize
409
432
  set_root_path!
410
433
 
411
434
  self.frameworks = default_frameworks
412
- self.framework_paths = default_framework_paths
413
435
  self.load_paths = default_load_paths
414
436
  self.load_once_paths = default_load_once_paths
415
437
  self.eager_load_paths = default_eager_load_paths
@@ -421,7 +443,9 @@ module Bowline
421
443
  self.database_configuration_file = default_database_configuration_file
422
444
  self.app_config_file = default_app_config_file
423
445
  self.gems = default_gems
446
+ self.gem_path = default_gem_path
424
447
  self.plugin_glob = default_plugin_glob
448
+ self.helper_glob = default_helper_glob
425
449
  self.initializer_glob = default_initalizer_glob
426
450
 
427
451
  for framework in default_frameworks
@@ -462,6 +486,10 @@ module Bowline
462
486
  YAML::load(ERB.new(IO.read(database_configuration_file)).result) if File.exists?(database_configuration_file)
463
487
  end
464
488
 
489
+ def helpers
490
+ Dir[helper_glob].map {|f| File.basename(f, '.rb').classify }
491
+ end
492
+
465
493
  # Adds a block which will be executed after bowline has been fully initialized.
466
494
  # Useful for per-environment configuration which depends on the framework being
467
495
  # fully initialized.
@@ -479,16 +507,7 @@ module Bowline
479
507
  def default_frameworks
480
508
  [:active_support, :bowline]
481
509
  end
482
-
483
- def default_framework_paths
484
- [
485
- File.join(root_path, 'vendor', 'bowline', 'lib'),
486
- File.join(root_path, 'vendor', 'rails', 'activesupport', 'lib'),
487
- File.join(root_path, 'vendor', 'rails', 'activerecord', 'lib'),
488
- File.join(root_path, 'vendor', 'rails', 'activeresource', 'lib')
489
- ]
490
- end
491
-
510
+
492
511
  def default_load_paths
493
512
  paths = []
494
513
 
@@ -498,6 +517,7 @@ module Bowline
498
517
  app/binders
499
518
  app/models
500
519
  app/remote
520
+ app/helpers
501
521
  lib
502
522
  vendor
503
523
  ).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
@@ -512,9 +532,10 @@ module Bowline
512
532
 
513
533
  def default_eager_load_paths
514
534
  %w(
535
+ app/binders
515
536
  app/models
516
537
  app/remote
517
- app/binders
538
+ app/helpers
518
539
  ).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
519
540
  end
520
541
 
@@ -547,13 +568,26 @@ module Bowline
547
568
  end
548
569
 
549
570
  def default_gems
550
- []
571
+ gems = []
572
+ gems << Dependencies::Dependency.new(
573
+ "bowline", Bowline::Version::STRING, :lib => false
574
+ )
575
+ gems << Dependencies::Dependency.new("activesupport")
576
+ gems
577
+ end
578
+
579
+ def default_gem_path
580
+ File.join(root_path, *%w{ vendor gems })
551
581
  end
552
582
 
553
583
  def default_plugin_glob
554
584
  File.join(root_path, *%w{ vendor plugins * })
555
585
  end
556
586
 
587
+ def default_helper_glob
588
+ File.join(root_path, *%w{ app helpers *.rb })
589
+ end
590
+
557
591
  def default_initalizer_glob
558
592
  File.join(root_path, *%w{ config initializers **/*.rb })
559
593
  end
@@ -1,4 +1,4 @@
1
- # o = Observer.new
1
+ # o = Observable.new
2
2
  # o.append('greet') {
3
3
  # puts 'hi'
4
4
  # }
@@ -7,35 +7,58 @@
7
7
  # def greet(who)
8
8
  # puts "Hi #{who}"
9
9
  # end
10
- # o.append('greet', method(:greet), 'Alex')
10
+ # event = o.append('greet', method(:greet), 'Alex')
11
11
  # o.call('greet')
12
+ # event.remove
12
13
 
13
14
  module Bowline
14
- class Observer
15
+ class Observable
16
+ class Event
17
+ attr_reader :type, :callback
18
+ def initialize(observable, type, callback = nil)
19
+ @observable = observable
20
+ @type = type
21
+ @callback = callback
22
+ end
23
+
24
+ def call(*args)
25
+ @callback.call(*args)
26
+ end
27
+
28
+ def remove
29
+ @observable.remove(self)
30
+ end
31
+ end
32
+
15
33
  def initialize
16
34
  @listeners = {}
17
35
  end
18
-
19
- # Append block/method to listeners
20
- def append(event, method = nil, *args, &block)
21
- (@listeners[event.to_s] ||= []) << [method||block, args]
36
+
37
+ def append(event, method = nil, &block)
38
+ event = Event.new(self, event, method||block)
39
+ (@listeners[event] ||= []) << event
40
+ event
22
41
  end
23
-
24
- # Like append, but adds it to the body too
25
- def on(event, method = nil, &block)
26
- append(event, method, &block)
27
- JQuery.bind(event.to_s, method(:call), event)
42
+
43
+ def call(event, *args)
44
+ return unless @listeners[event]
45
+ @listeners[event].each do |callback|
46
+ callback.call(*args)
47
+ end
28
48
  end
29
49
 
30
- # Call event
31
- def call(event)
32
- event = event.to_s
33
- @listeners[event].each do |callback|
34
- callback[0].call(*callback[1])
50
+ def remove(event, value=nil)
51
+ return unless @listeners[event]
52
+ if value
53
+ @listeners[event].delete(value)
54
+ if @listeners[event].empty?
55
+ @listeners.delete(event)
56
+ end
57
+ else
58
+ @listeners.delete(event)
35
59
  end
36
- @listeners.delete(event)
37
60
  end
38
-
61
+
39
62
  def clear
40
63
  @listeners = {}
41
64
  end
@@ -1,90 +1,156 @@
1
1
  require 'fileutils'
2
- namespace :app do
3
- desc "Bundles up app into executables"
4
- task :bundle => ["bundle:windows", "bundle:linux", "bundle:osx"]
5
-
6
- namespace :bundle do
7
- task :windows => :environment do
8
- end
9
-
10
- task :linux => :environment do
2
+ namespace :app do
3
+ task :configure => :environment do
4
+ build_path = File.join(APP_ROOT, 'build')
5
+
6
+ conf = Bowline.configuration
7
+
8
+ # Titanium complains about whitespace
9
+ manifest = <<-EOF
10
+ #appname:#{conf.name}
11
+ #appid:#{conf.id}
12
+ #publisher:#{conf.publisher}
13
+ #image:public/logo.png
14
+ #url:#{conf.url}
15
+ #guid:0e70684a-dd4b-4d97-9396-6bc01ba10a4e
16
+ #desc:#{conf.description}
17
+ #type:desktop
18
+ runtime:0.4.4
19
+ api:0.4.4
20
+ tiapp:0.4.4
21
+ tifilesystem:0.4.4
22
+ tiplatform:0.4.4
23
+ tiui:0.4.4
24
+ javascript:0.4.4
25
+ ruby:0.4.4
26
+ tidatabase:0.4.4
27
+ tidesktop:0.4.4
28
+ tigrowl:0.4.4
29
+ timedia:0.4.4
30
+ timonkey:0.4.4
31
+ tinetwork:0.4.4
32
+ tinotification:0.4.4
33
+ tiprocess:0.4.4
34
+ EOF
35
+
36
+ conf.publisher ||= 'Bowline'
37
+ conf.copyright ||= "Copyright © #{Time.now.year}"
38
+
39
+ tiapp = <<-EOF
40
+ <?xml version='1.0' encoding='UTF-8'?>
41
+ <ti:app xmlns:ti='http://ti.appcelerator.org'>
42
+ <id>#{conf.id}</id>
43
+ <name>#{conf.name}</name>
44
+ <version>#{conf.version}</version>
45
+ <publisher>#{conf.publisher}</publisher>
46
+ <url>#{conf.url}</url>
47
+ <icon>public/icon.png</icon>
48
+ <copyright>#{conf.copyright}</copyright>
49
+ <window>
50
+ <id>initial</id>
51
+ <title>#{conf.name}</title>
52
+ <url>app://public/index.html</url>
53
+ <width>700</width>
54
+ <max-width>3000</max-width>
55
+ <min-width>0</min-width>
56
+ <height>800</height>
57
+ <max-height>3000</max-height>
58
+ <min-height>0</min-height>
59
+ <fullscreen>false</fullscreen>
60
+ <resizable>true</resizable>
61
+ <chrome scrollbars="true">true</chrome>
62
+ <maximizable>true</maximizable>
63
+ <minimizable>true</minimizable>
64
+ <closeable>true</closeable>
65
+ </window>
66
+ </ti:app>
67
+ EOF
68
+
69
+ FileUtils.makedirs(build_path)
70
+ FileUtils.cd(build_path) do
71
+ File.open('manifest', 'w+') {|f| f.write manifest }
72
+ File.open('tiapp.xml', 'w+') {|f| f.write tiapp }
11
73
  end
74
+ end
12
75
 
13
- task :osx => :environment do
14
- build_path = File.join(APP_ROOT, 'build')
15
- titanium_path = ENV['TIPATH']
16
- raise 'You need to provide TIPATH' unless titanium_path
17
- titanium_path = File.expand_path(titanium_path)
76
+ desc "Bundles up app into executables"
77
+ task :bundle do
78
+ build_path = File.join(APP_ROOT, 'build')
79
+ app_path = File.join(build_path, 'app')
18
80
 
19
- titanium_path = File.join(titanium_path, 'build', 'osx')
20
- build_path = File.join(build_path, 'osx')
21
- FileUtils.rm_rf(build_path)
81
+ tiapp = File.join(build_path, 'tiapp.xml')
82
+ manifest = File.join(build_path, 'manifest')
22
83
 
23
- build_path = File.join(build_path, "#{APP_NAME}.app", 'Contents')
24
- FileUtils.mkdir_p(build_path)
84
+ if !File.exists?(tiapp) || !File.exists?(manifest)
85
+ Rake::Task['app:configure'].invoke
86
+ end
25
87
 
26
- exec_path = File.join(build_path, 'MacOS')
27
- FileUtils.mkdir_p(exec_path)
88
+ FileUtils.rm_rf(app_path)
89
+ FileUtils.makedirs(app_path)
28
90
 
29
- FileUtils.cd(titanium_path) do
30
- FileUtils.cp_r('runtime/template/kboot', File.join(exec_path, APP_NAME))
31
- FileUtils.cp_r('runtime/installer', build_path)
32
- FileUtils.cp_r('modules', build_path)
33
- FileUtils.cp_r('runtime', build_path)
34
- # FileUtils.cp_r('Frameworks', build_path) # todo
35
- end
36
-
37
- # Todo - put this in config?
38
- File.open(File.join(build_path, 'Info.plist'), 'w+') do |f|
39
- f.write <<-EOF
40
- <?xml version="1.0" encoding="UTF-8"?>
41
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
42
- <plist version="1.0">
43
- <dict>
44
- <key>CFBundleDevelopmentRegion</key>
45
- <string>English</string>
46
- <key>CFBundleExecutable</key>
47
- <string>#{APP_NAME}</string>
48
- <key>CFBundleIconFile</key>
49
- <string>titanium.icns</string>
50
- <key>CFBundleIdentifier</key>
51
- <string>com.titaniumapp.testapp</string>
52
- <key>CFBundleInfoDictionaryVersion</key>
53
- <string>6.0</string>
54
- <key>CFBundleName</key>
55
- <string>#{APP_NAME}</string>
56
- <key>CFBundlePackageType</key>
57
- <string>APPL</string>
58
- <key>CFBundleSignature</key>
59
- <string>WRUN</string>
60
- <key>CFBundleVersion</key>
61
- <string>0.4</string>
62
- <key>NSMainNibFile</key>
63
- <string>MainMenu</string>
64
- <key>NSPrincipalClass</key>
65
- <string>NSApplication</string>
66
- </dict>
67
- </plist>
68
- EOF
69
- end
91
+ FileUtils.cp(tiapp, app_path)
92
+ FileUtils.cp(manifest, app_path)
70
93
 
71
- resources_path = File.join(build_path, 'Resources')
72
- FileUtils.mkdir_p(resources_path)
94
+ dirs = Dir[File.join(APP_ROOT, '**')]
95
+ dirs.delete(build_path)
96
+ dirs.delete(File.join(APP_ROOT, 'log'))
97
+ dirs.delete(File.join(APP_ROOT, 'tmp'))
98
+ dirs.delete(File.join(APP_ROOT, 'db'))
99
+ dirs.delete_if {|i| i =~ /\.svn|\.DS_Store/ }
73
100
 
74
- english_path = File.join(resources_path, 'English.lproj')
75
- FileUtils.mkdir_p(english_path)
76
- FileUtils.cd(build_path) do
77
- FileUtils.cp_r('runtime/template/MainMenu.nib', english_path)
78
- FileUtils.cp_r('runtime/template/titanium.icns', english_path)
101
+ FileUtils.cd(app_path) do
102
+ FileUtils.makedirs('Resources')
103
+ FileUtils.cp_r(dirs, 'Resources')
104
+ schema_path = File.join(APP_ROOT, 'db', 'schema.rb')
105
+ if File.exists?(schema_path)
106
+ FileUtils.cp(
107
+ schema_path,
108
+ File.join('Resources', 'db')
109
+ )
79
110
  end
80
-
81
- dirs = Dir[File.join(APP_ROOT, '*')] - [File.join(APP_ROOT, 'build')]
82
- FileUtils.cp_r(dirs, resources_path)
83
-
84
- FileUtils.cd(resources_path) do
85
- FileUtils.mv(File.join('config', 'manifest'), build_path)
86
- FileUtils.mv(File.join('config', 'tiapp.xml'), build_path)
111
+ end
112
+ end
113
+
114
+ desc "Use the Titanium SDK to build the app"
115
+ task :build do
116
+ build_path = File.join(APP_ROOT, 'build')
117
+ app_path = File.join(build_path, 'app')
118
+
119
+ ti_path = ENV['TIPATH'] || begin
120
+ if RUBY_PLATFORM =~ /darwin/
121
+ '/Library/Application Support/Titanium'
122
+ elsif RUBY_PLATFORM =~ /win/
123
+ 'C:/ProgramData/Titanium'
124
+ elsif RUBY_PLATFORM =~ /linux/
125
+ '/opt/titanium'
126
+ else
127
+ raise "Unknown platform"
87
128
  end
88
129
  end
130
+
131
+ unless File.directory?(ti_path)
132
+ raise "Titanium SDK not found, " \
133
+ "install the SDK or " \
134
+ "specify the ENV variable TIPATH"
135
+ end
136
+
137
+ ti_lib_path = Dir[File.join(ti_path, "sdk", "*", "*")][-1]
138
+
139
+ # Space in osx path
140
+ ti_path.gsub!(' ', '\ ')
141
+ ti_lib_path.gsub!(' ', '\ ')
142
+
143
+ command = []
144
+ command << File.join(ti_lib_path, "tibuild.py")
145
+ command << "-d #{build_path}"
146
+ command << "-s #{ti_path}"
147
+ command << "-r" if ENV['TIRUN']
148
+ command << "-a #{ti_lib_path}"
149
+ command << app_path
150
+
151
+ exec(command.join(' '))
89
152
  end
90
- end
153
+ end
154
+
155
+ desc "Bundle and build app"
156
+ task :app => ["app:bundle", "app:build"]