rucola 0.0.1

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 (107) hide show
  1. data/ChangeLog +628 -0
  2. data/History.txt +4 -0
  3. data/License.txt +20 -0
  4. data/Manifest.txt +106 -0
  5. data/README.txt +126 -0
  6. data/Rakefile +32 -0
  7. data/TODO +28 -0
  8. data/app_generators/rucola/USAGE +6 -0
  9. data/app_generators/rucola/rucola_generator.rb +112 -0
  10. data/app_generators/rucola/templates/Rakefile.erb +12 -0
  11. data/app_generators/rucola/templates/Rakefile.erb.old +156 -0
  12. data/app_generators/rucola/templates/app/controllers/application_controller.rb +22 -0
  13. data/app_generators/rucola/templates/config/Info.plist.erb +28 -0
  14. data/app_generators/rucola/templates/config/boot.rb +2 -0
  15. data/app_generators/rucola/templates/config/environment.rb +11 -0
  16. data/app_generators/rucola/templates/config/environments/debug.rb +3 -0
  17. data/app_generators/rucola/templates/config/environments/release.rb +3 -0
  18. data/app_generators/rucola/templates/config/environments/test.rb +3 -0
  19. data/app_generators/rucola/templates/config/ib_external_class_defs.yml +13 -0
  20. data/app_generators/rucola/templates/misc/English.lproj/InfoPlist.strings.erb +3 -0
  21. data/app_generators/rucola/templates/misc/English.lproj/MainMenu.nib/classes.nib +40 -0
  22. data/app_generators/rucola/templates/misc/English.lproj/MainMenu.nib/info.nib +18 -0
  23. data/app_generators/rucola/templates/misc/English.lproj/MainMenu.nib/keyedobjects.nib +0 -0
  24. data/app_generators/rucola/templates/misc/main.m.erb +15 -0
  25. data/app_generators/rucola/templates/misc/rb_main.rb.erb +13 -0
  26. data/app_generators/rucola/templates/project.pbxproj.erb +299 -0
  27. data/app_generators/rucola/templates/script/plugin +84 -0
  28. data/app_generators/rucola/templates/test/controllers/test_application_controller.rb +10 -0
  29. data/app_generators/rucola/templates/test/test_helper.rb +10 -0
  30. data/bin/rucola +12 -0
  31. data/config/hoe.rb +71 -0
  32. data/config/requirements.rb +17 -0
  33. data/lib/rucola.rb +3 -0
  34. data/lib/rucola/info_plist.rb +37 -0
  35. data/lib/rucola/initializer.rb +313 -0
  36. data/lib/rucola/nib.rb +99 -0
  37. data/lib/rucola/rucola_support.rb +9 -0
  38. data/lib/rucola/rucola_support/controllers.rb +2 -0
  39. data/lib/rucola/rucola_support/controllers/rc_controller.rb +7 -0
  40. data/lib/rucola/rucola_support/controllers/rc_window_controller.rb +12 -0
  41. data/lib/rucola/rucola_support/core_ext.rb +2 -0
  42. data/lib/rucola/rucola_support/core_ext/objc.rb +4 -0
  43. data/lib/rucola/rucola_support/core_ext/objc/nsobject.rb +22 -0
  44. data/lib/rucola/rucola_support/core_ext/ruby.rb +4 -0
  45. data/lib/rucola/rucola_support/core_ext/ruby/string.rb +21 -0
  46. data/lib/rucola/rucola_support/initialize_hooks.rb +21 -0
  47. data/lib/rucola/rucola_support/models.rb +1 -0
  48. data/lib/rucola/rucola_support/models/rc_document.rb +10 -0
  49. data/lib/rucola/rucola_support/notifications.rb +1 -0
  50. data/lib/rucola/rucola_support/notifications/notifications.rb +146 -0
  51. data/lib/rucola/rucola_support/rc_app.rb +101 -0
  52. data/lib/rucola/tasks/freeze.rake +44 -0
  53. data/lib/rucola/tasks/interface_builder.rake +80 -0
  54. data/lib/rucola/tasks/main.rake +29 -0
  55. data/lib/rucola/tasks/xcode.rake +43 -0
  56. data/lib/rucola/test_helper.rb +57 -0
  57. data/lib/rucola/version.rb +9 -0
  58. data/lib/rucola/xcode.rb +148 -0
  59. data/log/debug.log +0 -0
  60. data/rucola_generators/controller/USAGE +5 -0
  61. data/rucola_generators/controller/controller_generator.rb +84 -0
  62. data/rucola_generators/controller/templates/controller_template.rb.erb +5 -0
  63. data/rucola_generators/controller/templates/test_controller_template.rb.erb +10 -0
  64. data/rucola_generators/document_model/USAGE +5 -0
  65. data/rucola_generators/document_model/document_model_generator.rb +67 -0
  66. data/rucola_generators/document_model/templates/document_model_template.rb.erb +27 -0
  67. data/rucola_generators/document_model/templates/test_document_model_template.rb.erb +10 -0
  68. data/rucola_generators/window_controller/USAGE +6 -0
  69. data/rucola_generators/window_controller/templates/Window.nib/classes.nib.erb +35 -0
  70. data/rucola_generators/window_controller/templates/Window.nib/info.nib +16 -0
  71. data/rucola_generators/window_controller/templates/Window.nib/keyedobjects.nib +0 -0
  72. data/rucola_generators/window_controller/templates/test_window_controller_template.rb.erb +10 -0
  73. data/rucola_generators/window_controller/templates/window_controller_template.rb.erb +19 -0
  74. data/rucola_generators/window_controller/window_controller_generator.rb +74 -0
  75. data/script/destroy +14 -0
  76. data/script/generate +14 -0
  77. data/script/txt2html +74 -0
  78. data/setup.rb +1585 -0
  79. data/tasks/deployment.rake +27 -0
  80. data/tasks/environment.rake +7 -0
  81. data/tasks/website.rake +17 -0
  82. data/test/fixtures/Info.plist +28 -0
  83. data/test/fixtures/MainMenu.nib/classes.nib +32 -0
  84. data/test/fixtures/MainMenu.nib/info.nib +18 -0
  85. data/test/fixtures/MainMenu.nib/keyedobjects.nib +0 -0
  86. data/test/test_controller_generator.rb +75 -0
  87. data/test/test_core_ext.rb +15 -0
  88. data/test/test_document_model_generator.rb +64 -0
  89. data/test/test_generator_helper.rb +20 -0
  90. data/test/test_helper.rb +13 -0
  91. data/test/test_info_plist.rb +31 -0
  92. data/test/test_nib.rb +73 -0
  93. data/test/test_notifications.rb +75 -0
  94. data/test/test_objc_core_ext.rb +37 -0
  95. data/test/test_rc_app.rb +63 -0
  96. data/test/test_rc_document.rb +18 -0
  97. data/test/test_rc_window_controller.rb +13 -0
  98. data/test/test_rucola.rb +11 -0
  99. data/test/test_rucola_generator.rb +87 -0
  100. data/test/test_window_controller_generator.rb +50 -0
  101. data/test/test_xcode.rb +128 -0
  102. data/website/index.html +199 -0
  103. data/website/index.txt +126 -0
  104. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  105. data/website/stylesheets/screen.css +138 -0
  106. data/website/template.rhtml +48 -0
  107. metadata +189 -0
