rucola 0.0.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/ChangeLog +468 -0
  2. data/History.txt +25 -0
  3. data/License.txt +1 -1
  4. data/Manifest.txt +32 -0
  5. data/README.txt +9 -67
  6. data/Rakefile +39 -31
  7. data/TODO +10 -18
  8. data/app_generators/rucola/rucola_generator.rb +15 -8
  9. data/app_generators/rucola/templates/Rakefile.erb +35 -7
  10. data/app_generators/rucola/templates/config/boot.rb +0 -1
  11. data/app_generators/rucola/templates/config/dependencies.rb +31 -0
  12. data/app_generators/rucola/templates/config/environment.rb +0 -1
  13. data/app_generators/rucola/templates/config/environments/debug.rb +13 -1
  14. data/app_generators/rucola/templates/config/environments/release.rb +15 -1
  15. data/app_generators/rucola/templates/config/environments/test.rb +7 -1
  16. data/app_generators/rucola/templates/misc/rb_main.rb.erb +12 -1
  17. data/app_generators/rucola/templates/project.pbxproj.erb +4 -0
  18. data/app_generators/rucola/templates/script/console +10 -0
  19. data/app_generators/rucola/templates/test/controllers/test_application_controller.rb +22 -10
  20. data/app_generators/rucola/templates/test/test_helper.rb +1 -0
  21. data/bin/rucola +4 -2
  22. data/lib/rucola/dependencies.rb +241 -0
  23. data/lib/rucola/dependencies/exclusions.rb +20 -0
  24. data/lib/rucola/dependencies/override_require_and_gem.rb +30 -0
  25. data/lib/rucola/dependencies/resolver.rb +68 -0
  26. data/lib/rucola/fsevents.rb +108 -0
  27. data/lib/rucola/initializer.rb +149 -117
  28. data/lib/rucola/log.rb +61 -0
  29. data/lib/rucola/nib.rb +3 -3
  30. data/lib/rucola/reloader.rb +39 -0
  31. data/lib/rucola/ruby_debug.rb +27 -0
  32. data/lib/rucola/rucola_support.rb +1 -2
  33. data/lib/rucola/rucola_support/core_ext.rb +4 -2
  34. data/lib/rucola/rucola_support/core_ext/objc.rb +9 -4
  35. data/lib/rucola/rucola_support/core_ext/objc/nsimage.rb +22 -0
  36. data/lib/rucola/rucola_support/core_ext/ruby.rb +11 -4
  37. data/lib/rucola/rucola_support/core_ext/ruby/file.rb +11 -0
  38. data/lib/rucola/rucola_support/core_ext/ruby/kernel.rb +16 -0
  39. data/lib/rucola/rucola_support/core_ext/ruby/object.rb +47 -0
  40. data/lib/rucola/rucola_support/core_ext/ruby/string.rb +8 -0
  41. data/lib/rucola/rucola_support/notifications/notifications.rb +26 -28
  42. data/lib/rucola/rucola_support/rc_app.rb +18 -0
  43. data/lib/rucola/tasks/dependencies.rake +49 -0
  44. data/lib/rucola/tasks/deploy.rake +131 -0
  45. data/lib/rucola/tasks/main.rake +39 -6
  46. data/lib/rucola/tasks/xcode.rake +54 -11
  47. data/lib/rucola/test_case.rb +138 -0
  48. data/lib/rucola/test_helper.rb +11 -5
  49. data/lib/rucola/version.rb +2 -2
  50. data/lib/rucola/xcode.rb +39 -9
  51. data/rucola_generators/controller/templates/test_controller_template.rb.erb +19 -7
  52. data/rucola_generators/simple_model/USAGE +5 -0
  53. data/rucola_generators/simple_model/simple_model_generator.rb +54 -0
  54. data/rucola_generators/simple_model/templates/simple_model.rb.erb +2 -0
  55. data/rucola_generators/simple_model/templates/test_simple_model.rb.erb +11 -0
  56. data/rucola_generators/window_controller/templates/test_window_controller_template.rb.erb +24 -13
  57. data/test/fixtures/dependencies/foo.rb +2 -0
  58. data/test/fixtures/dependencies/foo/bar.rb +0 -0
  59. data/test/fixtures/dependencies/foo/baz.rb +0 -0
  60. data/test/fixtures/dependencies/requires_fileutils.rb +1 -0
  61. data/test/fixtures/some_reloadable_class.rb +4 -0
  62. data/test/test_core_ext.rb +80 -0
  63. data/test/test_dependencies.rb +205 -0
  64. data/test/test_fsevents.rb +152 -0
  65. data/test/test_helper.rb +30 -1
  66. data/test/test_initializer.rb +56 -23
  67. data/test/test_log.rb +44 -0
  68. data/test/test_objc_core_ext.rb +23 -0
  69. data/test/test_rc_app.rb +5 -0
  70. data/test/test_reloader.rb +28 -0
  71. data/test/test_rucola_generator.rb +7 -0
  72. data/test/test_simple_model_generator.rb +48 -0
  73. data/test/test_xcode.rb +85 -5
  74. data/website/index.html +17 -91
  75. data/website/index.txt +14 -81
  76. data/website/template.rhtml +1 -1
  77. metadata +120 -76
