diff --git a/lib/sashimi/repositories/abstract_repository.rb b/lib/sashimi/repositories/abstract_repository.rb index 1b6786d..82f7e5e 100644 --- a/lib/sashimi/repositories/abstract_repository.rb +++ b/lib/sashimi/repositories/abstract_repository.rb @@ -1,8 +1,7 @@ module Sashimi class PluginNotFound < StandardError #:nodoc: def initialize(plugin_name, message = nil) - @plugin_name = plugin_name - @message = message + @plugin_name, @message = plugin_name, message end def to_s @@ -23,10 +22,11 @@ def initialize(plugin) # Remove the repository def uninstall - change_dir_to_local_repository - raise PluginNotFound.new(plugin.name) unless File.exists?(plugin.name) - FileUtils.rm_rf(plugin.name) - remove_from_cache + with_path local_repository_path do + raise PluginNotFound.new(plugin.name) unless File.exists?(plugin.name) + FileUtils.rm_rf(plugin.name) + remove_from_cache + end end # Add to a Rails app. @@ -45,11 +45,13 @@ def copy_plugin_and_remove_hidden_folders class << self def instantiate_repository(plugin) - unless plugin.name.nil? - instantiate_repository_by_cache(plugin) - else - instantiate_repository_by_url(plugin) - end.new(plugin) + with_path local_repository_path do + unless plugin.name.nil? + instantiate_repository_by_cache(plugin) + else + instantiate_repository_by_url(plugin) + end.new(plugin) + end end # Return all installed plugin names and summary, formatted for stdout. @@ -66,20 +68,22 @@ def plugins_names # Update the plugins installed in a rails app. def update_rails_plugins(plugins_names) - change_dir(path_to_rails_app) - if under_version_control? - update_versioned_rails_plugins(plugins_names) - else - update_unversioned_rails_plugins(plugins_names) + with_path path_to_rails_app do + if under_version_control? + update_versioned_rails_plugins(plugins_names) + else + update_unversioned_rails_plugins(plugins_names) + end end end # Update the plugins installed in a non versioned rails app. def update_unversioned_rails_plugins(plugins_names) - change_dir(plugins_dir) - plugins_names.each do |plugin_name| - FileUtils.rm_rf(plugin_name) - Plugin.new(plugin_name).add + with_path plugins_dir do + plugins_names.each do |plugin_name| + FileUtils.rm_rf(plugin_name) + Plugin.new(plugin_name).add + end end end @@ -126,8 +130,9 @@ def path_to_rails_app # Read the cache file and return the content as an Hash. def cache_content - change_dir_to_local_repository - @@cache_content ||= (YAML::load_file(cache_file) || {}).to_hash + with_path local_repository_path do + @@cache_content ||= (YAML::load_file(cache_file) || {}).to_hash + end end def instantiate_repository_by_url(plugin) @@ -139,26 +144,17 @@ def instantiate_repository_by_cache(plugin) raise PluginNotFound.new(plugin.name) if cached_plugin.nil? cached_plugin['type'] == 'git' ? GitRepository : SvnRepository end - - # Changes the current directory with the given one - def change_dir(dir) - FileUtils.cd(dir) - end - - # Change the current directory with local_repository_path - def change_dir_to_local_repository - change_dir(local_repository_path) - end - + # Change the current directory with the fully qualified # path to Rails app and plugins_dir. - def change_dir_to_absolute_plugins_dir - change_dir(File.join(File.expand_path(path_to_rails_app), plugins_dir)) + def absolute_rails_plugins_path + @@absolute_rails_plugins_path ||= File.join(File.expand_path(path_to_rails_app), + rails_plugins_path) end # Rails app plugins dir - def plugins_dir - @@plugins_dir ||= File.join('vendor', 'plugins') + def rails_plugins_path + @@rails_plugins_path ||= File.join('vendor', 'plugins') end # Check if the current working directory is under version control @@ -194,6 +190,16 @@ def find_home def git_url?(url) url =~ /^git:\/\// || url =~ /\.git$/ end + + def with_path(path, &block) + begin + old_path = Dir.pwd + FileUtils.cd(path) + yield + ensure + FileUtils.cd(old_path) + end + end end # Return the SCM type @@ -207,46 +213,51 @@ def scm_type # Read the content of the about.yml. # New feature of Rails 2.1.x http:://dev.rubyonrails.org/changeset/9098 def about - change_dir_to_plugin_path - return {} unless File.exists?('about.yml') - (YAML::load_file('about.yml') || {}).to_hash + with_path plugin_path do + return {} unless File.exists?('about.yml') + (YAML::load_file('about.yml') || {}).to_hash + end end # Returns a list of files that should be scheduled for SCM add. def files_scheduled_for_add - change_dir_to_absolute_plugins_dir - Dir[plugin.name+"-tmp/**/*"].collect {|fn| fn.gsub(plugin.name+'-tmp', '.')} - - Dir[plugin.name+"/**/*"].collect{|fn| fn.gsub(plugin.name, '.')} + with_path absolute_rails_plugins_path do + Dir[plugin.name+"-tmp/**/*"].collect {|fn| fn.gsub(plugin.name+'-tmp', '.')} - + Dir[plugin.name+"/**/*"].collect{|fn| fn.gsub(plugin.name, '.')} + end end # Returns a list of files that should be scheduled for SCM remove. def files_scheduled_for_remove - change_dir_to_absolute_plugins_dir - Dir[plugin.name+"/**/*"].collect {|fn| fn.gsub(plugin.name, '.')} - - Dir[plugin.name+"-tmp/**/*"].collect {|fn| fn.gsub(plugin.name+"-tmp", '.')} + with_path absolute_rails_plugins_path do + Dir[plugin.name+"/**/*"].collect {|fn| fn.gsub(plugin.name, '.')} - + Dir[plugin.name+"-tmp/**/*"].collect {|fn| fn.gsub(plugin.name+"-tmp", '.')} + end end # Remove the temp folder, used by update process. def remove_temp_folder - change_dir_to_absolute_plugins_dir - FileUtils.rm_rf(plugin.name+'-tmp') + with_path absolute_rails_plugins_path do + FileUtils.rm_rf(plugin.name+'-tmp') + end end - class_method_proxy :change_dir, :change_dir_to_local_repository, - :change_dir_to_absolute_plugins_dir, :local_repository_path, - :cache_file, :cache_content, :plugins_dir, :path_to_rails_app + class_method_proxy :local_repository_path, :cache_file, + :cache_content, :path_to_rails_app, :rails_plugins_path, + :with_path private - # Change the current directory with the plugin one - def change_dir_to_plugin_path - change_dir(File.join(local_repository_path, plugin.name || plugin.guess_name)) + # Returns the path to the plugin + def plugin_path + File.join(local_repository_path, plugin.name || plugin.guess_name) end # Prepare the plugin installation def prepare_installation FileUtils.mkdir_p(local_repository_path) - change_dir_to_local_repository - FileUtils.touch(cache_file) + with_path local_repository_path do + FileUtils.touch(cache_file) + end end # Add a plugin into the cache @@ -262,17 +273,20 @@ def remove_from_cache # Write all the plugins into the cache def write_to_cache(plugins) - change_dir_to_local_repository - FileUtils.mv(cache_file, "#{cache_file}-backup") - File.open(cache_file, 'w'){|f| f.write(plugins.to_yaml)} - FileUtils.rm("#{cache_file}-backup") + with_path local_repository_path do + FileUtils.mv(cache_file, "#{cache_file}-backup") + File.open(cache_file, 'w'){|f| f.write(plugins.to_yaml)} + FileUtils.rm("#{cache_file}-backup") + end end # Copy a plugin to a Rails app. def copy_plugin_to_rails_app - change_dir(path_to_rails_app) - FileUtils.mkdir_p(plugins_dir) - FileUtils.cp_r(File.join(local_repository_path, plugin.name), File.join(plugins_dir, plugin.name+'-tmp')) + with_path path_to_rails_app do + FileUtils.mkdir_p(plugins_path) + FileUtils.cp_r(File.join(local_repository_path, plugin.name), + File.join(plugins_path, plugin.name+'-tmp')) + end end # Rename the *-tmp folder used by the installation process. @@ -280,18 +294,21 @@ def copy_plugin_to_rails_app # Example: # click-to-globalize-tmp # => click-to-globalize def rename_temp_folder - change_dir(path_to_rails_app) - FileUtils.mv(File.join(plugins_dir, plugin.name+'-tmp'), File.join(plugins_dir, plugin.name)) + with_path path_to_rails_app do + FileUtils.mv(File.join(plugins_dir, plugin.name+'-tmp'), + File.join(plugins_dir, plugin.name)) + end end # Remove SCM hidden folders. def remove_hidden_folders require 'find' - change_dir(File.join(path_to_rails_app, plugins_dir, plugin.name+'-tmp')) - Find.find('./') do |path| - if File.basename(path) == '.'+scm_type - FileUtils.remove_dir(path, true) - Find.prune + with_path File.join(absolute_rails_plugins_path, plugin.name + '-tmp') do + Find.find('./') do |path| + if File.basename(path) == '.'+scm_type + FileUtils.remove_dir(path, true) + Find.prune + end end end end diff --git a/lib/sashimi/repositories/git_repository.rb b/lib/sashimi/repositories/git_repository.rb index a154a7b..c13c1b6 100644 --- a/lib/sashimi/repositories/git_repository.rb +++ b/lib/sashimi/repositories/git_repository.rb @@ -9,8 +9,9 @@ def install def update puts plugin.name.titleize + "\n\n" - change_dir_to_plugin_path - Kernel.system('git pull') + with_path plugin_path do + Kernel.system('git pull') + end end end end diff --git a/lib/sashimi/repositories/svn_repository.rb b/lib/sashimi/repositories/svn_repository.rb index bbfbb49..26b8822 100644 --- a/lib/sashimi/repositories/svn_repository.rb +++ b/lib/sashimi/repositories/svn_repository.rb @@ -9,8 +9,9 @@ def install def update puts plugin.name.titleize + "\n\n" - change_dir_to_plugin_path - Kernel.system("svn up") + with_path plugin_path do + Kernel.system("svn up") + end end end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 73a6a1f..3ce97e7 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -9,12 +9,27 @@ def assert_not(condition, message = nil) end private - def initialize_repository_for_test(&block) - repository.prepare_installation - create_cache_file - create_plugin_directories - yield - remove_local_repository_path # make sure of clean up tmp dirs + def create_test_repository + prepare_installation + with_path plugins_path do + create_cache_file + create_plugin_directories + end + end + + def destroy_test_repository + FileUtils.rm_rf(local_repository_path) + end + + alias_method :setup, :create_test_repository + alias_method :teardown, :destroy_test_repository + + def local_repository_path + @local_repository_path ||= File.join(repository.class.find_home, 'sashimi_test') + end + + def plugins_path + @plugins_path ||= File.join(local_repository_path, '.rails', 'plugins') end def repository @@ -22,7 +37,7 @@ def repository end def create_repository(plugin_name = 'sashimi', url = 'git://github.com/jodosha/sashimi.git') - @repository ||= AbstractRepository.new(Plugin.new(plugin_name, url)) + AbstractRepository.new(Plugin.new(plugin_name, url)) end def plugin @@ -39,6 +54,10 @@ def cached_plugin 'plug-in' => {'type' => 'svn'} } end + def cache_file + '.plugins' + end + def create_plugin_directories { 'plugin' => true, 'plug-in' => false }.each do |plugin, about| create_plugin_directory(plugin, about) @@ -46,32 +65,44 @@ def create_plugin_directories end def create_plugin_directory(plugin, about = true) - AbstractRepository.change_dir_to_local_repository FileUtils.mkdir(plugin) unless File.exists?(plugin) FileUtils.cd(plugin) File.open('about.yml', 'w+'){|f| f.write({'summary' => "Plugin summary"}.to_yaml)} if about - AbstractRepository.change_dir_to_local_repository end - def create_cache_file - File.open(repository.cache_file, 'w+'){|f| f.write(cached_plugin.to_yaml)} + def prepare_installation + FileUtils.mkdir_p(plugins_path) end - def remove_local_repository_path - FileUtils.rm_rf(File.join(repository.class.find_home, 'sashimi_test')) - end + def create_cache_file + File.open(cache_file, 'w+'){|f| f.write(cached_plugin.to_yaml)} + end + + def with_local_repository_path(&block) + with_path(local_repository_path, &block) + end + + # FIXME why often Dir.pwd returns nil ? + def with_path(path, &block) + begin + old_path = Dir.pwd rescue plugins_path + FileUtils.cd(path) + yield + ensure + FileUtils.cd(old_path) + end + end end module Sashimi class AbstractRepository @@local_repository_sub_path = 'sashimi_test/.rails/plugins' + cattr_accessor :local_repository_sub_path public :add_to_cache, :cache_content, :cache_file, - :change_dir, :change_dir_to_absolute_plugins_dir, - :change_dir_to_local_repository, :change_dir_to_plugin_path, :copy_plugin_to_rails_app, :local_repository_path, :path_to_rails_app, - :plugins_dir, :prepare_installation, :remove_from_cache, + :prepare_installation, :remove_from_cache, :rails_plugins_path, :remove_hidden_folders, :rename_temp_folder, :run_install_hook, - :write_to_cache + :write_to_cache, :with_path, :plugin_path end end diff --git a/test/unit/plugin_test.rb b/test/unit/plugin_test.rb index 51e784d..270270f 100644 --- a/test/unit/plugin_test.rb +++ b/test/unit/plugin_test.rb @@ -30,9 +30,7 @@ def test_should_instantiate_svn_repository_for_not_git_url end def test_should_serialize_to_hash - initialize_repository_for_test do - expected = {'plugin' => {'type' => 'svn', 'summary' => 'Plugin summary'}} - assert_equal(expected, create_plugin('plugin', 'http://dev.repository.com/svn/plugin/trunk').to_hash) - end + expected = {'plug-in' => {'type' => 'svn', 'summary' => nil}} + assert_equal(expected, create_plugin('plug-in', 'http://dev.repository.com/svn/plug-in/trunk').to_hash) end end diff --git a/test/unit/repositories/abstract_repository_test.rb b/test/unit/repositories/abstract_repository_test.rb index 7b4fa77..fd03d3b 100644 --- a/test/unit/repositories/abstract_repository_test.rb +++ b/test/unit/repositories/abstract_repository_test.rb @@ -2,125 +2,99 @@ require 'test/test_helper' class AbstractRepositoryTest < Test::Unit::TestCase - def test_initialize - assert repository - assert repository.plugin.name - assert repository.plugin.url - end - - # CLASS CONSTANTS - def test_local_repository_path - assert_match(/\.rails\/plugins$/, repository.local_repository_path) - end - - def test_cache_file - assert_equal(".plugins", repository.cache_file) - end + uses_mocha 'AbstractRepositoryTest' do + def test_initialize + assert repository + assert repository.plugin.name + assert repository.plugin.url + end - def test_plugins_dir - assert_equal('vendor/plugins', repository.plugins_dir) - end + # CLASS CONSTANTS + def test_local_repository_path + assert_match(/\.rails\/plugins$/, repository.local_repository_path) + end - # INSTANTIATE - def test_should_instantiate_repository_by_url - assert_kind_of(SvnRepository, AbstractRepository.instantiate_repository(create_plugin(nil, 'http://svn.com'))) - assert_kind_of(GitRepository, AbstractRepository.instantiate_repository(plugin)) - end - - def test_should_instantiate_repository_by_cache - initialize_repository_for_test do - assert AbstractRepository.instantiate_repository(create_plugin('sashimi', '')) + def test_cache_file + assert_equal(".plugins", repository.cache_file) end - end - - def test_should_recognize_git_url - assert AbstractRepository.git_url?('git://github.com/jodosha/sashimi.git') - end - - # COMMANDS - def test_should_list_all_installed_plugins - initialize_repository_for_test do + + def test_plugins_path + assert_equal('vendor/plugins', repository.rails_plugins_path) + end + + # INSTANTIATE + def test_should_instantiate_repository_by_url + assert_kind_of(SvnRepository, AbstractRepository.instantiate_repository(create_plugin(nil, 'http://svn.com'))) + assert_kind_of(GitRepository, AbstractRepository.instantiate_repository(plugin)) + end + + def test_should_instantiate_repository_by_cache + assert AbstractRepository.instantiate_repository(create_plugin('plugin', '')) + end + + def test_should_recognize_git_url + assert AbstractRepository.git_url?('git://github.com/jodosha/sashimi.git') + end + + # COMMANDS + def test_should_list_all_installed_plugins assert_equal("plug-in\t\t\nplugin\t\t\nsashimi\t\t", AbstractRepository.list) end - end - - def test_should_return_all_installed_plugins_names - initialize_repository_for_test do + + def test_should_return_all_installed_plugins_names assert_equal(['plug-in', 'plugin'], AbstractRepository.plugins_names) end - end - - # DIRECTORIES - def test_should_change_current_dir - repository.change_dir(repository.class.find_home) - assert_equal(repository.class.find_home, Dir.pwd) - end - - def test_should_change_current_dir_with_local_repository_path - initialize_repository_for_test do - repository.change_dir_to_local_repository - assert_equal(repository.local_repository_path, Dir.pwd) + + def test_should_uninstall_plugin + Dir.stubs(:pwd).returns repository.class.find_home + r = create_repository('plugin', '') + r.uninstall + assert_not repository.cache_content.keys.include?('plugin') end - end - - def test_should_change_current_dir_with_plugin_cache_path - initialize_repository_for_test do - FileUtils.mkdir_p(cached_plugin_path) - repository.change_dir_to_plugin_path - assert_equal(cached_plugin_path, Dir.pwd) + + def test_should_raise_exception_if_plugin_was_not_found + Dir.stubs(:pwd).returns repository.class.find_home + assert_raise(Sashimi::PluginNotFound) { repository.uninstall } end - end - - def _ignore_test_should_copy_plugin_to_a_rails_app - initialize_repository_for_test do + + # DIRECTORIES + def _ignore_test_should_copy_plugin_to_a_rails_app repository.change_dir_to_local_repository create_repository('plugin', '').copy_plugin_to_rails_app assert File.exists?(File.join('vendor', 'plugins', 'plugin', 'about.yml')) end - end - - # REPOSITORY - def test_should_prepare_installation - initialize_repository_for_test do + + # REPOSITORY + def test_should_prepare_installation assert File.exists?(repository.local_repository_path) + Dir.expects(:pwd).returns plugins_path assert_equal(repository.local_repository_path, Dir.pwd) assert File.exists?(repository.cache_file) end - end - # CACHE - def test_should_read_cache_content - initialize_repository_for_test do + # CACHE + def test_should_read_cache_content assert_equal(cache_content, repository.cache_content) end - end - - def test_should_add_plugin_to_the_cache - initialize_repository_for_test do + + def test_should_add_plugin_to_the_cache expected = cache_content.merge(cached_plugin) repository.add_to_cache(cached_plugin) assert_equal expected, cache_content end - end - - def test_should_remove_plugin_from_cache - initialize_repository_for_test do + + def test_should_remove_plugin_from_cache AbstractRepository.new(create_plugin('sashimi', '')).remove_from_cache assert_equal({"plugin"=>{"type"=>"svn"}, "plug-in"=>{"type"=>"svn"}}, cache_content) end - end - - # ABOUT - def test_should_return_about_contents_from_about_yml - initialize_repository_for_test do + + # ABOUT + def test_should_return_about_contents_from_about_yml plugin = create_plugin('plugin', 'http://dev.repository.com/svn/plugin/trunk') assert_equal({'summary' => "Plugin summary"}, plugin.about) end - end - - def test_should_return_empty_hash_for_unexstistent_about_yml - initialize_repository_for_test do - + + def test_should_return_empty_hash_for_unexstistent_about_yml plugin = create_plugin('plug-in', 'http://dev.repository.com/svn/plug-in/trunk') assert_equal({}, plugin.about) end diff --git a/test/unit/repositories/git_repository_test.rb b/test/unit/repositories/git_repository_test.rb index 087d3a3..edb94d0 100644 --- a/test/unit/repositories/git_repository_test.rb +++ b/test/unit/repositories/git_repository_test.rb @@ -20,7 +20,7 @@ def test_should_raise_exception_for_non_repository_url end def test_should_create_git_repository - initialize_repository_for_test do + repository.with_path plugins_path do FileUtils.mkdir_p('sashimi') Kernel.expects(:system).with('git clone git://github.com/jodosha/sashimi.git') GitRepository.new(plugin).install diff --git a/test/unit/repositories/svn_repository_test.rb b/test/unit/repositories/svn_repository_test.rb index 408a723..8536fc3 100644 --- a/test/unit/repositories/svn_repository_test.rb +++ b/test/unit/repositories/svn_repository_test.rb @@ -19,8 +19,8 @@ def test_should_raise_exception_for_non_repository_url assert_raise(Errno::ENOENT) { repository.install } end - def test_should_create_git_repository - initialize_repository_for_test do + def test_should_create_svn_repository + repository.with_path plugins_path do FileUtils.mkdir_p('sashimi') Kernel.expects(:system).with('svn co http://dev.repository.com/svn/sashimi/trunk sashimi') SvnRepository.new(create_plugin(nil, 'http://dev.repository.com/svn/sashimi/trunk')).install