@@ -0,0 +1,99 @@
1
+ require 'osx/cocoa'
2
+ require 'fileutils'
3
+
4
+ module Rucola
5
+ module Nib
6
+
7
+ def self.backup(path)
8
+ nib = File.dirname(path)
9
+ nib_name = File.basename(nib)
10
+ backup = "/tmp/#{nib_name}.bak"
11
+ unless $TESTING
12
+ puts "\n========================================================================="
13
+ puts "Backing up #{nib} to #{backup}"
14
+ puts "Please retrieve that one if for some reason the nib was damaged!"
15
+ puts "=========================================================================\n\n"
16
+ end
17
+ FileUtils.rm_rf(backup) if File.exists?(backup)
18
+ FileUtils.cp_r(nib, backup)
19
+ end
20
+
21
+ class Classes
22
+ attr_reader :data
23
+
24
+ def self.open(classes_nib_path)
25
+ new(classes_nib_path)
26
+ end
27
+
28
+ def initialize(classes_nib_path)
29
+ @path = File.expand_path(classes_nib_path)
30
+ @data = OSX::NSDictionary.dictionaryWithContentsOfFile(@path)
31
+ end
32
+
33
+ def classes
34
+ @data['IBClasses']
35
+ end
36
+
37
+ def add_class(class_name)
38
+ classes.push({
39
+ 'CLASS' => class_name,
40
+ 'SUPERCLASS' => 'NSObject',
41
+ 'LANGUAGE' => 'ObjC'
42
+ })
43
+ end
44
+
45
+ def has_class?(class_name)
46
+ classes.any? { |klass| klass['CLASS'] == class_name }
47
+ end
48
+
49
+ def save
50
+ Rucola::Nib.backup(@path)
51
+ @data.writeToFile_atomically(@path, true)
52
+ end
53
+
54
+ end
55
+
56
+ class KeyedObjects
57
+ attr_reader :data
58
+
59
+ def self.open(path)
60
+ new(path)
61
+ end
62
+
63
+ def initialize(path)
64
+ @path = path
65
+ @data, format, error = OSX::NSPropertyListSerialization.propertyListFromData_mutabilityOption_format_errorDescription(
66
+ OSX::NSData.dataWithContentsOfFile(@path),
67
+ OSX::NSPropertyListMutableContainersAndLeaves
68
+ )
69
+ end
70
+
71
+ def files_owner_class
72
+ @data['$objects'][3]
73
+ end
74
+
75
+ # Changes the custom class of the File's Owner.
76
+ def change_files_owner_class(new_class)
77
+ # With a fresh nib the name of the custom class always appears as the 4th object
78
+ # in the $objects array. But this might not always be the case. At least for
79
+ # setting the initial custom class with a known nib, such as the one we use
80
+ # as a template, will work.
81
+ @data['$objects'][3] = new_class
82
+ end
83
+
84
+ # Save the keyedobjects.nib back to the original path.
85
+ # Or alternatively pass it a new path.
86
+ def save(new_path = nil)
87
+ new_data, new_error = OSX::NSPropertyListSerialization.dataFromPropertyList_format_errorDescription(@data, OSX::NSPropertyListBinaryFormat_v1_0)
88
+
89
+ Rucola::Nib.backup(@path)
90
+
91
+ path = (new_path.nil? ? @path : new_path)
92
+ dirname = File.dirname(path)
93
+ FileUtils.mkdir_p(dirname) unless File.exists?(dirname)
94
+
95
+ new_data.writeToFile_atomically(path, true)
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,9 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'rucola_support/rc_app'
5
+ require 'rucola_support/initialize_hooks'
6
+ require 'rucola_support/core_ext'
7
+ require 'rucola_support/controllers'
8
+ require 'rucola_support/models'
9
+ require 'rucola/rucola_support/notifications'
@@ -0,0 +1,2 @@
1
+ require 'rucola_support/controllers/rc_controller'
2
+ require 'rucola_support/controllers/rc_window_controller'
@@ -0,0 +1,7 @@
1
+ require 'osx/cocoa'
2
+
3
+ module Rucola
4
+ class RCController < OSX::NSObject
5
+ include Rucola::RCApp
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ require 'osx/cocoa'
2
+
3
+ module Rucola
4
+ class RCWindowController < OSX::NSWindowController
5
+ # Loads the nib that corresponds to this subclass.
6
+ # So for instance a class PreferencesWindowController,
7
+ # will look for a nib in: app/views/Preferences.nib
8
+ def init
9
+ self if self.initWithWindowNibPath_owner(Rucola::RCApp.path_for_view(self), self)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,2 @@
1
+ require 'rucola_support/core_ext/ruby'
2
+ require 'rucola_support/core_ext/objc'
@@ -0,0 +1,4 @@
1
+ Dir[File.dirname(__FILE__) + "/objc/*.rb"].sort.each do |path|
2
+ filename = File.basename(path)
3
+ require "rucola_support/core_ext/objc/#{filename}"
4
+ end
@@ -0,0 +1,22 @@
1
+ require 'osx/cocoa'
2
+
3
+ class OSX::NSObject
4
+ class << self
5
+ alias_method :_inherited_before_rucola, :inherited
6
+
7
+ def inherited(subclass)
8
+ # First let RubyCocoa do it's magic!
9
+ _inherited_before_rucola(subclass)
10
+
11
+ # We only want to mixin modules into subclasses of classes
12
+ # that start with 'Rucola::RC'.
13
+ class_prefix = subclass.superclass.name.to_s[0..9]
14
+ if class_prefix == 'Rucola::RC'
15
+ subclass.class_eval do
16
+ include Rucola::InitializeHooks
17
+ include Rucola::Notifications
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,4 @@
1
+ Dir[File.dirname(__FILE__) + "/ruby/*.rb"].sort.each do |path|
2
+ filename = File.basename(path)
3
+ require "rucola_support/core_ext/ruby/#{filename}"
4
+ end
@@ -0,0 +1,21 @@
1
+ class String
2
+ # These 2 methods are taken blatently from the Merb string extensions.
3
+
4
+ # "FooBar".snake_case #=> "foo_bar"
5
+ def snake_case
6
+ gsub(/\B[A-Z]/, '_\&').downcase
7
+ end
8
+
9
+ # "foo_bar".camel_case #=> "FooBar"
10
+ def camel_case
11
+ if self.include? '_'
12
+ self.split('_').map{|e| e.capitalize}.join
13
+ else
14
+ unless self =~ (/^[A-Z]/)
15
+ self.capitalize
16
+ else
17
+ self
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ module Rucola
2
+ module InitializeHooks
3
+ module ClassMethods
4
+ # Adds the given proc to the initialize hooks queue,
5
+ # which will be ran after object initialization.
6
+ def _rucola_register_initialize_hook(hook)
7
+ (@_rucola_initialize_hooks ||= []).push hook
8
+ end
9
+ end
10
+
11
+ def initialize
12
+ # get the hooks, if they exist let them all do their after initialization work.
13
+ hooks = self.class.instance_variable_get(:@_rucola_initialize_hooks)
14
+ hooks.each { |hook| self.instance_eval(&hook) } unless hooks.nil?
15
+ end
16
+
17
+ def self.included(base) # :nodoc
18
+ base.extend(ClassMethods)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1 @@
1
+ require 'rucola_support/models/rc_document'
@@ -0,0 +1,10 @@
1
+ require 'osx/cocoa'
2
+
3
+ module Rucola
4
+ class RCDocument < OSX::NSDocument
5
+ def makeWindowControllers
6
+ @@_window_controller ||= Object.const_get("#{self.class.name.to_s.camel_case}Controller")
7
+ addWindowController @@_window_controller.alloc.init
8
+ end
9
+ end
10
+ end
@@ -0,0 +1 @@
1
+ require 'rucola_support/notifications/notifications'
@@ -0,0 +1,146 @@
1
+ require 'osx/cocoa'
2
+
3
+ module Rucola
4
+ module Notifications
5
+ # This Notifications module will add a class method called +notify_on+, which registers
6
+ # your object for the given notification and executes the given block when the
7
+ # notification is posted to the OSX::NSNotificationCenter.defaultCenter.
8
+ #
9
+ # class FooController < OSX::NSObject
10
+ #
11
+ # notify_on OSX::NSApplicationDidFinishLaunchingNotification do |notification|
12
+ # puts "Application did finish launching."
13
+ # p notification
14
+ # end
15
+ #
16
+ # # code
17
+ #
18
+ # end
19
+ #
20
+ # In addition to notify_on, you also get a method called notify which allows you to specify methods
21
+ # to be invoked when a notification is posted.
22
+ #
23
+ # class FooController < OSX::NSObject
24
+ # notify :some_method, :when => :application_did_finish_launching
25
+ #
26
+ # def some_method(notification)
27
+ # puts "Application finished launching"
28
+ # end
29
+ # end
30
+
31
+
32
+ module ClassMethods
33
+ # Add prefix shortcuts as a hash.
34
+ #
35
+ # class FooController < OSX::NSObject
36
+ # acts_as_notifiable
37
+ #
38
+ # # This will make sure that :win_ is expanded to :window_ in the notifications that you register.
39
+ # notification_prefix :win => :window
40
+ #
41
+ # notify_on :win_did_become_key do |notification|
42
+ # # code
43
+ # end
44
+ # end
45
+ #
46
+ # By default the shortcut <tt>{ :app => :application }</tt> is registered.
47
+ def notification_prefix(prefixes)
48
+ (@_notification_prefixes ||= {}).merge! prefixes
49
+ end
50
+
51
+ # Registers the object for the given notification and executes the given block when the
52
+ # notification is posted to the OSX::NSNotificationCenter.defaultCenter.
53
+ #
54
+ # class FooController < OSX::NSObject
55
+ #
56
+ # notify_on OSX::NSApplicationDidFinishLaunchingNotification do |notification|
57
+ # puts "Application did finish launching."
58
+ # p notification
59
+ # end
60
+ #
61
+ # # code
62
+ #
63
+ # end
64
+ #
65
+ # You can also pass it a symbol as +notification+ in which case it will be exapnded.
66
+ # It will first check if the name + 'Notification' exists, if not it will prepend 'NS'.
67
+ # So :application_did_finish_launching becomes 'NSApplicationDidFinishLaunchingNotification'.
68
+ #
69
+ # You can even register shortcut prefixes. See +notification_prefix+.
70
+ def notify_on(notification, &block)
71
+ notification_name = notification
72
+
73
+ if notification_name.is_a? Symbol
74
+ notification_name = notification_name.to_s
75
+
76
+ # first check if this notification_name uses a shortcut prefix
77
+ splitted_notification_name = notification_name.split('_')
78
+ prefix = splitted_notification_name.first.to_sym
79
+ if @_notification_prefixes and @_notification_prefixes.has_key? prefix
80
+ notification_name = @_notification_prefixes[prefix].to_s << '_' << splitted_notification_name[1..-1].join('_')
81
+ end
82
+
83
+ begin
84
+ # try with only Notification appended
85
+ notification_name = notification_name.camel_case << 'Notification'
86
+ OSX.const_get(notification_name)
87
+ rescue NameError
88
+ begin
89
+ # then try with NS prepended
90
+ notification_name = 'NS' << notification_name
91
+ OSX.const_get(notification_name)
92
+ rescue NameError
93
+ raise NameError, "Unable to find the notification corresponding to :#{notification}"
94
+ end
95
+ end
96
+ end
97
+
98
+ method_name = "_handle_#{notification_name.snake_case}".to_sym
99
+
100
+ # define the handle method
101
+ class_eval do
102
+ define_method(method_name, &block)
103
+ end
104
+
105
+ @_registered_notifications ||= {}
106
+ @_registered_notifications[notification_name.to_s] = method_name
107
+ end
108
+
109
+ # Register a callback when a notification is posted.
110
+ #
111
+ # class FooController < OSX::NSObject
112
+ # notify :some_method, :when => :application_did_finish_launching
113
+ #
114
+ # def some_method(notification)
115
+ # puts "Application finished launching"
116
+ # end
117
+ # end
118
+ #
119
+ def notify(method_to_notify, options = {})
120
+ @_registered_notifications ||= {}
121
+ @_registered_notifications[options[:when]] = method_to_notify
122
+ end
123
+
124
+ end
125
+
126
+ def self.included(base) # :nodoc
127
+ base.extend(ClassMethods)
128
+
129
+ # register the initialize hook which actually registers the notifications for the instance.
130
+ base._rucola_register_initialize_hook lambda { self._register_notifications }
131
+
132
+ # register default shortcut
133
+ base.notification_prefix :app => :application
134
+ end
135
+
136
+ # this instance method is called after object initialization by the initialize hook
137
+ def _register_notifications # :nodoc:
138
+ notifications = self.class.instance_variable_get(:@_registered_notifications)
139
+ return if notifications.nil?
140
+ center = OSX::NSNotificationCenter.defaultCenter
141
+ notifications.each do |notification_name, notification_handler|
142
+ center.addObserver_selector_name_object(self, notification_handler, notification_name, nil)
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,101 @@
1
+ module Rucola
2
+ module RCApp
3
+ # Returns the path to the current source root of the application.
4
+ #
5
+ # So in debug & test mode this will point to your development source root.
6
+ #
7
+ # In release however this will point to the equivalent of:
8
+ # <tt>NSBundle.mainBundle.resourcePath</tt>
9
+ def root_path
10
+ RUBYCOCOA_ROOT.to_s
11
+ end
12
+ module_function :root_path
13
+
14
+ # Returns the path to the current used app/controllers dir.
15
+ #
16
+ # So in debug & test mode this will point to your development
17
+ # source_root/app/controllers.
18
+ #
19
+ # In release however this will point to the equivalent of:
20
+ # NSBundle.mainBundle.resourcePath + 'app/controllers'
21
+ def controllers_path
22
+ (RUBYCOCOA_ROOT + 'app/controllers').to_s
23
+ end
24
+ module_function :controllers_path
25
+
26
+ # Returns the path to the current used app/models dir.
27
+ #
28
+ # So in debug & test mode this will point to your development
29
+ # source_root/app/models.
30
+ #
31
+ # In release however this will point to the equivalent of:
32
+ # NSBundle.mainBundle.resourcePath + 'app/models'
33
+ def models_path
34
+ (RUBYCOCOA_ROOT + 'app/models').to_s
35
+ end
36
+ module_function :models_path
37
+
38
+ # Returns the path to the current used app/assets dir.
39
+ #
40
+ # So in debug & test mode this will point to your development
41
+ # source_root/app/assets.
42
+ #
43
+ # In release however this will point to the equivalent of:
44
+ # NSBundle.mainBundle.resourcePath + 'app/assets'
45
+ def assets_path
46
+ (RUBYCOCOA_ROOT + 'app/assets').to_s
47
+ end
48
+ module_function :assets_path
49
+
50
+ # Returns the path to the current used app/views dir.
51
+ #
52
+ # So in debug & test mode this will point to your development
53
+ # source_root/app/views.
54
+ #
55
+ # In release however this will point to the equivalent of:
56
+ # NSBundle.mainBundle.resourcePath + 'app/views'
57
+ def views_path
58
+ (RUBYCOCOA_ROOT + 'app/views').to_s
59
+ end
60
+ module_function :views_path
61
+
62
+ # Returns the path to a +controller+ file.
63
+ #
64
+ # Rucola::RCApp.path_for_controller(ApplicationController) #=> 'root/app/controllers/application_controller.rb'
65
+ def path_for_controller(controller)
66
+ "#{controllers_path}/#{controller.name.to_s.snake_case}.rb"
67
+ end
68
+ module_function :path_for_controller
69
+
70
+ # Returns the path to a +model+ file.
71
+ #
72
+ # Rucola::RCApp.path_for_model(Person) #=> 'root/app/models/person.rb'
73
+ def path_for_model(model)
74
+ "#{models_path}/#{model.name.to_s.snake_case}.rb"
75
+ end
76
+ module_function :path_for_model
77
+
78
+ # Returns the path to a +view+ file.
79
+ #
80
+ # Rucola::RCApp.path_for_controller('preferences') #=> 'root/app/views/Preferences.nib'
81
+ # Rucola::RCApp.path_for_controller('Preferences') #=> 'root/app/views/Preferences.nib'
82
+ #
83
+ # Rucola::RCApp.path_for_controller(PreferencesController) #=> 'root/app/views/Preferences.nib'
84
+ # Rucola::RCApp.path_for_controller(PreferencesController.alloc.init) #=> 'root/app/views/Preferences.nib'
85
+ def path_for_view(view)
86
+ view = view.class unless view.is_a?(String) or view.is_a?(Class)
87
+ view = view.name.to_s.sub(/Controller$/, '') if view.is_a? Class
88
+ "#{views_path}/#{view.camel_case}.nib"
89
+ end
90
+ module_function :path_for_view
91
+
92
+ # Returns the path to an +asset+ file.
93
+ #
94
+ # Rucola::RCApp.path_for_asset('somefile.png') #=> 'root/app/assets/somefile.png'
95
+ def path_for_asset(asset)
96
+ "#{assets_path}/#{asset}"
97
+ end
98
+ module_function :path_for_asset
99
+
100
+ end
101
+ end