@@ -0,0 +1,20 @@
1
+ module Rucola
2
+ class Dependencies
3
+ class << self
4
+ def exclusions
5
+ @exclusions ||= []
6
+ end
7
+
8
+ def exclude(regexp)
9
+ exclusions << regexp
10
+ end
11
+
12
+ def exclude?(name)
13
+ exclusions.any? { |regexp| name =~ regexp }
14
+ end
15
+ end
16
+
17
+ # define libs that should not be resolved here
18
+ exclude(/osx\//)
19
+ end
20
+ end
@@ -0,0 +1,30 @@
1
+ # These monkey patches are used in a app if it has rucola bundled
2
+
3
+ # make Gem work
4
+ unless defined? Gem
5
+ module Gem #:nodoc:
6
+ class LoadError < StandardError #:nodoc:
7
+ end
8
+ end
9
+ end
10
+
11
+ module Rucola
12
+ class Dependencies
13
+ def self.override_require_and_gem!
14
+ Kernel.module_eval do
15
+ alias_method :__require_before_rucola_standalone_app, :require
16
+ def require(name)
17
+ return if name == 'rubygems' # atm we don't want to allow rubygems
18
+ # check if there's an exception for this requirement and load it, otherwise load the original
19
+ exception = Rucola::Dependencies.instance.exceptions[name] if Rucola::Dependencies.respond_to?(:instance) # check if everything is done loading
20
+ __require_before_rucola_standalone_app(exception || name)
21
+ end
22
+
23
+ def gem(name, version)
24
+ #puts "Gem required: #{name}"
25
+ require(name)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,68 @@
1
+ require 'yaml'
2
+ require 'osx/cocoa'
3
+
4
+ require File.expand_path('../exclusions', __FILE__)
5
+
6
+ class DependencyResolver #:nodoc:
7
+ class UnableToResolveError < StandardError #:nodoc:
8
+ end
9
+
10
+ def initialize(name, version)
11
+ @name, @version = name, version
12
+ end
13
+
14
+ def require!
15
+ verbose_before = $VERBOSE
16
+ $VERBOSE = nil
17
+ begin
18
+ if Kernel.private_methods.include? 'gem_original_require'
19
+ gem_original_require(@name)
20
+ else
21
+ require(@name)
22
+ end
23
+ rescue LoadError
24
+ # unfortunately, rubygems will always require 'etc.bundle' & 'fileutils' so there's no real way of knowing
25
+ # wether or not it was required by rubygems or the actual library.
26
+ begin
27
+ Gem.activate(@name, true, @version)
28
+ require(@name)
29
+ rescue NameError
30
+ raise UnableToResolveError, "Unable to resolve: '#{@name}', '#{@version}'"
31
+ end
32
+ end
33
+ $VERBOSE = verbose_before
34
+ end
35
+
36
+ def difference_in_loaded_features
37
+ # save this to set it back to what it originally was
38
+ loaded_features_before_rubygems = $LOADED_FEATURES.dup
39
+
40
+ $LOADED_FEATURES.replace([])
41
+ require 'rubygems' rescue LoadError
42
+
43
+ Kernel.module_eval do
44
+ alias_method :__require_before_dependency_resolver, :require
45
+ def require(name)
46
+ unless Rucola::Dependencies.exclude?(name)
47
+ __require_before_dependency_resolver(name)
48
+ end
49
+ end
50
+ end
51
+
52
+ # save this so we can compare what else was added except for rubygems
53
+ loaded_features_before = $LOADED_FEATURES.dup
54
+
55
+ require!
56
+
57
+ result = ($LOADED_FEATURES - loaded_features_before)
58
+ $LOADED_FEATURES.replace(loaded_features_before_rubygems)
59
+ result
60
+ end
61
+ end
62
+
63
+ name, version = ARGV[0..1]
64
+ $LOAD_PATH.replace(YAML.load(ARGV[2])) unless ARGV[2].nil?
65
+
66
+ dr = DependencyResolver.new(name, version)
67
+ # print to stdout the serialized results array
68
+ puts YAML.dump(dr.difference_in_loaded_features)
@@ -0,0 +1,108 @@
1
+ OSX.require_framework '/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework'
2
+
3
+ module Rucola
4
+ class FSEvents
5
+ class FSEvent
6
+ attr_reader :fsevents_object
7
+ attr_reader :id
8
+ attr_reader :path
9
+ def initialize(fsevents_object, id, path)
10
+ @fsevents_object, @id, @path = fsevents_object, id, path
11
+ end
12
+
13
+ # Returns an array of the files/dirs in the path that the event occurred in.
14
+ # The files are sorted by the modification time, the first entry is the last modified file.
15
+ def files
16
+ Dir.glob("#{File.expand_path(path)}/*").sort_by {|f| File.mtime(f) }.reverse
17
+ end
18
+
19
+ # Returns the last modified file in the path that the event occurred in.
20
+ def last_modified_file
21
+ files.first
22
+ end
23
+ end
24
+
25
+ class StreamError < StandardError; end
26
+
27
+ attr_reader :paths
28
+ attr_reader :stream
29
+
30
+ attr_accessor :allocator
31
+ attr_accessor :context
32
+ attr_accessor :since
33
+ attr_accessor :latency
34
+ attr_accessor :flags
35
+
36
+ class << self
37
+ # Initializes a new FSEvents `watchdog` object,
38
+ # creates, starts and then returns the stream.
39
+ #
40
+ # Pass it a block which will be used as a callback.
41
+ # The block will receive an array of FSEvent objects.
42
+ #
43
+ # fsevents = Rucola::FSEvents.start_watching('/some/path') do |events|
44
+ # events.each do |event|
45
+ # p event
46
+ # end
47
+ # end
48
+ # p fsevents
49
+ def start_watching(*paths, &block)
50
+ fsevents = new(paths.flatten, &block)
51
+ fsevents.create_stream
52
+ fsevents.start
53
+ fsevents
54
+ end
55
+ end
56
+
57
+ # Creates a new FSEvents `watchdog` object.
58
+ # Pass it an array of paths and a block with your callback. Options allow you to specify in more detail how
59
+ # the events watcher should behave.
60
+ #
61
+ # *:since: The service will report events that have happened after the supplied event ID. Never use 0 because that
62
+ # will cause every fsevent since the "beginning of time" to be reported. Use OSX::KFSEventStreamEventIdSinceNow
63
+ # if you want to receive events that have happened after this call. (Default: OSX::KFSEventStreamEventIdSinceNow).
64
+ # *:latency: Number of seconds to wait until an FSEvent is reported, this allows the service to bundle events. (Default: 0.0)
65
+ #
66
+ # For the rest of the options read the Cocoa documentation.
67
+ def initialize(paths, options={}, &block)
68
+ raise ArgumentError, 'No callback block was specified.' unless block_given?
69
+ paths.each { |path| raise ArgumentError, "The specified path (#{path}) does not exist." unless File.exist?(path) }
70
+
71
+ @allocator = options[:allocator] || OSX::KCFAllocatorDefault
72
+ @context = options[:context] || nil
73
+ @since = options[:since] || OSX::KFSEventStreamEventIdSinceNow
74
+ @latency = options[:latency] || 0.0
75
+ @flags = options[:flags] || 0
76
+ @stream = options[:stream] || nil
77
+
78
+ @paths = paths
79
+ @user_callback = block
80
+ @callback = Proc.new do |stream, client_callback_info, number_of_events, paths_pointer, event_flags, event_ids|
81
+ paths_pointer.regard_as('*')
82
+ events = []
83
+ number_of_events.times {|i| events << Rucola::FSEvents::FSEvent.new(self, event_ids[i], paths_pointer[i]) }
84
+ @user_callback.call(events)
85
+ end
86
+ end
87
+
88
+ # Create the stream.
89
+ # Raises a Rucola::FSEvents::StreamError if the stream could not be created.
90
+ def create_stream
91
+ @stream = OSX.FSEventStreamCreate(@allocator, @callback, @context, @paths, @since, @latency, @flags)
92
+ raise(StreamError, 'Unable to create FSEvents stream.') unless @stream
93
+ OSX.FSEventStreamScheduleWithRunLoop(@stream, OSX.CFRunLoopGetCurrent, OSX::KCFRunLoopDefaultMode)
94
+ end
95
+
96
+ # Start the stream.
97
+ # Raises a Rucola::FSEvents::StreamError if the stream could not be started.
98
+ def start
99
+ raise(StreamError, 'Unable to start FSEvents stream.') unless OSX.FSEventStreamStart(@stream)
100
+ end
101
+
102
+ # Stop the stream.
103
+ # You can resume it by calling `start` again.
104
+ def stop
105
+ OSX.FSEventStreamStop(@stream)
106
+ end
107
+ end
108
+ end
@@ -1,39 +1,40 @@
1
1
  require 'osx/cocoa'
2
2
  require 'pathname'
3
3
 
4
- require 'rucola/rucola_support/rc_app'
5
- require 'rucola/plugin'
6
-
7
- unless ENV['RUBYCOCOA_ENV'].nil?
8
- RUBYCOCOA_ENV = ENV['RUBYCOCOA_ENV']
9
- else
10
- unless ENV['DYLD_LIBRARY_PATH'].nil?
11
- env = ENV['DYLD_LIBRARY_PATH'].split('/').last.downcase
12
- if %(debug release test).include?(env)
13
- RUBYCOCOA_ENV = env
4
+ if !defined?(RUBYCOCOA_ENV) or RUBYCOCOA_ENV.nil?
5
+ if ENV['RUBYCOCOA_ENV']
6
+ RUBYCOCOA_ENV = ENV['RUBYCOCOA_ENV']
7
+ else
8
+ if ENV['DYLD_LIBRARY_PATH']
9
+ env = ENV['DYLD_LIBRARY_PATH'].split('/').last.downcase
10
+ if %(debug release test).include?(env)
11
+ RUBYCOCOA_ENV = env
12
+ else
13
+ RUBYCOCOA_ENV = 'debug'
14
+ end
14
15
  else
15
- RUBYCOCOA_ENV = 'debug'
16
+ RUBYCOCOA_ENV = 'release'
16
17
  end
17
- else
18
- RUBYCOCOA_ENV = 'release'
19
18
  end
20
19
  end
21
20
 
22
- unless ENV['RUBYCOCOA_ROOT'].nil?
23
- # rake will set the RUBYCOCOA_ROOT for debugging purpose
24
- RUBYCOCOA_ROOT = Pathname.new(ENV['RUBYCOCOA_ROOT'])
25
- else
26
- # We are running in debug from xcode, which doesn't set RUBYCOCOA_ROOT.
27
- # Or we are simply running in release.
28
- RUBYCOCOA_ROOT =
29
- if RUBYCOCOA_ENV == 'release'
30
- Pathname.new(OSX::NSBundle.mainBundle.resourcePath.fileSystemRepresentation)
31
- else
32
- Pathname.new(ENV['DYLD_LIBRARY_PATH'] + "../../../").cleanpath
33
- end
21
+ if !defined?(RUBYCOCOA_ROOT) or RUBYCOCOA_ROOT.nil?
22
+ if ENV['RUBYCOCOA_ROOT']
23
+ # rake will set the RUBYCOCOA_ROOT for debugging purpose
24
+ RUBYCOCOA_ROOT = Pathname.new(ENV['RUBYCOCOA_ROOT'])
25
+ else
26
+ # We are running in debug from xcode, which doesn't set RUBYCOCOA_ROOT.
27
+ # Or we are simply running in release.
28
+ RUBYCOCOA_ROOT =
29
+ if RUBYCOCOA_ENV == 'release'
30
+ Pathname.new(OSX::NSBundle.mainBundle.resourcePath.fileSystemRepresentation)
31
+ else
32
+ Pathname.new(ENV['DYLD_LIBRARY_PATH'] + "../../../").cleanpath
33
+ end
34
+ end
34
35
  end
35
36
 
36
- $:.unshift(RUBYCOCOA_ROOT)
37
+ $:.unshift(RUBYCOCOA_ROOT.to_s)
37
38
 
38
39
  module Rucola
39
40
  # Are we building and running or just running this application by clicking on
@@ -44,15 +45,23 @@ module Rucola
44
45
  end
45
46
 
46
47
 
47
- # Environment initialization scheme ported/derived from Rails' Initializer.
48
- require 'erb'
48
+ # we need to require everything that would be needed by a standalone application
49
+ require 'erb' # FIXME: this should only be required if we're really gonna use erb (AR project)
50
+ require 'rucola/rucola_support'
51
+ require 'rucola/dependencies'
52
+ require 'rucola/dependencies/exclusions'
53
+ require 'rucola/dependencies/override_require_and_gem'
54
+ require 'rucola/plugin'
55
+ require 'rucola/ruby_debug'
56
+
49
57
  module Rucola
50
58
  # Rails-like Initializer responsible for processing configuration.
51
59
  class Initializer
52
- # The Configuration instance used by this Initializer instance.
53
- attr_reader :configuration
54
-
55
60
  class << self
61
+ def instance
62
+ @initializer ||= new
63
+ end
64
+
56
65
  # Load the config/boot.rb file.
57
66
  def boot
58
67
  Rucola::Plugin.before_boot
@@ -64,7 +73,7 @@ module Rucola
64
73
  # to alter behaviour before any of the application's files are required
65
74
  # and the app is started.
66
75
  def do_boot
67
- require RUBYCOCOA_ROOT + 'config/boot'
76
+ Kernel.require Rucola::RCApp.root_path + '/config/boot'
68
77
  end
69
78
 
70
79
  # Returns the path to the plugins root directory. Eg /MyApp/vendor/plugins.
@@ -77,53 +86,71 @@ module Rucola
77
86
  root = plugins_root
78
87
  if root.exist?
79
88
  root.children.each do |plugin|
80
- next unless plugin.directory?
81
- Kernel.require plugin + 'init.rb'
89
+ init_rb = plugin + 'init.rb'
90
+ next unless init_rb.exist?
91
+ Kernel.require init_rb
82
92
  end
83
93
  end
84
94
  end
85
95
 
86
- # Run the initializer and start the application. The #process method is run by default which
87
- # runs all the initialization routines. You can alternatively specify
88
- # a command to run.
89
- #
90
- # OSX::Initializer.run(:set_load_path)
96
+ # Run the initializer and start the application.
97
+ # Pass it a block to set the configuration.
91
98
  #
92
- def run(command = :process, configuration = Configuration.new)
93
- yield configuration if block_given?
94
- initializer = new configuration
95
- initializer.send(command)
96
- start_app
99
+ # Rucola::Initializer.run do |config|
100
+ # config.use_debugger = true
101
+ # # See +Configuration+ for more info on the options.
102
+ # end
103
+ def run
104
+ if @initializer.nil?
105
+ @initializer = new
106
+
107
+ yield @initializer.configuration if block_given?
108
+ @initializer.process
109
+
110
+ start_app
111
+ else
112
+ yield @initializer.configuration if block_given?
113
+ end
97
114
  end
98
115
 
99
116
  # Starts the application's run loop.
100
117
  def start_app
101
- OSX.NSApplicationMain(0, nil) unless RUBYCOCOA_ENV == 'test' || ENV['DONT_START_RUBYCOCOA_APP']
118
+ OSX.NSApplicationMain(0, nil) unless Rucola::RCApp.test? || ENV['DONT_START_RUBYCOCOA_APP']
102
119
  end
103
120
  end
104
121
 
105
- # Create an initializer instance that references the given
106
- # Configuration instance.
107
- def initialize(configuration)
108
- @configuration = configuration
122
+ # The Configuration instance used by this Initializer instance.
123
+ attr_reader :configuration
124
+
125
+ # Create an initializer instance.
126
+ def initialize
127
+ @configuration = Configuration.new
109
128
  end
110
129
 
111
- # Step through the initialization routines, skipping the active_record
112
- # routines if active_record isnt' being used.
130
+ # Step through the initialization routines.
113
131
  def process
114
132
  Rucola::Plugin.before_process(self)
115
- unless ENV['DYLD_LIBRARY_PATH'].nil?
116
- set_load_path
117
- copy_load_paths_for_release
118
- end
119
133
 
120
- require_rucola_support
134
+ # load the environment config
135
+ @configuration.load_environment_configuration!
136
+
137
+ Rucola::Debugger.use! if @configuration.use_debugger
138
+ use_reloader! if @configuration.use_reloader
139
+
140
+ require_dependencies
121
141
  require_frameworks
142
+ require_lib_source_files
122
143
  require_ruby_source_files
123
- load_environment
144
+
124
145
  Rucola::Plugin.after_process(self)
125
146
  end
126
147
 
148
+ # Requires all the dependencies specified in config/dependencies.rb
149
+ def require_dependencies
150
+ deps_file = (RUBYCOCOA_ROOT + 'config/dependencies.rb').to_s
151
+ Rucola::Dependencies.load(deps_file).require!
152
+ end
153
+
127
154
  # Requires all frameworks specified by the Configuration#objc_frameworks
128
155
  # list. This is also responsible for including osx/active_record_proxy if
129
156
  # use_active_record? is true
@@ -131,11 +158,6 @@ module Rucola
131
158
  configuration.objc_frameworks.each { |framework| OSX.require_framework(framework) }
132
159
  end
133
160
 
134
- # Loads the Rucola support library
135
- def require_rucola_support
136
- require Pathname.new(__FILE__).dirname + 'rucola_support'
137
- end
138
-
139
161
  # Recursively requires any ruby source file that it finds.
140
162
  def require_ruby_source_files_in_dir_recursive(dir)
141
163
  dir.children.each do |child|
@@ -147,6 +169,13 @@ module Rucola
147
169
  end
148
170
  end
149
171
 
172
+ # Requires any ruby source files in the app/lib/ directory.
173
+ def require_lib_source_files
174
+ Dir[RUBYCOCOA_ROOT + 'lib/*.rb'].each do |f|
175
+ require f
176
+ end
177
+ end
178
+
150
179
  # Loops through the subdirectories of the app/ directory.
151
180
  # It requires any ruby file in any of the subdirectories and registers
152
181
  # the required file in the hash +@require_ruby_source_files+ with the name
@@ -159,45 +188,26 @@ module Rucola
159
188
  end
160
189
  end
161
190
 
162
- def load_application_initializers
163
- Dir["#{configuration.root_path}/config/initializers/**/*.rb"].sort.each do |initializer|
164
- load(initializer)
191
+ # Loads the +Reloader+ lib if +use_reloader+ is set to +true+ on the +Configuration+.
192
+ def use_reloader!
193
+ if configuration.use_reloader
194
+ Kernel.require 'rucola/reloader'
195
+ Rucola::Reloader.start!
165
196
  end
166
197
  end
167
198
 
168
- # Loads the environment specified by Configuration#environment_path, which
169
- # can be debug or release
170
- def load_environment
171
- return if @environment_loaded
172
- @environment_loaded = true
173
-
174
- config = configuration
175
- constants = self.class.constants
176
- eval(IO.read(configuration.environment_path), binding, configuration.environment_path)
177
-
178
- (self.class.constants - constants).each do |const|
179
- Object.const_set(const, self.class.const_get(const))
199
+ def load_application_initializers
200
+ Dir["#{configuration.root_path}/config/initializers/**/*.rb"].sort.each do |initializer|
201
+ load(initializer)
180
202
  end
181
203
  end
182
204
 
183
205
  # Set the paths from which your application will automatically load source files.
184
- def set_load_path
185
- load_paths = configuration.load_paths
186
- load_paths.reverse_each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) } unless RUBYCOCOA_ENV == 'test' # FIXME: why??
206
+ def set_load_path!
207
+ load_paths = configuration.load_paths || [] # TODO: from script/console the configuration isn't ran.
208
+ load_paths.reverse_each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) } unless Rucola::RCApp.test? # FIXME: why??
187
209
  $LOAD_PATH.uniq!
