swivel 0.0.146 → 0.0.149

Sign up to get free protection for your applications and to get access to all the features.
Files changed (183) hide show
  1. data/README +4 -1
  2. data/Rakefile +1 -1
  3. data/lib/swivel.rb +1 -1
  4. data/lib/swivel2/benchmarking.rb +1 -0
  5. data/lib/swivel2/config.rb +45 -0
  6. data/lib/swivel2/connection.rb +89 -0
  7. data/lib/swivel2/formats.rb +11 -0
  8. data/lib/swivel2/logging.rb +1 -0
  9. data/lib/swivel2/performance.rb +21 -0
  10. data/lib/swivel2/response.rb +5 -0
  11. data/lib/swivel2/swivelrc.default +5 -0
  12. data/vendor/activeresource-2.0.2-/CHANGELOG +223 -0
  13. data/vendor/activeresource-2.0.2-/README +165 -0
  14. data/vendor/activeresource-2.0.2-/Rakefile +133 -0
  15. data/vendor/activeresource-2.0.2-/lib/active_resource.rb +47 -0
  16. data/vendor/activeresource-2.0.2-/lib/active_resource/base.rb +872 -0
  17. data/vendor/activeresource-2.0.2-/lib/active_resource/connection.rb +172 -0
  18. data/vendor/activeresource-2.0.2-/lib/active_resource/custom_methods.rb +105 -0
  19. data/vendor/activeresource-2.0.2-/lib/active_resource/formats.rb +14 -0
  20. data/vendor/activeresource-2.0.2-/lib/active_resource/formats/json_format.rb +23 -0
  21. data/vendor/activeresource-2.0.2-/lib/active_resource/formats/xml_format.rb +34 -0
  22. data/vendor/activeresource-2.0.2-/lib/active_resource/http_mock.rb +147 -0
  23. data/vendor/activeresource-2.0.2-/lib/active_resource/validations.rb +288 -0
  24. data/vendor/activeresource-2.0.2-/lib/active_resource/version.rb +9 -0
  25. data/vendor/activeresource-2.0.2-/lib/activeresource.rb +1 -0
  26. data/vendor/activeresource-2.0.2-/test/abstract_unit.rb +10 -0
  27. data/vendor/activeresource-2.0.2-/test/authorization_test.rb +82 -0
  28. data/vendor/activeresource-2.0.2-/test/base/custom_methods_test.rb +96 -0
  29. data/vendor/activeresource-2.0.2-/test/base/equality_test.rb +43 -0
  30. data/vendor/activeresource-2.0.2-/test/base/load_test.rb +111 -0
  31. data/vendor/activeresource-2.0.2-/test/base_errors_test.rb +48 -0
  32. data/vendor/activeresource-2.0.2-/test/base_test.rb +454 -0
  33. data/vendor/activeresource-2.0.2-/test/connection_test.rb +170 -0
  34. data/vendor/activeresource-2.0.2-/test/fixtures/beast.rb +14 -0
  35. data/vendor/activeresource-2.0.2-/test/fixtures/person.rb +3 -0
  36. data/vendor/activeresource-2.0.2-/test/fixtures/street_address.rb +4 -0
  37. data/vendor/activeresource-2.0.2-/test/format_test.rb +42 -0
  38. data/vendor/activeresource-2.0.2-/test/setter_trap.rb +27 -0
  39. data/vendor/activesupport-2.0.2-/CHANGELOG +986 -0
  40. data/vendor/activesupport-2.0.2-/README +43 -0
  41. data/vendor/activesupport-2.0.2-/lib/active_support.rb +49 -0
  42. data/vendor/activesupport-2.0.2-/lib/active_support/basic_object.rb +5 -0
  43. data/vendor/activesupport-2.0.2-/lib/active_support/buffered_logger.rb +107 -0
  44. data/vendor/activesupport-2.0.2-/lib/active_support/clean_logger.rb +127 -0
  45. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext.rb +4 -0
  46. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array.rb +13 -0
  47. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/access.rb +28 -0
  48. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/conversions.rb +94 -0
  49. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/extract_options.rb +19 -0
  50. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/grouping.rb +68 -0
  51. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/random_access.rb +12 -0
  52. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/bigdecimal.rb +2 -0
  53. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/bigdecimal/conversions.rb +6 -0
  54. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/blank.rb +50 -0
  55. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/cgi.rb +5 -0
  56. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +14 -0
  57. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class.rb +4 -0
  58. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class/attribute_accessors.rb +48 -0
  59. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class/delegating_attributes.rb +40 -0
  60. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class/inheritable_attributes.rb +140 -0
  61. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class/removal.rb +24 -0
  62. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date.rb +10 -0
  63. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date/behavior.rb +13 -0
  64. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date/calculations.rb +188 -0
  65. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date/conversions.rb +98 -0
  66. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date_time.rb +10 -0
  67. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date_time/calculations.rb +77 -0
  68. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date_time/conversions.rb +74 -0
  69. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/duplicable.rb +37 -0
  70. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/enumerable.rb +63 -0
  71. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/exception.rb +33 -0
  72. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/file.rb +21 -0
  73. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/float.rb +5 -0
  74. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/float/rounding.rb +24 -0
  75. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash.rb +13 -0
  76. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/conversions.rb +242 -0
  77. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/diff.rb +19 -0
  78. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/except.rb +24 -0
  79. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/indifferent_access.rb +102 -0
  80. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/keys.rb +54 -0
  81. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/reverse_merge.rb +25 -0
  82. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/slice.rb +28 -0
  83. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/integer.rb +7 -0
  84. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/integer/even_odd.rb +24 -0
  85. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/integer/inflections.rb +21 -0
  86. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel.rb +5 -0
  87. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/agnostics.rb +11 -0
  88. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/daemonizing.rb +15 -0
  89. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/debugger.rb +13 -0
  90. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/reporting.rb +51 -0
  91. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/requires.rb +24 -0
  92. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/load_error.rb +38 -0
  93. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/logger.rb +16 -0
  94. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module.rb +8 -0
  95. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/aliasing.rb +70 -0
  96. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/attr_accessor_with_default.rb +31 -0
  97. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/attr_internal.rb +31 -0
  98. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/attribute_accessors.rb +48 -0
  99. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/delegation.rb +62 -0
  100. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/inclusion.rb +11 -0
  101. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/introspection.rb +35 -0
  102. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/loading.rb +13 -0
  103. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/name_error.rb +17 -0
  104. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/numeric.rb +7 -0
  105. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/numeric/bytes.rb +44 -0
  106. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/numeric/time.rb +91 -0
  107. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object.rb +4 -0
  108. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object/conversions.rb +14 -0
  109. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object/extending.rb +58 -0
  110. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object/instance_variables.rb +22 -0
  111. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object/misc.rb +59 -0
  112. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/pathname.rb +7 -0
  113. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/pathname/clean_within.rb +14 -0
  114. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/proc.rb +12 -0
  115. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range.rb +11 -0
  116. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range/blockless_step.rb +22 -0
  117. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range/conversions.rb +23 -0
  118. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range/include_range.rb +22 -0
  119. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range/overlaps.rb +12 -0
  120. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string.rb +23 -0
  121. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/access.rb +58 -0
  122. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/conversions.rb +28 -0
  123. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/inflections.rb +153 -0
  124. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/iterators.rb +17 -0
  125. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/starts_ends_with.rb +27 -0
  126. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/unicode.rb +42 -0
  127. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/xchar.rb +11 -0
  128. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/symbol.rb +14 -0
  129. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/test.rb +1 -0
  130. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/test/unit/assertions.rb +62 -0
  131. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/time.rb +19 -0
  132. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/time/behavior.rb +13 -0
  133. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/time/calculations.rb +224 -0
  134. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/time/conversions.rb +94 -0
  135. data/vendor/activesupport-2.0.2-/lib/active_support/dependencies.rb +540 -0
  136. data/vendor/activesupport-2.0.2-/lib/active_support/deprecation.rb +204 -0
  137. data/vendor/activesupport-2.0.2-/lib/active_support/duration.rb +96 -0
  138. data/vendor/activesupport-2.0.2-/lib/active_support/inflections.rb +53 -0
  139. data/vendor/activesupport-2.0.2-/lib/active_support/inflector.rb +282 -0
  140. data/vendor/activesupport-2.0.2-/lib/active_support/json.rb +31 -0
  141. data/vendor/activesupport-2.0.2-/lib/active_support/json/decoding.rb +60 -0
  142. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/date.rb +5 -0
  143. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/date_time.rb +5 -0
  144. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/enumerable.rb +12 -0
  145. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/false_class.rb +5 -0
  146. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/hash.rb +50 -0
  147. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/nil_class.rb +5 -0
  148. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/numeric.rb +5 -0
  149. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/object.rb +6 -0
  150. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/regexp.rb +5 -0
  151. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/string.rb +30 -0
  152. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/symbol.rb +5 -0
  153. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/time.rb +5 -0
  154. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/true_class.rb +5 -0
  155. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoding.rb +38 -0
  156. data/vendor/activesupport-2.0.2-/lib/active_support/json/variable.rb +10 -0
  157. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte.rb +9 -0
  158. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/chars.rb +141 -0
  159. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/generators/generate_tables.rb +149 -0
  160. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/handlers/passthru_handler.rb +9 -0
  161. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/handlers/utf8_handler.rb +564 -0
  162. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/handlers/utf8_handler_proc.rb +43 -0
  163. data/vendor/activesupport-2.0.2-/lib/active_support/option_merger.rb +25 -0
  164. data/vendor/activesupport-2.0.2-/lib/active_support/ordered_options.rb +49 -0
  165. data/vendor/activesupport-2.0.2-/lib/active_support/test_case.rb +5 -0
  166. data/vendor/activesupport-2.0.2-/lib/active_support/testing.rb +1 -0
  167. data/vendor/activesupport-2.0.2-/lib/active_support/testing/default.rb +12 -0
  168. data/vendor/activesupport-2.0.2-/lib/active_support/values/time_zone.rb +181 -0
  169. data/vendor/activesupport-2.0.2-/lib/active_support/values/unicode_tables.dat +0 -0
  170. data/vendor/activesupport-2.0.2-/lib/active_support/vendor.rb +14 -0
  171. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/blankslate.rb +113 -0
  172. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder.rb +13 -0
  173. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb +20 -0
  174. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/css.rb +250 -0
  175. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb +115 -0
  176. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb +139 -0
  177. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb +63 -0
  178. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb +328 -0
  179. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/xml-simple-1.0.11/xmlsimple.rb +1021 -0
  180. data/vendor/activesupport-2.0.2-/lib/active_support/version.rb +9 -0
  181. data/vendor/activesupport-2.0.2-/lib/active_support/whiny_nil.rb +38 -0
  182. data/vendor/activesupport-2.0.2-/lib/activesupport.rb +1 -0
  183. metadata +222 -2
