Skip to content

Commit

Permalink
Upgrade to latest development version of engines
Browse files Browse the repository at this point in the history
This is commit 4cb49974cc62e6e89c15b03d08bab3ba07f7213a from the
git://github.com/lazyatom/engines.git repository.  The released
version of engines doesn't seem to support Rails 2.2 at the
moment.

Note that the unit tests still won't run.
  • Loading branch information
emk committed Dec 4, 2008
1 parent 6aefe20 commit 1cda19e
Show file tree
Hide file tree
Showing 109 changed files with 1,263 additions and 169 deletions.
3 changes: 3 additions & 0 deletions vendor/plugins/engines/.gitignore
@@ -0,0 +1,3 @@
.DS_Store
test_app
doc
16 changes: 16 additions & 0 deletions vendor/plugins/engines/CHANGELOG
@@ -1,3 +1,19 @@
= EDGE

* Samuel Williams (http://www.oriontransfer.co.nz/):
Thanks to Tekin for his patches.
Updated migrations system to tie in more closely with the current rails mechanism.
Rake task for updating database schema info
rake db:migrate:upgrade_plugin_migrations
Please see http://engines.lighthouseapp.com/projects/10178-engines-plugin/tickets/17 for more information.

* Refactored the view loading to work with changes in Edge Rails

* Fixed integration of plugin migrations with the new, default timestamped migrations in Edge Rails

* Refactored tests into the plugin itself - the plugin can now generate its own test_app harness and run tests within it.


= 2.0.0 - (ANOTHER) MASSIVE INTERNAL REFACTORING

* Engines now conforms to the new plugin loading mechanism, delegating plugin load order and lots of other things to Rails itself.
Expand Down
2 changes: 1 addition & 1 deletion vendor/plugins/engines/MIT-LICENSE
@@ -1,4 +1,4 @@
Copyright (c) 2007 James Adam
Copyright (c) 2008 James Adam

The MIT License

Expand Down
24 changes: 22 additions & 2 deletions vendor/plugins/engines/README
Expand Up @@ -23,7 +23,7 @@ In addition to the regular set of plugin-supported files (lib, init.rb, tasks, g
Include these files in an <tt>app</tt> directory just like you would in a normal Rails application. If you need to override a method, view or partial, create the corresponding file in your main <tt>app</tt> directory and it will be used instead.

* Controllers & Helpers: See Engines::RailsExtensions::Dependencies for more information.
* Views: See Engines::RailsExtensions::Templates for more information.
* Views: now handled almost entirely by ActionView itself (see Engines::Plugin#add_plugin_view_paths for more information)

=== Models

Expand Down Expand Up @@ -60,4 +60,24 @@ The engines plugin enhances and adds to the suite of default rake tasks for work

rake -T

to see the set of rake tasks available.
to see the set of rake tasks available.

= Testing the engines plugin itself

Because of the way the engines plugin modifies Rails, the simplest way to consistently test it against multiple versions is by generating a test harness application - a full Rails application that includes tests to verify the engines plugin behaviour in a real, running environment.

Run the tests like this:

$ cd engines
$ rake test

This will generate a test_app directory within the engines plugin (using the default 'rails' command), import tests and code into that application and then run the test suite.

If you wish to test against a specific version of Rails, run the tests with the RAILS environment variable set to the local directory containing your Rails checkout

$ rake test RAILS=/Users/james/Code/rails_edge_checkout

Alternatively, you can clone the latest version of Rails ('edge rails') from github like so:

$ rake test RAILS=edge

183 changes: 182 additions & 1 deletion vendor/plugins/engines/Rakefile
Expand Up @@ -29,4 +29,185 @@ task :cruise do
['db:migrate', 'test', 'test:plugins'].each do |t|
Rake::Task[t].invoke
end
end
end

task :clean => [:clobber_doc, "test:clean"]

namespace :test do

# Yields a block with STDOUT and STDERR silenced. If you *really* want
# to output something, the block is yielded with the original output
# streams, i.e.
#
# silence do |o, e|
# puts 'hello!' # no output produced
# o.puts 'hello!' # output on STDOUT
# end
#
# (based on silence_stream in ActiveSupport.)
def silence
yield(STDOUT, STDERR) if ENV['VERBOSE']
streams = [STDOUT, STDERR]
actual_stdout = STDOUT.dup
actual_stderr = STDERR.dup
streams.each do |s|
s.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null')
s.sync = true
end
yield actual_stdout, actual_stderr
ensure
STDOUT.reopen(actual_stdout)
STDERR.reopen(actual_stderr)
end

def test_app_dir
File.join(File.dirname(__FILE__), 'test_app')
end

def run(cmd)
cmd = cmd.join(" && ") if cmd.is_a?(Array)
system(cmd) || raise("failed running '#{cmd}'")
end

desc 'Remove the test application'
task :clean do
FileUtils.rm_r(test_app_dir) if File.exist?(test_app_dir)
end

desc 'Build the test rails application (use RAILS=[edge,<directory>] to test against specific version)'
task :generate_app do
silence do |out, err|
out.puts "> Creating test application at #{test_app_dir}"

if ENV['RAILS']
vendor_dir = File.join(test_app_dir, 'vendor')
FileUtils.mkdir_p vendor_dir

if ENV['RAILS'] == 'edge'
out.puts " Cloning Edge Rails from GitHub"
run "cd #{vendor_dir} && git clone --depth 1 git://github.com/rails/rails.git"
elsif ENV['RAILS'] =~ /\d\.\d\.\d/
if ENV['CURL']
out.puts " Cloning Rails Tag #{ENV['RAILS']} from GitHub using curl and tar"
run ["cd #{vendor_dir}",
"mkdir rails",
"cd rails",
"curl -s -L http://github.com/rails/rails/tarball/#{ENV['RAILS']} | tar xzv --strip-components 1"]
else
out.puts " Cloning Rails Tag #{ENV['RAILS']} from GitHub (can be slow - set CURL=true to use curl)"
run ["cd #{vendor_dir}",
"git clone git://github.com/rails/rails.git",
"cd rails",
"git pull",
"git checkout v#{ENV['RAILS']}"]
end
elsif File.exist?(ENV['RAILS'])
out.puts " Linking rails from #{ENV['RAILS']}"
run "cd #{vendor_dir} && ln -s #{ENV['RAILS']} rails"
else
raise "Couldn't build test application from '#{ENV['RAILS']}'"
end

out.puts " generating rails default directory structure"
run "ruby #{File.join(vendor_dir, 'rails', 'railties', 'bin', 'rails')} #{test_app_dir}"
else
version = `rails --version`.chomp.split.last
out.puts " building rails using the 'rails' command (rails version: #{version})"
run "rails #{test_app_dir}"
end

# get the database config and schema in place
out.puts " writing database.yml"
require 'yaml'
File.open(File.join(test_app_dir, 'config', 'database.yml'), 'w') do |f|
f.write(%w(development test).inject({}) do |h, env|
h[env] = {"adapter" => "sqlite3", "database" => "engines_#{env}.sqlite3"} ; h
end.to_yaml)
end
out.puts " installing exception_notification plugin"
run "cd #{test_app_dir} && ./script/plugin install exception_notification"
end
end

# We can't link the plugin, as it needs to be present for script/generate to find
# the plugin generator.
# TODO: find and +1/create issue for loading generators from symlinked plugins
desc 'Mirror the engines plugin into the test application'
task :copy_engines_plugin do
puts "> Copying engines plugin into test application"
engines_plugin = File.join(test_app_dir, "vendor", "plugins", "engines")
FileUtils.rm_r(engines_plugin) if File.exist?(engines_plugin)
FileUtils.mkdir_p(engines_plugin)
FileList["*"].exclude("test_app").each do |file|
FileUtils.cp_r(file, engines_plugin)
end
end

def insert_line(line, options)
line = line + "\n"
target_file = File.join(test_app_dir, options[:into])
lines = File.readlines(target_file)
return if lines.include?(line)

if options[:after]
if options[:after].is_a?(String)
after_line = options[:after] + "\n"
else
after_line = lines.find { |l| l =~ options[:after] }
raise "couldn't find a line matching #{options[:after].inspect} in #{target_file}" unless after_line
end
index = lines.index(after_line)
raise "couldn't find line '#{after_line}' in #{target_file}" unless index
lines.insert(index + 1, line)
else
lines << line
end
File.open(target_file, 'w') { |f| f.write lines.join }
end

def mirror_test_files(src, dest=nil)
destination_dir = File.join(*([test_app_dir, dest].compact))
FileUtils.cp_r(File.join(File.dirname(__FILE__), 'test', src), destination_dir)
end

desc 'Update the plugin and tests files in the test application from the plugin'
task :mirror_engine_files => [:test_app, :copy_engines_plugin] do
puts "> Modifying default config files to load engines plugin"
insert_line("require File.join(File.dirname(__FILE__), '../vendor/plugins/engines/boot')",
:into => 'config/environment.rb',
:after => "require File.join(File.dirname(__FILE__), 'boot')")

insert_line('map.from_plugin :test_routing', :into => 'config/routes.rb',
:after => /\AActionController::Routing::Routes/)

insert_line("require 'engines_test_helper'", :into => 'test/test_helper.rb')

puts "> Mirroring test application files into #{test_app_dir}"
mirror_test_files('app')
mirror_test_files('lib')
mirror_test_files('plugins', 'vendor')
mirror_test_files('unit', 'test')
mirror_test_files('functional', 'test')
end

desc 'Prepare the engines test environment'
task :test_app do
version_tag = File.join(test_app_dir, 'RAILS_VERSION')
existing_version = File.read(version_tag).chomp rescue 'unknown'
if existing_version == ENV['RAILS']
puts "> Reusing existing test application (#{ENV['RAILS']})"
else
puts "> Recreating test application"
Rake::Task["test:clean"].invoke
Rake::Task["test:generate_app"].invoke

File.open(version_tag, "w") { |f| f.write ENV['RAILS'] }
end
end
end

task :test => "test:mirror_engine_files" do
puts "> Loading the test application environment and running tests"
# We use exec here to replace the current running rake process
exec("cd #{test_app_dir} && rake db:migrate && rake")
end
2 changes: 1 addition & 1 deletion vendor/plugins/engines/about.yml
Expand Up @@ -4,4 +4,4 @@ homepage: http://www.rails-engines.org
summary: Enhances the plugin mechanism to perform more flexible sharing
description: The Rails Engines plugin allows the sharing of almost any type of code or asset that you could use in a Rails application, including controllers, models, stylesheets, and views.
license: MIT
version: 2.0.0-RC1
version: 2.1.0
5 changes: 2 additions & 3 deletions vendor/plugins/engines/boot.rb
@@ -1,8 +1,7 @@
begin
require 'rails/version'
unless Rails::VERSION::MAJOR >= 2 ||
(Rails::VERSION::MAJOR >= 1 && Rails::VERSION::MINOR >= 99)
raise "This version of the engines plugin requires Rails 2.0 or later!"
unless Rails::VERSION::MAJOR >= 2 && Rails::VERSION::MINOR >= 2 && Rails::VERSION::TINY >= 0
raise "This version of the engines plugin requires Rails 2.2.0 or later!"
end
end

Expand Down
Expand Up @@ -2,11 +2,15 @@
# within the database.
class PluginMigrationGenerator < Rails::Generator::Base

# 255 characters max for Windows NTFS (http://en.wikipedia.org/wiki/Filename)
# minus 14 for timestamp, minus some extra chars for dot, underscore, file
# extension. So let's have 230.
MAX_FILENAME_LENGTH = 230

def initialize(runtime_args, runtime_options={})
super
@options = {:assigns => {}}

ensure_plugin_schema_table_exists
ensure_schema_table_exists
get_plugins_to_migrate(runtime_args)

if @plugins_to_migrate.empty?
Expand All @@ -25,11 +29,10 @@ def manifest
end

protected

# Create the plugin schema table if it doesn't already exist. See
# Engines::RailsExtensions::Migrations#initialize_schema_information_with_engine_additions
def ensure_plugin_schema_table_exists
ActiveRecord::Base.connection.initialize_schema_information

# Create the schema table if it doesn't already exist.
def ensure_schema_table_exists
ActiveRecord::Base.connection.initialize_schema_migrations_table
end

# Determine all the plugins which have migrations that aren't present
Expand Down Expand Up @@ -69,11 +72,27 @@ def get_plugins_to_migrate(plugin_names)
@options[:assigns][:current_versions] = @current_versions
end

# Construct a unique migration name based on the plugins involved and the
# versions they should reach after this migration is run.
# Returns a migration name. If the descriptive migration name based on the
# plugin names involved is shorter than 230 characters that one will be
# used. Otherwise a shorter name will be returned.
def build_migration_name
returning descriptive_migration_name do |name|
name.replace short_migration_name if name.length > MAX_FILENAME_LENGTH
end
end

# Construct a unique migration name based on the plugins involved and the
# versions they should reach after this migration is run. The name constructed
# needs to be lowercase
def descriptive_migration_name
@plugins_to_migrate.map do |plugin|
"#{plugin.name}_to_version_#{@new_versions[plugin.name]}"
end.join("_and_")
end
end.join("_and_").downcase
end

# Short migration name that will be used if the descriptive_migration_name
# exceeds 230 characters
def short_migration_name
'plugin_migrations'
end
end
6 changes: 5 additions & 1 deletion vendor/plugins/engines/init.rb
@@ -1 +1,5 @@
Engines.init if defined? :Engines
# Only call Engines.init once, in the after_initialize block so that Rails
# plugin reloading works when turned on
config.after_initialize do
Engines.init if defined? :Engines
end
17 changes: 11 additions & 6 deletions vendor/plugins/engines/lib/engines.rb
Expand Up @@ -43,7 +43,7 @@ module Engines

# List of extensions to load, can be changed in init.rb before calling Engines.init
mattr_accessor :rails_extensions
self.rails_extensions = %w(active_record action_mailer asset_helpers routing migrations dependencies)
self.rails_extensions = %w(action_mailer asset_helpers routing migrations dependencies)

# The name of the public directory to mirror public engine assets into.
# Defaults to <tt>RAILS_ROOT/public/plugin_assets</tt>.
Expand Down Expand Up @@ -131,18 +131,23 @@ def select_existing_paths(paths)
def mix_code_from(*types)
self.code_mixing_file_types += types.map { |x| x.to_s.singularize }
end

# A general purpose method to mirror a directory (+source+) into a destination
# directory, including all files and subdirectories. Files will not be mirrored
# if they are identical already (checked via FileUtils#identical?).
def mirror_files_from(source, destination)
return unless File.directory?(source)

# TODO: use Rake::FileList#pathmap?
source_files = Dir[source + "/**/*"]
source_dirs = source_files.select { |d| File.directory?(d) }
source_files -= source_dirs

source_files -= source_dirs

unless source_files.empty?
base_target_dir = File.join(destination, File.dirname(source_files.first).gsub(source, ''))
FileUtils.mkdir_p(base_target_dir)
end

source_dirs.each do |dir|
# strip down these paths so we have simple, relative paths we can
# add to the destination
Expand All @@ -153,7 +158,7 @@ def mirror_files_from(source, destination)
raise "Could not create directory #{target_dir}: \n" + e
end
end

source_files.each do |file|
begin
target = File.join(destination, file.gsub(source, ''))
Expand Down

0 comments on commit 1cda19e

Please sign in to comment.