188
210
  end
189
-
190
- # Copy the default load paths to the resource directory for the application if
191
- # we are building a release, otherwise we do nothing. When in debug or test mode,
192
- # the files are loaded directly from your working directory.
193
- #
194
- # TODO: Remove debug database from released app if it exists.
195
- def copy_load_paths_for_release
196
- return unless configuration.environment == 'release'
197
- configuration.load_paths.each do |path|
198
- `cp -R #{path} #{RUBYCOCOA_ROOT}/#{File.basename(path)}` if File.directory?(path)
199
- end
200
- end
201
211
  end
202
212
 
203
213
  class Configuration
@@ -215,37 +225,59 @@ module Rucola
215
225
  # all +models+, +config+, +controllers+ and +db+ paths are included in this list.
216
226
  attr_accessor :load_paths
217
227
 
218
- def initialize
219
- set_root_path!
220
- set_application_support_path!
221
-
222
- self.objc_frameworks = []
223
- self.load_paths = default_load_paths
224
- end
228
+ # Defines wether or not you want to use the +Reloader+.
229
+ #
230
+ # Turning on the reloader will start a fsevent loop which watches the files in app/ for changes
231
+ # and try to reload any classes that have been saved while the app is running.
232
+ #
233
+ # It could however lead to erratic behaviour so use it with caution.
234
+ attr_accessor :use_reloader
225
235
 
