rucola 0.0.3 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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