Merge branch 'release/6.0.0' into feature/sonoma-clt
This commit is contained in:
Коммит
080499c0de
24
CHANGELOG.md
24
CHANGELOG.md
|
@ -1,19 +1,27 @@
|
|||
# Changelog
|
||||
|
||||
=======
|
||||
## [6.0.0] - 2023-06-30
|
||||
|
||||
### Removed
|
||||
- Removed the `plist` resource
|
||||
|
||||
### Fixed
|
||||
- Fixed issues with ARD not working on macOS Monterey.
|
||||
|
||||
### Added
|
||||
- Added additional functionality to the [remote_management](resources/remote_management.rb) resource.
|
||||
- You can now specify the users to whose privileges will be configured.
|
||||
- You can now specify the privileges to bestow upon the given users.
|
||||
- You can now set the computer info fields; this is helpful for stratifying computers within ARD.
|
||||
|
||||
## [5.1.0] - 2023-06-27
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed issues with ARD not working on macOS Monterey.
|
||||
- Ensured that CLT demand file always exists before we query the SWU catalog.
|
||||
|
||||
### Added
|
||||
|
||||
- Added additional functionality to the [remote_management](resources/remote_management.rb) resource.
|
||||
- You can now specify the users to whose privileges will be configured.
|
||||
- You can now specify the privileges to bestow upon the given users.
|
||||
- You can now set the computer info fields; this is helpful for stratifying computers within ARD.
|
||||
|
||||
-
|
||||
## [5.0.6] - 2023-06-23
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -19,9 +19,6 @@ Chef resources and recipes for managing and provisioning macOS.
|
|||
- macOS 12 Monterey
|
||||
|
||||
## Resources
|
||||
**The plist resource is deprecated and will be removed in the next major release of macos-cookbook. Please use the [plist resource included with Chef Client](https://docs.chef.io/resources/plist/).**
|
||||
|
||||
- [`plist`](https://github.com/Microsoft/macos-cookbook/blob/master/documentation/resource_plist.md) :warning: **DEPRECATED** :warning:
|
||||
- [`automatic_software_updates`](https://github.com/Microsoft/macos-cookbook/blob/master/documentation/resource_automatic_software_updates.md)
|
||||
- [`certificate`](https://github.com/Microsoft/macos-cookbook/blob/master/documentation/resource_certificate.md)
|
||||
- [`command_line_tools`](https://github.com/Microsoft/macos-cookbook/blob/master/documentation/resource_command_line_tools.md)
|
||||
|
|
|
@ -72,8 +72,8 @@ jobs:
|
|||
- template: test-kitchen.yml@templates
|
||||
parameters:
|
||||
jobName: "vintage"
|
||||
platforms:
|
||||
- big-sur-x86
|
||||
- monterey-x86
|
||||
suites: ${{ parameters.kitchenSuites }}
|
||||
kitchenFile: kitchen.yml
|
||||
platforms:
|
||||
- big-sur-x86
|
||||
- monterey-x86
|
||||
suites: ${{ parameters.kitchenSuites }}
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
plist
|
||||
=====
|
||||
|
||||
Use the **plist** resource to manage property list files (plists) and their content.
|
||||
The [**plist**](https://github.com/Microsoft/macos-cookbook/blob/master/resources/plist.rb) resource manages the state
|
||||
the delared plist `path`. Since each plist resource instance represents only one
|
||||
setting, you may end up with several plist resource calls in a given recipe. Although
|
||||
this may seem like overkill, it allows us to have a fully idempotent resource with
|
||||
fine granularity.
|
||||
|
||||
During the `chef-client` run, the client knows to check the state of the plist
|
||||
before changing any values. It also makes sure that the plist is in binary format
|
||||
so that the settings can be interpreted correctly by the operating system.
|
||||
|
||||
Prior knowledge of using commandline utilities such as
|
||||
`defaults`,
|
||||
`plutil`,
|
||||
and `PlistBuddy`
|
||||
will be useful when implementing the **plist** resource.
|
||||
|
||||
Syntax
|
||||
------
|
||||
|
||||
The full syntax for all of the properties that are available to the **plist**
|
||||
resource is:
|
||||
|
||||
```ruby
|
||||
plist 'description' do
|
||||
path String # defaults to 'description' if not specified
|
||||
entry String
|
||||
value TrueClass, FalseClass, String, Integer, Float
|
||||
action Symbol # defaults to :set if not specified
|
||||
encoding String # defaults to 'binary' if not specified.
|
||||
owner String # defaults to 'root' if not specified.
|
||||
group String # defaults to 'wheel' if not specified.
|
||||
mode String, Integer
|
||||
end
|
||||
```
|
||||
|
||||
Actions
|
||||
-------
|
||||
|
||||
This resource has the following actions:
|
||||
|
||||
`:set`
|
||||
|
||||
Set `entry` to `value` in `path`
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
**Show invisible files**
|
||||
|
||||
```ruby
|
||||
plist 'show hidden files' do
|
||||
path '/Users/vagrant/Library/Preferences/com.apple.finder.plist'
|
||||
entry 'AppleShowAllFiles'
|
||||
value true
|
||||
end
|
||||
```
|
||||
|
||||
where
|
||||
|
||||
`path` is the absolute path to the `com.apple.finder.plist` plist file
|
||||
|
||||
`entry` is the representing the plist entry `'AppleShowAllFiles'`
|
||||
|
||||
`value` is the entry's value to boolean type: `true`
|
|
@ -18,16 +18,16 @@ Properties
|
|||
-------
|
||||
|
||||
* `users`
|
||||
* **Description:** the user(s) whoose ARD privileges will be configured.
|
||||
* **Usage:** a single user can be specified in the form of a string, or multiple users can be specified as an array of strings. Specifying 'all' is a special case; all local users will be configured.
|
||||
* **Description:** the user(s) whose ARD privileges will be configured.
|
||||
* **Usage:** a single user can be specified as a string, or multiple users can be specified as an array of strings. Specifying 'all' is a particular case; all local users will be configured.
|
||||
* **Default:** `'all'`
|
||||
* Privileges will be configured for all local users.
|
||||
* **Constraints:** specified users must exist on the system.
|
||||
<br></br>
|
||||
|
||||
* `privileges`
|
||||
* **Description:** the desired privileges to bestow upon the given user(s).
|
||||
**Usage:** a single privilege can be specified in the form of a string, or multiple privileges can be specified as an array of strings.
|
||||
* **Description:** the desired privileges for the given user(s).
|
||||
* **Usage:** a single privilege can be specified in the form of a string, or multiple privileges can be specified as an array of strings.
|
||||
* **Default:** `'all'`
|
||||
* **Constraints:** the list of optional privileges bellow
|
||||
* `all` → grant all privileges (default)
|
||||
|
@ -45,8 +45,8 @@ Properties
|
|||
<br></br>
|
||||
|
||||
* `computer_info`
|
||||
* **Description:** Info fields; helpful for stratifying computers in the ARD client app.
|
||||
* **Usage** a single info field can be added as a string, or multiple info fields can be added as an array of strings.
|
||||
* **Description:** Info fields are helpful for stratifying computers in the ARD client app.
|
||||
* **Usage** a single info field can be added as a string, or multiple fields can be added as an array of strings.
|
||||
* **Default:** `[]`
|
||||
* No info fields will be added.
|
||||
* **Constraints:** there is a maximum of four info fields allowed.
|
||||
|
|
16
kitchen.yml
16
kitchen.yml
|
@ -23,36 +23,20 @@ platforms:
|
|||
- name: big-sur-x86
|
||||
driver:
|
||||
box: microsoft/macos-big-sur
|
||||
box_version: 11.7.8
|
||||
|
||||
- name: monterey-x86
|
||||
driver:
|
||||
box: microsoft/macos-monterey
|
||||
box_version: 12.6.7
|
||||
|
||||
- name: ventura-x86
|
||||
driver:
|
||||
box: microsoft/macos-ventura
|
||||
box_version: 13.4.1
|
||||
|
||||
- name: ventura-arm
|
||||
driver:
|
||||
box: microsoft/macos-ventura-arm
|
||||
box_version: 13.4.1
|
||||
|
||||
suites:
|
||||
- name: default
|
||||
provisioner:
|
||||
multiple_converge: 3
|
||||
enforce_idempotency: true
|
||||
run_list:
|
||||
- recipe[macos_test::preferences]
|
||||
verifier:
|
||||
controls:
|
||||
- dock-appearance
|
||||
- show-all-files
|
||||
- plist-creation
|
||||
|
||||
- name: software-updates
|
||||
provisioner:
|
||||
enforce_idempotency: true
|
||||
|
|
|
@ -1,149 +0,0 @@
|
|||
require 'shellwords'
|
||||
|
||||
module MacOS
|
||||
module PlistHelpers
|
||||
def convert_to_data_type_from_string(type, value)
|
||||
case type
|
||||
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
|
||||
when 'integer'
|
||||
value.to_i
|
||||
when 'float'
|
||||
value.to_f
|
||||
when 'string'
|
||||
value
|
||||
when 'dictionary'
|
||||
value
|
||||
when nil
|
||||
''
|
||||
else
|
||||
raise "Unknown or unsupported data type: #{type.class}"
|
||||
end
|
||||
end
|
||||
|
||||
def convert_to_string_from_data_type(value)
|
||||
case value
|
||||
when Array
|
||||
"-array #{value.map { |x| convert_to_string_from_data_type(x) }.join(' ')}"
|
||||
when Integer
|
||||
"-integer #{value}"
|
||||
when FalseClass
|
||||
"-bool #{value}"
|
||||
when TrueClass
|
||||
"-bool #{value}"
|
||||
when Hash
|
||||
"-dict #{value.map do |k, v|
|
||||
Shellwords.shellescape(k) + ' ' + convert_to_string_from_data_type(v)
|
||||
end.join(' ')}"
|
||||
when String
|
||||
"-string #{Shellwords.shellescape(value)}"
|
||||
when Float
|
||||
"-float #{value}"
|
||||
else
|
||||
raise "Unknown or unsupported data type: #{value} of #{value.class}"
|
||||
end
|
||||
end
|
||||
|
||||
def type_to_commandline_string(value)
|
||||
case value
|
||||
when Array
|
||||
'array'
|
||||
when Integer
|
||||
'integer'
|
||||
when FalseClass
|
||||
'bool'
|
||||
when TrueClass
|
||||
'bool'
|
||||
when Hash
|
||||
'dict'
|
||||
when String
|
||||
'string'
|
||||
when Float
|
||||
'float'
|
||||
else
|
||||
raise "Unknown or unsupported data type: #{value} of #{value.class}"
|
||||
end
|
||||
end
|
||||
|
||||
def entry_in_plist?(entry, path)
|
||||
print_entry = plistbuddy_command :print, entry, path
|
||||
cmd = shell_out print_entry
|
||||
cmd.exitstatus == 0
|
||||
end
|
||||
|
||||
def hardware_uuid
|
||||
system_profiler_hardware_output = shell_out('system_profiler', 'SPHardwareDataType').stdout
|
||||
hardware_overview = Psych.load(system_profiler_hardware_output)['Hardware']['Hardware Overview']
|
||||
hardware_overview['Hardware UUID']
|
||||
end
|
||||
|
||||
def plistbuddy_command(subcommand, entry, path, value = nil)
|
||||
sep = ' '
|
||||
arg = case subcommand.to_s
|
||||
when 'add'
|
||||
type_to_commandline_string(value)
|
||||
when 'set'
|
||||
if value.instance_of?(Hash)
|
||||
sep = ':'
|
||||
value.map { |k, v| "#{k} #{v}" }
|
||||
else
|
||||
value
|
||||
end
|
||||
else
|
||||
''
|
||||
end
|
||||
entry_with_arg = ["\"#{entry}\"", arg].join(sep).strip
|
||||
subcommand = "#{subcommand.capitalize} :#{entry_with_arg}"
|
||||
[plistbuddy_executable, '-c', "\'#{subcommand}\'", "\"#{path}\""].join(' ')
|
||||
end
|
||||
|
||||
def setting_from_plist(entry, path)
|
||||
defaults_read_type_output = shell_out(defaults_executable, 'read-type', path, entry).stdout
|
||||
data_type = defaults_read_type_output.split.last
|
||||
|
||||
if value.instance_of?(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
|
||||
|
||||
def plutil_format_map
|
||||
{ 'us-ascii' => 'xml1',
|
||||
'text/xml' => 'xml1',
|
||||
'utf-8' => 'xml1',
|
||||
'binary' => 'binary1' }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def plutil_executable
|
||||
'/usr/bin/plutil'
|
||||
end
|
||||
|
||||
def defaults_executable
|
||||
'/usr/bin/defaults'
|
||||
end
|
||||
|
||||
def plistbuddy_executable
|
||||
'/usr/libexec/PlistBuddy'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Chef::Deprecated
|
||||
class Base
|
||||
BASE_URL = 'https://github.com/microsoft/macos-cookbook/blob/master/README.md'.freeze
|
||||
end
|
||||
|
||||
class Plistresource < Base
|
||||
end
|
||||
end
|
||||
|
||||
Chef::Resource.include MacOS::PlistHelpers
|
||||
Chef::DSL::Recipe.include MacOS::PlistHelpers
|
|
@ -4,7 +4,7 @@ maintainer_email 'chef@microsoft.com'
|
|||
license 'MIT'
|
||||
description 'Resources for configuring and provisioning macOS'
|
||||
chef_version '>= 14.0'
|
||||
version '5.1.1'
|
||||
version '6.0.0'
|
||||
|
||||
source_url 'https://github.com/Microsoft/macos-cookbook'
|
||||
issues_url 'https://github.com/Microsoft/macos-cookbook/issues'
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
unified_mode true
|
||||
|
||||
provides :plist
|
||||
|
||||
property :path, String, name_property: true
|
||||
property :entry, String
|
||||
property :value, [TrueClass, FalseClass, String, Integer, Float, Hash]
|
||||
property :encoding, String, default: 'binary'
|
||||
property :owner, String, default: 'root'
|
||||
property :group, String, default: 'wheel'
|
||||
property :mode, [String, Integer]
|
||||
|
||||
load_current_value do |desired|
|
||||
current_value_does_not_exist! unless ::File.exist? desired.path
|
||||
entry desired.entry if entry_in_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])
|
||||
|
||||
file_type_cmd = shell_out '/usr/bin/file', '--brief', '--mime-encoding', '--preserve-date', desired.path
|
||||
encoding file_type_cmd.stdout.chomp
|
||||
|
||||
file_owner_cmd = shell_out('/usr/bin/stat', '-f', '%Su', desired.path)
|
||||
owner file_owner_cmd.stdout.chomp
|
||||
|
||||
file_group_cmd = shell_out('/usr/bin/stat', '-f', '%Sg', desired.path)
|
||||
group file_group_cmd.stdout.chomp
|
||||
end
|
||||
|
||||
action :set do
|
||||
deprecation_warning = 'The plist resource is deprecated and will be removed in the next major release of macos-cookbook. Please use the plist resource included with Chef Client >=16'
|
||||
|
||||
Chef.deprecated :plistresource, deprecation_warning
|
||||
Chef::Log.warn deprecation_warning
|
||||
|
||||
converge_if_changed :path do
|
||||
converge_by "create new plist: '#{new_resource.path}'" do
|
||||
file new_resource.path do
|
||||
empty_plist = {}.to_plist
|
||||
content empty_plist
|
||||
owner new_resource.owner
|
||||
group new_resource.group
|
||||
mode new_resource.mode if property_is_set?(:mode)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
plist_file_name = new_resource.path.split('/').last
|
||||
|
||||
converge_if_changed :entry do
|
||||
converge_by "add entry \"#{new_resource.entry}\" to #{plist_file_name}" do
|
||||
execute plistbuddy_command(:add, new_resource.entry, new_resource.path, new_resource.value) do
|
||||
action :run
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
converge_if_changed :value do
|
||||
converge_by "#{plist_file_name}: set #{new_resource.entry} to #{new_resource.value}" do
|
||||
execute plistbuddy_command(:set, new_resource.entry, new_resource.path, new_resource.value) do
|
||||
action :run
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
converge_if_changed :encoding do
|
||||
converge_by 'change format' do
|
||||
raise("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)
|
||||
execute [plutil_executable, '-convert', plutil_format_map[new_resource.encoding], new_resource.path] do
|
||||
action :run
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
converge_if_changed :owner do
|
||||
converge_by "update owner to #{new_resource.owner}" do
|
||||
file new_resource.path do
|
||||
owner new_resource.owner
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
converge_if_changed :group do
|
||||
converge_by "update group to #{new_resource.group}" do
|
||||
file new_resource.path do
|
||||
group new_resource.group
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,83 @@
|
|||
unified_mode true
|
||||
|
||||
provides :remote_management
|
||||
default_action :enable
|
||||
|
||||
property :users,
|
||||
[String, Array],
|
||||
default: 'all',
|
||||
description: 'The user(s) whoose ARD privileges will be configured.',
|
||||
coerce: ->(p) { [p].flatten }
|
||||
|
||||
property :privileges,
|
||||
[String, Array, Integer],
|
||||
default: 'all',
|
||||
description: 'The desired privileges to bestow upon the given users.',
|
||||
coerce: ->(p) { p.is_a?(Integer) ? p : RemoteManagement::BitMask.mask_from_privileges(p) },
|
||||
callbacks: { 'is invalid. See https://ss64.com/osx/kickstart.html for valid privileges' => ->(p) { RemoteManagement::BitMask.valid_mask?(p) } }
|
||||
|
||||
property :computer_info,
|
||||
[String, Array],
|
||||
default: [],
|
||||
description: 'Info fields; helpful for stratifing computers in ARD client app.',
|
||||
coerce: ->(p) { p.compact.map(&:to_s) },
|
||||
callbacks: { 'has too many elements; computer info excepts up to four info fields' => ->(p) { (p.is_a?(Array) && p.size < 4) } }
|
||||
|
||||
load_current_value do |desired|
|
||||
current_value_does_not_exist! unless RemoteManagement.activated?
|
||||
privileges RemoteManagement.current_mask(desired.users)
|
||||
computer_info RemoteManagement.current_computer_info
|
||||
end
|
||||
|
||||
# TODO; the enable action should be decoupled from configuration; configure action should be added; default action should be [:configure, :enable]
|
||||
|
||||
action :enable do
|
||||
converge_if_changed(:privileges, :computer_info) do
|
||||
raise(RemoteManagement::Exceptions::TCCError) unless RemoteManagement::TCC::DB.correct_privileges?
|
||||
|
||||
execute 'restart the TCC daemon' do
|
||||
command 'sudo pkill -9 tccd'
|
||||
only_if { platform_version >= Chef::Version.new('12.0.0') }
|
||||
not_if { RemoteManagement::TCC::State.enabled? }
|
||||
end
|
||||
|
||||
converge_if_changed(:privileges) do
|
||||
if new_resource.users.include?('all')
|
||||
converge_by('setting privileges for all users') do
|
||||
execute 'set privileges for all users' do
|
||||
command [RemoteManagement.kickstart, '-configure', '-allowAccessFor', '-allUsers', '-access', '-on', '-privs', '-mask', new_resource.privileges]
|
||||
end
|
||||
end
|
||||
else
|
||||
converge_by('setting privileges for specified users') do
|
||||
execute 'set up Remote Management to only grant access to users with privileges' do
|
||||
command [RemoteManagement.kickstart, '-configure', '-allowAccessFor', '-specifiedUsers']
|
||||
end
|
||||
|
||||
execute "set privileges for #{new_resource.users.join(', ')}" do
|
||||
command [RemoteManagement.kickstart, '-configure', '-access', '-on', '-privs', '-mask', new_resource.privileges, '-users', new_resource.users.join(',')]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
converge_if_changed(:computer_info) do
|
||||
new_resource.computer_info.each_with_index do |info, i|
|
||||
execute "set computer info field #{i + 1}" do
|
||||
command [RemoteManagement.kickstart, '-configure', '-computerinfo', "-set#{i + 1}", "-#{i + 1}", info]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
execute 'activate the Remote Management service and restart the agent' do
|
||||
command [RemoteManagement.kickstart, '-activate', '-restart', '-agent']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
action :disable do
|
||||
execute 'stop the Remote Management service and deactivate it so it will not start after the next restart' do
|
||||
command [RemoteManagement.kickstart, '-deactivate', '-stop']
|
||||
only_if { RemoteManagement.activated? }
|
||||
end
|
||||
end
|
|
@ -3,7 +3,6 @@ require 'chefspec/berkshelf'
|
|||
|
||||
require_relative '../libraries/macos_user'
|
||||
require_relative '../libraries/metadata_util'
|
||||
require_relative '../libraries/plist'
|
||||
require_relative '../libraries/system'
|
||||
require_relative '../libraries/xcode'
|
||||
require_relative '../libraries/xcversion'
|
||||
|
|
|
@ -1,169 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
include MacOS::PlistHelpers
|
||||
|
||||
describe MacOS::PlistHelpers, '#plist_command' do
|
||||
context 'Adding a value to a plist' do
|
||||
it 'the bool arguments contain the data type' do
|
||||
expect(plistbuddy_command(:add, 'FooEntry', 'path/to/file.plist', true)).to eq "/usr/libexec/PlistBuddy -c 'Add :\"FooEntry\" bool' \"path/to/file.plist\""
|
||||
end
|
||||
|
||||
it 'the add command only adds the data type' do
|
||||
expect(plistbuddy_command(:add, 'QuuxEntry', 'path/to/file.plist', 50)).to eq "/usr/libexec/PlistBuddy -c 'Add :\"QuuxEntry\" integer' \"path/to/file.plist\""
|
||||
end
|
||||
|
||||
it 'the delete command is formatted properly' do
|
||||
expect(plistbuddy_command(:delete, 'BarEntry', 'path/to/file.plist')).to eq "/usr/libexec/PlistBuddy -c 'Delete :\"BarEntry\"' \"path/to/file.plist\""
|
||||
end
|
||||
|
||||
it 'the set command is formatted properly' do
|
||||
expect(plistbuddy_command(:set, 'BazEntry', 'path/to/file.plist', false)).to eq "/usr/libexec/PlistBuddy -c 'Set :\"BazEntry\" false' \"path/to/file.plist\""
|
||||
end
|
||||
|
||||
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\""
|
||||
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
|
||||
|
||||
context 'The value provided contains spaces' do
|
||||
it 'returns the value properly formatted with double quotes' do
|
||||
expect(plistbuddy_command(:print, 'Foo Bar Baz', 'path/to/file.plist')).to eq "/usr/libexec/PlistBuddy -c 'Print :\"Foo Bar Baz\"' \"path/to/file.plist\""
|
||||
end
|
||||
end
|
||||
|
||||
context 'The value to be added contains spaces' do
|
||||
it 'returns the value properly formatted with double quotes' do
|
||||
expect(plistbuddy_command(:add, 'Foo Bar Baz', 'path/to/file.plist', true)).to eq "/usr/libexec/PlistBuddy -c 'Add :\"Foo Bar Baz\" bool' \"path/to/file.plist\""
|
||||
end
|
||||
end
|
||||
|
||||
context 'The plist itself contains spaces' do
|
||||
it 'returns the value properly formatted with double quotes' do
|
||||
expect(plistbuddy_command(:print, 'Foo Bar Baz', 'Library/Preferences/com.parallels.Parallels Desktop.plist')).to eq "/usr/libexec/PlistBuddy -c 'Print :\"Foo Bar Baz\"' \"Library/Preferences/com.parallels.Parallels Desktop.plist\""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe MacOS::PlistHelpers, '#convert_to_data_type_from_string' do
|
||||
context 'When the type is boolean and given a 1 or 0' do
|
||||
it 'returns true if entry is 1' do
|
||||
expect(convert_to_data_type_from_string('boolean', '1')).to eq true
|
||||
end
|
||||
|
||||
it 'returns false if entry is 0' do
|
||||
expect(convert_to_data_type_from_string('boolean', '0')).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
context 'When the type is integer and the value is 1' do
|
||||
it 'returns the value as an integer' do
|
||||
expect(convert_to_data_type_from_string('integer', '1')).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
context 'When the type is integer and the value is 0' do
|
||||
it 'returns the value as an integer' do
|
||||
expect(convert_to_data_type_from_string('integer', '0')).to eq 0
|
||||
end
|
||||
end
|
||||
|
||||
context 'When the type is integer and the value is 950224' do
|
||||
it 'returns the correct value as an integer' do
|
||||
expect(convert_to_data_type_from_string('integer', '950224')).to eq 950224
|
||||
end
|
||||
end
|
||||
|
||||
context 'When the type is string and the value is also a string' do
|
||||
it 'returns the correct value still as a string' do
|
||||
expect(convert_to_data_type_from_string('string', 'corge')).to eq 'corge'
|
||||
end
|
||||
end
|
||||
|
||||
context 'When the type is float and the value is 3.14159265359' do
|
||||
it 'returns the correct value as a float' do
|
||||
expect(convert_to_data_type_from_string('float', '3.14159265359')).to eq 3.14159265359
|
||||
end
|
||||
end
|
||||
|
||||
context 'When the type nor the value is given' do
|
||||
it 'returns an empty string' do
|
||||
expect(convert_to_data_type_from_string(nil, '')).to eq ''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe MacOS::PlistHelpers, '#type_to_commandline_string' do
|
||||
context 'When given a certain data type' do
|
||||
it 'returns the required boolean entry type as a string' do
|
||||
expect(type_to_commandline_string(true)).to eq 'bool'
|
||||
end
|
||||
|
||||
it 'returns the required array entry type as a string' do
|
||||
expect(type_to_commandline_string(['foo', 'bar'])).to eq 'array'
|
||||
end
|
||||
|
||||
it 'returns the required dictionary entry type as a string' do
|
||||
expect(type_to_commandline_string('baz' => 'qux')).to eq 'dict'
|
||||
end
|
||||
|
||||
it 'returns the required string entry type as a string' do
|
||||
expect(type_to_commandline_string('quux')).to eq 'string'
|
||||
end
|
||||
|
||||
it 'returns the required integer entry type as a string' do
|
||||
expect(type_to_commandline_string(1)).to eq 'integer'
|
||||
end
|
||||
|
||||
it 'returns the required float entry type as a string' do
|
||||
expect(type_to_commandline_string(1.0)).to eq 'float'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe MacOS::PlistHelpers, '#convert_to_string_from_data_type' do
|
||||
context 'When given a certain data type' do
|
||||
it 'returns the required boolean entry' do
|
||||
expect(convert_to_string_from_data_type(true)).to eq '-bool true'
|
||||
end
|
||||
|
||||
it 'returns the required string entry' do
|
||||
expect(convert_to_string_from_data_type('qu ux')).to eq '-string qu\ ux'
|
||||
end
|
||||
|
||||
it 'returns the required string entry with embedded quotes' do
|
||||
expect(convert_to_string_from_data_type('qu "ux"')).to eq '-string qu\ \"ux\"'
|
||||
end
|
||||
|
||||
it 'returns the required integer entry' do
|
||||
expect(convert_to_string_from_data_type(1)).to eq '-integer 1'
|
||||
end
|
||||
|
||||
it 'returns the required float entry' do
|
||||
expect(convert_to_string_from_data_type(1.0)).to eq '-float 1.0'
|
||||
end
|
||||
|
||||
it 'returns the required dictionary entry' do
|
||||
expect(convert_to_string_from_data_type({ 'a' => 'b', 'c' => 'd' })).to eq '-dict a -string b c -string d'
|
||||
end
|
||||
|
||||
it 'returns the required dictionary entry with embedded quotes and numbers' do
|
||||
expect(convert_to_string_from_data_type({ 'a' => 3, 'c' => '"d"' })).to eq '-dict a -integer 3 c -string \"d\"'
|
||||
end
|
||||
|
||||
it 'returns the required array entry' do
|
||||
expect(convert_to_string_from_data_type(['a', 'b', 'c'])).to eq '-array -string a -string b -string c'
|
||||
end
|
||||
|
||||
it 'returns the required array entry with embedded quotes' do
|
||||
expect(convert_to_string_from_data_type(['a', 'b "quotes"', 'c'])).to eq '-array -string a -string b\ \"quotes\" -string c'
|
||||
end
|
||||
|
||||
it 'returns the required array entry with integer data' do
|
||||
expect(convert_to_string_from_data_type(['a', 'b "quotes"', 3])).to eq '-array -string a -string b\ \"quotes\" -integer 3'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,19 +0,0 @@
|
|||
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
|
|
@ -1,45 +0,0 @@
|
|||
dock_plist = '/Users/vagrant/Library/Preferences/com.apple.dock.plist'
|
||||
macoscookbook_plist = '/Users/vagrant/com.microsoft.macoscookbook.plist'
|
||||
|
||||
plist 'show hidden files' do
|
||||
path '/Users/vagrant/Library/Preferences/com.apple.finder.plist'
|
||||
entry 'AppleShowAllFiles'
|
||||
value true
|
||||
owner 'vagrant'
|
||||
group 'staff'
|
||||
end
|
||||
|
||||
plist 'put the Dock on the left side' do
|
||||
path dock_plist
|
||||
entry 'orientation'
|
||||
value 'left'
|
||||
owner 'vagrant'
|
||||
group 'staff'
|
||||
end
|
||||
|
||||
plist 'disable window animations and Get Info animations' do
|
||||
path dock_plist
|
||||
entry 'DisableAllAnimations'
|
||||
value true
|
||||
owner 'vagrant'
|
||||
group 'staff'
|
||||
end
|
||||
|
||||
plist 'create a plist that does not exist to test plist creation' do
|
||||
path macoscookbook_plist
|
||||
entry 'PokeballEatenByDog'
|
||||
value true
|
||||
owner 'vagrant'
|
||||
group 'staff'
|
||||
encoding 'us-ascii'
|
||||
mode '0600'
|
||||
end
|
||||
|
||||
plist 'add another value to the new plist' do
|
||||
path macoscookbook_plist
|
||||
entry 'CaughtEmAll'
|
||||
value false
|
||||
owner 'vagrant'
|
||||
group 'staff'
|
||||
encoding 'us-ascii'
|
||||
end
|
|
@ -17,24 +17,3 @@ control 'show-all-files' do
|
|||
its('mode') { should cmp '0600' }
|
||||
end
|
||||
end
|
||||
|
||||
control 'plist-creation' do
|
||||
title 'arbitrary plist creation'
|
||||
desc 'creation and modification of a property list'
|
||||
|
||||
macos_cookbook_plist = '/Users/vagrant/com.microsoft.macoscookbook.plist'
|
||||
|
||||
describe command("/usr/libexec/PlistBuddy -c 'Print :PokeballEatenByDog' #{macos_cookbook_plist}") do
|
||||
its('stdout') { should match 'true' }
|
||||
end
|
||||
|
||||
describe command("/usr/libexec/PlistBuddy -c 'Print :CaughtEmAll' #{macos_cookbook_plist}") do
|
||||
its('stdout') { should match 'false' }
|
||||
end
|
||||
|
||||
describe file(macos_cookbook_plist) do
|
||||
its('owner') { should eq 'vagrant' }
|
||||
its('group') { should eq 'staff' }
|
||||
its('mode') { should cmp '0600' }
|
||||
end
|
||||
end
|
||||
|
|
Загрузка…
Ссылка в новой задаче