226
- def set_root_path!
227
- @root_path = Pathname.new(::RUBYCOCOA_ROOT).realpath.to_s
228
- end
236
+ # Defines wether or not you want to use the +debugger+.
237
+ #
238
+ # The debugger allows you to easily set breakpoints and debug them.
239
+ # See the documentation from ruby-debug for its usage:
240
+ # http://www.datanoise.com/ruby-debug/
241
+ attr_accessor :use_debugger
229
242
 
230
- def set_application_support_path!
231
- # TODO: we might want to set this to something in test mode.
232
- return if RUBYCOCOA_ENV == 'test'
233
-
234
- user_app_support_path = File.join(OSX::NSSearchPathForDirectoriesInDomains(OSX::NSLibraryDirectory, OSX::NSUserDomainMask, true)[0].to_s, "Application Support")
235
- @application_support_path = File.join(user_app_support_path, Rucola::RCApp.app_name)
236
- end
243
+ # Defines wether or not you want to allow the use of RubyGems.
244
+ #
245
+ # You can completely disable the usage of RubyGems by setting this to false.
246
+ #
247
+ # Unless you're using gems which are installed on a system by default, it's
248
+ # better to set it to false. This will enable you to debug wether or not your
249
+ # application has been bundled succesfully, PLUS not using rubygems will improve
250
+ # the performance of your application.
251
+ attr_accessor :use_rubygems
237
252
 
