lib/jamf/utility.rb in ruby-jss-1.5.3 vs lib/jamf/utility.rb in ruby-jss-1.6.0b1

- old
+ new

@@ -185,34 +185,62 @@ raise Jamf::InvalidDataError, 'Input must be a comma-separated String or an Array of Strings' end # case { stringform: valstr, arrayform: valarr } end # to_s_and_a - # Parse a plist into a Ruby data structure. - # This enhances Plist::parse_xml taking file paths, as well as XML Strings - # and reading the files regardless of binary/XML format. + # Parse a plist into a Ruby data structure. The plist parameter may be + # a String containing an XML plist, or a path to a plist file, or it may be + # a Pathname object pointing to a plist file. The plist files may be XML or + # binary. # # @param plist[Pathname, String] the plist XML, or the path to a plist file # + # @param symbol_keys[Boolean] should any Hash keys in the result be converted + # into Symbols rather than remain as Strings? + # # @return [Object] the parsed plist as a ruby hash,array, etc. # - def self.parse_plist(plist) + def self.parse_plist(plist, symbol_keys: false) + require 'cfpropertylist' + # did we get a string of xml, or a string pathname? case plist when String - return Plist.parse_xml plist if plist.include? '</plist>' + return CFPropertyList.native_types(CFPropertyList::List.new(data: plist).value, symbol_keys) if plist.include? '</plist>' + plist = Pathname.new plist when Pathname true else raise ArgumentError, 'Argument must be a path (as a Pathname or String) or a String of XML' end # case plist # if we're here, its a Pathname - raise Jamf::MissingDataError, "No such file: #{plist}" unless plist.file? + raise JSS::MissingDataError, "No such file: #{plist}" unless plist.file? - Plist.parse_xml `/usr/libexec/PlistBuddy -x -c print #{Shellwords.escape(plist.to_s)}`.force_encoding('UTF-8') + CFPropertyList.native_types(CFPropertyList::List.new(file: plist).value, symbol_keys) end # parse_plist + + # Convert any ruby data to an XML plist. + # + # NOTE: Binary data is tricky. Easiest way is to pass in a + # Pathname or IO object (anything that responds to `read` and + # returns a bytestring) + # and then the CFPropertyList.guess method will read it and + # convert it to a Plist <data> element with base64 encoded + # data. + # For more info, see CFPropertyList.guess + # + # @param data [Object] the data to be converted, usually a Hash + # + # @return [String] the object converted into an XML plist + # + def self.xml_plist_from(data) + require 'cfpropertylist' + plist = CFPropertyList::List.new + plist.value = CFPropertyList.guess(data, convert_unknown_to_string: true) + plist.to_str(CFPropertyList::List::FORMAT_XML) + end # TODO: Sill needed in Jamf API? # # Converts anything that responds to #to_s to a Time, or nil #