comparison vendor/plugins/engines/lib/.svn/text-base/engines.rb.svn-base @ 0:513646585e45

* Import Redmine trunk SVN rev 3859
author Chris Cannam
date Fri, 23 Jul 2010 15:52:44 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:513646585e45
1 require 'active_support'
2 require File.join(File.dirname(__FILE__), 'engines/plugin')
3 require File.join(File.dirname(__FILE__), 'engines/plugin/list')
4 require File.join(File.dirname(__FILE__), 'engines/plugin/loader')
5 require File.join(File.dirname(__FILE__), 'engines/plugin/locator')
6 require File.join(File.dirname(__FILE__), 'engines/assets')
7 require File.join(File.dirname(__FILE__), 'engines/rails_extensions/rails')
8
9 # == Parameters
10 #
11 # The Engines module has a number of public configuration parameters:
12 #
13 # [+public_directory+] The directory into which plugin assets should be
14 # mirrored. Defaults to <tt>RAILS_ROOT/public/plugin_assets</tt>.
15 # [+schema_info_table+] The table to use when storing plugin migration
16 # version information. Defaults to +plugin_schema_info+.
17 #
18 # Additionally, there are a few flags which control the behaviour of
19 # some of the features the engines plugin adds to Rails:
20 #
21 # [+disable_application_view_loading+] A boolean flag determining whether
22 # or not views should be loaded from
23 # the main <tt>app/views</tt> directory.
24 # Defaults to false; probably only
25 # useful when testing your plugin.
26 # [+disable_application_code_loading+] A boolean flag determining whether
27 # or not to load controllers/helpers
28 # from the main +app+ directory,
29 # if corresponding code exists within
30 # a plugin. Defaults to false; again,
31 # probably only useful when testing
32 # your plugin.
33 # [+disable_code_mixing+] A boolean flag indicating whether all plugin
34 # copies of a particular controller/helper should
35 # be loaded and allowed to override each other,
36 # or if the first matching file should be loaded
37 # instead. Defaults to false.
38 #
39 module Engines
40 # The set of all loaded plugins
41 mattr_accessor :plugins
42 self.plugins = Engines::Plugin::List.new
43
44 # List of extensions to load, can be changed in init.rb before calling Engines.init
45 mattr_accessor :rails_extensions
46 self.rails_extensions = %w(asset_helpers form_tag_helpers migrations dependencies)
47
48 # The name of the public directory to mirror public engine assets into.
49 # Defaults to <tt>RAILS_ROOT/public/plugin_assets</tt>.
50 mattr_accessor :public_directory
51 self.public_directory = File.join(RAILS_ROOT, 'public', 'plugin_assets')
52
53 # The table in which to store plugin schema information. Defaults to
54 # "plugin_schema_info".
55 mattr_accessor :schema_info_table
56 self.schema_info_table = "plugin_schema_info"
57
58 #--
59 # These attributes control the behaviour of the engines extensions
60 #++
61
62 # Set this to true if views should *only* be loaded from plugins
63 mattr_accessor :disable_application_view_loading
64 self.disable_application_view_loading = false
65
66 # Set this to true if controller/helper code shouldn't be loaded
67 # from the application
68 mattr_accessor :disable_application_code_loading
69 self.disable_application_code_loading = false
70
71 # Set this to true if code should not be mixed (i.e. it will be loaded
72 # from the first valid path on $LOAD_PATH)
73 mattr_accessor :disable_code_mixing
74 self.disable_code_mixing = false
75
76 # This is used to determine which files are candidates for the "code
77 # mixing" feature that the engines plugin provides, where classes from
78 # plugins can be loaded, and then code from the application loaded
79 # on top of that code to override certain methods.
80 mattr_accessor :code_mixing_file_types
81 self.code_mixing_file_types = %w(controller helper)
82
83 class << self
84 def init(initializer)
85 load_extensions
86 Engines::Assets.initialize_base_public_directory
87 end
88
89 def logger
90 RAILS_DEFAULT_LOGGER
91 end
92
93 def load_extensions
94 rails_extensions.each { |name| require "engines/rails_extensions/#{name}" }
95 # load the testing extensions, if we are in the test environment.
96 require "engines/testing" if RAILS_ENV == "test"
97 end
98
99 def select_existing_paths(paths)
100 paths.select { |path| File.directory?(path) }
101 end
102
103 # The engines plugin will, by default, mix code from controllers and helpers,
104 # allowing application code to override specific methods in the corresponding
105 # controller or helper classes and modules. However, if other file types should
106 # also be mixed like this, they can be added by calling this method. For example,
107 # if you want to include "things" within your plugin and override them from
108 # your applications, you should use the following layout:
109 #
110 # app/
111 # +-- things/
112 # | +-- one_thing.rb
113 # | +-- another_thing.rb
114 # ...
115 # vendor/
116 # +-- plugins/
117 # +-- my_plugin/
118 # +-- app/
119 # +-- things/
120 # +-- one_thing.rb
121 # +-- another_thing.rb
122 #
123 # The important point here is that your "things" are named <whatever>_thing.rb,
124 # and that they are placed within plugin/app/things (the pluralized form of 'thing').
125 #
126 # It's important to note that you'll also want to ensure that the "things" are
127 # on your load path by including them in Rails load path mechanism, e.g. in init.rb:
128 #
129 # ActiveSupport::Dependencies.load_paths << File.join(File.dirname(__FILE__), 'app', 'things'))
130 #
131 def mix_code_from(*types)
132 self.code_mixing_file_types += types.map { |x| x.to_s.singularize }
133 end
134
135 # A general purpose method to mirror a directory (+source+) into a destination
136 # directory, including all files and subdirectories. Files will not be mirrored
137 # if they are identical already (checked via FileUtils#identical?).
138 def mirror_files_from(source, destination)
139 return unless File.directory?(source)
140
141 # TODO: use Rake::FileList#pathmap?
142 source_files = Dir[source + "/**/*"]
143 source_dirs = source_files.select { |d| File.directory?(d) }
144 source_files -= source_dirs
145
146 unless source_files.empty?
147 base_target_dir = File.join(destination, File.dirname(source_files.first).gsub(source, ''))
148 FileUtils.mkdir_p(base_target_dir)
149 end
150
151 source_dirs.each do |dir|
152 # strip down these paths so we have simple, relative paths we can
153 # add to the destination
154 target_dir = File.join(destination, dir.gsub(source, ''))
155 begin
156 FileUtils.mkdir_p(target_dir)
157 rescue Exception => e
158 raise "Could not create directory #{target_dir}: \n" + e
159 end
160 end
161
162 source_files.each do |file|
163 begin
164 target = File.join(destination, file.gsub(source, ''))
165 unless File.exist?(target) && FileUtils.identical?(file, target)
166 FileUtils.cp(file, target)
167 end
168 rescue Exception => e
169 raise "Could not copy #{file} to #{target}: \n" + e
170 end
171 end
172 end
173 end
174 end