@@ -0,0 +1,94 @@
1
+ module ActiveSupport #:nodoc:
2
+ module CoreExtensions #:nodoc:
3
+ module Time #:nodoc:
4
+ # Getting times in different convenient string representations and other objects
5
+ module Conversions
6
+ DATE_FORMATS = {
7
+ :db => "%Y-%m-%d %H:%M:%S",
8
+ :time => "%H:%M",
9
+ :short => "%d %b %H:%M",
10
+ :long => "%B %d, %Y %H:%M",
11
+ :long_ordinal => lambda { |time| time.strftime("%B #{time.day.ordinalize}, %Y %H:%M") },
12
+ :rfc822 => "%a, %d %b %Y %H:%M:%S %z"
13
+ }
14
+
15
+ def self.included(base)
16
+ base.class_eval do
17
+ alias_method :to_default_s, :to_s
18
+ alias_method :to_s, :to_formatted_s
19
+ end
20
+ end
21
+
22
+ # Convert to a formatted string - see DATE_FORMATS for predefined formats.
23
+ # You can also add your own formats to the DATE_FORMATS constant and use them with this method.
24
+ #
25
+ # This method is also aliased as <tt>to_s</tt>.
26
+ #
27
+ # ==== Examples:
28
+ # time = Time.now # => Thu Jan 18 06:10:17 CST 2007
29
+ #
30
+ # time.to_formatted_s(:time) # => "06:10:17"
31
+ # time.to_s(:time) # => "06:10:17"
32
+ #
33
+ # time.to_formatted_s(:db) # => "2007-01-18 06:10:17"
34
+ # time.to_formatted_s(:short) # => "18 Jan 06:10"
35
+ # time.to_formatted_s(:long) # => "January 18, 2007 06:10"
36
+ # time.to_formatted_s(:long_ordinal) # => "January 18th, 2007 06:10"
37
+ # time.to_formatted_s(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
38
+ def to_formatted_s(format = :default)
39
+ if formatter = DATE_FORMATS[format]
40
+ if formatter.respond_to?(:call)
41
+ formatter.call(self).to_s
42
+ else
43
+ strftime(formatter)
44
+ end
45
+ else
46
+ to_default_s
47
+ end
48
+ end
49
+
50
+ # Convert a Time object to a Date, dropping hour, minute, and second precision.
51
+ #
52
+ # ==== Examples
53
+ # my_time = Time.now
54
+ # # => Mon Nov 12 22:59:51 -0500 2007
55
+ #
56
+ # my_time.to_date
57
+ # #=> Mon, 12 Nov 2007
58
+ #
59
+ # your_time = Time.parse("1/13/2009 1:13:03 P.M.")
60
+ # # => Tue Jan 13 13:13:03 -0500 2009
61
+ #
62
+ # your_time.to_date
63
+ # # => Tue, 13 Jan 2009
64
+ def to_date
65
+ ::Date.new(year, month, day)
66
+ end
67
+
68
+ # A method to keep Time, Date and DateTime instances interchangeable on conversions.
69
+ # In this case, it simply returns +self+.
70
+ def to_time
71
+ self
72
+ end
73
+
74
+ # Converts a Time instance to a Ruby DateTime instance, preserving UTC offset.
75
+ #
76
+ # ==== Examples
77
+ # my_time = Time.now
78
+ # # => Mon Nov 12 23:04:21 -0500 2007
79
+ #
80
+ # my_time.to_datetime
81
+ # # => Mon, 12 Nov 2007 23:04:21 -0500
82
+ #
83
+ # your_time = Time.parse("1/13/2009 1:13:03 P.M.")
84
+ # # => Tue Jan 13 13:13:03 -0500 2009
85
+ #
86
+ # your_time.to_datetime
87
+ # # => Tue, 13 Jan 2009 13:13:03 -0500
88
+ def to_datetime
89
+ ::DateTime.civil(year, month, day, hour, min, sec, Rational(utc_offset, 86400))
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,540 @@
1
+ require 'set'
2
+ require 'active_support/core_ext/module/attribute_accessors'
3
+ require 'active_support/core_ext/load_error'
4
+ require 'active_support/core_ext/kernel'
5
+
6
+ module Dependencies #:nodoc:
7
+ extend self
8
+
9
+ # Should we turn on Ruby warnings on the first load of dependent files?
10
+ mattr_accessor :warnings_on_first_load
11
+ self.warnings_on_first_load = false
12
+
13
+ # All files ever loaded.
14
+ mattr_accessor :history
15
+ self.history = Set.new
16
+
17
+ # All files currently loaded.
18
+ mattr_accessor :loaded
19
+ self.loaded = Set.new
20
+
21
+ # Should we load files or require them?
22
+ mattr_accessor :mechanism
23
+ self.mechanism = :load
24
+
25
+ # The set of directories from which we may automatically load files. Files
26
+ # under these directories will be reloaded on each request in development mode,
27
+ # unless the directory also appears in load_once_paths.
28
+ mattr_accessor :load_paths
29
+ self.load_paths = []
30
+
31
+ # The set of directories from which automatically loaded constants are loaded
32
+ # only once. All directories in this set must also be present in +load_paths+.
33
+ mattr_accessor :load_once_paths
34
+ self.load_once_paths = []
35
+
36
+ # An array of qualified constant names that have been loaded. Adding a name to
37
+ # this array will cause it to be unloaded the next time Dependencies are cleared.
38
+ mattr_accessor :autoloaded_constants
39
+ self.autoloaded_constants = []
40
+
41
+ # An array of constant names that need to be unloaded on every request. Used
42
+ # to allow arbitrary constants to be marked for unloading.
43
+ mattr_accessor :explicitly_unloadable_constants
44
+ self.explicitly_unloadable_constants = []
45
+
46
+ # Set to true to enable logging of const_missing and file loads
47
+ mattr_accessor :log_activity
48
+ self.log_activity = false
49
+
50
+ # An internal stack used to record which constants are loaded by any block.
51
+ mattr_accessor :constant_watch_stack
52
+ self.constant_watch_stack = []
53
+
54
+ def load?
55
+ mechanism == :load
56
+ end
57
+
58
+ def depend_on(file_name, swallow_load_errors = false)
59
+ path = search_for_file(file_name)
60
+ require_or_load(path || file_name)
61
+ rescue LoadError
62
+ raise unless swallow_load_errors
63
+ end
64
+
65
+ def associate_with(file_name)
66
+ depend_on(file_name, true)
67
+ end
68
+
69
+ def clear
70
+ log_call
71
+ loaded.clear
72
+ remove_unloadable_constants!
73
+ end
74
+
75
+ def require_or_load(file_name, const_path = nil)
76
+ log_call file_name, const_path
77
+ file_name = $1 if file_name =~ /^(.*)\.rb$/
78
+ expanded = File.expand_path(file_name)
79
+ return if loaded.include?(expanded)
80
+
81
+ # Record that we've seen this file *before* loading it to avoid an
82
+ # infinite loop with mutual dependencies.
83
+ loaded << expanded
84
+
85
+ if load?
86
+ log "loading #{file_name}"
87
+ begin
88
+ # Enable warnings iff this file has not been loaded before and
89
+ # warnings_on_first_load is set.
90
+ load_args = ["#{file_name}.rb"]
91
+ load_args << const_path unless const_path.nil?
92
+
93
+ if !warnings_on_first_load or history.include?(expanded)
94
+ result = load_file(*load_args)
95
+ else
96
+ enable_warnings { result = load_file(*load_args) }
97
+ end
98
+ rescue Exception
99
+ loaded.delete expanded
100
+ raise
101
+ end
102
+ else
103
+ log "requiring #{file_name}"
104
+ result = require file_name
105
+ end
106
+
107
+ # Record history *after* loading so first load gets warnings.
108
+ history << expanded
109
+ return result
110
+ end
111
+
112
+ # Is the provided constant path defined?
113
+ def qualified_const_defined?(path)
114
+ raise NameError, "#{path.inspect} is not a valid constant name!" unless
115
+ /^(::)?([A-Z]\w*)(::[A-Z]\w*)*$/ =~ path
116
+
117
+ names = path.to_s.split('::')
118
+ names.shift if names.first.empty?
119
+
120
+ # We can't use defined? because it will invoke const_missing for the parent
121
+ # of the name we are checking.
122
+ names.inject(Object) do |mod, name|
123
+ return false unless mod.const_defined? name
124
+ mod.const_get name
125
+ end
126
+ return true
127
+ end
128
+
129
+ # Given +path+, a filesystem path to a ruby file, return an array of constant
130
+ # paths which would cause Dependencies to attempt to load this file.
131
+ #
132
+ def loadable_constants_for_path(path, bases = load_paths)
133
+ path = $1 if path =~ /\A(.*)\.rb\Z/
134
+ expanded_path = File.expand_path(path)
135
+
136
+ bases.collect do |root|
137
+ expanded_root = File.expand_path(root)
138
+ next unless %r{\A#{Regexp.escape(expanded_root)}(/|\\)} =~ expanded_path
139
+
140
+ nesting = expanded_path[(expanded_root.size)..-1]
141
+ nesting = nesting[1..-1] if nesting && nesting[0] == ?/
142
+ next if nesting.blank?
143
+
144
+ [
145
+ nesting.camelize,
146
+ # Special case: application.rb might define ApplicationControlller.
147
+ ('ApplicationController' if nesting == 'application')
148
+ ]
149
+ end.flatten.compact.uniq
150
+ end
151
+
152
+ # Search for a file in load_paths matching the provided suffix.
153
+ def search_for_file(path_suffix)
154
+ path_suffix = path_suffix + '.rb' unless path_suffix.ends_with? '.rb'
155
+ load_paths.each do |root|
156
+ path = File.join(root, path_suffix)
157
+ return path if File.file? path
158
+ end
159
+ nil # Gee, I sure wish we had first_match ;-)
160
+ end
161
+
162
+ # Does the provided path_suffix correspond to an autoloadable module?
163
+ # Instead of returning a boolean, the autoload base for this module is returned.
164
+ def autoloadable_module?(path_suffix)
165
+ load_paths.each do |load_path|
166
+ return load_path if File.directory? File.join(load_path, path_suffix)
167
+ end
168
+ nil
169
+ end
170
+
171
+ def load_once_path?(path)
172
+ load_once_paths.any? { |base| path.starts_with? base }
173
+ end
174
+
175
+ # Attempt to autoload the provided module name by searching for a directory
176
+ # matching the expect path suffix. If found, the module is created and assigned
177
+ # to +into+'s constants with the name +const_name+. Provided that the directory
178
+ # was loaded from a reloadable base path, it is added to the set of constants
179
+ # that are to be unloaded.
180
+ def autoload_module!(into, const_name, qualified_name, path_suffix)
181
+ return nil unless base_path = autoloadable_module?(path_suffix)
182
+ mod = Module.new
183
+ into.const_set const_name, mod
184
+ autoloaded_constants << qualified_name unless load_once_paths.include?(base_path)
185
+ return mod
186
+ end
187
+
188
+ # Load the file at the provided path. +const_paths+ is a set of qualified
189
+ # constant names. When loading the file, Dependencies will watch for the
190
+ # addition of these constants. Each that is defined will be marked as
191
+ # autoloaded, and will be removed when Dependencies.clear is next called.
192
+ #
193
+ # If the second parameter is left off, then Dependencies will construct a set
194
+ # of names that the file at +path+ may define. See
195
+ # +loadable_constants_for_path+ for more details.
196
+ def load_file(path, const_paths = loadable_constants_for_path(path))
197
+ log_call path, const_paths
198
+ const_paths = [const_paths].compact unless const_paths.is_a? Array
199
+ parent_paths = const_paths.collect { |const_path| /(.*)::[^:]+\Z/ =~ const_path ? $1 : :Object }
200
+
201
+ result = nil
202
+ newly_defined_paths = new_constants_in(*parent_paths) do
203
+ result = load_without_new_constant_marking path
204
+ end
205
+
206
+ autoloaded_constants.concat newly_defined_paths unless load_once_path?(path)
207
+ autoloaded_constants.uniq!
208
+ log "loading #{path} defined #{newly_defined_paths * ', '}" unless newly_defined_paths.empty?
209
+ return result
210
+ end
211
+
212
+ # Return the constant path for the provided parent and constant name.
213
+ def qualified_name_for(mod, name)
214
+ mod_name = to_constant_name mod
215
+ (%w(Object Kernel).include? mod_name) ? name.to_s : "#{mod_name}::#{name}"
216
+ end
217
+
218
+ # Load the constant named +const_name+ which is missing from +from_mod+. If
219
+ # it is not possible to load the constant into from_mod, try its parent module
220
+ # using const_missing.
221
+ def load_missing_constant(from_mod, const_name)
222
+ log_call from_mod, const_name
223
+ if from_mod == Kernel
224
+ if ::Object.const_defined?(const_name)
225
+ log "Returning Object::#{const_name} for Kernel::#{const_name}"
226
+ return ::Object.const_get(const_name)
227
+ else
228
+ log "Substituting Object for Kernel"
229
+ from_mod = Object
230
+ end
231
+ end
232
+
233
+ # If we have an anonymous module, all we can do is attempt to load from Object.
234
+ from_mod = Object if from_mod.name.blank?
235
+
236
+ unless qualified_const_defined?(from_mod.name) && from_mod.name.constantize.object_id == from_mod.object_id
237
+ raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!"
238
+ end
239
+
240
+ raise ArgumentError, "#{from_mod} is not missing constant #{const_name}!" if from_mod.const_defined?(const_name)
241
+
242
+ qualified_name = qualified_name_for from_mod, const_name
243
+ path_suffix = qualified_name.underscore
244
+ name_error = NameError.new("uninitialized constant #{qualified_name}")
245
+
246
+ file_path = search_for_file(path_suffix)
247
+ if file_path && ! loaded.include?(File.expand_path(file_path)) # We found a matching file to load
248
+ require_or_load file_path
249
+ raise LoadError, "Expected #{file_path} to define #{qualified_name}" unless from_mod.const_defined?(const_name)
250
+ return from_mod.const_get(const_name)
251
+ elsif mod = autoload_module!(from_mod, const_name, qualified_name, path_suffix)
252
+ return mod
253
+ elsif (parent = from_mod.parent) && parent != from_mod &&
254
+ ! from_mod.parents.any? { |p| p.const_defined?(const_name) }
255
+ # If our parents do not have a constant named +const_name+ then we are free
256
+ # to attempt to load upwards. If they do have such a constant, then this
257
+ # const_missing must be due to from_mod::const_name, which should not
258
+ # return constants from from_mod's parents.
259
+ begin
260
+ return parent.const_missing(const_name)
261
+ rescue NameError => e
262
+ raise unless e.missing_name? qualified_name_for(parent, const_name)
263
+ raise name_error
264
+ end
265
+ else
266
+ raise name_error
267
+ end
268
+ end
269
+
270
+ # Remove the constants that have been autoloaded, and those that have been
271
+ # marked for unloading.
272
+ def remove_unloadable_constants!
273
+ autoloaded_constants.each { |const| remove_constant const }
274
+ autoloaded_constants.clear
275
+ explicitly_unloadable_constants.each { |const| remove_constant const }
276
+ end
277
+
278
+ # Determine if the given constant has been automatically loaded.
279
+ def autoloaded?(desc)
280
+ # No name => anonymous module.
281
+ return false if desc.is_a?(Module) && desc.name.blank?
282
+ name = to_constant_name desc
283
+ return false unless qualified_const_defined? name
284
+ return autoloaded_constants.include?(name)
285
+ end
286
+
287
+ # Will the provided constant descriptor be unloaded?
288
+ def will_unload?(const_desc)
289
+ autoloaded?(desc) ||
290
+ explicitly_unloadable_constants.include?(to_constant_name(const_desc))
291
+ end
292
+
293
+ # Mark the provided constant name for unloading. This constant will be
294
+ # unloaded on each request, not just the next one.
295
+ def mark_for_unload(const_desc)
296
+ name = to_constant_name const_desc
297
+ if explicitly_unloadable_constants.include? name
298
+ return false
299
+ else
300
+ explicitly_unloadable_constants << name
301
+ return true
302
+ end
303
+ end
304
+
305
+ # Run the provided block and detect the new constants that were loaded during
306
+ # its execution. Constants may only be regarded as 'new' once -- so if the
307
+ # block calls +new_constants_in+ again, then the constants defined within the
308
+ # inner call will not be reported in this one.
309
+ #
310
+ # If the provided block does not run to completion, and instead raises an
311
+ # exception, any new constants are regarded as being only partially defined
312
+ # and will be removed immediately.
313
+ def new_constants_in(*descs)
314
+ log_call(*descs)
315
+
316
+ # Build the watch frames. Each frame is a tuple of
317
+ # [module_name_as_string, constants_defined_elsewhere]
318
+ watch_frames = descs.collect do |desc|
319
+ if desc.is_a? Module
320
+ mod_name = desc.name
321
+ initial_constants = desc.local_constants
322
+ elsif desc.is_a?(String) || desc.is_a?(Symbol)
323
+ mod_name = desc.to_s
324
+
325
+ # Handle the case where the module has yet to be defined.
326
+ initial_constants = if qualified_const_defined?(mod_name)
327
+ mod_name.constantize.local_constants
328
+ else
329
+ []
330
+ end
331
+ else
332
+ raise Argument, "#{desc.inspect} does not describe a module!"
333
+ end
334
+
335
+ [mod_name, initial_constants]
336
+ end
337
+
338
+ constant_watch_stack.concat watch_frames
339
+
340
+ aborting = true
341
+ begin
342
+ yield # Now yield to the code that is to define new constants.
343
+ aborting = false
344
+ ensure
345
+ # Find the new constants.
346
+ new_constants = watch_frames.collect do |mod_name, prior_constants|
347
+ # Module still doesn't exist? Treat it as if it has no constants.
348
+ next [] unless qualified_const_defined?(mod_name)
349
+
350
+ mod = mod_name.constantize
351
+ next [] unless mod.is_a? Module
352
+ new_constants = mod.local_constants - prior_constants
353
+
354
+ # Make sure no other frames takes credit for these constants.
355
+ constant_watch_stack.each do |frame_name, constants|
356
+ constants.concat new_constants if frame_name == mod_name
357
+ end
358
+
359
+ new_constants.collect do |suffix|
360
+ mod_name == "Object" ? suffix : "#{mod_name}::#{suffix}"
361
+ end
362
+ end.flatten
363
+
364
+ log "New constants: #{new_constants * ', '}"
365
+
366
+ if aborting
367
+ log "Error during loading, removing partially loaded constants "
368
+ new_constants.each { |name| remove_constant name }
369
+ new_constants.clear
370
+ end
371
+ end
372
+
373
+ return new_constants
374
+ ensure
375
+ # Remove the stack frames that we added.
376
+ if defined?(watch_frames) && ! watch_frames.empty?
377
+ frame_ids = watch_frames.collect(&:object_id)
378
+ constant_watch_stack.delete_if do |watch_frame|
379
+ frame_ids.include? watch_frame.object_id
380
+ end
381
+ end
382
+ end
383
+
384
+ class LoadingModule #:nodoc:
385
+ # Old style environment.rb referenced this method directly. Please note, it doesn't
386
+ # actually *do* anything any more.
387
+ def self.root(*args)
388
+ if defined?(RAILS_DEFAULT_LOGGER)
389
+ RAILS_DEFAULT_LOGGER.warn "Your environment.rb uses the old syntax, it may not continue to work in future releases."
390
+ RAILS_DEFAULT_LOGGER.warn "For upgrade instructions please see: http://manuals.rubyonrails.com/read/book/19"
391
+ end
392
+ end
393
+ end
394
+
395
+ # Convert the provided const desc to a qualified constant name (as a string).
396
+ # A module, class, symbol, or string may be provided.
397
+ def to_constant_name(desc) #:nodoc:
398
+ name = case desc
399
+ when String then desc.starts_with?('::') ? desc[2..-1] : desc
400
+ when Symbol then desc.to_s
401
+ when Module
402
+ raise ArgumentError, "Anonymous modules have no name to be referenced by" if desc.name.blank?
403
+ desc.name
404
+ else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
405
+ end
406
+ end
407
+
408
+ def remove_constant(const) #:nodoc:
409
+ return false unless qualified_const_defined? const
410
+
411
+ const = $1 if /\A::(.*)\Z/ =~ const.to_s
412
+ names = const.to_s.split('::')
413
+ if names.size == 1 # It's under Object
414
+ parent = Object
415
+ else
416
+ parent = (names[0..-2] * '::').constantize
417
+ end
418
+
419
+ log "removing constant #{const}"
420
+ parent.instance_eval { remove_const names.last }
421
+ return true
422
+ end
423
+
424
+ protected
425
+ def log_call(*args)
426
+ arg_str = args.collect(&:inspect) * ', '
427
+ /in `([a-z_\?\!]+)'/ =~ caller(1).first
428
+ selector = $1 || '<unknown>'
429
+ log "called #{selector}(#{arg_str})"
430
+ end
431
+
432
+ def log(msg)
433
+ if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER && log_activity
434
+ RAILS_DEFAULT_LOGGER.debug "Dependencies: #{msg}"
435
+ end
436
+ end
437
+
438
+ end
439
+
440
+ Object.instance_eval do
441
+ define_method(:require_or_load) { |file_name| Dependencies.require_or_load(file_name) } unless Object.respond_to?(:require_or_load)
442
+ define_method(:require_dependency) { |file_name| Dependencies.depend_on(file_name) } unless Object.respond_to?(:require_dependency)
443
+ define_method(:require_association) { |file_name| Dependencies.associate_with(file_name) } unless Object.respond_to?(:require_association)
444
+ end
445
+
446
+ class Module #:nodoc:
447
+ # Rename the original handler so we can chain it to the new one
448
+ alias :rails_original_const_missing :const_missing
449
+
450
+ # Use const_missing to autoload associations so we don't have to
451
+ # require_association when using single-table inheritance.
452
+ def const_missing(class_id)
453
+ Dependencies.load_missing_constant self, class_id
454
+ end
455
+
456
+ def unloadable(const_desc = self)
457
+ super(const_desc)
458
+ end
459
+
460
+ end
461
+
462
+ class Class
463
+ def const_missing(const_name)
464
+ if [Object, Kernel].include?(self) || parent == self
465
+ super
466
+ else
467
+ begin
468
+ begin
469
+ Dependencies.load_missing_constant self, const_name
470
+ rescue NameError
471
+ parent.send :const_missing, const_name
472
+ end
473
+ rescue NameError => e
474
+ # Make sure that the name we are missing is the one that caused the error
475
+ parent_qualified_name = Dependencies.qualified_name_for parent, const_name
476
+ raise unless e.missing_name? parent_qualified_name
477
+ qualified_name = Dependencies.qualified_name_for self, const_name
478
+ raise NameError.new("uninitialized constant #{qualified_name}").copy_blame!(e)
479
+ end
480
+ end
481
+ end
482
+ end
483
+
484
+ class Object
485
+
486
+ alias_method :load_without_new_constant_marking, :load
487
+
488
+ def load(file, *extras) #:nodoc:
489
+ Dependencies.new_constants_in(Object) { super(file, *extras) }
490
+ rescue Exception => exception # errors from loading file
491
+ exception.blame_file! file
492
+ raise
493
+ end
494
+
495
+ def require(file, *extras) #:nodoc:
496
+ Dependencies.new_constants_in(Object) { super(file, *extras) }
497
+ rescue Exception => exception # errors from required file
498
+ exception.blame_file! file
499
+ raise
500
+ end
501
+
502
+ # Mark the given constant as unloadable. Unloadable constants are removed each
503
+ # time dependencies are cleared.
504
+ #
505
+ # Note that marking a constant for unloading need only be done once. Setup
506
+ # or init scripts may list each unloadable constant that may need unloading;
507
+ # each constant will be removed for every subsequent clear, as opposed to for
508
+ # the first clear.
509
+ #
510
+ # The provided constant descriptor may be a (non-anonymous) module or class,
511
+ # or a qualified constant name as a string or symbol.
512
+ #
513
+ # Returns true if the constant was not previously marked for unloading, false
514
+ # otherwise.
515
+ def unloadable(const_desc)
516
+ Dependencies.mark_for_unload const_desc
517
+ end
518
+
519
+ end
520
+
521
+ # Add file-blaming to exceptions
522
+ class Exception #:nodoc:
523
+ def blame_file!(file)
524
+ (@blamed_files ||= []).unshift file
525
+ end
526
+
527
+ def blamed_files
528
+ @blamed_files ||= []
529
+ end
530
+
531
+ def describe_blame
532
+ return nil if blamed_files.empty?
533
+ "This error occurred while loading the following files:\n #{blamed_files.join "\n "}"
534
+ end
535
+
536
+ def copy_blame!(exc)
537
+ @blamed_files = exc.blamed_files.clone
538
+ self
539
+ end
540
+ end