238
- # Returns the value of RUBYCOCOA_ENV
239
- def environment
240
- ::RUBYCOCOA_ENV
253
+ # Declare which dependency types should be bundled with a release build.
254
+ # Most of the times you would probably only bundle gems if you're targeting
255
+ # a ruby which is compatible and contains the right site libs.
256
+ #
257
+ # # Only bundles gems
258
+ # config.dependency_types = :gem
259
+ #
260
+ # # Bundles gems and site libs
261
+ # config.dependency_types = :gem, :site
262
+ #
263
+ # # Bundles site and other libs, where other are libs outside any of the default load paths.
264
+ # config.dependency_types = :site, :other
265
+ attr_accessor :dependency_types
266
+
267
+ def initialize
268
+ @objc_frameworks = []
269
+ @load_paths = default_load_paths
270
+ @dependency_types = []
271
+ @use_reloader = @use_debugger = @use_debugger = false
241
272
  end
242
273
 
243
- # The path to the current environment's file (development.rb, etc.). By
244
- # default the file is at <tt>config/environments/#{environment}.rb</tt>.
245
- def environment_path
246
- "#{root_path}/config/environments/#{environment}.rb"
274
+ # Loads the current environment's file (debug.rb, release.rb, test.rb).
275
+ # By default the file is at <tt>config/environments/#{environment}.rb</tt>.
276
+ def load_environment_configuration!
277
+ root = defined?(SOURCE_ROOT) ? SOURCE_ROOT : RCApp.root_path
278
+ require "#{root}/config/environments/#{RCApp.env}.rb"
247
279
  end
248
-
280
+
249
281
  private
250
282
  # Set the load paths, which specifies what directories should be copied over on release.
251
283
  # We can't use RUBYCOCOA_ROOT here because when building for release the .app file is the