fixes for plugins in gems/plugins/

fixes CNVS-15130

allows access to a plugin's models (during truncation for specs),
migrations, assets, periodic jobs, prepended routes, api routes (during
documentation), flagging as reloadable, spec docs, etc. once the plugin
lives in gems/plugins/ instead of vendor/plugins/

Change-Id: Ia7a2fdf5ad6258c5de962e982b6bf62ebaf4d075
Reviewed-on: https://gerrit.instructure.com/42287
Reviewed-by: Rob Orton <rob@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Product-Review: Jacob Fugal <jacob@instructure.com>
This commit is contained in:
Jacob Fugal 2014-10-03 08:42:54 -06:00
parent 7a5463f0d3
commit 8d29be0dc6
10 changed files with 27 additions and 19 deletions

View File

@ -52,6 +52,7 @@ class ActiveRecord::Base
@from_files ||= Dir[
"#{Rails.root}/app/models/**/*.rb",
"#{Rails.root}/vendor/plugins/*/app/models/**/*.rb",
"#{Rails.root}/gems/plugins/*/app/models/**/*.rb",
].sort.collect { |file|
model = file.sub(%r{.*/app/models/(.*)\.rb$}, '\1').camelize.constantize
next unless model < ActiveRecord::Base
@ -1394,6 +1395,7 @@ class ActiveRecord::Migrator
end
ActiveRecord::Migrator.migrations_paths.concat Dir[Rails.root.join('vendor', 'plugins', '*', 'db', 'migrate')]
ActiveRecord::Migrator.migrations_paths.concat Dir[Rails.root.join('gems', 'plugins', '*', 'db', 'migrate')]
ActiveRecord::ConnectionAdapters::SchemaStatements.class_eval do
def add_index_with_length_raise(table_name, column_name, options = {})
unless options[:name].to_s =~ /^temp_/

View File

@ -9,9 +9,9 @@ def maintain_plugin_symlinks(local_path, plugin_path=nil)
end
# create new ones
Dir.glob("vendor/plugins/*/#{plugin_path}").each do |plugin_dir|
Dir.glob("{gems,vendor}/plugins/*/#{plugin_path}").each do |plugin_dir|
FileUtils.makedirs("#{local_path}/plugins") unless File.exists?("#{local_path}/plugins")
plugin = plugin_dir.gsub(%r{^vendor/plugins/(.*)/#{plugin_path}$}, '\1')
plugin = plugin_dir.gsub(%r{^(?:gems|vendor)/plugins/(.*)/#{plugin_path}$}, '\1')
source = "#{local_path}/plugins/#{plugin}"
target = "#{local_path.gsub(%r{[^/]+}, '..')}/../#{plugin_dir}"
unless File.symlink?(source) && File.readlink(source) == target

View File

@ -1,7 +1,7 @@
full_path_glob = '(/*full_path)'
# allow plugins to prepend routes
Dir["vendor/plugins/*/config/pre_routes.rb"].each { |pre_routes|
Dir["{gems,vendor}/plugins/*/config/pre_routes.rb"].each { |pre_routes|
load pre_routes
}

View File

@ -25,7 +25,7 @@ CanvasRails::Application.routes.disable_clear_and_finalize = true
# load routing files, including those in plugins
require 'config/routes'
Dir.glob('vendor/plugins/*/config/routes.rb').each do |plugin_routes|
Dir.glob('{gems,vendor}/plugins/*/config/routes.rb').each do |plugin_routes|
require plugin_routes.gsub(/\.rb$/, '')
end

View File

@ -129,11 +129,13 @@ module Canvas
# can be called by plugins to allow reloading of that plugin in dev mode
# pass in the path to the plugin directory
# e.g., in the vendor/plugins/<plugin_name>/init.rb:
# e.g., in the vendor/plugins/<plugin_name>/init.rb or
# gems/plugins/<plugin_name>/lib/<plugin_name>/engine.rb:
# Canvas.reloadable_plugin(File.dirname(__FILE__))
def self.reloadable_plugin(dirname)
return unless Rails.env.development?
base_path = File.expand_path(dirname)
base_path.gsub(%r{/lib/[^/]*$}, '')
ActiveSupport::Dependencies.autoload_once_paths.reject! { |p|
p[0, base_path.length] == base_path
}

View File

@ -1,7 +1,7 @@
# pull in the bundles from the various plugins' config/assets.yml extension
# files and combine them under a plugins.<plugin> dictionary. so e.g. the
# stylesheets bundles from vendor/plugins/myplugin/config/assets.yml will
# be added under
# stylesheets bundles from {gems,vendor}/plugins/myplugin/config/assets.yml
# will be added under
#
# plugins:
# myplugin:
@ -33,8 +33,8 @@ class PluginAssets
def initialize( options = {} )
@anchors = { 'stylesheets' => {} }
@asset_matcher = options[:asset_matcher] || 'vendor/plugins/*/config/assets.yml'
@plugin_matcher = options[:plugin_matcher] || %r{^vendor/plugins/(.*)/config/assets\.yml$}
@asset_matcher = options[:asset_matcher] || '{gems,vendor}/plugins/*/config/assets.yml'
@plugin_matcher = options[:plugin_matcher] || %r{^(?:gems|vendor)/plugins/(.*)/config/assets\.yml$}
end
# this is the yaml that can be dropped into the top of assets.yml

View File

@ -22,8 +22,8 @@ module Canvas
# Foo so you can do stuff to it anytime somebody requires "foo" as
# per usual.
GLOB = "vendor/plugins/*/app/coffeescripts/extensions"
REGEXP = Regexp.new GLOB.gsub('*', '([^/]*)')
GLOB = "{gems,vendor}/plugins/*/app/coffeescripts/extensions"
REGEXP = %r{(?:gems|vendor)/plugins/([^/]*)/app/coffeescripts/extensions}
# added to require config paths so that when you require an
# extended module, you instead get the glue module which gives you

View File

@ -16,8 +16,8 @@ namespace :doc do
t.before = proc { FileUtils.rm_rf(API_DOC_DIR) }
t.files = %w[
app/controllers/**/*.rb
vendor/plugins/*/app/controllers/*.rb
vendor/plugins/*/lib/*.rb
{gems,vendor}/plugins/*/app/controllers/*.rb
{gems,vendor}/plugins/*/lib/*.rb
]
t.options = %W[

View File

@ -20,7 +20,7 @@ unless Rails.env.production? || ARGV.any? { |a| a =~ /\Agems/ }
#{"*" * 80}
* You are trying to run an rspec rake task defined in
* #{__FILE__},
* but rspec can not be found in vendor/gems, vendor/plugins or system gems.
* but rspec can not be found in vendor/gems or system gems.
#{"*" * 80}
MSG
end
@ -96,7 +96,7 @@ unless Rails.env.production? || ARGV.any? { |a| a =~ /\Agems/ }
desc "Print Specdoc for all plugin examples"
klass.new(:plugin_doc) do |t|
t.spec_opts = ["--format", "specdoc", "--dry-run"]
t.send(spec_files_attr, FileList['vendor/plugins/**/spec/**/*/*_spec.rb'].exclude('vendor/plugins/rspec/*'))
t.send(spec_files_attr, FileList['{gems,vendor}/plugins/**/spec/**/*/*_spec.rb'].exclude('vendor/plugins/rspec/*'))
end
[:models, :services, :controllers, :views, :helpers, :lib, :selenium].each do |sub|
@ -107,7 +107,7 @@ unless Rails.env.production? || ARGV.any? { |a| a =~ /\Agems/ }
end
end
desc "Run the code examples in vendor/plugins (except RSpec's own)"
desc "Run the code examples in {gems,vendor}/plugins (except RSpec's own)"
klass.new(:coverage) do |t|
t.spec_opts = ['--options', "\"#{Rails.root}/spec/spec.opts\""]
t.send(spec_files_attr, FileList['{gems,vendor}/plugins/*/spec_canvas/**/*_spec.rb'].exclude(%r'spec_canvas/selenium') + FileList['spec/**/*_spec.rb'].exclude(%r'spec/selenium'))

View File

@ -17,12 +17,12 @@ describe PluginAssets do
describe '#asset_matcher' do
subject { super().asset_matcher }
it { is_expected.to eq 'vendor/plugins/*/config/assets.yml' }
it { is_expected.to eq '{gems,vendor}/plugins/*/config/assets.yml' }
end
describe '#plugin_matcher' do
subject { super().plugin_matcher }
it { is_expected.to eq %r{^vendor/plugins/(.*)/config/assets\.yml$} }
it { is_expected.to eq %r{^(?:gems|vendor)/plugins/(.*)/config/assets\.yml$} }
end
end
@ -120,10 +120,14 @@ describe PluginAssets do
end
describe '#plugin_name_for' do
it 'pulls the plugin name out of well formed paths' do
it 'pulls the plugin name out of well formed vendor/plugin paths' do
expect(plugin_assets.plugin_name_for('vendor/plugins/analytics/config/assets.yml')).to eq 'analytics'
end
it 'pulls the plugin name out of well formed gems/plugin paths' do
expect(plugin_assets.plugin_name_for('gems/plugins/analytics/config/assets.yml')).to eq 'analytics'
end
it 'errors on badly formed paths' do
expect { plugin_assets.plugin_name_for('bogus/path/blargh.yml') }.to raise_error(ArgumentError, 'must provide a valid plugin asset.yml path')
end