diff --git a/padrino-core/lib/padrino-core/loader.rb b/padrino-core/lib/padrino-core/loader.rb index 5d79ab96d..2301c5dc0 100644 --- a/padrino-core/lib/padrino-core/loader.rb +++ b/padrino-core/lib/padrino-core/loader.rb @@ -129,8 +129,9 @@ def loaded? # require_dependencies("#{Padrino.root}/lib/**/*.rb") # def require_dependencies(*paths) - options = paths.extract_options!.merge( :cyclic => true ) - files = paths.flatten.map{ |path| Dir.glob(path).sort_by{ |filename| filename.count('/') } }.flatten.uniq + options = { :cyclic => true }.update(paths.last.is_a?(Hash) ? paths.pop : {}) + + files = paths.flatten.flat_map{ |path| Dir.glob(path).sort_by{ |filename| filename.count('/') } }.uniq until files.empty? error, fatal, loaded = nil, nil, nil @@ -141,6 +142,7 @@ def require_dependencies(*paths) files.delete(file) loaded = true rescue NameError, LoadError => error + raise if Reloader.exclude.any?{ |path| file.start_with?(path) } || options[:cyclic] == false logger.devel "Cyclic dependency reload for #{error.class}: #{error.message}" rescue Exception => fatal break diff --git a/padrino-core/lib/padrino-core/reloader/storage.rb b/padrino-core/lib/padrino-core/reloader/storage.rb index 53ac024da..719db6cfd 100644 --- a/padrino-core/lib/padrino-core/reloader/storage.rb +++ b/padrino-core/lib/padrino-core/reloader/storage.rb @@ -41,7 +41,13 @@ def commit(name) def rollback(name) new_constants = ObjectSpace.new_classes(@old_entries[name][:constants]) - new_constants.each{ |klass| Reloader.remove_constant(klass) } + new_constants.each do |klass| + loaded_in_name = files.each do |file, data| + next if file == name + break if data[:constants].include?(klass) + end + Reloader.remove_constant(klass) if loaded_in_name + end @old_entries.delete(name) end diff --git a/padrino-core/test/fixtures/dependencies/linear/h.rb b/padrino-core/test/fixtures/dependencies/linear/h.rb new file mode 100644 index 000000000..c25c697ac --- /dev/null +++ b/padrino-core/test/fixtures/dependencies/linear/h.rb @@ -0,0 +1 @@ +raise LoadError diff --git a/padrino-core/test/fixtures/dependencies/linear/i.rb b/padrino-core/test/fixtures/dependencies/linear/i.rb new file mode 100644 index 000000000..9dae856c3 --- /dev/null +++ b/padrino-core/test/fixtures/dependencies/linear/i.rb @@ -0,0 +1 @@ +fail diff --git a/padrino-core/test/fixtures/dependencies/nested/j.rb b/padrino-core/test/fixtures/dependencies/nested/j.rb new file mode 100644 index 000000000..b2c6c551a --- /dev/null +++ b/padrino-core/test/fixtures/dependencies/nested/j.rb @@ -0,0 +1,2 @@ +class J < K +end diff --git a/padrino-core/test/fixtures/dependencies/nested/k.rb b/padrino-core/test/fixtures/dependencies/nested/k.rb new file mode 100644 index 000000000..c3a6e443e --- /dev/null +++ b/padrino-core/test/fixtures/dependencies/nested/k.rb @@ -0,0 +1,2 @@ +class K +end diff --git a/padrino-core/test/fixtures/dependencies/nested/l.rb b/padrino-core/test/fixtures/dependencies/nested/l.rb new file mode 100644 index 000000000..af2ed4ba1 --- /dev/null +++ b/padrino-core/test/fixtures/dependencies/nested/l.rb @@ -0,0 +1,4 @@ +Padrino.require_dependencies( + Padrino.root("fixtures/dependencies/nested/m.rb"), + Padrino.root("fixtures/dependencies/nested/n.rb") +) diff --git a/padrino-core/test/fixtures/dependencies/nested/m.rb b/padrino-core/test/fixtures/dependencies/nested/m.rb new file mode 100644 index 000000000..d8536a760 --- /dev/null +++ b/padrino-core/test/fixtures/dependencies/nested/m.rb @@ -0,0 +1,5 @@ +class M + def self.hello + "hello" + end +end diff --git a/padrino-core/test/fixtures/dependencies/nested/n.rb b/padrino-core/test/fixtures/dependencies/nested/n.rb new file mode 100644 index 000000000..64332bdeb --- /dev/null +++ b/padrino-core/test/fixtures/dependencies/nested/n.rb @@ -0,0 +1,2 @@ +class N < J +end diff --git a/padrino-core/test/fixtures/dependencies/nested/ooo.rb b/padrino-core/test/fixtures/dependencies/nested/ooo.rb new file mode 100644 index 000000000..844558013 --- /dev/null +++ b/padrino-core/test/fixtures/dependencies/nested/ooo.rb @@ -0,0 +1,2 @@ +class OOO < RRR +end diff --git a/padrino-core/test/fixtures/dependencies/nested/ppp.rb b/padrino-core/test/fixtures/dependencies/nested/ppp.rb new file mode 100644 index 000000000..250f9d00a --- /dev/null +++ b/padrino-core/test/fixtures/dependencies/nested/ppp.rb @@ -0,0 +1,2 @@ +class PPP +end diff --git a/padrino-core/test/fixtures/dependencies/nested/qqq.rb b/padrino-core/test/fixtures/dependencies/nested/qqq.rb new file mode 100644 index 000000000..006adfcf9 --- /dev/null +++ b/padrino-core/test/fixtures/dependencies/nested/qqq.rb @@ -0,0 +1,4 @@ +Padrino.require_dependencies( + Padrino.root("fixtures/dependencies/nested/rrr.rb"), + Padrino.root("fixtures/dependencies/nested/sss.rb") +) diff --git a/padrino-core/test/fixtures/dependencies/nested/rrr.rb b/padrino-core/test/fixtures/dependencies/nested/rrr.rb new file mode 100644 index 000000000..a1e1bd2a7 --- /dev/null +++ b/padrino-core/test/fixtures/dependencies/nested/rrr.rb @@ -0,0 +1,5 @@ +class RRR + def self.hello + "hello" + end +end diff --git a/padrino-core/test/fixtures/dependencies/nested/sss.rb b/padrino-core/test/fixtures/dependencies/nested/sss.rb new file mode 100644 index 000000000..8ee0037cf --- /dev/null +++ b/padrino-core/test/fixtures/dependencies/nested/sss.rb @@ -0,0 +1,8 @@ +class RollbackTarget + def self.hello + "hello" + end +end + +class SSS < OOO +end diff --git a/padrino-core/test/test_dependencies.rb b/padrino-core/test/test_dependencies.rb index d50790fb9..c5a3c06fb 100644 --- a/padrino-core/test/test_dependencies.rb +++ b/padrino-core/test/test_dependencies.rb @@ -53,5 +53,57 @@ assert_equal ["name"], F.fields assert_equal "", @io.string end + + it 'should not silence LoadError raised in dependencies excluded from reloading' do + capture_io do + assert_raises(LoadError) do + Padrino::Reloader.exclude << Padrino.root("fixtures/dependencies/linear/h.rb") + Padrino.require_dependencies( + Padrino.root("fixtures/dependencies/linear/h.rb"), + Padrino.root("fixtures/dependencies/linear/i.rb"), + ) + end + end + end + + it 'should not remove constants that are newly commited in nested require_dependencies' do + capture_io do + Padrino.require_dependencies( + Padrino.root("fixtures/dependencies/nested/j.rb"), + Padrino.root("fixtures/dependencies/nested/k.rb"), + Padrino.root("fixtures/dependencies/nested/l.rb") + ) + end + assert_equal "hello", M.hello + end + + + describe "change log level for :devel" do + before do + @log_level_devel = Padrino::Logger::Config[:test] + @io = StringIO.new + Padrino::Logger::Config[:test] = { :log_level => :devel, :stream => @io } + Padrino::Logger.setup! + end + + after do + Padrino::Logger::Config[:test] = @log_level_devel + Padrino::Logger.setup! + end + + it 'should resolve interdependence by out/in side nested require_dependencies' do + capture_io do + Padrino.require_dependencies( + Padrino.root("fixtures/dependencies/nested/ooo.rb"), + Padrino.root("fixtures/dependencies/nested/ppp.rb"), + Padrino.root("fixtures/dependencies/nested/qqq.rb") + ) + end + assert_equal "hello", RRR.hello + assert_equal "hello", OOO.hello + assert_equal "hello", RollbackTarget.hello + assert_match /Removed constant RollbackTarget from Object/, @io.string + end + end end end