facter 1.5.4 → 1.5.5

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.

Potentially problematic release.


This version of facter might be problematic. Click here for more details.

Files changed (47) hide show
  1. data/CHANGELOG +75 -22
  2. data/COPYING +289 -623
  3. data/Rakefile +60 -55
  4. data/bin/facter +39 -26
  5. data/conf/osx/PackageInfo.plist +30 -30
  6. data/conf/osx/createpackage.sh +17 -17
  7. data/conf/osx/preflight +1 -1
  8. data/install.rb +226 -226
  9. data/lib/facter.rb +12 -12
  10. data/lib/facter/architecture.rb +14 -3
  11. data/lib/facter/ec2.rb +35 -0
  12. data/lib/facter/hardwareisa.rb +1 -1
  13. data/lib/facter/id.rb +1 -1
  14. data/lib/facter/ipaddress.rb +41 -41
  15. data/lib/facter/kernel.rb +2 -2
  16. data/lib/facter/kernelmajversion.rb +5 -0
  17. data/lib/facter/lsb.rb +5 -5
  18. data/lib/facter/lsbmajdistrelease.rb +1 -1
  19. data/lib/facter/macaddress.rb +6 -6
  20. data/lib/facter/manufacturer.rb +8 -8
  21. data/lib/facter/memory.rb +5 -4
  22. data/lib/facter/netmask.rb +4 -4
  23. data/lib/facter/network.rb +4 -5
  24. data/lib/facter/operatingsystem.rb +13 -7
  25. data/lib/facter/operatingsystemrelease.rb +5 -5
  26. data/lib/facter/selinux.rb +45 -0
  27. data/lib/facter/timezone.rb +1 -1
  28. data/lib/facter/uniqueid.rb +2 -2
  29. data/lib/facter/uptime.rb +3 -3
  30. data/lib/facter/util/confine.rb +12 -12
  31. data/lib/facter/util/ip.rb +18 -22
  32. data/lib/facter/util/macosx.rb +5 -0
  33. data/lib/facter/util/manufacturer.rb +37 -37
  34. data/lib/facter/util/plist/generator.rb +181 -179
  35. data/lib/facter/util/plist/parser.rb +162 -163
  36. data/lib/facter/util/resolution.rb +2 -2
  37. data/lib/facter/util/uptime.rb +10 -12
  38. data/lib/facter/util/values.rb +14 -0
  39. data/lib/facter/virtual.rb +54 -34
  40. data/spec/unit/data/darwin_ifconfig_all_with_multiple_interfaces +10 -0
  41. data/spec/unit/operatingsystem.rb +36 -0
  42. data/spec/unit/selinux.rb +48 -0
  43. data/spec/unit/util/confine.rb +70 -5
  44. data/spec/unit/util/ip.rb +29 -3
  45. metadata +89 -77
  46. data/documentation/custom.page +0 -22
  47. data/documentation/index.page +0 -19
@@ -1,5 +1,5 @@
1
1
  Facter.add("timezone") do
2
- setcode do
2
+ setcode do
3
3
  Time.new.zone
4
4
  end
5
5
  end
@@ -1,4 +1,4 @@
1
1
  Facter.add(:uniqueid) do
2
- setcode 'hostid', '/bin/sh'
3
- confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE SLES Debian Ubuntu Gentoo AIX}
2
+ setcode 'hostid', '/bin/sh'
3
+ confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE SLES Debian Ubuntu Gentoo AIX OEL OVS}
4
4
  end
@@ -12,9 +12,9 @@ if FileTest.exists?("/proc/uptime")
12
12
 
13
13
  %w{days hours seconds}.each do |label|
14
14
  Facter.add("uptime_" + label) do
15
- setcode do
16
- Facter::Util::Uptime.get_uptime_period(uptime, label)
17
- end
15
+ setcode do
16
+ Facter::Util::Uptime.get_uptime_period(uptime, label)
17
+ end
18
18
  end
19
19
  end
20
20
  end
@@ -1,22 +1,20 @@
1
1
  # A restricting tag for fact resolution mechanisms. The tag must be true
2
2
  # for the resolution mechanism to be suitable.
3
+
4
+ require 'facter/util/values'
5
+
3
6
  class Facter::Util::Confine
4
7
  attr_accessor :fact, :values
5
8
 
9
+ include Facter::Util::Values
10
+
6
11
  # Add the restriction. Requires the fact name, an operator, and the value
7
12
  # we're comparing to.
8
13
  def initialize(fact, *values)
9
14
  raise ArgumentError, "The fact name must be provided" unless fact
10
15
  raise ArgumentError, "One or more values must be provided" if values.empty?
11
- fact = fact.to_s if fact.is_a? Symbol
12
16
  @fact = fact
13
- @values = values.collect do |value|
14
- if value.is_a? String
15
- value
16
- else
17
- value.to_s
18
- end
19
- end
17
+ @values = values
20
18
  end
21
19
 
22
20
  def to_s
@@ -29,13 +27,15 @@ class Facter::Util::Confine
29
27
  Facter.debug "No fact for %s" % @fact
30
28
  return false
31
29
  end
32
- value = fact.value
30
+ value = convert(fact.value)
33
31
 
34
32
  return false if value.nil?
35
33
 
36
- @values.each { |v|
37
- return true if value.downcase == v.downcase
38
- }
34
+ @values.each do |v|
35
+ v = convert(v)
36
+ next unless v.class == value.class
37
+ return true if value == v
38
+ end
39
39
  return false
40
40
  end
41
41
  end
@@ -5,20 +5,20 @@ module Facter::Util::IP
5
5
  # a given platform or set of platforms.
6
6
  REGEX_MAP = {
7
7
  :linux => {
8
- :ipaddress => /inet addr:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
9
- :macaddress => /(?:ether|HWaddr)\s+(\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2})/,
10
- :netmask => /Mask:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
8
+ :ipaddress => /inet addr:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
9
+ :macaddress => /(?:ether|HWaddr)\s+(\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2})/,
10
+ :netmask => /Mask:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
11
11
  },
12
- :bsd => {
13
- :aliases => [:openbsd, :netbsd, :freebsd, :darwin],
14
- :ipaddress => /inet\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
15
- :macaddress => /(?:ether|lladdr)\s+(\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)/,
16
- :netmask => /netmask\s+0x(\w{8})/
12
+ :bsd => {
13
+ :aliases => [:openbsd, :netbsd, :freebsd, :darwin],
14
+ :ipaddress => /inet\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
15
+ :macaddress => /(?:ether|lladdr)\s+(\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)/,
16
+ :netmask => /netmask\s+0x(\w{8})/
17
17
  },
18
18
  :sunos => {
19
- :addr => /inet\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
20
- :macaddress => /(?:ether|lladdr)\s+(\w?\w:\w?\w:\w?\w:\w?\w:\w?\w:\w?\w)/,
21
- :netmask => /netmask\s+(\w{8})/
19
+ :ipaddress => /inet\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
20
+ :macaddress => /(?:ether|lladdr)\s+(\w?\w:\w?\w:\w?\w:\w?\w:\w?\w:\w?\w)/,
21
+ :netmask => /netmask\s+(\w{8})/
22
22
  }
23
23
  }
24
24
 
@@ -45,17 +45,13 @@ module Facter::Util::IP
45
45
  end
46
46
 
47
47
  def self.get_interfaces
48
- int = nil
49
-
50
- output = Facter::Util::IP.get_all_interface_output()
48
+ return [] unless output = Facter::Util::IP.get_all_interface_output()
51
49
 
52
- # We get lots of warnings on platforms that don't get an output
53
- # made.
54
- if output
55
- int = output.scan(/^\w+[.:]?\d+/)
56
- else
57
- []
58
- end
50
+ # Our regex appears to be stupid, in that it leaves colons sitting
51
+ # at the end of interfaces. So, we have to trim those trailing
52
+ # characters. I tried making the regex better but supporting all
53
+ # platforms with a single regex is probably a bit too much.
54
+ output.scan(/^\w+[.:]?\d+[.:]?\d*[.:]?\w*/).collect { |i| i.sub(/:$/, '') }
59
55
  end
