csd 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. data/COPYING +1 -2
  2. data/README.rdoc +7 -1
  3. data/Rakefile +7 -2
  4. data/VERSION +1 -1
  5. data/csd.gemspec +18 -216
  6. data/lib/csd.rb +6 -16
  7. data/lib/csd/application.rb +2 -2
  8. data/lib/csd/application/default.rb +15 -14
  9. data/lib/csd/application/default/base.rb +1 -1
  10. data/lib/csd/application/minisip.rb +43 -11
  11. data/lib/csd/application/minisip/about.yml +5 -5
  12. data/lib/csd/application/minisip/base.rb +82 -70
  13. data/lib/csd/application/minisip/error.rb +1 -1
  14. data/lib/csd/application/minisip/options/common.rb +1 -1
  15. data/lib/csd/application/minisip/options/compile.rb +1 -1
  16. data/lib/csd/application/minisip/options/package.rb +1 -1
  17. data/lib/csd/application/minisip/unix.rb +40 -27
  18. data/lib/csd/application/minisip/unix/darwin.rb +12 -0
  19. data/lib/csd/application/minisip/unix/linux.rb +1 -11
  20. data/lib/csd/application/minisip/unix/linux/debian.rb +14 -25
  21. data/lib/csd/application/minisip/unix/linux/debian/ubuntu10.rb +12 -13
  22. data/lib/csd/applications.rb +5 -5
  23. data/lib/csd/commands.rb +164 -89
  24. data/lib/csd/container.rb +61 -0
  25. data/lib/csd/error.rb +10 -1
  26. data/lib/csd/extensions.rb +3 -2
  27. data/lib/csd/extensions/core/array.rb +29 -1
  28. data/lib/csd/extensions/core/dir.rb +15 -24
  29. data/lib/csd/extensions/core/object.rb +10 -2
  30. data/lib/csd/extensions/core/option_parser.rb +22 -3
  31. data/lib/csd/extensions/core/pathname.rb +30 -2
  32. data/lib/csd/extensions/core/string.rb +51 -4
  33. data/lib/csd/extensions/gem/platform.rb +18 -3
  34. data/lib/csd/{options.rb → options_parser.rb} +16 -20
  35. data/lib/csd/path_container.rb +24 -0
  36. data/lib/csd/user_interface.rb +2 -0
  37. data/lib/csd/user_interface/base.rb +26 -0
  38. data/lib/csd/user_interface/cli.rb +37 -0
  39. data/lib/csd/vendor/active_support/MIT-LICENSE +20 -0
  40. data/lib/csd/vendor/active_support/inflector.rb +155 -0
  41. data/lib/csd/vendor/term/GPL2-LICENSE +339 -0
  42. data/lib/csd/vendor/term/ansicolor.rb +113 -0
  43. data/lib/csd/version.rb +13 -4
  44. data/test/application/test_minisip.rb +45 -0
  45. data/test/functional/test_applications.rb +10 -16
  46. data/test/functional/test_commands.rb +260 -23
  47. data/test/unit/test_string.rb +1 -1
  48. metadata +18 -216
  49. data/lib/active_support.rb +0 -75
  50. data/lib/active_support/all.rb +0 -3
  51. data/lib/active_support/backtrace_cleaner.rb +0 -94
  52. data/lib/active_support/base64.rb +0 -42
  53. data/lib/active_support/basic_object.rb +0 -21
  54. data/lib/active_support/benchmarkable.rb +0 -60
  55. data/lib/active_support/buffered_logger.rb +0 -132
  56. data/lib/active_support/builder.rb +0 -6
  57. data/lib/active_support/cache.rb +0 -626
  58. data/lib/active_support/cache/compressed_mem_cache_store.rb +0 -13
  59. data/lib/active_support/cache/file_store.rb +0 -188
  60. data/lib/active_support/cache/mem_cache_store.rb +0 -191
  61. data/lib/active_support/cache/memory_store.rb +0 -159
  62. data/lib/active_support/cache/strategy/local_cache.rb +0 -164
  63. data/lib/active_support/cache/synchronized_memory_store.rb +0 -11
  64. data/lib/active_support/callbacks.rb +0 -600
  65. data/lib/active_support/concern.rb +0 -29
  66. data/lib/active_support/configurable.rb +0 -36
  67. data/lib/active_support/core_ext.rb +0 -3
  68. data/lib/active_support/core_ext/array.rb +0 -7
  69. data/lib/active_support/core_ext/array/access.rb +0 -46
  70. data/lib/active_support/core_ext/array/conversions.rb +0 -164
  71. data/lib/active_support/core_ext/array/extract_options.rb +0 -29
  72. data/lib/active_support/core_ext/array/grouping.rb +0 -100
  73. data/lib/active_support/core_ext/array/random_access.rb +0 -20
  74. data/lib/active_support/core_ext/array/uniq_by.rb +0 -17
  75. data/lib/active_support/core_ext/array/wrap.rb +0 -22
  76. data/lib/active_support/core_ext/benchmark.rb +0 -7
  77. data/lib/active_support/core_ext/big_decimal.rb +0 -1
  78. data/lib/active_support/core_ext/big_decimal/conversions.rb +0 -27
  79. data/lib/active_support/core_ext/cgi.rb +0 -1
  80. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -19
  81. data/lib/active_support/core_ext/class.rb +0 -4
  82. data/lib/active_support/core_ext/class/attribute.rb +0 -67
  83. data/lib/active_support/core_ext/class/attribute_accessors.rb +0 -63
  84. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -44
  85. data/lib/active_support/core_ext/class/inheritable_attributes.rb +0 -232
  86. data/lib/active_support/core_ext/class/subclasses.rb +0 -55
  87. data/lib/active_support/core_ext/date/acts_like.rb +0 -8
  88. data/lib/active_support/core_ext/date/calculations.rb +0 -240
  89. data/lib/active_support/core_ext/date/conversions.rb +0 -99
  90. data/lib/active_support/core_ext/date/freeze.rb +0 -31
  91. data/lib/active_support/core_ext/date_time/acts_like.rb +0 -13
  92. data/lib/active_support/core_ext/date_time/calculations.rb +0 -113
  93. data/lib/active_support/core_ext/date_time/conversions.rb +0 -102
  94. data/lib/active_support/core_ext/date_time/zones.rb +0 -17
  95. data/lib/active_support/core_ext/enumerable.rb +0 -119
  96. data/lib/active_support/core_ext/exception.rb +0 -3
  97. data/lib/active_support/core_ext/file.rb +0 -2
  98. data/lib/active_support/core_ext/file/atomic.rb +0 -41
  99. data/lib/active_support/core_ext/file/path.rb +0 -5
  100. data/lib/active_support/core_ext/float.rb +0 -1
  101. data/lib/active_support/core_ext/float/rounding.rb +0 -19
  102. data/lib/active_support/core_ext/hash.rb +0 -8
  103. data/lib/active_support/core_ext/hash/conversions.rb +0 -150
  104. data/lib/active_support/core_ext/hash/deep_merge.rb +0 -16
  105. data/lib/active_support/core_ext/hash/diff.rb +0 -13
  106. data/lib/active_support/core_ext/hash/except.rb +0 -24
  107. data/lib/active_support/core_ext/hash/indifferent_access.rb +0 -14
  108. data/lib/active_support/core_ext/hash/keys.rb +0 -45
  109. data/lib/active_support/core_ext/hash/reverse_merge.rb +0 -28
  110. data/lib/active_support/core_ext/hash/slice.rb +0 -38
  111. data/lib/active_support/core_ext/integer.rb +0 -3
  112. data/lib/active_support/core_ext/integer/inflections.rb +0 -14
  113. data/lib/active_support/core_ext/integer/multiple.rb +0 -6
  114. data/lib/active_support/core_ext/integer/time.rb +0 -39
  115. data/lib/active_support/core_ext/kernel.rb +0 -5
  116. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  117. data/lib/active_support/core_ext/kernel/debugger.rb +0 -16
  118. data/lib/active_support/core_ext/kernel/reporting.rb +0 -62
  119. data/lib/active_support/core_ext/kernel/requires.rb +0 -26
  120. data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -13
  121. data/lib/active_support/core_ext/load_error.rb +0 -23
  122. data/lib/active_support/core_ext/logger.rb +0 -146
  123. data/lib/active_support/core_ext/module.rb +0 -12
  124. data/lib/active_support/core_ext/module/aliasing.rb +0 -70
  125. data/lib/active_support/core_ext/module/anonymous.rb +0 -24
  126. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +0 -31
  127. data/lib/active_support/core_ext/module/attr_internal.rb +0 -32
  128. data/lib/active_support/core_ext/module/attribute_accessors.rb +0 -66
  129. data/lib/active_support/core_ext/module/delegation.rb +0 -146
  130. data/lib/active_support/core_ext/module/deprecation.rb +0 -9
  131. data/lib/active_support/core_ext/module/introspection.rb +0 -88
  132. data/lib/active_support/core_ext/module/method_names.rb +0 -14
  133. data/lib/active_support/core_ext/module/reachable.rb +0 -10
  134. data/lib/active_support/core_ext/module/remove_method.rb +0 -6
  135. data/lib/active_support/core_ext/module/synchronization.rb +0 -42
  136. data/lib/active_support/core_ext/name_error.rb +0 -18
  137. data/lib/active_support/core_ext/numeric.rb +0 -2
  138. data/lib/active_support/core_ext/numeric/bytes.rb +0 -44
  139. data/lib/active_support/core_ext/numeric/time.rb +0 -77
  140. data/lib/active_support/core_ext/object.rb +0 -14
  141. data/lib/active_support/core_ext/object/acts_like.rb +0 -10
  142. data/lib/active_support/core_ext/object/blank.rb +0 -76
  143. data/lib/active_support/core_ext/object/conversions.rb +0 -4
  144. data/lib/active_support/core_ext/object/duplicable.rb +0 -65
  145. data/lib/active_support/core_ext/object/extending.rb +0 -11
  146. data/lib/active_support/core_ext/object/instance_variables.rb +0 -67
  147. data/lib/active_support/core_ext/object/misc.rb +0 -2
  148. data/lib/active_support/core_ext/object/returning.rb +0 -42
  149. data/lib/active_support/core_ext/object/to_param.rb +0 -49
  150. data/lib/active_support/core_ext/object/to_query.rb +0 -27
  151. data/lib/active_support/core_ext/object/try.rb +0 -36
  152. data/lib/active_support/core_ext/object/with_options.rb +0 -26
  153. data/lib/active_support/core_ext/proc.rb +0 -14
  154. data/lib/active_support/core_ext/process.rb +0 -1
  155. data/lib/active_support/core_ext/process/daemon.rb +0 -23
  156. data/lib/active_support/core_ext/range.rb +0 -4
  157. data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
  158. data/lib/active_support/core_ext/range/conversions.rb +0 -21
  159. data/lib/active_support/core_ext/range/include_range.rb +0 -21
  160. data/lib/active_support/core_ext/range/overlaps.rb +0 -8
  161. data/lib/active_support/core_ext/regexp.rb +0 -5
  162. data/lib/active_support/core_ext/rexml.rb +0 -46
  163. data/lib/active_support/core_ext/string.rb +0 -12
  164. data/lib/active_support/core_ext/string/access.rb +0 -99
  165. data/lib/active_support/core_ext/string/behavior.rb +0 -7
  166. data/lib/active_support/core_ext/string/conversions.rb +0 -61
  167. data/lib/active_support/core_ext/string/encoding.rb +0 -11
  168. data/lib/active_support/core_ext/string/exclude.rb +0 -6
  169. data/lib/active_support/core_ext/string/filters.rb +0 -49
  170. data/lib/active_support/core_ext/string/inflections.rb +0 -149
  171. data/lib/active_support/core_ext/string/interpolation.rb +0 -2
  172. data/lib/active_support/core_ext/string/multibyte.rb +0 -72
  173. data/lib/active_support/core_ext/string/output_safety.rb +0 -109
  174. data/lib/active_support/core_ext/string/starts_ends_with.rb +0 -4
  175. data/lib/active_support/core_ext/string/xchar.rb +0 -18
  176. data/lib/active_support/core_ext/time/acts_like.rb +0 -8
  177. data/lib/active_support/core_ext/time/calculations.rb +0 -282
  178. data/lib/active_support/core_ext/time/conversions.rb +0 -85
  179. data/lib/active_support/core_ext/time/marshal.rb +0 -56
  180. data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
  181. data/lib/active_support/core_ext/time/zones.rb +0 -78
  182. data/lib/active_support/core_ext/uri.rb +0 -22
  183. data/lib/active_support/dependencies.rb +0 -628
  184. data/lib/active_support/dependencies/autoload.rb +0 -50
  185. data/lib/active_support/deprecation.rb +0 -18
  186. data/lib/active_support/deprecation/behaviors.rb +0 -38
  187. data/lib/active_support/deprecation/method_wrappers.rb +0 -29
  188. data/lib/active_support/deprecation/proxy_wrappers.rb +0 -74
  189. data/lib/active_support/deprecation/reporting.rb +0 -56
  190. data/lib/active_support/duration.rb +0 -105
  191. data/lib/active_support/gzip.rb +0 -25
  192. data/lib/active_support/hash_with_indifferent_access.rb +0 -145
  193. data/lib/active_support/i18n.rb +0 -8
  194. data/lib/active_support/inflections.rb +0 -56
  195. data/lib/active_support/inflector.rb +0 -7
  196. data/lib/active_support/inflector/inflections.rb +0 -211
  197. data/lib/active_support/inflector/methods.rb +0 -141
  198. data/lib/active_support/inflector/transliterate.rb +0 -97
  199. data/lib/active_support/json.rb +0 -2
  200. data/lib/active_support/json/backends/jsongem.rb +0 -43
  201. data/lib/active_support/json/backends/yajl.rb +0 -40
  202. data/lib/active_support/json/backends/yaml.rb +0 -90
  203. data/lib/active_support/json/decoding.rb +0 -51
  204. data/lib/active_support/json/encoding.rb +0 -254
  205. data/lib/active_support/json/variable.rb +0 -11
  206. data/lib/active_support/lazy_load_hooks.rb +0 -27
  207. data/lib/active_support/locale/en.yml +0 -36
  208. data/lib/active_support/memoizable.rb +0 -103
  209. data/lib/active_support/message_encryptor.rb +0 -71
  210. data/lib/active_support/message_verifier.rb +0 -62
  211. data/lib/active_support/multibyte.rb +0 -44
  212. data/lib/active_support/multibyte/chars.rb +0 -480
  213. data/lib/active_support/multibyte/exceptions.rb +0 -8
  214. data/lib/active_support/multibyte/unicode.rb +0 -393
  215. data/lib/active_support/multibyte/utils.rb +0 -60
  216. data/lib/active_support/notifications.rb +0 -81
  217. data/lib/active_support/notifications/fanout.rb +0 -93
  218. data/lib/active_support/notifications/instrumenter.rb +0 -56
  219. data/lib/active_support/option_merger.rb +0 -25
  220. data/lib/active_support/ordered_hash.rb +0 -158
  221. data/lib/active_support/ordered_options.rb +0 -27
  222. data/lib/active_support/railtie.rb +0 -100
  223. data/lib/active_support/rescuable.rb +0 -114
  224. data/lib/active_support/ruby/shim.rb +0 -22
  225. data/lib/active_support/secure_random.rb +0 -199
  226. data/lib/active_support/string_inquirer.rb +0 -21
  227. data/lib/active_support/test_case.rb +0 -42
  228. data/lib/active_support/testing/assertions.rb +0 -82
  229. data/lib/active_support/testing/declarative.rb +0 -40
  230. data/lib/active_support/testing/default.rb +0 -9
  231. data/lib/active_support/testing/deprecation.rb +0 -55
  232. data/lib/active_support/testing/isolation.rb +0 -154
  233. data/lib/active_support/testing/pending.rb +0 -48
  234. data/lib/active_support/testing/performance.rb +0 -455
  235. data/lib/active_support/testing/setup_and_teardown.rb +0 -111
  236. data/lib/active_support/time.rb +0 -34
  237. data/lib/active_support/time/autoload.rb +0 -5
  238. data/lib/active_support/time_with_zone.rb +0 -341
  239. data/lib/active_support/values/time_zone.rb +0 -377
  240. data/lib/active_support/values/unicode_tables.dat +0 -0
  241. data/lib/active_support/version.rb +0 -10
  242. data/lib/active_support/whiny_nil.rb +0 -60
  243. data/lib/active_support/xml_mini.rb +0 -158
  244. data/lib/active_support/xml_mini/jdom.rb +0 -168
  245. data/lib/active_support/xml_mini/libxml.rb +0 -80
  246. data/lib/active_support/xml_mini/libxmlsax.rb +0 -85
  247. data/lib/active_support/xml_mini/nokogiri.rb +0 -78
  248. data/lib/active_support/xml_mini/nokogirisax.rb +0 -83
  249. data/lib/active_support/xml_mini/rexml.rb +0 -129
  250. data/lib/csd/extensions/core/file.rb +0 -14
  251. data/lib/csd/global_open_struct.rb +0 -19
  252. data/lib/csd/path.rb +0 -32
  253. data/lib/csd/ui.rb +0 -2
  254. data/lib/csd/ui/cli.rb +0 -8
  255. data/lib/csd/ui/ui.rb +0 -45
  256. data/lib/term/ansicolor.rb +0 -102
  257. data/lib/term/ansicolor/.keep +0 -0
  258. data/lib/term/ansicolor/version.rb +0 -10
