public
Fork of technoweenie/mephisto
Description: A mirror of the mephisto code-base
Homepage: http://mephistoblog.com/
Clone URL: git://github.com/b3b0p/mephisto.git
mephisto / vendor / plugins / engines / lib / engines / plugin.rb
100644 126 lines (107 sloc) 4.477 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# An instance of Plugin is created for each plugin loaded by Rails, and
# stored in the <tt>Engines.plugins</tt> PluginList
# (see Engines::RailsExtensions::RailsInitializer for more details).
#
# Engines.plugins[:plugin_name]
#
# If this plugin contains paths in directories other than <tt>app/controllers</tt>,
# <tt>app/helpers</tt>, <tt>app/models</tt> and <tt>components</tt>, authors can
# declare this by adding extra paths to #code_paths:
#
# Rails.plugin[:my_plugin].code_paths << "app/sweepers" << "vendor/my_lib"
#
# Other properties of the Plugin instance can also be set.
module Engines
  class Plugin < Rails::Plugin
    # Plugins can add code paths to this attribute in init.rb if they
    # need plugin directories to be added to the load path, i.e.
    #
    # plugin.code_paths << 'app/other_classes'
    #
    # Defaults to ["app/controllers", "app/helpers", "app/models", "components"]
    attr_accessor :code_paths
 
    # Plugins can add paths to this attribute in init.rb if they need
    # controllers loaded from additional locations.
    attr_accessor :controller_paths
  
    # The directory in this plugin to mirror into the shared directory
    # under +public+.
    #
    # Defaults to "assets" (see default_public_directory).
    attr_accessor :public_directory
    
    protected
  
      # The default set of code paths which will be added to $LOAD_PATH
      # and Dependencies.load_paths
      def default_code_paths
        # lib will actually be removed from the load paths when we call
        # uniq! in #inject_into_load_paths, but it's important to keep it
        # around (for the documentation tasks, for instance).
        %w(app/controllers app/helpers app/models components lib)
      end
    
      # The default set of code paths which will be added to the routing system
      def default_controller_paths
        %w(app/controllers components)
      end
 
      # Attempts to detect the directory to use for public files.
      # If +assets+ exists in the plugin, this will be used. If +assets+ is missing
      # but +public+ is found, +public+ will be used.
      def default_public_directory
        Engines.select_existing_paths(%w(assets public).map { |p| File.join(directory, p) }).first
      end
    
    public
  
    def initialize(directory)
      super directory
      @code_paths = default_code_paths
      @controller_paths = default_controller_paths
      @public_directory = default_public_directory
    end
  
    # Returns a list of paths this plugin wishes to make available in $LOAD_PATH
    #
    # Overwrites the correspondend method in the superclass
    def load_paths
      report_nonexistant_or_empty_plugin! unless valid?
      select_existing_paths :code_paths
    end
    
    # Extends the superclass' load method to additionally mirror public assets
    def load(initializer)
      return if loaded?
      super initializer
      add_plugin_view_paths
      Assets.mirror_files_for(self)
    end
  
    # for code_paths and controller_paths select those paths that actually
    # exist in the plugin's directory
    def select_existing_paths(name)
      Engines.select_existing_paths(self.send(name).map { |p| File.join(directory, p) })
    end
 
    def add_plugin_view_paths
      view_path = File.join(directory, 'app', 'views')
      if File.exist?(view_path)
        ActionController::Base.view_paths.insert(1, view_path) # push it just underneath the app
      end
    end
 
    # The path to this plugin's public files
    def public_asset_directory
      "#{File.basename(Engines.public_directory)}/#{name}"
    end
    
    # The path to this plugin's routes file
    def routes_path
      File.join(directory, "routes.rb")
    end
 
    # The directory containing this plugin's migrations (<tt>plugin/db/migrate</tt>)
    def migration_directory
      File.join(self.directory, 'db', 'migrate')
    end
  
    # Returns the version number of the latest migration for this plugin. Returns
    # nil if this plugin has no migrations.
    def latest_migration
      migrations = Dir[migration_directory+"/*.rb"]
      return nil if migrations.empty?
      migrations.map { |p| File.basename(p) }.sort.last.match(/0*(\d+)\_/)[1].to_i
    end
  
    # Migrate this plugin to the given version. See Engines::Plugin::Migrator for more
    # information.
    def migrate(version = nil)
      Engines::Plugin::Migrator.migrate_plugin(self, version)
    end
  end
end