Skip to content

Instantly share code, notes, and snippets.

@chriseppstein
Created November 6, 2010 19:13
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chriseppstein/665634 to your computer and use it in GitHub Desktop.
Save chriseppstein/665634 to your computer and use it in GitHub Desktop.
This gist is some helper functions and a rake task that allows you to quickly, safely , and easily vendor modules into your gems.
require 'fileutils'
def subsume_modules(*vendor_modules)
options = vendor_modules.pop
options[:modules] = vendor_modules + Array(options[:additional_modules])
options[:module_names] = options[:modules].map{|m| m.capitalize.gsub(/_[a-z]/){|s| s[-1..-1].upcase}}
vendor_modules.each do |vendor_module|
copy_module vendor_module, options
subsume_module vendor_module, options
end
end
def copy_module(vendor_module, options)
from_path = "#{options[:from]}/#{(options[:locations]||{}).fetch(vendor_module, "lib/#{vendor_module}")}"
to_path = "#{options[:to]}/#{vendor_module}"
FileUtils.rm_rf(["#{to_path}.rb", "#{to_path}"])
globs = ["#{from_path}.rb", "#{from_path}/**/*.rb"]
globs += Array(options[:additonal_extensions]).map {|ext| "#{from_path}/**/*.#{ext}"}
vendor_files = FileList.new(*globs)
vendor_files.each do |vendor_file|
target_file = vendor_file.gsub(/#{Regexp.escape(from_path)}/,to_path)
FileUtils.mkdir_p(File.dirname(target_file))
FileUtils.cp "#{vendor_file}", "#{target_file}"
end
end
def subsume_module(vendor_module, options)
vendor_files = FileList.new("#{options[:to]}/#{vendor_module}.rb",
"#{options[:to]}/#{vendor_module}/**/*.rb")
vendor_files.each do |vendor_file|
subsume(vendor_file, options)
end
end
def scope_subsumed_constants!(contents, options)
contents.gsub!(/#{options[:module_names].join('|')}/) {|m| "#{options[:scope]}::#{m}"}
end
def subsume(vendor_file, options)
contents = File.read(vendor_file)
unless contents =~ /#{options[:scope]}/
puts "Processing: #{vendor_file}"
contents.gsub!(/^(.*\$\:)/,'# \1') if options[:disable_path_munging]
contents.gsub!(/(require\s+['"])(#{options[:modules].join("|")})/,"\\1#{options[:require_prefix]}/\\2")
contents.gsub!(/(autoload\s+:[\w:"]+,\s+['"])(#{options[:modules].join("|")})/,"\\1#{options[:require_prefix]}/\\2")
unscoped = options[:unscoped] && vendor_file =~ options[:unscoped]
contents = "module #{options[:scope]}\n#{contents}" unless unscoped
base_name = vendor_file[(options[:from].size+1)..-1]
unless unscoped
if ending = options.fetch(:end_placements,{})[base_name]
before, after = contents.split(ending.first, 2)
puts after.inspect
scope_subsumed_constants!(after, options)
contents = before + ending.last + after
else
contents = contents.rstrip + "\nend\n"
end
end
if unscoped
scope_subsumed_constants!(contents, options)
end
contents<<"\n" unless contents[-1..-1] == "\n"
open(vendor_file, "w") {|f| f.write(contents)}
end
end
desc "example of how to vendor some modules. Usage: rake vendor[path/to/rails]"
task :vendor, :rails_path do |task, args|
subsume_modules "active_support","active_model","active_resource",
:from => args[:rails_path],
:to => "lib/caring/directory/vendor",
:require_prefix => "caring/directory/vendor",
:scope => "Caring::Directory::Vendor",
:unscoped => /core_ext|whiny_nil/,
:disable_path_munging => true,
:locations => {
"active_support" => "activesupport/lib/active_support",
"active_model" => "activemodel/lib/active_model",
"active_resource" => "activeresource/lib/active_resource"
},
:additonal_extensions => ["yml", "dat"],
:end_placements => {
"active_support/json/encoding.rb" => ["end\n\nclass Object", "end\nend\n\nclass Object"] # This file does some core extensions so we have to add the end in the middle of the file.
}
end
diff --git a/gems/directory_client/lib/caring/directory/active_model.rb b/gems/directory_client/lib/caring/directory/active_model.rb
index be0f24f..dde14b8 100644
--- a/gems/directory_client/lib/caring/directory/active_model.rb
+++ b/gems/directory_client/lib/caring/directory/active_model.rb
@@ -1,3 +1,4 @@
+module Caring::Directory
#--
# Copyright (c) 2004-2010 David Heinemeier Hansson
#
@@ -22,25 +23,25 @@
#++
activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__)
-$:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)
-require 'active_support'
-require 'active_model/version'
+# $:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)
+require 'caring/directory/active_support'
+require 'caring/directory/active_model/version'
module ActiveModel
extend ActiveSupport::Autoload
autoload :AttributeMethods
- autoload :BlockValidator, 'active_model/validator'
+ autoload :BlockValidator, 'caring/directory/active_model/validator'
autoload :Callbacks
autoload :Conversion
autoload :Dirty
- autoload :EachValidator, 'active_model/validator'
+ autoload :EachValidator, 'caring/directory/active_model/validator'
autoload :Errors
autoload :Lint
autoload :MassAssignmentSecurity
- autoload :Name, 'active_model/naming'
+ autoload :Name, 'caring/directory/active_model/naming'
autoload :Naming
- autoload :Observer, 'active_model/observing'
+ autoload :Observer, 'caring/directory/active_model/observing'
autoload :Observing
autoload :Serialization
autoload :TestCase
@@ -56,5 +57,6 @@ module ActiveModel
end
end
-require 'active_support/i18n'
+require 'caring/directory/active_support/i18n'
I18n.load_path << File.dirname(__FILE__) + '/active_model/locale/en.yml'
+end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment