plist4r 0.2.1 → 0.2.2

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.
@@ -1,169 +1,177 @@
1
- #--
2
- # Copyright (c) 2005 David Hansson,
3
- # Copyright (c) 2007 Mauricio Fernandez, Sam Stephenson
4
- # Copyright (c) 2008 Steve Purcell, Josh Peek
5
- # Copyright (c) 2009 Christoffer Sawicki
6
- #
7
- # Permission is hereby granted, free of charge, to any person obtaining
8
- # a copy of this software and associated documentation files (the
9
- # "Software"), to deal in the Software without restriction, including
10
- # without limitation the rights to use, copy, modify, merge, publish,
11
- # distribute, sublicense, and/or sell copies of the Software, and to
12
- # permit persons to whom the Software is furnished to do so, subject to
13
- # the following conditions:
14
- #
15
- # The above copyright notice and this permission notice shall be
16
- # included in all copies or substantial portions of the Software.
17
- #
18
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
- #++
26
-
27
- # OrderedHash is namespaced to prevent conflicts with other implementations
28
- module ActiveSupport
29
- # Hash is ordered in Ruby 1.9!
30
- if RUBY_VERSION >= '1.9'
31
- class OrderedHash < ::Hash #:nodoc:
32
- end
33
- else
34
- class OrderedHash < Hash #:nodoc:
35
- def initialize(*args, &block)
36
- super
37
- @keys = []
38
- end
39
1
 
40
- def self.[](*args)
41
- ordered_hash = new
2
+ module Plist4r
3
+ module ActiveSupport
4
+ # Hash is ordered in Ruby 1.9!
5
+ unless RUBY_VERSION >= '1.9'
6
+ # {ActiveSupport::OrderedHash}
7
+ #
8
+ # Copyright (c) 2005 David Hansson,
9
+ # Copyright (c) 2007 Mauricio Fernandez, Sam Stephenson
10
+ # Copyright (c) 2008 Steve Purcell, Josh Peek
11
+ # Copyright (c) 2009 Christoffer Sawicki
12
+ #
13
+ # Permission is hereby granted, free of charge, to any person obtaining
14
+ # a copy of this software and associated documentation files (the
15
+ # "Software"), to deal in the Software without restriction, including
16
+ # without limitation the rights to use, copy, modify, merge, publish,
17
+ # distribute, sublicense, and/or sell copies of the Software, and to
18
+ # permit persons to whom the Software is furnished to do so, subject to
19
+ # the following conditions:
20
+ #
21
+ # The above copyright notice and this permission notice shall be
22
+ # included in all copies or substantial portions of the Software.
23
+ #
24
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
+ #
32
+ class OrderedHash < Hash
33
+ def initialize(*args, &block)
34
+ super
35
+ @keys = []
36
+ end
37
+
38
+ def self.[](*args)
39
+ ordered_hash = new
42
40
 
43
- if (args.length == 1 && args.first.is_a?(Array))
44
- args.first.each do |key_value_pair|
45
- next unless (key_value_pair.is_a?(Array))
46
- ordered_hash[key_value_pair[0]] = key_value_pair[1]
41
+ if (args.length == 1 && args.first.is_a?(Array))
42
+ args.first.each do |key_value_pair|
43
+ next unless (key_value_pair.is_a?(Array))
44
+ ordered_hash[key_value_pair[0]] = key_value_pair[1]
45
+ end
46
+
47
+ return ordered_hash
47
48
  end
48
49
 
49
- return ordered_hash
50
- end
50
+ unless (args.size % 2 == 0)
51
+ raise ArgumentError.new("odd number of arguments for Hash")
52
+ end
51
53
 
52
- unless (args.size % 2 == 0)
53
- raise ArgumentError.new("odd number of arguments for Hash")
54
- end
54
+ args.each_with_index do |val, ind|
55
+ next if (ind % 2 != 0)
56
+ ordered_hash[val] = args[ind + 1]
57
+ end
55
58
 
56
- args.each_with_index do |val, ind|
57
- next if (ind % 2 != 0)
58
- ordered_hash[val] = args[ind + 1]
59
+ ordered_hash
59
60
  end
60
61
 
61
- ordered_hash
62
- end
63
-
64
- def initialize_copy(other)
65
- super
66
- # make a deep copy of keys
67
- @keys = other.keys
68
- end
62
+ def initialize_copy(other)
63
+ super
64
+ # make a deep copy of keys
65
+ @keys = other.keys
66
+ end
69
67
 
70
- def []=(key, value)
71
- @keys << key if !has_key?(key)
72
- super
73
- end
68
+ def []=(key, value)
69
+ @keys << key if !has_key?(key)
70
+ super
71
+ end
74
72
 
75
- def delete(key)
76
- if has_key? key
77
- index = @keys.index(key)
78
- @keys.delete_at index
73
+ def delete(key)
74
+ if has_key? key
75
+ index = @keys.index(key)
76
+ @keys.delete_at index
77
+ end
78
+ super
79
79
  end
80
- super
81
- end
82
80
 
83
- def delete_if
84
- super
85
- sync_keys!
86
- self
87
- end
81
+ def delete_if
82
+ super
83
+ sync_keys!
84
+ self
85
+ end
88
86
 
89
- def reject!
90
- super
91
- sync_keys!
92
- self
93
- end
87
+ def reject!
88
+ super
89
+ sync_keys!
90
+ self
91
+ end
94
92
 
95
- def reject(&block)
96
- dup.reject!(&block)
97
- end
93
+ def reject(&block)
94
+ dup.reject!(&block)
95
+ end
98
96
 
99
- def keys
100
- @keys.dup
101
- end
97
+ def keys
98
+ @keys.dup
99
+ end
102
100
 
103
- def values
104
- @keys.collect { |key| self[key] }
105
- end
101
+ def values
102
+ @keys.collect { |key| self[key] }
103
+ end
106
104
 
107
- def to_hash
108
- self
109
- end
105
+ def to_hash
106
+ self
107
+ end
110
108
 
111
- def to_a
112
- @keys.map { |key| [ key, self[key] ] }
113
- end
109
+ def to_a
110
+ @keys.map { |key| [ key, self[key] ] }
111
+ end
114
112
 
115
- def each_key
116
- @keys.each { |key| yield key }
117
- end
113
+ def each_key
114
+ @keys.each { |key| yield key }
115
+ end
118
116
 
119
- def each_value
120
- @keys.each { |key| yield self[key]}
121
- end
117
+ def each_value
118
+ @keys.each { |key| yield self[key]}
119
+ end
122
120
 
123
- def each
124
- @keys.each {|key| yield [key, self[key]]}
125
- end
121
+ def each
122
+ @keys.each {|key| yield [key, self[key]]}
123
+ end
126
124
 
127
- alias_method :each_pair, :each
125
+ alias_method :each_pair, :each
128
126
 
129
- def clear
130
- super
131
- @keys.clear
132
- self
133
- end
127
+ def clear
128
+ super
129
+ @keys.clear
130
+ self
131
+ end
134
132
 
135
- def shift
136
- k = @keys.first
137
- v = delete(k)
138
- [k, v]
139
- end
133
+ def shift
134
+ k = @keys.first
135
+ v = delete(k)
136
+ [k, v]
137
+ end
140
138
 
141
- def merge!(other_hash)
142
- other_hash.each {|k,v| self[k] = v }
143
- self
144
- end
139
+ def merge!(other_hash)
140
+ other_hash.each {|k,v| self[k] = v }
141
+ self
142
+ end
145
143
 
146
- def merge(other_hash)
147
- dup.merge!(other_hash)
148
- end
144
+ def merge(other_hash)
145
+ dup.merge!(other_hash)
146
+ end
149
147
 
150
- # When replacing with another hash, the initial order of our keys must come from the other hash -ordered or not.
151
- def replace(other)
152
- super
153
- @keys = other.keys
154
- self
155
- end
148
+ # When replacing with another hash, the initial order of our keys must come from the other hash -ordered or not.
149
+ def replace(other)
150
+ super
151
+ @keys = other.keys
152
+ self
153
+ end
156
154
 
157
- # This breaks passing the Hash through Stdin to RubyCocoa
158
- # def inspect
159
- # "#<OrderedHash #{super}>"
160
- # end
155
+ # This breaks passing the Hash through Stdin to RubyCocoa
156
+ # def inspect
157
+ # "#<OrderedHash #{super}>"
158
+ # end
161
159
 
162
- private
160
+ private
163
161
 
164
- def sync_keys!
165
- @keys.delete_if {|k| !has_key?(k)}
162
+ def sync_keys!
163
+ @keys.delete_if {|k| !has_key?(k)}
164
+ end
165
+ end
166
+ else
167
+ class OrderedHash < ::Hash
166
168
  end
167
169
  end
168
170
  end
169
171
  end
172
+
173
+ module Plist4r
174
+ # This is an {ActiveSupport::OrderedHash}
175
+ class OrderedHash < ActiveSupport::OrderedHash
176
+ end
177
+ end
@@ -7,12 +7,32 @@ module Plist4r
7
7
  module Popen4
8
8
  class << self
9
9
  # This is taken directly from Ara T Howard's Open4 library, and then
10
- # modified to suit the needs of Chef. Any bugs here are most likely
11
- # my own, and not Ara's.
10
+ # modified to suit the needs of the Chef project.
11
+ #
12
+ # http://github.com/ahoward/open4
13
+ #
14
+ # http://www.ruby-forum.com/topic/54593
15
+ #
16
+ # Don't use the "Block form" calling method. It screws up on the pipes IO.
17
+ #
18
+ # Use "Simple form", always. Simple form == more robust IO handling.
12
19
  #
13
- # The original appears in external/open4.rb in its unmodified form.
14
- #
15
- # Thanks Ara!
20
+ # @example Simple form
21
+ # def popen4_exec stdin_str, cmd, *args
22
+ # require 'plist4r/mixin/popen4'
23
+ #
24
+ # pid, stdin, stdout, stderr = ::Plist4r::Popen4::popen4 [cmd, *args]
25
+ #
26
+ # stdin.puts stdin_str
27
+ #
28
+ # stdin.close
29
+ # ignored, status = Process::waitpid2 pid
30
+ #
31
+ # stdout_result = stdout.read.strip
32
+ # stderr_result = stderr.read.strip
33
+ #
34
+ # return [cmd, status, stdout_result, stderr_result]
35
+ # end
16
36
  def popen4(cmd, args={}, &b)
17
37
 
18
38
  # Waitlast - this is magic.
@@ -3,6 +3,13 @@
3
3
  # we don't want to upset anyone else's code
4
4
 
5
5
  class Object
6
+ # The method name
7
+ # @return [String] The name of the current method
8
+ # @example
9
+ # def my_method
10
+ # method_name
11
+ # end
12
+ # my_method => "my_method"
6
13
  def method_name
7
14
  if /`(.*)'/.match(caller.first)
8
15
  return $1
@@ -11,13 +18,18 @@ class Object
11
18
  end
12
19
  end
13
20
 
14
-
15
21
  class String
22
+ # A Camel-ized string. The reverse of {#snake_case}
23
+ # @example
24
+ # "my_plist_key".camelcase => "MyPlistKey"
16
25
  def camelcase
17
26
  str = self.dup.capitalize.gsub(/[-_.\s]([a-zA-Z0-9])/) { $1.upcase } \
18
27
  .gsub('+', 'x')
19
28
  end
20
29
 
30
+ # A snake-cased string. The reverse of {#camelcase}
31
+ # @example
32
+ # "MyPlistKey".snake_case => "my_plist_key"
21
33
  def snake_case
22
34
  str = self.dup.gsub(/[A-Z]/) {|s| "_" + s}
23
35
  str = str.downcase.sub(/^\_/, "")
@@ -0,0 +1,44 @@
1
+ require 'plist4r/mixin/mixlib_cli'
2
+ require 'plist4r/mixin/mixlib_config'
3
+
4
+ module Plist4r
5
+ # Defines options for the `plist4r` command line utility
6
+ class CLI
7
+ include Plist4r::Mixlib::CLI
8
+
9
+ # The Plist4r CLI Options
10
+ #
11
+ # @example
12
+ # Usage: bin/plist4r (options)
13
+ # -b, --brew Customize for Brew. Use with --ruby-lib.
14
+ # -d, --dir DIR The directory to dump files into. Use with --ruby-lib. Defaults to cwd.
15
+ # -r, --ruby-lib Convert plist4r gem into a ruby lib, and write to the filesystem. (required)
16
+ # -h, --help Show this message
17
+ def self.plist4r_cli_options
18
+ option :ruby_lib, :required => true,
19
+ :short => "-r", :long => "--ruby-lib", :boolean => true, :default => false,
20
+ :description => "Convert plist4r gem into a ruby lib, and write to the filesystem."
21
+
22
+ option :brew,
23
+ :short => "-b", :long => "--brew", :boolean => true, :default => false,
24
+ :description => "Customize for Brew. Use with --ruby-lib."
25
+
26
+ option :dir,
27
+ :short => "-d DIR", :long => "--dir DIR", :default => nil,
28
+ :description => "The directory to dump files into. Use with --ruby-lib. Defaults to cwd."
29
+
30
+ option :help, :short => "-h", :long => "--help", :boolean => true,
31
+ :description => "Show this message",
32
+ :on => :tail,
33
+ :show_options => true,
34
+ :exit => 0
35
+ end
36
+ plist4r_cli_options
37
+
38
+ def parse argv=ARGV
39
+ parse_options(argv)
40
+ config
41
+ end
42
+
43
+ end
44
+ end
data/lib/plist4r/plist.rb CHANGED
@@ -8,14 +8,36 @@ require 'plist4r/backend'
8
8
 
9
9
  module Plist4r
10
10
  class Plist
11
- PlistOptionsHash = %w[filename path file_format plist_type unsupported_keys backends from_string]
11
+ # Recognised keys of the options hash. Passed when instantiating a new Plist Object
12
+ # @see #initialize
13
+ # @see #parse_opts
14
+ PlistOptionsHash = %w[filename path file_format plist_type strict_keys backends from_string]
15
+ # The plist file formats, written as symbols.
16
+ # @see #file_format
12
17
  FileFormats = %w[binary xml next_step]
13
-
18
+
19
+ # Instantiate a new Plist4r::Plist object. We usually set our per-application defaults in {Plist4r::Config} beforehand.
20
+ #
21
+ # @param [String] filename
22
+ # @param [Hash] options - for advanced usage
23
+ # @example Create new, empty plist
24
+ # Plist4r::Plist.new => #<Plist4r::Plist:0x111546c @file_format=nil, ...>
25
+ # @example Load from file
26
+ # Plist4r::Plist.new("example.plist") => #<Plist4r::Plist:0x1152d1c @file_format="xml", ...>
27
+ # @example Load from string
28
+ # plist_string = "{ \"key1\" = \"value1\"; \"key2\" = \"value2\"; }"
29
+ # Plist4r::Plist.new({ :from_string => plist_string })
30
+ # => #<Plist4r::Plist:0x11e161c @file_format="xml", ...>
31
+ # @example Advanced options
32
+ # plist_working_dir = `pwd`.strip
33
+ # Plist4r::Plist.new({ :filename => "example.plist", :path => plist_working_dir, :backends => ["libxml4r","ruby_cocoa"]})
34
+ # => #<Plist4r::Plist:0x111546c @file_format=nil, ...>
35
+ # @return [Plist4r::Plist] The new Plist object
14
36
  def initialize *args, &blk
15
- @hash = ::ActiveSupport::OrderedHash.new
37
+ @hash = ::Plist4r::OrderedHash.new
16
38
  @plist_type = plist_type :plist
17
39
 
18
- @unsupported_keys = Config[:unsupported_keys]
40
+ @strict_keys = Config[:strict_keys]
19
41
  @backends = Config[:backends]
20
42
 
21
43
  @from_string = nil
@@ -37,6 +59,12 @@ module Plist4r
37
59
  @plist_cache ||= PlistCache.new self
38
60
  end
39
61
 
62
+ # Reinitialize plist object from string (overwrites the current contents). Usually called from {Plist#initialize}
63
+ # @example Load from string
64
+ # plist = Plist4r::Plist.new
65
+ # => #<Plist4r::Plist:0x11e161c @file_format=nil, ...>
66
+ # plist.from_string "{ \"key1\" = \"value1\"; \"key2\" = \"value2\"; }"
67
+ # => #<Plist4r::Plist:0x11e161c @file_format="next_step", ...>
40
68
  def from_string string=nil
41
69
  case string
42
70
  when String
@@ -55,6 +83,12 @@ module Plist4r
55
83
  end
56
84
  end
57
85
 
86
+ # Set or return the filename attribute of the plist object.
87
+ # @param [String] filename either a relative path or absolute
88
+ # @return The plist's filename
89
+ # @see Plist::Plist#open
90
+ # @see Plist::Plist#save
91
+ # @see Plist::Plist#save_as
58
92
  def filename filename=nil
59
93
  case filename
60
94
  when String
@@ -66,6 +100,10 @@ module Plist4r
66
100
  end
67
101
  end
68
102
 
103
+ # Set or return the path attribute of the plist object. Pre-pended to the plist's filename (if filename is path-relative)
104
+ # @param [String] path (must be an absolute pathname)
105
+ # @return The plist's working path
106
+ # @see Plist::Plist#filename_path
69
107
  def path path=nil
70
108
  case path
71
109
  when String
@@ -77,6 +115,12 @@ module Plist4r
77
115
  end
78
116
  end
79
117
 
118
+ # Set or return the combined filename+path.
119
+ # We use this method in the backends api as the full path to load / save
120
+ # @param [String] filename_path concactenation of both filename and path elements. Also sets the @filename and @path attributes
121
+ # @return the full, expanded path to the plist file
122
+ # @see filename
123
+ # @see path
80
124
  def filename_path filename_path=nil
81
125
  case path
82
126
  when String
@@ -89,6 +133,11 @@ module Plist4r
89
133
  end
90
134
  end
91
135
 
136
+ # The file format of the plist file we are loading / saving. Written as a symbol.
137
+ # One of {Plist4r::Plist.FileFormats}. Defaults to :xml
138
+ # @param [Symbol, String] file_format Can be :binary, :xml, :next_step
139
+ # @return The file format associated to this current plist object
140
+ # @see Plist4r::Plist.FileFormats
92
141
  def file_format file_format=nil
93
142
  case file_format
94
143
  when Symbol, String
@@ -104,6 +153,11 @@ module Plist4r
104
153
  end
105
154
  end
106
155
 
156
+ # Called automatically on plist load / instantiation. This method detects the "Plist Type",
157
+ # using an algorithm that stats the plist data. The plist types with the highest stat (score)
158
+ # is chosen to be the object's "Plist Type".
159
+ # @see Plist4r::PlistType
160
+ # @return [true] always
107
161
  def detect_plist_type
108
162
  stat_m = {}
109
163
  stat_r = {}
@@ -139,6 +193,11 @@ module Plist4r
139
193
  return true
140
194
  end
141
195
 
196
+ # Set or return the plist_type of the current object. We can use this to override the automatic type detection.
197
+ # @param [Symbol, String] plist_type. Must be a sublcass of {Plist4r::PlistType}
198
+ # @return The plist's known type, written as a symbol. Will be a sublcass of Plist4r::PlistType. Defaults to :plist
199
+ # @see Plist4r::PlistType
200
+ # @see Plist4r::PlistType::Plist
142
201
  def plist_type plist_type=nil
143
202
  begin
144
203
  case plist_type
@@ -160,17 +219,29 @@ module Plist4r
160
219
  end
161
220
  end
162
221
 
163
- def unsupported_keys bool=nil
222
+ # Set or return strict_keys mode
223
+ # @param [true, false] bool If true, then raise an error for any unrecognized keys that dont belong to the {#plist_type}
224
+ # @return The strict_keys setting for this object
225
+ # @see Plist4r::Config
226
+ def strict_keys bool=nil
164
227
  case bool
165
228
  when true,false
166
- @unsupported_keys = bool
229
+ @strict_keys = bool
167
230
  when nil
168
- @unsupported_keys
231
+ @strict_keys
169
232
  else
170
233
  raise "Please specify true or false to enable / disable this option"
171
234
  end
172
235
  end
173
-
236
+
237
+ # An array of strings, symbols or class names which correspond to the active Plist4r::Backends for this object.
238
+ # The priority order in which backends are executed is determined by the in sequence array order.
239
+ # @param [Array] backends Inherited from {Plist4r::Config}[:backends]
240
+ # @return The backends for this object
241
+ # @example Execute haml before resorting to RubyCocoa
242
+ # plist.backends [:haml, :ruby_cocoa]
243
+ # @see Plist4r::Backend
244
+ # @see Plist4r::Backend::Example
174
245
  def backends backends=nil
175
246
  case backends
176
247
  when Array
@@ -182,6 +253,10 @@ module Plist4r
182
253
  end
183
254
  end
184
255
 
256
+ # Sets up those valid (settable) plist attributes as found the options hash.
257
+ # Normally we dont call this method ourselves. Called from {#initialize}.
258
+ # @param [Hash <PlistOptionsHash>] opts The options hash, containing keys of {PlistOptionsHash}
259
+ # @see #initialize
185
260
  def parse_opts opts
186
261
  PlistOptionsHash.each do |opt|
187
262
  if opts[opt.to_sym]
@@ -191,16 +266,46 @@ module Plist4r
191
266
  end
192
267
  end
193
268
 
269
+ # Opens a plist file
270
+ #
271
+ # @param [String] filename plist file to load. Uses the @filename attribute when nil
272
+ # @return [Plist4r::Plist] The loaded Plist object
273
+ # @example Load from file
274
+ # plist = Plist4r.new
275
+ # plist.open("example.plist") => #<Plist4r::Plist:0x1152d1c @file_format="xml", ...>
194
276
  def open filename=nil
195
277
  @filename = filename if filename
196
278
  raise "No filename specified" unless @filename
197
279
  @plist_cache.open
198
280
  end
199
281
 
282
+ # An alias of {#edit}
283
+ # @example
284
+ # plist.<< do
285
+ # set "PFReleaseVersion" "0.1.1"
286
+ # end
287
+ # @see #edit
200
288
  def << *args, &blk
201
289
  edit *args, &blk
202
290
  end
203
291
 
292
+ # Edit a plist object. Set or return plist keys. Add or remove a selection of keys.
293
+ # Plist key accessor methods are snake-cased versions of the key string.
294
+ # @example Set some arbitrary keys and values via {DataMethods#set}
295
+ # plist.edit do
296
+ # set "PFInstance" "4982394823"
297
+ # set "PFReleaseVersion" "0.1.1"
298
+ # end
299
+ # @example Retrieve, and modify a plist key, value pair, with {DataMethods#set} and {DataMethods#value_of}
300
+ # plist.edit do
301
+ # new_ver = value_of("PFReleaseVersion") + 0.1
302
+ # set "PFReleaseVersion" new_ver
303
+ # end
304
+ # @example Modify a Launchd plist, by camel-cased accessor methods
305
+ # plist.edit do
306
+ # new_ver = value_of("PFReleaseVersion") + 0.1
307
+ # set "PFReleaseVersion" new_ver
308
+ # end
204
309
  def edit *args, &blk
205
310
  @plist_type.hash @hash
206
311
  instance_eval *args, &blk
@@ -208,42 +313,79 @@ module Plist4r
208
313
  @plist_cache.update_checksum
209
314
  end
210
315
 
316
+ # Pass down unknown method calls to the selected plist_type, to set or return plist keys.
317
+ # All plist data manipulation API is called through method_missing -> PlistType -> DataMethods.
318
+ # @example This will actually call {DataMethods#set}
319
+ # plist.set "CFBundleVersion" "0.1.0"
320
+ # @see Plist4r::DataMethods#method_missing
321
+ # @see #plist_type
211
322
  def method_missing method_sym, *args, &blk
212
323
  @plist_type.send method_sym, *args, &blk
213
324
  end
214
325
 
326
+ # Backend method to set or return all new plist data resulting from a backend API. Used in load operations.
327
+ # @param [Plist4r::OrderedHash, nil] hash sets the new root object. Replaces all previous plist data.
328
+ # @return If no argument given, then clears all plist data, returning the new @hash root object
329
+ # @see Backend::Example
215
330
  def import_hash hash=nil
216
331
  case hash
217
- when ::ActiveSupport::OrderedHash
332
+ when ::Plist4r::OrderedHash
218
333
  @hash = hash
219
334
  when nil
220
- @hash = ::ActiveSupport::OrderedHash.new
335
+ @hash = ::Plist4r::OrderedHash.new
221
336
  else
222
- raise "Please use ::ActiveSupport::OrderedHash.new for your hashes"
337
+ raise "Please use ::Plist4r::OrderedHash.new for your hashes"
223
338
  end
224
339
  end
225
340
 
341
+ # The primary storage object for plist data
342
+ #
343
+ # @return [::Plist4r::OrderedHash] Nested hash of ruby objects. The raw Plist data
344
+ # @see ::Plist4r::OrderedHash
345
+ # @example
346
+ # plist = "{ \"key1\" = \"value1\"; \"key2\" = \"value2\"; }".to_plist
347
+ # plist.to_hash => {"key1"=>"value1", "key2"=>"value2"}
226
348
  def to_hash
227
349
  @hash
228
350
  end
229
-
351
+
352
+ # Calls out to the plist cache
353
+ #
354
+ # @return [String] An xml string which represents the entire plist, as would be the plist xml file
355
+ # @example
356
+ # plist = "{ \"key1\" = \"value1\"; \"key2\" = \"value2\"; }".to_plist
357
+ # plist.to_xml
358
+ # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>key1</key>\n\t<string>value1</string>\n\t<key>key2</key>\n\t<string>value2</string>\n</dict>\n</plist>"
230
359
  def to_xml
231
360
  @plist_cache.to_xml
232
361
  end
233
362
 
363
+ # @example
364
+ # plist = "{ \"key1\" = \"value1\"; \"key2\" = \"value2\"; }".to_plist
365
+ # plist.to_binary
366
+ # => "bplist00\322\001\002\003\004Tkey2Tkey1Vvalue2Vvalue1\b\r\022\027\036\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000%"
234
367
  def to_binary
235
368
  @plist_cache.to_binary
236
369
  end
237
370
 
371
+ # @todo Needs a backend
372
+ # We are missing a backend for writing out :next_step strings and saving :next_step files to disk
238
373
  def to_next_step
239
374
  @plist_cache.to_next_step
240
375
  end
241
376
 
377
+ # Save plist to #filename
378
+ # @raise [RuntimeError] if the {#filename} attribute is nil
379
+ # @see #filename
380
+ # @see #path
242
381
  def save
243
382
  raise "No filename specified" unless @filename
244
383
  @plist_cache.save
245
384
  end
246
385
 
386
+ # Save the plist under a new filename
387
+ # @param [String] filename The new file name to save as. If a relative path, will be concactenated to plist.path
388
+ # @see #save
247
389
  def save_as filename
248
390
  @filename = filename
249
391
  save
@@ -252,6 +394,7 @@ module Plist4r
252
394
  end
253
395
 
254
396
  module Plist4r
397
+ # @private
255
398
  class OldPlist
256
399
 
257
400
  def initialize path_prefix, plist_str, &blk
@@ -268,7 +411,7 @@ module Plist4r
268
411
  @shortname = @filename.match(/^.*\.(.*)$/)[1]
269
412
 
270
413
  @block = blk
271
- @hash = @orig = ::ActiveSupport::OrderedHash.new
414
+ @hash = @orig = ::Plist4r::OrderedHash.new
272
415
 
273
416
  instance_eval(&@block) if @block
274
417
  end