Merge pull request #216 from microsoft/feature/plist-dicts

Implement basic dict support for plist resource
This commit is contained in:
Jacob Zaval 2019-12-09 11:32:24 -08:00 коммит произвёл GitHub
Родитель b51cec1d87 587523d74f
Коммит cfbcfcdef4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 57 добавлений и 11 удалений

Просмотреть файл

@ -3,6 +3,9 @@ module MacOS
def convert_to_data_type_from_string(type, value) def convert_to_data_type_from_string(type, value)
case type case type
when 'boolean' when 'boolean'
# Since we've determined this is a boolean data type, we can assume that:
# If the value as an int is 1, return true
# If the value as an int is 0 (not 1), return false
value.to_i == 1 value.to_i == 1
when 'integer' when 'integer'
value.to_i value.to_i
@ -10,6 +13,8 @@ module MacOS
value.to_f value.to_f
when 'string' when 'string'
value value
when 'dictionary'
value
when nil when nil
'' ''
else else
@ -49,8 +54,9 @@ module MacOS
end end
end end
def print_entry_value(entry, path) def entry_in_plist?(entry, path)
cmd = shell_out(plistbuddy_command(:print, entry, path)) print_entry = plistbuddy_command :print, entry, path
cmd = shell_out print_entry
cmd.exitstatus == 0 cmd.exitstatus == 0
end end
@ -61,23 +67,36 @@ module MacOS
end end
def plistbuddy_command(subcommand, entry, path, value = nil) def plistbuddy_command(subcommand, entry, path, value = nil)
sep = ' '
arg = case subcommand.to_s arg = case subcommand.to_s
when 'add' when 'add'
type_to_commandline_string(value) type_to_commandline_string(value)
when 'print' when 'set'
'' if value.class == Hash
sep = ':'
value.map { |k, v| "#{k} #{v}" }
else
value
end
else else
value ''
end end
entry_with_arg = ["\"#{entry}\"", arg].join(' ').strip entry_with_arg = ["\"#{entry}\"", arg].join(sep).strip
subcommand = "#{subcommand.capitalize} :#{entry_with_arg}" subcommand = "#{subcommand.capitalize} :#{entry_with_arg}"
[plistbuddy_executable, '-c', "\'#{subcommand}\'", "\"#{path}\""].join(' ') [plistbuddy_executable, '-c', "\'#{subcommand}\'", "\"#{path}\""].join(' ')
end end
def setting_from_plist(entry, path) def setting_from_plist(entry, path)
defaults_read_type_output = shell_out(defaults_executable, 'read-type', path, entry).stdout defaults_read_type_output = shell_out(defaults_executable, 'read-type', path, entry).stdout
defaults_read_output = shell_out(defaults_executable, 'read', path, entry).stdout data_type = defaults_read_type_output.split.last
{ key_type: defaults_read_type_output.split.last, key_value: defaults_read_output.strip }
if value.class == Hash
plutil_output = shell_out(plutil_executable, '-extract', entry, 'xml1', '-o', '-', path).stdout.chomp
{ key_type: data_type, key_value: Plist.parse_xml(plutil_output) }
else
defaults_read_output = shell_out(defaults_executable, 'read', path, entry).stdout
{ key_type: data_type, key_value: defaults_read_output.strip }
end
end end
def plutil_format_map def plutil_format_map
@ -89,6 +108,10 @@ module MacOS
private private
def plutil_executable
'/usr/bin/plutil'
end
def defaults_executable def defaults_executable
'/usr/bin/defaults' '/usr/bin/defaults'
end end

Просмотреть файл

@ -2,7 +2,7 @@ resource_name :plist
property :path, String, name_property: true, desired_state: true property :path, String, name_property: true, desired_state: true
property :entry, String, desired_state: true property :entry, String, desired_state: true
property :value, [TrueClass, FalseClass, String, Integer, Float], desired_state: true property :value, [TrueClass, FalseClass, String, Integer, Float, Hash], desired_state: true
property :encoding, String, desired_state: true, default: 'binary' property :encoding, String, desired_state: true, default: 'binary'
property :owner, String, desired_state: true, default: 'root' property :owner, String, desired_state: true, default: 'root'
property :group, String, desired_state: true, default: 'wheel' property :group, String, desired_state: true, default: 'wheel'
@ -10,7 +10,7 @@ property :mode, [String, Integer]
load_current_value do |desired| load_current_value do |desired|
current_value_does_not_exist! unless ::File.exist? desired.path current_value_does_not_exist! unless ::File.exist? desired.path
entry desired.entry if print_entry_value desired.entry, desired.path entry desired.entry if entry_in_plist? desired.entry, desired.path
setting = setting_from_plist desired.entry, desired.path setting = setting_from_plist desired.entry, desired.path
value convert_to_data_type_from_string(setting[:key_type], setting[:key_value]) value convert_to_data_type_from_string(setting[:key_type], setting[:key_value])
@ -61,7 +61,7 @@ action :set do
Chef::Application.fatal!( Chef::Application.fatal!(
"Option encoding must be equal to one of: #{plutil_format_map.keys}! You passed \"#{new_resource.encoding}\"." "Option encoding must be equal to one of: #{plutil_format_map.keys}! You passed \"#{new_resource.encoding}\"."
) unless plutil_format_map.key?(new_resource.encoding) ) unless plutil_format_map.key?(new_resource.encoding)
execute ['/usr/bin/plutil', '-convert', plutil_format_map[new_resource.encoding], new_resource.path] do execute [plutil_executable, '-convert', plutil_format_map[new_resource.encoding], new_resource.path] do
action :run action :run
end end
end end

Просмотреть файл

@ -23,6 +23,10 @@ describe MacOS::PlistHelpers, '#plist_command' do
it 'the print command is formatted properly' do it 'the print command is formatted properly' do
expect(plistbuddy_command(:print, 'QuxEntry', 'path/to/file.plist')).to eq "/usr/libexec/PlistBuddy -c 'Print :\"QuxEntry\"' \"path/to/file.plist\"" expect(plistbuddy_command(:print, 'QuxEntry', 'path/to/file.plist')).to eq "/usr/libexec/PlistBuddy -c 'Print :\"QuxEntry\"' \"path/to/file.plist\""
end end
it 'the command to set a dictionary data type is formatted properly' do
expect(plistbuddy_command(:set, 'AppleFirstWeekday', 'path/to/file.plist', gregorian: 4)).to eq "/usr/libexec/PlistBuddy -c 'Set :\"AppleFirstWeekday\":gregorian 4' \"path/to/file.plist\""
end
end end
context 'The value provided contains spaces' do context 'The value provided contains spaces' do

Просмотреть файл

@ -0,0 +1,19 @@
require 'spec_helper'
describe 'setting the first day of the week to monday' do
step_into :plist
platform 'mac_os_x', 10.14
recipe do
plist 'make Monday the first DOW' do
path '/Users/somebody/Library/Preferences/.GlobalPreferences.plist'
entry 'AppleFirstWeekday'
value(gregorian: 4)
owner 'somebody'
group 'staff'
end
end
it { is_expected.to run_execute("/usr/libexec/PlistBuddy -c 'Set :\"AppleFirstWeekday\":gregorian 4' \"/Users/somebody/Library/Preferences/.GlobalPreferences.plist\"") }
end