@@ -1,10 +0,0 @@
1
- require 'date'
2
-
3
- class Time
4
- # Ruby 1.8-cvs and early 1.9 series define private Time#to_date
5
- %w(to_date to_datetime).each do |method|
6
- if private_instance_methods.include?(method) || private_instance_methods.include?(method.to_sym)
7
- public method
8
- end
9
- end
10
- end
@@ -1,78 +0,0 @@
1
- require 'active_support/time_with_zone'
2
-
3
- class Time
4
- class << self
5
- attr_accessor :zone_default
6
-
7
- # Returns the TimeZone for the current request, if this has been set (via Time.zone=).
8
- # If <tt>Time.zone</tt> has not been set for the current request, returns the TimeZone specified in <tt>config.time_zone</tt>.
9
- def zone
10
- Thread.current[:time_zone] || zone_default
11
- end
12
-
13
- # Sets <tt>Time.zone</tt> to a TimeZone object for the current request/thread.
14
- #
15
- # This method accepts any of the following:
16
- #
17
- # * A Rails TimeZone object.
18
- # * An identifier for a Rails TimeZone object (e.g., "Eastern Time (US & Canada)", <tt>-5.hours</tt>).
19
- # * A TZInfo::Timezone object.
20
- # * An identifier for a TZInfo::Timezone object (e.g., "America/New_York").
21
- #
22
- # Here's an example of how you might set <tt>Time.zone</tt> on a per request basis -- <tt>current_user.time_zone</tt>
23
- # just needs to return a string identifying the user's preferred TimeZone:
24
- #
25
- # class ApplicationController < ActionController::Base
26
- # before_filter :set_time_zone
27
- #
28
- # def set_time_zone
29
- # Time.zone = current_user.time_zone
30
- # end
31
- # end
32
- def zone=(time_zone)
33
- Thread.current[:time_zone] = get_zone(time_zone)
34
- end
35
-
36
- # Allows override of <tt>Time.zone</tt> locally inside supplied block; resets <tt>Time.zone</tt> to existing value when done.
37
- def use_zone(time_zone)
38
- old_zone, ::Time.zone = ::Time.zone, get_zone(time_zone)
39
- yield
40
- ensure
41
- ::Time.zone = old_zone
42
- end
43
-
44
- # Returns <tt>Time.zone.now</tt> when <tt>config.time_zone</tt> is set, otherwise just returns <tt>Time.now</tt>.
45
- def current
46
- ::Time.zone_default ? ::Time.zone.now : ::Time.now
47
- end
48
-
49
- private
50
- def get_zone(time_zone)
51
- return time_zone if time_zone.nil? || time_zone.is_a?(ActiveSupport::TimeZone)
52
- # lookup timezone based on identifier (unless we've been passed a TZInfo::Timezone)
53
- unless time_zone.respond_to?(:period_for_local)
54
- time_zone = ActiveSupport::TimeZone[time_zone] || TZInfo::Timezone.get(time_zone) rescue nil
55
- end
56
- # Return if a TimeZone instance, or wrap in a TimeZone instance if a TZInfo::Timezone
57
- if time_zone
58
- time_zone.is_a?(ActiveSupport::TimeZone) ? time_zone : ActiveSupport::TimeZone.create(time_zone.name, nil, time_zone)
59
- end
60
- end
61
- end
62
-
63
- # Returns the simultaneous time in <tt>Time.zone</tt>.
64
- #
65
- # Time.zone = 'Hawaii' # => 'Hawaii'
66
- # Time.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
67
- #
68
- # This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt> as the local zone
69
- # instead of the operating system's time zone.
70
- #
71
- # You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument,
72
- # and the conversion will be based on that zone instead of <tt>Time.zone</tt>.
73
- #
74
- # Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
75
- def in_time_zone(zone = ::Time.zone)
76
- ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.__send__(:get_zone, zone))
77
- end
78
- end
@@ -1,22 +0,0 @@
1
- # encoding: utf-8
2
-
3
- if RUBY_VERSION >= '1.9'
4
- require 'uri'
5
-
6
- str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese.
7
-
8
- parser = URI::Parser.new
9
-
10
- unless str == parser.unescape(parser.escape(str))
11
- URI::Parser.class_eval do
12
- remove_method :unescape
13
- def unescape(str, escaped = /%[a-fA-F\d]{2}/)
14
- # TODO: Are we actually sure that ASCII == UTF-8?
15
- # YK: My initial experiments say yes, but let's be sure please
16
- enc = str.encoding
17
- enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
18
- str.gsub(escaped) { [$&[1, 2].hex].pack('C') }.force_encoding(enc)
19
- end
20
- end
21
- end
22
- end
@@ -1,628 +0,0 @@
1
- require 'set'
2
- require 'thread'
3
- require 'pathname'
4
- require 'active_support/core_ext/module/aliasing'
5
- require 'active_support/core_ext/module/attribute_accessors'
6
- require 'active_support/core_ext/module/introspection'
7
- require 'active_support/core_ext/module/anonymous'
8
- require 'active_support/core_ext/object/blank'
9
- require 'active_support/core_ext/load_error'
10
- require 'active_support/core_ext/name_error'
11
- require 'active_support/core_ext/string/starts_ends_with'
12
- require 'active_support/inflector'
13
-
14
- module ActiveSupport #:nodoc:
15
- module Dependencies #:nodoc:
16
- extend self
17
-
18
- # Should we turn on Ruby warnings on the first load of dependent files?
19
- mattr_accessor :warnings_on_first_load
20
- self.warnings_on_first_load = false
21
-
22
- # All files ever loaded.
23
- mattr_accessor :history
24
- self.history = Set.new
25
-
26
- # All files currently loaded.
27
- mattr_accessor :loaded
28
- self.loaded = Set.new
29
-
30
- # Should we load files or require them?
31
- mattr_accessor :mechanism
32
- self.mechanism = ENV['NO_RELOAD'] ? :require : :load
33
-
34
- # The set of directories from which we may automatically load files. Files
35
- # under these directories will be reloaded on each request in development mode,
36
- # unless the directory also appears in load_once_paths.
37
- mattr_accessor :load_paths
38
- self.load_paths = []
39
-
40
- # The set of directories from which automatically loaded constants are loaded
41
- # only once. All directories in this set must also be present in +load_paths+.
42
- mattr_accessor :load_once_paths
43
- self.load_once_paths = []
44
-
45
- # An array of qualified constant names that have been loaded. Adding a name to
46
- # this array will cause it to be unloaded the next time Dependencies are cleared.
47
- mattr_accessor :autoloaded_constants
48
- self.autoloaded_constants = []
49
-
50
- mattr_accessor :references
51
- self.references = {}
52
-
53
- # An array of constant names that need to be unloaded on every request. Used
54
- # to allow arbitrary constants to be marked for unloading.
55
- mattr_accessor :explicitly_unloadable_constants
56
- self.explicitly_unloadable_constants = []
57
-
58
- # The logger is used for generating information on the action run-time (including benchmarking) if available.
59
- # Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers.
60
- mattr_accessor :logger
61
-
62
- # Set to true to enable logging of const_missing and file loads
63
- mattr_accessor :log_activity
64
- self.log_activity = false
65
-
66
- class WatchStack < Array
67
- def initialize
68
- @mutex = Mutex.new
69
- end
70
-
71
- def self.locked(*methods)
72
- methods.each { |m| class_eval "def #{m}(*) lock { super } end", __FILE__, __LINE__ }
73
- end
74
-
75
- def get(key)
76
- (val = assoc(key)) ? val[1] : []
77
- end
78
-
79
- locked :concat, :each, :delete_if, :<<
80
-
81
- def new_constants_for(frames)
82
- constants = []
83
- frames.each do |mod_name, prior_constants|
84
- mod = Inflector.constantize(mod_name) if Dependencies.qualified_const_defined?(mod_name)
85
- next unless mod.is_a?(Module)
86
-
87
- new_constants = mod.local_constant_names - prior_constants
88
- get(mod_name).concat(new_constants)
89
-
90
- new_constants.each do |suffix|
91
- constants << ([mod_name, suffix] - ["Object"]).join("::")
92
- end
93
- end
94
- constants
95
- end
96
-
97
- # Add a set of modules to the watch stack, remembering the initial constants
98
- def add_modules(modules)
99
- list = modules.map do |desc|
100
- name = Dependencies.to_constant_name(desc)
101
- consts = Dependencies.qualified_const_defined?(name) ?
102
- Inflector.constantize(name).local_constant_names : []
103
- [name, consts]
104
- end
105
- concat(list)
106
- list
107
- end
108
-
109
- def lock
110
- @mutex.synchronize { yield self }
111
- end
112
- end
113
-
114
- # An internal stack used to record which constants are loaded by any block.
115
- mattr_accessor :constant_watch_stack
116
- self.constant_watch_stack = WatchStack.new
117
-
118
- # Module includes this module
119
- module ModuleConstMissing #:nodoc:
120
- def self.append_features(base)
121
- base.class_eval do
122
- # Emulate #exclude via an ivar
123
- return if defined?(@_const_missing) && @_const_missing
124
- @_const_missing = instance_method(:const_missing)
125
- remove_method(:const_missing)
126
- end
127
- super
128
- end
129
-
130
- def self.exclude_from(base)
131
- base.class_eval do
132
- define_method :const_missing, @_const_missing
133
- @_const_missing = nil
134
- end
135
- end
136
-
137
- # Use const_missing to autoload associations so we don't have to
138
- # require_association when using single-table inheritance.
139
- def const_missing(const_name, nesting = nil)
140
- klass_name = name.presence || "Object"
141
-
142
- if !nesting
143
- # We'll assume that the nesting of Foo::Bar is ["Foo::Bar", "Foo"]
144
- # even though it might not be, such as in the case of
145
- # class Foo::Bar; Baz; end
146
- nesting = []
147
- klass_name.to_s.scan(/::|$/) { nesting.unshift $` }
148
- end
149
-
150
- # If there are multiple levels of nesting to search under, the top
151
- # level is the one we want to report as the lookup fail.
152
- error = nil
153
-
154
- nesting.each do |namespace|
155
- begin
156
- return Dependencies.load_missing_constant namespace.constantize, const_name
157
- rescue NoMethodError then raise
158
- rescue NameError => e
159
- error ||= e
160
- end
161
- end
162
-
163
- # Raise the first error for this set. If this const_missing came from an
164
- # earlier const_missing, this will result in the real error bubbling
165
- # all the way up
166
- raise error
167
- end
168
-
169
- def unloadable(const_desc = self)
170
- super(const_desc)
171
- end
172
- end
173
-
174
- # Object includes this module
175
- module Loadable #:nodoc:
176
- def self.exclude_from(base)
177
- base.class_eval { define_method(:load, Kernel.instance_method(:load)) }
178
- end
179
-
180
- def require_or_load(file_name)
181
- Dependencies.require_or_load(file_name)
182
- end
183
-
184
- def require_dependency(file_name, message = "No such file to load -- %s")
185
- unless file_name.is_a?(String)
186
- raise ArgumentError, "the file name must be a String -- you passed #{file_name.inspect}"
187
- end
188
-
189
- Dependencies.depend_on(file_name, false, message)
190
- end
191
-
192
- def require_association(file_name)
193
- Dependencies.associate_with(file_name)
194
- end
195
-
196
- def load_dependency(file)
197
- if Dependencies.load?
198
- Dependencies.new_constants_in(Object) { yield }.presence
199
- else
200
- yield
201
- end
202
- rescue Exception => exception # errors from loading file
203
- exception.blame_file! file
204
- raise
205
- end
206
-
207
- def load(file, *)
208
- load_dependency(file) { super }
209
- end
210
-
211
- def require(file, *)
212
- load_dependency(file) { super }
213
- end
214
-
215
- # Mark the given constant as unloadable. Unloadable constants are removed each
216
- # time dependencies are cleared.
217
- #
218
- # Note that marking a constant for unloading need only be done once. Setup
219
- # or init scripts may list each unloadable constant that may need unloading;
220
- # each constant will be removed for every subsequent clear, as opposed to for
221
- # the first clear.
222
- #
223
- # The provided constant descriptor may be a (non-anonymous) module or class,
224
- # or a qualified constant name as a string or symbol.
225
- #
226
- # Returns true if the constant was not previously marked for unloading, false
227
- # otherwise.
228
- def unloadable(const_desc)
229
- Dependencies.mark_for_unload const_desc
230
- end
231
- end
232
-
233
- # Exception file-blaming
234
- module Blamable #:nodoc:
235
- def blame_file!(file)
236
- (@blamed_files ||= []).unshift file
237
- end
238
-
239
- def blamed_files
240
- @blamed_files ||= []
241
- end
242
-
243
- def describe_blame
244
- return nil if blamed_files.empty?
245
- "This error occurred while loading the following files:\n #{blamed_files.join "\n "}"
246
- end
247
-
248
- def copy_blame!(exc)
249
- @blamed_files = exc.blamed_files.clone
250
- self
251
- end
252
- end
253
-
254
- def hook!
255
- Object.class_eval { include Loadable }
256
- Module.class_eval { include ModuleConstMissing }
257
- Exception.class_eval { include Blamable }
258
- true
259
- end
260
-
261
- def unhook!
262
- ModuleConstMissing.exclude_from(Module)
263
- Loadable.exclude_from(Object)
264
- true
265
- end
266
-
267
- def load?
268
- mechanism == :load
269
- end
270
-
271
- def depend_on(file_name, swallow_load_errors = false, message = "No such file to load -- %s.rb")
272
- path = search_for_file(file_name)
273
- require_or_load(path || file_name)
274
- rescue LoadError => load_error
275
- unless swallow_load_errors
276
- if file_name = load_error.message[/ -- (.*?)(\.rb)?$/, 1]
277
- raise LoadError.new(message % file_name).copy_blame!(load_error)
278
- end
279
- raise
280
- end
281
- end
282
-
283
- def associate_with(file_name)
284
- depend_on(file_name, true)
285
- end
286
-
287
- def clear
288
- log_call
289
- loaded.clear
290
- remove_unloadable_constants!
291
- end
292
-
293
- def require_or_load(file_name, const_path = nil)
294
- log_call file_name, const_path
295
- file_name = $1 if file_name =~ /^(.*)\.rb$/
296
- expanded = File.expand_path(file_name)
297
- return if loaded.include?(expanded)
298
-
299
- # Record that we've seen this file *before* loading it to avoid an
300
- # infinite loop with mutual dependencies.
301
- loaded << expanded
302
-
303
- begin
304
- if load?
305
- log "loading #{file_name}"
306
-
307
- # Enable warnings iff this file has not been loaded before and
308
- # warnings_on_first_load is set.
309
- load_args = ["#{file_name}.rb"]
310
- load_args << const_path unless const_path.nil?
311
-
312
- if !warnings_on_first_load or history.include?(expanded)
313
- result = load_file(*load_args)
314
- else
315
- enable_warnings { result = load_file(*load_args) }
316
- end
317
- else
318
- log "requiring #{file_name}"
319
- result = require file_name
320
- end
321
- rescue Exception
322
- loaded.delete expanded
323
- raise
324
- end
325
-
326
- # Record history *after* loading so first load gets warnings.
327
- history << expanded
328
- return result
329
- end
330
-
331
- # Is the provided constant path defined?
332
- def qualified_const_defined?(path)
333
- names = path.sub(/^::/, '').to_s.split('::')
334
-
335
- names.inject(Object) do |mod, name|
336
- return false unless local_const_defined?(mod, name)
337
- mod.const_get name
338
- end
339
- end
340
-
341
- if Module.method(:const_defined?).arity == 1
342
- # Does this module define this constant?
343
- # Wrapper to accomodate changing Module#const_defined? in Ruby 1.9
344
- def local_const_defined?(mod, const)
345
- mod.const_defined?(const)
346
- end
347
- else
348
- def local_const_defined?(mod, const) #:nodoc:
349
- mod.const_defined?(const, false)
350
- end
351
- end
352
-
353
- # Given +path+, a filesystem path to a ruby file, return an array of constant
354
- # paths which would cause Dependencies to attempt to load this file.
355
- def loadable_constants_for_path(path, bases = load_paths)
356
- expanded_path = Pathname.new(path[/\A(.*?)(\.rb)?\Z/, 1]).expand_path
357
-
358
- bases.inject([]) do |paths, root|
359
- expanded_root = Pathname.new(root).expand_path
360
- nesting = expanded_path.relative_path_from(expanded_root).to_s
361
- next paths if nesting =~ /\.\./
362
- paths << nesting.camelize
363
- end.uniq
364
- end
365
-
366
- # Search for a file in load_paths matching the provided suffix.
367
- def search_for_file(path_suffix)
368
- path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb")
369
-
370
- load_paths.each do |root|
371
- path = File.join(root, path_suffix)
372
- return path if File.file? path
373
- end
374
- nil # Gee, I sure wish we had first_match ;-)
375
- end
376
-
377
- # Does the provided path_suffix correspond to an autoloadable module?
378
- # Instead of returning a boolean, the autoload base for this module is returned.
379
- def autoloadable_module?(path_suffix)
380
- load_paths.each do |load_path|
381
- return load_path if File.directory? File.join(load_path, path_suffix)
382
- end
383
- nil
384
- end
385
-
386
- def load_once_path?(path)
387
- load_once_paths.any? { |base| path.starts_with? base }
388
- end
389
-
390
- # Attempt to autoload the provided module name by searching for a directory
391
- # matching the expect path suffix. If found, the module is created and assigned
392
- # to +into+'s constants with the name +const_name+. Provided that the directory
393
- # was loaded from a reloadable base path, it is added to the set of constants
394
- # that are to be unloaded.
395
- def autoload_module!(into, const_name, qualified_name, path_suffix)
396
- return nil unless base_path = autoloadable_module?(path_suffix)
397
- mod = Module.new
398
- into.const_set const_name, mod
399
- autoloaded_constants << qualified_name unless load_once_paths.include?(base_path)
400
- return mod
401
- end
402
-
403
- # Load the file at the provided path. +const_paths+ is a set of qualified
404
- # constant names. When loading the file, Dependencies will watch for the
405
- # addition of these constants. Each that is defined will be marked as
406
- # autoloaded, and will be removed when Dependencies.clear is next called.
407
- #
408
- # If the second parameter is left off, then Dependencies will construct a set
409
- # of names that the file at +path+ may define. See
410
- # +loadable_constants_for_path+ for more details.
411
- def load_file(path, const_paths = loadable_constants_for_path(path))
412
- log_call path, const_paths
413
- const_paths = [const_paths].compact unless const_paths.is_a? Array
414
- parent_paths = const_paths.collect { |const_path| /(.*)::[^:]+\Z/ =~ const_path ? $1 : :Object }
415
-
416
- result = nil
417
- newly_defined_paths = new_constants_in(*parent_paths) do
418
- result = Kernel.load path
419
- end
420
-
421
- autoloaded_constants.concat newly_defined_paths unless load_once_path?(path)
422
- autoloaded_constants.uniq!
423
- log "loading #{path} defined #{newly_defined_paths * ', '}" unless newly_defined_paths.empty?
424
- return result
425
- end
426
-
427
- # Return the constant path for the provided parent and constant name.
428
- def qualified_name_for(mod, name)
429
- mod_name = to_constant_name mod
430
- mod_name == "Object" ? name.to_s : "#{mod_name}::#{name}"
431
- end
432
-
433
- # Load the constant named +const_name+ which is missing from +from_mod+. If
434
- # it is not possible to load the constant into from_mod, try its parent module
435
- # using const_missing.
436
- def load_missing_constant(from_mod, const_name)
437
- log_call from_mod, const_name
438
-
439
- unless qualified_const_defined?(from_mod.name) && Inflector.constantize(from_mod.name).equal?(from_mod)
440
- raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!"
441
- end
442
-
443
- raise ArgumentError, "#{from_mod} is not missing constant #{const_name}!" if local_const_defined?(from_mod, const_name)
444
-
445
- qualified_name = qualified_name_for from_mod, const_name
446
- path_suffix = qualified_name.underscore
447
-
448
- trace = caller.reject {|l| l =~ %r{#{Regexp.escape(__FILE__)}}}
449
- name_error = NameError.new("uninitialized constant #{qualified_name}")
450
- name_error.set_backtrace(trace)
451
-
452
- file_path = search_for_file(path_suffix)
453
-
454
- if file_path && ! loaded.include?(File.expand_path(file_path)) # We found a matching file to load
455
- require_or_load file_path
456
- raise LoadError, "Expected #{file_path} to define #{qualified_name}" unless local_const_defined?(from_mod, const_name)
457
- return from_mod.const_get(const_name)
458
- elsif mod = autoload_module!(from_mod, const_name, qualified_name, path_suffix)
459
- return mod
460
- elsif (parent = from_mod.parent) && parent != from_mod &&
461
- ! from_mod.parents.any? { |p| local_const_defined?(p, const_name) }
462
- # If our parents do not have a constant named +const_name+ then we are free
463
- # to attempt to load upwards. If they do have such a constant, then this
464
- # const_missing must be due to from_mod::const_name, which should not
465
- # return constants from from_mod's parents.
466
- begin
467
- return parent.const_missing(const_name)
468
- rescue NameError => e
469
- raise unless e.missing_name? qualified_name_for(parent, const_name)
470
- raise name_error
471
- end
472
- else
473
- raise name_error
474
- end
475
- end
476
-
477
- # Remove the constants that have been autoloaded, and those that have been
478
- # marked for unloading.
479
- def remove_unloadable_constants!
480
- autoloaded_constants.each { |const| remove_constant const }
481
- autoloaded_constants.clear
482
- Reference.clear!
483
- explicitly_unloadable_constants.each { |const| remove_constant const }
484
- end
485
-
486
- class Reference
487
- @@constants = Hash.new { |h, k| h[k] = Inflector.constantize(k) }
488
-
489
- attr_reader :name
490
-
491
- def initialize(name)
492
- @name = name.to_s
493
- @@constants[@name] = name if name.respond_to?(:name)
494
- end
495
-
496
- def get
497
- @@constants[@name]
498
- end
499
-
500
- def self.clear!
501
- @@constants.clear
502
- end
503
- end
504
-
505
- def ref(name)
506
- references[name] ||= Reference.new(name)
507
- end
508
-
509
- def constantize(name)
510
- ref(name).get
511
- end
512
-
513
- # Determine if the given constant has been automatically loaded.
514
- def autoloaded?(desc)
515
- # No name => anonymous module.
516
- return false if desc.is_a?(Module) && desc.anonymous?
517
- name = to_constant_name desc
518
- return false unless qualified_const_defined? name
519
- return autoloaded_constants.include?(name)
520
- end
521
-
522
- # Will the provided constant descriptor be unloaded?
523
- def will_unload?(const_desc)
524
- autoloaded?(const_desc) ||
525
- explicitly_unloadable_constants.include?(to_constant_name(const_desc))
526
- end
527
-
528
- # Mark the provided constant name for unloading. This constant will be
529
- # unloaded on each request, not just the next one.
530
- def mark_for_unload(const_desc)
531
- name = to_constant_name const_desc
532
- if explicitly_unloadable_constants.include? name
533
- return false
534
- else
535
- explicitly_unloadable_constants << name
536
- return true
537
- end
538
- end
539
-
540
- # Run the provided block and detect the new constants that were loaded during
541
- # its execution. Constants may only be regarded as 'new' once -- so if the
542
- # block calls +new_constants_in+ again, then the constants defined within the
543
- # inner call will not be reported in this one.
544
- #
545
- # If the provided block does not run to completion, and instead raises an
546
- # exception, any new constants are regarded as being only partially defined
547
- # and will be removed immediately.
548
- def new_constants_in(*descs)
549
- log_call(*descs)
550
- watch_frames = constant_watch_stack.add_modules(descs)
551
-
552
- aborting = true
553
- begin
554
- yield # Now yield to the code that is to define new constants.
555
- aborting = false
556
- ensure
557
- new_constants = constant_watch_stack.new_constants_for(watch_frames)
558
-
559
- log "New constants: #{new_constants * ', '}"
560
- return new_constants unless aborting
561
-
562
- log "Error during loading, removing partially loaded constants "
563
- new_constants.each {|c| remove_constant(c) }.clear
564
- end
565
-
566
- return []
567
- ensure
568
- # Remove the stack frames that we added.
569
- watch_frames.each {|f| constant_watch_stack.delete(f) } if watch_frames.present?
570
- end
571
-
572
- class LoadingModule #:nodoc:
573
- # Old style environment.rb referenced this method directly. Please note, it doesn't
574
- # actually *do* anything any more.
575
- def self.root(*args)
576
- if defined?(Rails) && Rails.logger
577
- Rails.logger.warn "Your environment.rb uses the old syntax, it may not continue to work in future releases."
578
- Rails.logger.warn "For upgrade instructions please see: http://manuals.rubyonrails.com/read/book/19"
579
- end
580
- end
581
- end
582
-
583
- # Convert the provided const desc to a qualified constant name (as a string).
584
- # A module, class, symbol, or string may be provided.
585
- def to_constant_name(desc) #:nodoc:
586
- name = case desc
587
- when String then desc.sub(/^::/, '')
588
- when Symbol then desc.to_s
589
- when Module
590
- desc.name.presence ||
591
- raise(ArgumentError, "Anonymous modules have no name to be referenced by")
592
- else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
593
- end
594
- end
595
-
596
- def remove_constant(const) #:nodoc:
597
- return false unless qualified_const_defined? const
598
-
599
- # Normalize ::Foo, Foo, Object::Foo, and ::Object::Foo to Object::Foo
600
- names = const.to_s.sub(/^::(Object)?/, 'Object::').split("::")
601
- to_remove = names.pop
602
- parent = Inflector.constantize(names * '::')
603
-
604
- log "removing constant #{const}"
605
- parent.instance_eval { remove_const to_remove }
606
-
607
- return true
608
- end
609
-
610
- protected
611
- def log_call(*args)
612
- if logger && log_activity
613
- arg_str = args.collect { |arg| arg.inspect } * ', '
614
- /in `([a-z_\?\!]+)'/ =~ caller(1).first
615
- selector = $1 || '<unknown>'
616
- log "called #{selector}(#{arg_str})"
617
- end
618
- end
619
-
620
- def log(msg)
621
- if logger && log_activity
622
- logger.debug "Dependencies: #{msg}"
623
- end
624
- end
625
- end
626
- end
627
-
628
- ActiveSupport::Dependencies.hook!