60
56
 
61
57
  def self.get_all_interface_output
@@ -124,7 +120,7 @@ module Facter::Util::IP
124
120
  output_int = get_single_interface_output(interface)
125
121
 
126
122
  if interface != /^lo[0:]?\d?/
127
- output_int.each do |s|
123
+ output_int.each_line do |s|
128
124
  if s =~ regex
129
125
  value = $1
130
126
  if label == 'netmask' && convert_from_hex?(kernel)
@@ -58,6 +58,11 @@ module Facter::Util::Macosx
58
58
  [ "productName", "productVersion", "buildVersion" ].each do |option|
59
59
  ver["macosx_#{option}"] = %x{sw_vers -#{option}}.strip
60
60
  end
61
+ productversion = ver["macosx_productVersion"]
62
+ if not productversion.nil?
63
+ ver["macosx_productversion_major"] = productversion.scan(/(\d+\.\d+)/)[0][0]
64
+ ver["macosx_productversion_minor"] = productversion.scan(/(\d+)\.(\d+)\.(\d+)/)[0].last
65
+ end
61
66
  ver
62
67
  end
63
68
  end
@@ -2,45 +2,45 @@
2
2
  # Support methods for manufacturer specific facts
3
3
 
4
4
  module Facter::Manufacturer
5
- def self.dmi_find_system_info(name)
6
- splitstr="Handle"
7
- case Facter.value(:kernel)
8
- when 'Linux'
9
- return nil unless FileTest.exists?("/usr/sbin/dmidecode")
10
-
11
- output=%x{/usr/sbin/dmidecode 2>/dev/null}
12
- when 'OpenBSD', 'FreeBSD'
13
- return nil unless FileTest.exists?("/usr/local/sbin/dmidecode")
14
-
15
- output=%x{/usr/local/sbin/dmidecode 2>/dev/null}
16
- when 'NetBSD'
17
- return nil unless FileTest.exists?("/usr/pkg/sbin/dmidecode")
5
+ def self.dmi_find_system_info(name)
6
+ splitstr="Handle"
7
+ case Facter.value(:kernel)
8
+ when 'Linux'
9
+ return nil unless FileTest.exists?("/usr/sbin/dmidecode")
18
10
 
19
- output=%x{/usr/pkg/sbin/dmidecode 2>/dev/null}
20
- when 'SunOS'
21
- return nil unless FileTest.exists?("/usr/sbin/smbios")
22
- splitstr="ID SIZE TYPE"
23
- output=%x{/usr/sbin/smbios 2>/dev/null}
11
+ output=%x{/usr/sbin/dmidecode 2>/dev/null}
12
+ when 'OpenBSD', 'FreeBSD'
13
+ return nil unless FileTest.exists?("/usr/local/sbin/dmidecode")
24
14
 
25
- else
26
- return
27
- end
28
- name.each_pair do |key,v|
29
- v.each do |v2|
30
- v2.each_pair do |value,facterkey|
31
- output.split(splitstr).each do |line|
32
- if line =~ /#{key}/ and ( line =~ /#{value} 0x\d+ \(([-\w].*)\)\n*./ or line =~ /#{value} ([-\w].*)\n*./ )
33
- result = $1
34
- Facter.add(facterkey) do
35
- confine :kernel => [ :linux, :freebsd, :netbsd, :openbsd, :sunos ]
36
- setcode do
37
- result
38
- end
39
- end
40
- end
41
- end
42
- end
43
- end
15
+ output=%x{/usr/local/sbin/dmidecode 2>/dev/null}
16
+ when 'NetBSD'
17
+ return nil unless FileTest.exists?("/usr/pkg/sbin/dmidecode")
18
+
19
+ output=%x{/usr/pkg/sbin/dmidecode 2>/dev/null}
20
+ when 'SunOS'
21
+ return nil unless FileTest.exists?("/usr/sbin/smbios")
22
+ splitstr="ID SIZE TYPE"
23
+ output=%x{/usr/sbin/smbios 2>/dev/null}
24
+
25
+ else
26
+ return
27
+ end
28
+ name.each_pair do |key,v|
29
+ v.each do |v2|
30
+ v2.each_pair do |value,facterkey|
31
+ output.split(splitstr).each do |line|
32
+ if line =~ /#{key}/ and ( line =~ /#{value} 0x\d+ \(([-\w].*)\)\n*./ or line =~ /#{value} ([-\w].*)\n*./ )
33
+ result = $1
34
+ Facter.add(facterkey) do
35
+ confine :kernel => [ :linux, :freebsd, :netbsd, :openbsd, :sunos ]
36
+ setcode do
37
+ result
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
44
  end
45
45
  end
46
46
  end
@@ -7,220 +7,222 @@
7
7
  #++
8
8
  # See Plist::Emit.
9
9
  module Plist
10
- # === Create a plist
11
- # You can dump an object to a plist in one of two ways:
12
- #
13
- # * <tt>Plist::Emit.dump(obj)</tt>
14
- # * <tt>obj.to_plist</tt>
15
- # * This requires that you mixin the <tt>Plist::Emit</tt> module, which is already done for +Array+ and +Hash+.
16
- #
17
- # The following Ruby classes are converted into native plist types:
18
- # Array, Bignum, Date, DateTime, Fixnum, Float, Hash, Integer, String, Symbol, Time, true, false
19
- # * +Array+ and +Hash+ are both recursive; their elements will be converted into plist nodes inside the <array> and <dict> containers (respectively).
20
- # * +IO+ (and its descendants) and +StringIO+ objects are read from and their contents placed in a <data> element.
21
- # * User classes may implement +to_plist_node+ to dictate how they should be serialized; otherwise the object will be passed to <tt>Marshal.dump</tt> and the result placed in a <data> element.
22
- #
23
- # For detailed usage instructions, refer to USAGE[link:files/docs/USAGE.html] and the methods documented below.
24
- module Emit
25
- # Helper method for injecting into classes. Calls <tt>Plist::Emit.dump</tt> with +self+.
26
- def to_plist(envelope = true)
27
- return Plist::Emit.dump(self, envelope)
28
- end
29
-
30
- # Helper method for injecting into classes. Calls <tt>Plist::Emit.save_plist</tt> with +self+.
31
- def save_plist(filename)
32
- Plist::Emit.save_plist(self, filename)
33
- end
34
-
35
- # The following Ruby classes are converted into native plist types:
36
- # Array, Bignum, Date, DateTime, Fixnum, Float, Hash, Integer, String, Symbol, Time
10
+ # === Create a plist
11
+ # You can dump an object to a plist in one of two ways:
37
12
  #
38
- # Write us (via RubyForge) if you think another class can be coerced safely into one of the expected plist classes.
13
+ # * <tt>Plist::Emit.dump(obj)</tt>
14
+ # * <tt>obj.to_plist</tt>
15
+ # * This requires that you mixin the <tt>Plist::Emit</tt> module, which is already done for +Array+ and +Hash+.
39
16
  #
40
- # +IO+ and +StringIO+ objects are encoded and placed in <data> elements; other objects are <tt>Marshal.dump</tt>'ed unless they implement +to_plist_node+.
17
+ # The following Ruby classes are converted into native plist types:
18
+ # Array, Bignum, Date, DateTime, Fixnum, Float, Hash, Integer, String, Symbol, Time, true, false
19
+ # * +Array+ and +Hash+ are both recursive; their elements will be converted into plist nodes inside the <array> and <dict> containers (respectively).
20
+ # * +IO+ (and its descendants) and +StringIO+ objects are read from and their contents placed in a <data> element.
21
+ # * User classes may implement +to_plist_node+ to dictate how they should be serialized; otherwise the object will be passed to <tt>Marshal.dump</tt> and the result placed in a <data> element.
41
22
  #
42
- # The +envelope+ parameters dictates whether or not the resultant plist fragment is wrapped in the normal XML/plist header and footer. Set it to false if you only want the fragment.
43
- def self.dump(obj, envelope = true)
44
- output = plist_node(obj)
23
+ # For detailed usage instructions, refer to USAGE[link:files/docs/USAGE.html] and the methods documented below.
24
+ module Emit
25
+ # Helper method for injecting into classes. Calls <tt>Plist::Emit.dump</tt> with +self+.
26
+ def to_plist(envelope = true)
27
+ return Plist::Emit.dump(self, envelope)
28
+ end
45
29
 
46
- output = wrap(output) if envelope
30
+ # Helper method for injecting into classes. Calls <tt>Plist::Emit.save_plist</tt> with +self+.
31
+ def save_plist(filename)
32
+ Plist::Emit.save_plist(self, filename)
33
+ end
47
34
 
48
- return output
49
- end
35
+ # The following Ruby classes are converted into native plist types:
36
+ # Array, Bignum, Date, DateTime, Fixnum, Float, Hash, Integer, String, Symbol, Time
37
+ #
38
+ # Write us (via RubyForge) if you think another class can be coerced safely into one of the expected plist classes.
39
+ #
40
+ # +IO+ and +StringIO+ objects are encoded and placed in <data> elements; other objects are <tt>Marshal.dump</tt>'ed unless they implement +to_plist_node+.
41
+ #
42
+ # The +envelope+ parameters dictates whether or not the resultant plist fragment is wrapped in the normal XML/plist header and footer. Set it to false if you only want the fragment.
43
+ def self.dump(obj, envelope = true)
44
+ output = plist_node(obj)
50
45
 
51
- # Writes the serialized object's plist to the specified filename.
52
- def self.save_plist(obj, filename)
53
- File.open(filename, 'wb') do |f|
54
- f.write(obj.to_plist)
55
- end
56
- end
46
+ output = wrap(output) if envelope
57
47
 
58
- private
59
- def self.plist_node(element)
60
- output = ''
61
-
62
- if element.respond_to? :to_plist_node
63
- output << element.to_plist_node
64
- else
65
- case element
66
- when Array
67
- if element.empty?
68
- output << "<array/>\n"
69
- else
70
- output << tag('array') {
71
- element.collect {|e| plist_node(e)}
72
- }
73
- end
74
- when Hash
75
- if element.empty?
76
- output << "<dict/>\n"
77
- else
78
- inner_tags = []
79
-
80
- element.keys.sort.each do |k|
81
- v = element[k]
82
- inner_tags << tag('key', CGI::escapeHTML(k.to_s))
83
- inner_tags << plist_node(v)
48
+ return output
49
+ end
50
+
51
+ # Writes the serialized object's plist to the specified filename.
52
+ def self.save_plist(obj, filename)
53
+ File.open(filename, 'wb') do |f|
54
+ f.write(obj.to_plist)
55
+ end
56
+ end
57
+
58
+ private
59
+ def self.plist_node(element)
60
+ output = ''
61
+
62
+ if element.respond_to? :to_plist_node
63
+ output << element.to_plist_node
64
+ else
65
+ case element
66
+ when Array
67
+ if element.empty?
68
+ output << "<array/>\n"
69
+ else
70
+ output << tag('array') {
71
+ element.collect {|e| plist_node(e)}
72
+ }
73
+ end
74
+ when Hash
75
+ if element.empty?
76
+ output << "<dict/>\n"
77
+ else
78
+ inner_tags = []
79
+
80
+ element.keys.sort.each do |k|
81
+ v = element[k]
82
+ inner_tags << tag('key', CGI::escapeHTML(k.to_s))
83
+ inner_tags << plist_node(v)
84
+ end
85
+
86
+ output << tag('dict') {
87
+ inner_tags
88
+ }
89
+ end
90
+ when true, false
91
+ output << "<#{element}/>\n"
92
+ when Time
93
+ output << tag('date', element.utc.strftime('%Y-%m-%dT%H:%M:%SZ'))
94
+ when Date # also catches DateTime
95
+ output << tag('date', element.strftime('%Y-%m-%dT%H:%M:%SZ'))
96
+ when String, Symbol, Fixnum, Bignum, Integer, Float
97
+ output << tag(element_type(element), CGI::escapeHTML(element.to_s))
98
+ when IO, StringIO
99
+ element.rewind
100
+ contents = element.read
101
+ # note that apple plists are wrapped at a different length then
102
+ # what ruby's base64 wraps by default.
103
+ # I used #encode64 instead of #b64encode (which allows a length arg)
104
+ # because b64encode is b0rked and ignores the length arg.
105
+ data = "\n"
106
+ Base64::encode64(contents).gsub(/\s+/, '').scan(/.{1,68}/o) { data << $& << "\n" }
107
+ output << tag('data', data)
108
+ else
109
+ output << comment( 'The <data> element below contains a Ruby object which has been serialized with Marshal.dump.' )
110
+ data = "\n"
111
+ Base64::encode64(Marshal.dump(element)).gsub(/\s+/, '').scan(/.{1,68}/o) { data << $& << "\n" }
112
+ output << tag('data', data )
113
+ end
84
114
  end
85
115
 
86
- output << tag('dict') {
87
- inner_tags
88
- }
89
- end
90
- when true, false
91
- output << "<#{element}/>\n"
92
- when Time
93
- output << tag('date', element.utc.strftime('%Y-%m-%dT%H:%M:%SZ'))
94
- when Date # also catches DateTime
95
- output << tag('date', element.strftime('%Y-%m-%dT%H:%M:%SZ'))
96
- when String, Symbol, Fixnum, Bignum, Integer, Float
97
- output << tag(element_type(element), CGI::escapeHTML(element.to_s))
98
- when IO, StringIO
99
- element.rewind
100
- contents = element.read
101
- # note that apple plists are wrapped at a different length then
102
- # what ruby's base64 wraps by default.
103
- # I used #encode64 instead of #b64encode (which allows a length arg)
104
- # because b64encode is b0rked and ignores the length arg.
105
- data = "\n"
106
- Base64::encode64(contents).gsub(/\s+/, '').scan(/.{1,68}/o) { data << $& << "\n" }
107
- output << tag('data', data)
108
- else
109
- output << comment( 'The <data> element below contains a Ruby object which has been serialized with Marshal.dump.' )
110
- data = "\n"
111
- Base64::encode64(Marshal.dump(element)).gsub(/\s+/, '').scan(/.{1,68}/o) { data << $& << "\n" }
112
- output << tag('data', data )
116
+ return output
113
117
  end
114
- end
115
118
 
116
- return output
117
- end
119
+ def self.comment(content)
120
+ return "<!-- #{content} -->\n"
121
+ end
118
122
 
119
- def self.comment(content)
120
- return "<!-- #{content} -->\n"
121
- end
123
+ def self.tag(type, contents = '', &block)
124
+ out = nil
125
+
126
+ if block_given?
127
+ out = IndentedString.new
128
+ out << "<#{type}>"
129
+ out.raise_indent
122
130
 
123
- def self.tag(type, contents = '', &block)
124
- out = nil
131
+ out << block.call
125
132
 
126
- if block_given?
127
- out = IndentedString.new
128
- out << "<#{type}>"
129
- out.raise_indent
133
+ out.lower_indent
134
+ out << "</#{type}>"
135
+ else
136
+ out = "<#{type}>#{contents.to_s}</#{type}>\n"
137
+ end
130
138
 
131
- out << block.call
139
+ return out.to_s
140
+ end
132
141
 
133
- out.lower_indent
134
- out << "</#{type}>"
135
- else
136
- out = "<#{type}>#{contents.to_s}</#{type}>\n"
137
- end
142
+ def self.wrap(contents)
143
+ output = ''
138
144
 
139
- return out.to_s
140
- end
145
+ output << '<?xml version="1.0" encoding="UTF-8"?>' + "\n"
146
+ output << '<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' + "\n"
147
+ output << '<plist version="1.0">' + "\n"
148
+
149
+ output << contents
150
+
151
+ output << '</plist>' + "\n"
141
152
 
142
- def self.wrap(contents)
143
- output = ''
153
+ return output
154
+ end
144
155
 
145
- output << '<?xml version="1.0" encoding="UTF-8"?>' + "\n"
146
- output << '<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' + "\n"
147
- output << '<plist version="1.0">' + "\n"
156
+ def self.element_type(item)
157
+ return case item
158
+ when String, Symbol; 'string'
159
+ when Fixnum, Bignum, Integer; 'integer'
160
+ when Float; 'real'
161
+ else
162
+ raise "Don't know about this data type... something must be wrong!"
163
+ end
164
+ end
148
165
 
149
- output << contents
166
+ private
150
167
 
151
- output << '</plist>' + "\n"
168
+ class IndentedString #:nodoc:
169
+ attr_accessor :indent_string
152
170
 
153
- return output
154
- end
171
+ @@indent_level = 0
155
172
 
156
- def self.element_type(item)
157
- return case item
158
- when String, Symbol; 'string'
159
- when Fixnum, Bignum, Integer; 'integer'
160
- when Float; 'real'
161
- else
162
- raise "Don't know about this data type... something must be wrong!"
163
- end
164
- end
165
- private
166
- class IndentedString #:nodoc:
167
- attr_accessor :indent_string
168
-
169
- @@indent_level = 0
170
-
171
- def initialize(str = "\t")
172
- @indent_string = str
173
- @contents = ''
174
- end
175
-
176
- def to_s
177
- return @contents
178
- end
179
-
180
- def raise_indent
181
- @@indent_level += 1
182
- end
183
-
184
- def lower_indent
185
- @@indent_level -= 1 if @@indent_level > 0
186
- end
187
-
188
- def <<(val)
189
- if val.is_a? Array
190
- val.each do |f|
191
- self << f
192
- end
193
- else
194
- # if it's already indented, don't bother indenting further
195
- unless val =~ /\A#{@indent_string}/
196
- indent = @indent_string * @@indent_level
197
-
198
- @contents << val.gsub(/^/, indent)
199
- else
200
- @contents << val
201
- end
202
-
203
- # it already has a newline, don't add another
204
- @contents << "\n" unless val =~ /\n$/
173
+ def initialize(str = "\t")
174
+ @indent_string = str
175
+ @contents = ''
176
+ end
177
+
178
+ def to_s
179
+ return @contents
180
+ end
181
+
182
+ def raise_indent
183
+ @@indent_level += 1
184
+ end
185
+
186
+ def lower_indent
187
+ @@indent_level -= 1 if @@indent_level > 0
188
+ end
189
+
190
+ def <<(val)
191
+ if val.is_a? Array
192
+ val.each do |f|
193
+ self << f
194
+ end
195
+ else
196
+ # if it's already indented, don't bother indenting further
197
+ unless val =~ /\A#{@indent_string}/
198
+ indent = @indent_string * @@indent_level
199
+
200
+ @contents << val.gsub(/^/, indent)
201
+ else
202
+ @contents << val
203
+ end
204
+
205
+ # it already has a newline, don't add another
206
+ @contents << "\n" unless val =~ /\n$/
207
+ end
208
+ end
205
209
  end
206
- end
207
210
  end
208
- end
209
211
  end
210
212
 
211
213
  # we need to add this so sorting hash keys works properly
212
214
  class Symbol #:nodoc:
213
- def <=> (other)
214
- self.to_s <=> other.to_s
215
- end
215
+ def <=> (other)
216
+ self.to_s <=> other.to_s
217
+ end
216
218
  end
217
219
 
218
220
  class Array #:nodoc:
219
- include Plist::Emit
221
+ include Plist::Emit
220
222
  end
221
223
 
222
224
  class Hash #:nodoc:
223
- include Plist::Emit
225
+ include Plist::Emit
224
226
  end
225
227
 
226
228
  # $Id: generator.rb 1781 2006-10-16 01:01:35Z luke $