From 6927637126b8d4ce1fe08687af9406af218c4e0f Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 00:30:58 -0700 Subject: [PATCH 01/83] first commit plistbuddy --- libraries/plistbuddy.rb | 47 +++++++++++++++++++++++ resources/plistbuddy.rb | 30 +++++++++++++++ spec/unit/libraries/plistbuddy_helpers.rb | 0 3 files changed, 77 insertions(+) create mode 100644 libraries/plistbuddy.rb create mode 100644 resources/plistbuddy.rb create mode 100644 spec/unit/libraries/plistbuddy_helpers.rb diff --git a/libraries/plistbuddy.rb b/libraries/plistbuddy.rb new file mode 100644 index 00000000..a4de3654 --- /dev/null +++ b/libraries/plistbuddy.rb @@ -0,0 +1,47 @@ +module OfficeMacDevEnv + module PlistbuddyHelpers + class PlistBuddy < Dir + include Chef::Mixin::ShellOut + + def exist?(entry, value) + shell_out!(plistbuddy_command('Print', entry, value)) + end + + private + + def convert_to_data_type(entry) + data_type_cases = { Array.to_s => "array #{value}", + Integer.to_s => "int #{value}", + TrueClass.to_s => 'bool TRUE', + FalseClass.to_s => 'bool FALSE', + Hash.to_s => "dict #{value}", + String.to_s => "string #{value}", + Float.to_s => "float #{value}" } + data_type_cases[entry] + end + + def execute_plistbuddy_command(command_action, entry, value) + entry = convert_to_data_type new_resource.entry + "/usr/libexec/Plistbuddy -c \':#{command_action.capitalize.to_s} #{entry} #{value}\'" + end + + end +end + +# +# The module you have defined may be extended within the recipe to grant the +# recipe the helper methods you define. +# +# Within your recipe you would write: +# +# extend OfficeMacDevEnv::PlistbuddyHelpers +# +# my_helper_method +# +# You may also add this to a single resource within a recipe: +# +# template '/etc/app.conf' do +# extend OfficeMacDevEnv::PlistbuddyHelpers +# variables specific_key: my_helper_method +# end +# diff --git a/resources/plistbuddy.rb b/resources/plistbuddy.rb new file mode 100644 index 00000000..ba5b57ff --- /dev/null +++ b/resources/plistbuddy.rb @@ -0,0 +1,30 @@ +resource_name :plistbuddy + +property :action, Symbol, name_property: true + +property :entry +property :value +property :file +property :clear +property :data_type +property :sub_command + +action_class do + def plistbuddy_command(command_action, entry, value) + entry = convert_to_data_type new_resource.entry + "/usr/libexec/Plistbuddy -c ':#{command_action.capitalize.to_s} #{entry} #{value}" + end + + private + + def convert_to_data_type(entry) + data_type_cases = { Array.to_s => "array #{value}", + Integer.to_s => "int #{value}", + TrueClass.to_s => 'bool TRUE', + FalseClass.to_s => 'bool FALSE', + Hash.to_s => "dict #{value}", + String.to_s => "string #{value}", + Float.to_s => "float #{value}" } + data_type_cases[entry] + end +end diff --git a/spec/unit/libraries/plistbuddy_helpers.rb b/spec/unit/libraries/plistbuddy_helpers.rb new file mode 100644 index 00000000..e69de29b From b6cc4f0c5aecf69f6aa28c5c0b1ee048ec094a6a Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 01:30:48 -0700 Subject: [PATCH 02/83] all recipe/plist in macos --- libraries/plistbuddy.rb | 64 +++++++++-------------- resources/plistbuddy.rb | 25 ++++----- spec/unit/libraries/plistbuddy_helpers.rb | 0 spec/unit/libraries/plistbuddy_spec.rb | 9 ++++ 4 files changed, 44 insertions(+), 54 deletions(-) delete mode 100644 spec/unit/libraries/plistbuddy_helpers.rb create mode 100644 spec/unit/libraries/plistbuddy_spec.rb diff --git a/libraries/plistbuddy.rb b/libraries/plistbuddy.rb index a4de3654..ebc7c6cd 100644 --- a/libraries/plistbuddy.rb +++ b/libraries/plistbuddy.rb @@ -1,47 +1,31 @@ module OfficeMacDevEnv module PlistbuddyHelpers - class PlistBuddy < Dir - include Chef::Mixin::ShellOut + module PlistBuddy + extend Dir + include Chef::Mixin::ShellOut - def exist?(entry, value) - shell_out!(plistbuddy_command('Print', entry, value)) - end - - private - - def convert_to_data_type(entry) - data_type_cases = { Array.to_s => "array #{value}", - Integer.to_s => "int #{value}", - TrueClass.to_s => 'bool TRUE', - FalseClass.to_s => 'bool FALSE', - Hash.to_s => "dict #{value}", - String.to_s => "string #{value}", - Float.to_s => "float #{value}" } - data_type_cases[entry] - end + def self.exist? + command = format_plistbuddy_command('print', entry, value) + shell_out(command).error? + end - def execute_plistbuddy_command(command_action, entry, value) - entry = convert_to_data_type new_resource.entry - "/usr/libexec/Plistbuddy -c \':#{command_action.capitalize.to_s} #{entry} #{value}\'" - end + private + def convert_to_string_from_data_type(entry) + data_type_cases = { Array.to_s => "array #{value}", + Integer.to_s => "int #{value}", + TrueClass.to_s => 'bool TRUE', + FalseClass.to_s => 'bool FALSE', + Hash.to_s => "dict #{value}", + String.to_s => "string #{value}", + Float.to_s => "float #{value}" } + data_type_cases[entry] + end + + def format_plistbuddy_command(action_property, entry, value) + entry = convert_to_data_type enty + "/usr/libexec/Plistbuddy -c \':#{action_property.to_s.capitalize} #{entry} #{value}\'" + end + end end end - -# -# The module you have defined may be extended within the recipe to grant the -# recipe the helper methods you define. -# -# Within your recipe you would write: -# -# extend OfficeMacDevEnv::PlistbuddyHelpers -# -# my_helper_method -# -# You may also add this to a single resource within a recipe: -# -# template '/etc/app.conf' do -# extend OfficeMacDevEnv::PlistbuddyHelpers -# variables specific_key: my_helper_method -# end -# diff --git a/resources/plistbuddy.rb b/resources/plistbuddy.rb index ba5b57ff..5d86d60f 100644 --- a/resources/plistbuddy.rb +++ b/resources/plistbuddy.rb @@ -2,29 +2,26 @@ property :action, Symbol, name_property: true -property :entry -property :value -property :file -property :clear -property :data_type -property :sub_command +property :name, String +property :entry, String +property :value, [Hash, String, Array, TrueClass, FalseClass, Int, Float] action_class do def plistbuddy_command(command_action, entry, value) entry = convert_to_data_type new_resource.entry - "/usr/libexec/Plistbuddy -c ':#{command_action.capitalize.to_s} #{entry} #{value}" + "/usr/libexec/Plistbuddy -c ':#{command_action.capitalize} #{entry} #{value}" end private def convert_to_data_type(entry) - data_type_cases = { Array.to_s => "array #{value}", - Integer.to_s => "int #{value}", - TrueClass.to_s => 'bool TRUE', - FalseClass.to_s => 'bool FALSE', - Hash.to_s => "dict #{value}", - String.to_s => "string #{value}", - Float.to_s => "float #{value}" } + data_type_cases = { Array.to_s => "array #{new_resource.value}", + Integer.to_s => "int #{new_resource.value}", + TrueClass.to_s => 'bool TRUE', + FalseClass.to_s => 'bool FALSE', + Hash.to_s => "dict #{new_resource.value}", + String.to_s => "string #{new_resource.value}", + Float.to_s => "float #{new_resource.value}" } data_type_cases[entry] end end diff --git a/spec/unit/libraries/plistbuddy_helpers.rb b/spec/unit/libraries/plistbuddy_helpers.rb deleted file mode 100644 index e69de29b..00000000 diff --git a/spec/unit/libraries/plistbuddy_spec.rb b/spec/unit/libraries/plistbuddy_spec.rb new file mode 100644 index 00000000..8b91b9ed --- /dev/null +++ b/spec/unit/libraries/plistbuddy_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +include OfficeMacDevEnv::PlistbuddyHelpers::PlistBuddy + +context 'When given some commands' do + it 'the command is formatted properly' do + expect(format_plistbuddy_command(:add, 'DidSeeSiriSetup', 0)).to eq "/usr/libexec/Plistbuddy -c ':Add DidSiriSetup 0'" + end +end From ed74b85aa6c7b557b7fcb51bc13db089a37950dc Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 10:44:30 -0700 Subject: [PATCH 03/83] extract plistbuddy to resource --- libraries/plistbuddy.rb | 48 +++++++++++++------------- spec/spec_helper.rb | 7 ++-- spec/unit/libraries/plistbuddy_spec.rb | 5 ++- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/libraries/plistbuddy.rb b/libraries/plistbuddy.rb index ebc7c6cd..a51099b7 100644 --- a/libraries/plistbuddy.rb +++ b/libraries/plistbuddy.rb @@ -1,31 +1,31 @@ -module OfficeMacDevEnv - module PlistbuddyHelpers - module PlistBuddy - extend Dir - include Chef::Mixin::ShellOut +module PlistBuddy + module Helper + include Chef::Mixin::ShellOut - def self.exist? - command = format_plistbuddy_command('print', entry, value) - shell_out(command).error? - end + def self.exist? + command = format_plistbuddy_command('print', entry, value) + shell_out(command).error? + end - private + private - def convert_to_string_from_data_type(entry) - data_type_cases = { Array.to_s => "array #{value}", - Integer.to_s => "int #{value}", - TrueClass.to_s => 'bool TRUE', - FalseClass.to_s => 'bool FALSE', - Hash.to_s => "dict #{value}", - String.to_s => "string #{value}", - Float.to_s => "float #{value}" } - data_type_cases[entry] - end + def convert_to_string_from_data_type(entry) + data_type_cases = { Array.to_s => "array #{value}", + Integer.to_s => "int #{value}", + TrueClass.to_s => 'bool TRUE', + FalseClass.to_s => 'bool FALSE', + Hash.to_s => "dict #{value}", + String.to_s => "string #{value}", + Float.to_s => "float #{value}" } + data_type_cases[entry] + end - def format_plistbuddy_command(action_property, entry, value) - entry = convert_to_data_type enty - "/usr/libexec/Plistbuddy -c \':#{action_property.to_s.capitalize} #{entry} #{value}\'" - end + def format_plistbuddy_command(action_property, entry, value) + entry = convert_to_data_type enty + "/usr/libexec/Plistbuddy -c \':#{action_property.to_s.capitalize} #{entry} #{value}\'" end end end + +Chef::Recipe.include(PlistBuddy::Helper) +Chef::Resource.include(PlistBuddy::Helper) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1dd5126b..b16fba26 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,2 +1,5 @@ -require 'chefspec' -require 'chefspec/berkshelf' +# require 'chefspec' +# require 'chefspec/berkshelf' + +require_relative '../libraries/plistbuddy' +require_relative '../libraries/xcode' \ No newline at end of file diff --git a/spec/unit/libraries/plistbuddy_spec.rb b/spec/unit/libraries/plistbuddy_spec.rb index 8b91b9ed..74528bff 100644 --- a/spec/unit/libraries/plistbuddy_spec.rb +++ b/spec/unit/libraries/plistbuddy_spec.rb @@ -1,9 +1,8 @@ require 'spec_helper' - -include OfficeMacDevEnv::PlistbuddyHelpers::PlistBuddy +include PlistBuddy::Helper context 'When given some commands' do it 'the command is formatted properly' do - expect(format_plistbuddy_command(:add, 'DidSeeSiriSetup', 0)).to eq "/usr/libexec/Plistbuddy -c ':Add DidSiriSetup 0'" + expect(Plist.format_plistbuddy_command(:add, 'DidSeeSiriSetup', 0)).to eq "/usr/libexec/Plistbuddy -c ':Add DidSiriSetup 0'" end end From 9beca33ee6128e198c3766faf8b3f948480de2e1 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 11:27:33 -0700 Subject: [PATCH 04/83] Straighten out unit tests - Correctly include modules - Correctly setup spec_helper - Correct unit test / respec setup --- libraries/plistbuddy.rb | 10 +++++----- spec/spec_helper.rb | 6 +++--- spec/unit/libraries/plistbuddy_spec.rb | 11 +++++++---- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/libraries/plistbuddy.rb b/libraries/plistbuddy.rb index a51099b7..9c456554 100644 --- a/libraries/plistbuddy.rb +++ b/libraries/plistbuddy.rb @@ -1,7 +1,7 @@ -module PlistBuddy - module Helper - include Chef::Mixin::ShellOut +include Chef::Mixin::ShellOut +module MacOS + module PlistBuddyHelpers def self.exist? command = format_plistbuddy_command('print', entry, value) shell_out(command).error? @@ -27,5 +27,5 @@ def format_plistbuddy_command(action_property, entry, value) end end -Chef::Recipe.include(PlistBuddy::Helper) -Chef::Resource.include(PlistBuddy::Helper) +Chef::Recipe.include(MacOS::PlistBuddyHelpers) +Chef::Resource.include(MacOS::PlistBuddyHelpers) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b16fba26..08509c91 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,5 @@ -# require 'chefspec' -# require 'chefspec/berkshelf' +require 'chefspec' +require 'chefspec/berkshelf' require_relative '../libraries/plistbuddy' -require_relative '../libraries/xcode' \ No newline at end of file +require_relative '../libraries/xcode' diff --git a/spec/unit/libraries/plistbuddy_spec.rb b/spec/unit/libraries/plistbuddy_spec.rb index 74528bff..b948fa96 100644 --- a/spec/unit/libraries/plistbuddy_spec.rb +++ b/spec/unit/libraries/plistbuddy_spec.rb @@ -1,8 +1,11 @@ require 'spec_helper' -include PlistBuddy::Helper -context 'When given some commands' do - it 'the command is formatted properly' do - expect(Plist.format_plistbuddy_command(:add, 'DidSeeSiriSetup', 0)).to eq "/usr/libexec/Plistbuddy -c ':Add DidSiriSetup 0'" +include MacOS::PlistBuddyHelpers + +describe MacOS::PlistBuddyHelpers, '#format_plistbuddy_command' do + context 'When given some commands' do + it 'the command is formatted properly' do + expect(format_plistbuddy_command(:add, 'DidSeeSiriSetup', 0)).to eq "/usr/libexec/Plistbuddy -c ':Add DidSiriSetup 0'" + end end end From 2bca4d53a88914997c1279c18f93bfa6cc2099b7 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 12:07:23 -0700 Subject: [PATCH 05/83] first passing test --- libraries/plistbuddy.rb | 31 ++++++++++++-------------- resources/plistbuddy.rb | 30 ++++++++++++------------- spec/unit/libraries/plistbuddy_spec.rb | 2 +- spec/unit/recipes/configurator.rb | 2 +- spec/unit/recipes/default_spec.rb | 2 +- spec/unit/recipes/keep_awake_spec.rb | 2 +- spec/unit/recipes/xcode_spec.rb | 2 +- 7 files changed, 34 insertions(+), 37 deletions(-) diff --git a/libraries/plistbuddy.rb b/libraries/plistbuddy.rb index 9c456554..6f514eb2 100644 --- a/libraries/plistbuddy.rb +++ b/libraries/plistbuddy.rb @@ -2,27 +2,24 @@ module MacOS module PlistBuddyHelpers - def self.exist? - command = format_plistbuddy_command('print', entry, value) - shell_out(command).error? - end - - private - - def convert_to_string_from_data_type(entry) - data_type_cases = { Array.to_s => "array #{value}", - Integer.to_s => "int #{value}", + # def self.exist? + # command = format_plistbuddy_command('print', entry, value) + # shell_out(command).error? + # end + def convert_to_string_from_data_type(plist_entry) + data_type_cases = { Array.to_s => "array #{plist_entry}", + Integer.to_s => "int #{plist_entry}", TrueClass.to_s => 'bool TRUE', FalseClass.to_s => 'bool FALSE', - Hash.to_s => "dict #{value}", - String.to_s => "string #{value}", - Float.to_s => "float #{value}" } - data_type_cases[entry] + Hash.to_s => "dict #{plist_entry}", + String.to_s => "string #{plist_entry}", + Float.to_s => "float #{plist_entry}" } + data_type_cases[plist_entry.class] end - def format_plistbuddy_command(action_property, entry, value) - entry = convert_to_data_type enty - "/usr/libexec/Plistbuddy -c \':#{action_property.to_s.capitalize} #{entry} #{value}\'" + def format_plistbuddy_command(action_property, plist_entry, plist_value = nil) + entry_wdt = convert_to_string_from_data_type plist_entry + "/usr/libexec/Plistbuddy -c \':#{action_property.to_s.capitalize} #{plist_entry} #{plist_value}#{entry_wdt}\'" end end end diff --git a/resources/plistbuddy.rb b/resources/plistbuddy.rb index 5d86d60f..12b55688 100644 --- a/resources/plistbuddy.rb +++ b/resources/plistbuddy.rb @@ -7,21 +7,21 @@ property :value, [Hash, String, Array, TrueClass, FalseClass, Int, Float] action_class do - def plistbuddy_command(command_action, entry, value) - entry = convert_to_data_type new_resource.entry - "/usr/libexec/Plistbuddy -c ':#{command_action.capitalize} #{entry} #{value}" - end + # def plistbuddy_command(command_action, entry, value) + # entry = convert_to_data_type new_resource.entry + # "/usr/libexec/Plistbuddy -c ':#{command_action.capitalize} #{entry} #{value}" + # end - private + # private - def convert_to_data_type(entry) - data_type_cases = { Array.to_s => "array #{new_resource.value}", - Integer.to_s => "int #{new_resource.value}", - TrueClass.to_s => 'bool TRUE', - FalseClass.to_s => 'bool FALSE', - Hash.to_s => "dict #{new_resource.value}", - String.to_s => "string #{new_resource.value}", - Float.to_s => "float #{new_resource.value}" } - data_type_cases[entry] - end + # def convert_to_data_type(entry) + # data_type_cases = { Array.to_s => "array #{new_resource.value}", + # Integer.to_s => "int #{new_resource.value}", + # TrueClass.to_s => 'bool TRUE', + # FalseClass.to_s => 'bool FALSE', + # Hash.to_s => "dict #{new_resource.value}", + # String.to_s => "string #{new_resource.value}", + # Float.to_s => "float #{new_resource.value}" } + # data_type_cases[entry] + # end end diff --git a/spec/unit/libraries/plistbuddy_spec.rb b/spec/unit/libraries/plistbuddy_spec.rb index b948fa96..4f950ecd 100644 --- a/spec/unit/libraries/plistbuddy_spec.rb +++ b/spec/unit/libraries/plistbuddy_spec.rb @@ -5,7 +5,7 @@ describe MacOS::PlistBuddyHelpers, '#format_plistbuddy_command' do context 'When given some commands' do it 'the command is formatted properly' do - expect(format_plistbuddy_command(:add, 'DidSeeSiriSetup', 0)).to eq "/usr/libexec/Plistbuddy -c ':Add DidSiriSetup 0'" + expect(format_plistbuddy_command(:add, 'DidSeeSiriSetup', 0)).to eq "/usr/libexec/Plistbuddy -c ':Add DidSeeSiriSetup 0'" end end end diff --git a/spec/unit/recipes/configurator.rb b/spec/unit/recipes/configurator.rb index 96969ac4..21c21940 100644 --- a/spec/unit/recipes/configurator.rb +++ b/spec/unit/recipes/configurator.rb @@ -13,7 +13,7 @@ runner.converge(described_recipe) end - it 'converges successfully' do + xit 'converges successfully' do expect { chef_run }.to_not raise_error end end diff --git a/spec/unit/recipes/default_spec.rb b/spec/unit/recipes/default_spec.rb index df3ad1c3..e677b686 100644 --- a/spec/unit/recipes/default_spec.rb +++ b/spec/unit/recipes/default_spec.rb @@ -7,7 +7,7 @@ runner.converge(described_recipe) end - it 'converges successfully' do + xit 'converges successfully' do expect { chef_run }.to_not raise_error end end diff --git a/spec/unit/recipes/keep_awake_spec.rb b/spec/unit/recipes/keep_awake_spec.rb index 4e731e2e..5f44447e 100644 --- a/spec/unit/recipes/keep_awake_spec.rb +++ b/spec/unit/recipes/keep_awake_spec.rb @@ -7,7 +7,7 @@ runner.converge(described_recipe) end - it 'converges successfully' do + xit 'converges successfully' do expect { chef_run }.to_not raise_error end end diff --git a/spec/unit/recipes/xcode_spec.rb b/spec/unit/recipes/xcode_spec.rb index 7f53222f..b8d8a17c 100644 --- a/spec/unit/recipes/xcode_spec.rb +++ b/spec/unit/recipes/xcode_spec.rb @@ -13,7 +13,7 @@ runner.converge(described_recipe) end - it 'converges successfully' do + xit 'converges successfully' do expect { chef_run }.to_not raise_error end end From b44a02320b44d2f1ed5a5ed1c231f807d7477c59 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 12:24:18 -0700 Subject: [PATCH 06/83] add more data type tests --- libraries/plistbuddy.rb | 9 +++++---- spec/unit/libraries/plistbuddy_spec.rb | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/libraries/plistbuddy.rb b/libraries/plistbuddy.rb index 6f514eb2..4642f43e 100644 --- a/libraries/plistbuddy.rb +++ b/libraries/plistbuddy.rb @@ -2,10 +2,11 @@ module MacOS module PlistBuddyHelpers - # def self.exist? - # command = format_plistbuddy_command('print', entry, value) - # shell_out(command).error? - # end + def self.exist? + command = format_plistbuddy_command('print', entry, value) + shell_out(command).error? + end + def convert_to_string_from_data_type(plist_entry) data_type_cases = { Array.to_s => "array #{plist_entry}", Integer.to_s => "int #{plist_entry}", diff --git a/spec/unit/libraries/plistbuddy_spec.rb b/spec/unit/libraries/plistbuddy_spec.rb index 4f950ecd..0c48d02a 100644 --- a/spec/unit/libraries/plistbuddy_spec.rb +++ b/spec/unit/libraries/plistbuddy_spec.rb @@ -9,3 +9,27 @@ end end end + +describe MacOS::PlistBuddyHelpers, '#convert_to_string_from_data_type' do + context 'When given a certain data type' do + it 'returns the required PlistBuddy boolean entry' do + expect(convert_to_string_from_data_type(true)).to eq 'bool TRUE' + end + + it 'returns the required PlistBuddy boolean entry' do + expect(convert_to_string_from_data_type(%w(foo bar))).to eq "array ['foo', 'bar']" + end + + it 'returns the required PlistBuddy boolean entry' do + expect(convert_to_string_from_data_type({'baz' => 'qux'})).to eq "dict {'baz' => 'qux'}" + end + + it 'returns the required PlistBuddy boolean entry' do + expect(convert_to_string_from_data_type('quux')).to eq 'string quux' + end + + it 'returns the required PlistBuddy boolean entry' do + expect(convert_to_string_from_data_type(1)).to eq 'int 1' + end + end +end \ No newline at end of file From 21dddd9c1b4290cad9b0c7875f11ff5f2e0e686c Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 13:09:08 -0700 Subject: [PATCH 07/83] Most data types passing - Boolean values are working - Array and data type values are not - PlistBuddy "commands" (add, print, etc.) are passing --- libraries/plistbuddy.rb | 18 +++++++++--------- spec/unit/libraries/plistbuddy_spec.rb | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libraries/plistbuddy.rb b/libraries/plistbuddy.rb index 4642f43e..4c3cc431 100644 --- a/libraries/plistbuddy.rb +++ b/libraries/plistbuddy.rb @@ -8,19 +8,19 @@ def self.exist? end def convert_to_string_from_data_type(plist_entry) - data_type_cases = { Array.to_s => "array #{plist_entry}", - Integer.to_s => "int #{plist_entry}", - TrueClass.to_s => 'bool TRUE', - FalseClass.to_s => 'bool FALSE', - Hash.to_s => "dict #{plist_entry}", - String.to_s => "string #{plist_entry}", - Float.to_s => "float #{plist_entry}" } + data_type_cases = { Array => "array #{plist_entry}", + Integer => "int #{plist_entry}", + TrueClass => 'bool TRUE', + FalseClass => 'bool FALSE', + Hash => "dict #{plist_entry}", + String => "string #{plist_entry}", + Float => "float #{plist_entry}" } data_type_cases[plist_entry.class] end def format_plistbuddy_command(action_property, plist_entry, plist_value = nil) - entry_wdt = convert_to_string_from_data_type plist_entry - "/usr/libexec/Plistbuddy -c \':#{action_property.to_s.capitalize} #{plist_entry} #{plist_value}#{entry_wdt}\'" + value_with_data_type = convert_to_string_from_data_type plist_value + "/usr/libexec/Plistbuddy -c \'#{action_property.to_s.capitalize} :#{plist_entry} #{value_with_data_type}\'" end end end diff --git a/spec/unit/libraries/plistbuddy_spec.rb b/spec/unit/libraries/plistbuddy_spec.rb index 0c48d02a..df66bab6 100644 --- a/spec/unit/libraries/plistbuddy_spec.rb +++ b/spec/unit/libraries/plistbuddy_spec.rb @@ -5,7 +5,7 @@ describe MacOS::PlistBuddyHelpers, '#format_plistbuddy_command' do context 'When given some commands' do it 'the command is formatted properly' do - expect(format_plistbuddy_command(:add, 'DidSeeSiriSetup', 0)).to eq "/usr/libexec/Plistbuddy -c ':Add DidSeeSiriSetup 0'" + expect(format_plistbuddy_command(:add, 'DidSeeSiriSetup', true)).to eq "/usr/libexec/Plistbuddy -c 'Add :DidSeeSiriSetup bool TRUE'" end end end @@ -21,7 +21,7 @@ end it 'returns the required PlistBuddy boolean entry' do - expect(convert_to_string_from_data_type({'baz' => 'qux'})).to eq "dict {'baz' => 'qux'}" + expect(convert_to_string_from_data_type('baz' => 'qux')).to eq "dict {'baz' => 'qux'}" end it 'returns the required PlistBuddy boolean entry' do @@ -32,4 +32,4 @@ expect(convert_to_string_from_data_type(1)).to eq 'int 1' end end -end \ No newline at end of file +end From 70f9d09e2ec4a8a3ef346daf0a9df9e1c51201bb Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 13:39:55 -0700 Subject: [PATCH 08/83] More testing - Skip Array and Dict types as their implementation will be more complicated - Add test for float type - Put the correct type in the test description - Cookstyle changes --- spec/unit/libraries/plistbuddy_spec.rb | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/spec/unit/libraries/plistbuddy_spec.rb b/spec/unit/libraries/plistbuddy_spec.rb index df66bab6..03c18cb3 100644 --- a/spec/unit/libraries/plistbuddy_spec.rb +++ b/spec/unit/libraries/plistbuddy_spec.rb @@ -16,20 +16,24 @@ expect(convert_to_string_from_data_type(true)).to eq 'bool TRUE' end - it 'returns the required PlistBuddy boolean entry' do - expect(convert_to_string_from_data_type(%w(foo bar))).to eq "array ['foo', 'bar']" + xit 'returns the required PlistBuddy array entry' do # TODO: Implement proper plist array syntax + expect(convert_to_string_from_data_type(%w(foo bar))).to eq 'array foo bar' end - it 'returns the required PlistBuddy boolean entry' do - expect(convert_to_string_from_data_type('baz' => 'qux')).to eq "dict {'baz' => 'qux'}" + xit 'returns the required PlistBuddy dictionary entry' do # TODO: Implement proper plist array syntax + expect(convert_to_string_from_data_type('baz' => 'qux')).to eq 'dict key value' end - it 'returns the required PlistBuddy boolean entry' do + it 'returns the required PlistBuddy string entry' do expect(convert_to_string_from_data_type('quux')).to eq 'string quux' end - it 'returns the required PlistBuddy boolean entry' do + it 'returns the required PlistBuddy int entry' do expect(convert_to_string_from_data_type(1)).to eq 'int 1' end + + it 'returns the required PlistBuddy float entry' do + expect(convert_to_string_from_data_type(1.0)).to eq 'float 1.0' + end end end From 4a942c3dc48dafb2af19ef2dae19044dd19881d6 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 15:38:14 -0700 Subject: [PATCH 09/83] PlistBuddy and testing update - Add separate test cookbook for PlistBuddy resource - Add kitchen.yml for the above purpose - Modify and update plistbuddy resource/helpers --- .kitchen.yml | 32 +++++++++++++++++++ libraries/plistbuddy.rb | 5 --- resources/plistbuddy.rb | 28 +++++++--------- spec/unit/libraries/plistbuddy_spec.rb | 20 +++++++++--- spec/unit/recipes/plistbuddy_spec.rb | 14 ++++++++ .../plistbuddy/recipes/customize_dock.rb | 5 +++ test/cookbooks/plistbuddy/recipes/default.rb | 2 ++ .../plistbuddy/recipes/show_hidden_files.rb | 5 +++ .../test/smoke/default/default_test.rb | 8 +++++ 9 files changed, 93 insertions(+), 26 deletions(-) create mode 100644 .kitchen.yml create mode 100644 spec/unit/recipes/plistbuddy_spec.rb create mode 100644 test/cookbooks/plistbuddy/recipes/customize_dock.rb create mode 100644 test/cookbooks/plistbuddy/recipes/default.rb create mode 100644 test/cookbooks/plistbuddy/recipes/show_hidden_files.rb create mode 100644 test/cookbooks/plistbuddy/test/smoke/default/default_test.rb diff --git a/.kitchen.yml b/.kitchen.yml new file mode 100644 index 00000000..a7be1b91 --- /dev/null +++ b/.kitchen.yml @@ -0,0 +1,32 @@ +--- +driver: + name: vagrant + provider: parallels + customize: + memory: 8192 + cpus: 2 + +provisioner: + name: chef_zero + +verifier: + name: inspec + +transport: + name: ssh + elevated: true + +platforms: + - name: apex/macos-10.12.6 + driver: + box: apex/macos-10.12.6 + box_url: http://imagr.corp.microsoft.com:8099/apex/macos-10.12.6 + box_check_update: true + +suites: + - name: plistbuddy + run_list: + - recipe[plistbuddy::default] + verifier: + inspec_tests: + - test/smoke/default diff --git a/libraries/plistbuddy.rb b/libraries/plistbuddy.rb index 4c3cc431..041e03d9 100644 --- a/libraries/plistbuddy.rb +++ b/libraries/plistbuddy.rb @@ -2,11 +2,6 @@ module MacOS module PlistBuddyHelpers - def self.exist? - command = format_plistbuddy_command('print', entry, value) - shell_out(command).error? - end - def convert_to_string_from_data_type(plist_entry) data_type_cases = { Array => "array #{plist_entry}", Integer => "int #{plist_entry}", diff --git a/resources/plistbuddy.rb b/resources/plistbuddy.rb index 12b55688..405611a7 100644 --- a/resources/plistbuddy.rb +++ b/resources/plistbuddy.rb @@ -3,25 +3,19 @@ property :action, Symbol, name_property: true property :name, String -property :entry, String +property :entry, String, required: true property :value, [Hash, String, Array, TrueClass, FalseClass, Int, Float] action_class do - # def plistbuddy_command(command_action, entry, value) - # entry = convert_to_data_type new_resource.entry - # "/usr/libexec/Plistbuddy -c ':#{command_action.capitalize} #{entry} #{value}" - # end - - # private + def entry_exists? + command = format_plistbuddy_command(:print, new_resource.entry, new_resource.value) + shell_out(command).error? + end +end - # def convert_to_data_type(entry) - # data_type_cases = { Array.to_s => "array #{new_resource.value}", - # Integer.to_s => "int #{new_resource.value}", - # TrueClass.to_s => 'bool TRUE', - # FalseClass.to_s => 'bool FALSE', - # Hash.to_s => "dict #{new_resource.value}", - # String.to_s => "string #{new_resource.value}", - # Float.to_s => "float #{new_resource.value}" } - # data_type_cases[entry] - # end +action :execute do + if new_resource.action == :set && !entry_exist? + format_plistbuddy_command(:add, new_resource.entry) + end + format_plistbuddy_command(new_resource.action, new_resource.entry, new_resource.value) end diff --git a/spec/unit/libraries/plistbuddy_spec.rb b/spec/unit/libraries/plistbuddy_spec.rb index 03c18cb3..75d7434a 100644 --- a/spec/unit/libraries/plistbuddy_spec.rb +++ b/spec/unit/libraries/plistbuddy_spec.rb @@ -4,8 +4,20 @@ describe MacOS::PlistBuddyHelpers, '#format_plistbuddy_command' do context 'When given some commands' do - it 'the command is formatted properly' do - expect(format_plistbuddy_command(:add, 'DidSeeSiriSetup', true)).to eq "/usr/libexec/Plistbuddy -c 'Add :DidSeeSiriSetup bool TRUE'" + it 'the add command is formatted properly' do + expect(format_plistbuddy_command(:add, 'FooEntry', true)).to eq "/usr/libexec/Plistbuddy -c 'Add :FooEntry bool TRUE'" + end + + it 'the delete command is formatted properly' do + expect(format_plistbuddy_command(:delete, 'BarEntry')).to eq "/usr/libexec/Plistbuddy -c 'Delete :BarEntry '" + end + + it 'the set command is formatted properly' do + expect(format_plistbuddy_command(:set, 'BazEntry', false)).to eq "/usr/libexec/Plistbuddy -c 'Set :BazEntry bool FALSE'" + end + + it 'the print command is formatted properly' do + expect(format_plistbuddy_command(:print, 'QuxEntry')).to eq "/usr/libexec/Plistbuddy -c 'Print :QuxEntry'" end end end @@ -16,11 +28,11 @@ expect(convert_to_string_from_data_type(true)).to eq 'bool TRUE' end - xit 'returns the required PlistBuddy array entry' do # TODO: Implement proper plist array syntax + xit 'returns the required PlistBuddy array entry' do # TODO: Implement proper plist array syntax (i.e. containers) expect(convert_to_string_from_data_type(%w(foo bar))).to eq 'array foo bar' end - xit 'returns the required PlistBuddy dictionary entry' do # TODO: Implement proper plist array syntax + xit 'returns the required PlistBuddy dictionary entry' do # TODO: Implement proper plist dict syntax (i.e. containers) expect(convert_to_string_from_data_type('baz' => 'qux')).to eq 'dict key value' end diff --git a/spec/unit/recipes/plistbuddy_spec.rb b/spec/unit/recipes/plistbuddy_spec.rb new file mode 100644 index 00000000..e677b686 --- /dev/null +++ b/spec/unit/recipes/plistbuddy_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe 'macos::default' do + context 'When all attributes are default, on macOS 10.12' do + let(:chef_run) do + runner = ChefSpec::ServerRunner.new(platform: 'mac_os_x', version: '10.12') + runner.converge(described_recipe) + end + + xit 'converges successfully' do + expect { chef_run }.to_not raise_error + end + end +end diff --git a/test/cookbooks/plistbuddy/recipes/customize_dock.rb b/test/cookbooks/plistbuddy/recipes/customize_dock.rb new file mode 100644 index 00000000..b81f8452 --- /dev/null +++ b/test/cookbooks/plistbuddy/recipes/customize_dock.rb @@ -0,0 +1,5 @@ +plistbuddy :set do + plist_path '/Users/vagrant/Library/Preferences/com.apple.dock.plist' + entry 'showMissionControlGestureEnabled' + value false +end diff --git a/test/cookbooks/plistbuddy/recipes/default.rb b/test/cookbooks/plistbuddy/recipes/default.rb new file mode 100644 index 00000000..0d12f25f --- /dev/null +++ b/test/cookbooks/plistbuddy/recipes/default.rb @@ -0,0 +1,2 @@ +include_recipe 'plistbuddy::customize_dock' +include_recipe 'plistbuddy::show_hidden_files' diff --git a/test/cookbooks/plistbuddy/recipes/show_hidden_files.rb b/test/cookbooks/plistbuddy/recipes/show_hidden_files.rb new file mode 100644 index 00000000..4926da21 --- /dev/null +++ b/test/cookbooks/plistbuddy/recipes/show_hidden_files.rb @@ -0,0 +1,5 @@ +plistbuddy :set do + path '~/Library/Preferences/com.apple.finder.plist' + entry 'AppleShowAllFiles' + value true +end diff --git a/test/cookbooks/plistbuddy/test/smoke/default/default_test.rb b/test/cookbooks/plistbuddy/test/smoke/default/default_test.rb new file mode 100644 index 00000000..13647208 --- /dev/null +++ b/test/cookbooks/plistbuddy/test/smoke/default/default_test.rb @@ -0,0 +1,8 @@ +describe command("/usr/libexec/PlistBuddy -c 'Print :showMissionControlGestureEnabled' /Users/vagrant/Library/Preferences/com.apple.dock.plist") do + its('stdout') { should be 'true' } +end + +describe command("/usr/libexec/PlistBuddy -c 'Print :AppleShowAllFiles' /Users/vagrant/Library/Preferences/com.apple.finder.plist") do + its('stdout') { should be 'true' } +end + From f481503589166af2384f43de95200599b4f38ed9 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 15:39:33 -0700 Subject: [PATCH 10/83] remove extra newline --- test/cookbooks/plistbuddy/test/smoke/default/default_test.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/test/cookbooks/plistbuddy/test/smoke/default/default_test.rb b/test/cookbooks/plistbuddy/test/smoke/default/default_test.rb index 13647208..98a29aa9 100644 --- a/test/cookbooks/plistbuddy/test/smoke/default/default_test.rb +++ b/test/cookbooks/plistbuddy/test/smoke/default/default_test.rb @@ -5,4 +5,3 @@ describe command("/usr/libexec/PlistBuddy -c 'Print :AppleShowAllFiles' /Users/vagrant/Library/Preferences/com.apple.finder.plist") do its('stdout') { should be 'true' } end - From 9d43d463f3cd272578a0271dfb4fea049d7f9461 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 15:56:55 -0700 Subject: [PATCH 11/83] add metadata file --- test/cookbooks/plistbuddy/metadata.rb | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 test/cookbooks/plistbuddy/metadata.rb diff --git a/test/cookbooks/plistbuddy/metadata.rb b/test/cookbooks/plistbuddy/metadata.rb new file mode 100644 index 00000000..b25a1b96 --- /dev/null +++ b/test/cookbooks/plistbuddy/metadata.rb @@ -0,0 +1,4 @@ +name 'osx-basic' +version '1.0.0' + +depends 'macos' From 9311a37bccf59473fbc665f3b3e3116827c168ef Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 16:04:02 -0700 Subject: [PATCH 12/83] edit metadata; add Berksfile --- test/cookbooks/Berksfile | 1 + test/cookbooks/plistbuddy/metadata.rb | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 test/cookbooks/Berksfile diff --git a/test/cookbooks/Berksfile b/test/cookbooks/Berksfile new file mode 100644 index 00000000..cde259ef --- /dev/null +++ b/test/cookbooks/Berksfile @@ -0,0 +1 @@ +cookbook 'macos', path: '../../../../macos/' \ No newline at end of file diff --git a/test/cookbooks/plistbuddy/metadata.rb b/test/cookbooks/plistbuddy/metadata.rb index b25a1b96..21d229d5 100644 --- a/test/cookbooks/plistbuddy/metadata.rb +++ b/test/cookbooks/plistbuddy/metadata.rb @@ -1,4 +1,4 @@ -name 'osx-basic' +name 'plistbuddy' version '1.0.0' -depends 'macos' +depends 'macos', '0.8.4' From f16ecae33604ff43d86412d761995b72db7965df Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 16:05:16 -0700 Subject: [PATCH 13/83] move Berksfile to correct location --- test/cookbooks/{ => plistbuddy}/Berksfile | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/cookbooks/{ => plistbuddy}/Berksfile (100%) diff --git a/test/cookbooks/Berksfile b/test/cookbooks/plistbuddy/Berksfile similarity index 100% rename from test/cookbooks/Berksfile rename to test/cookbooks/plistbuddy/Berksfile From 19645bc6d046344e916ea8eb96e7e7d2a4aa0897 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 16:11:07 -0700 Subject: [PATCH 14/83] add testing requirements for berks vendor --- metadata.rb | 2 +- test/cookbooks/plistbuddy/Berksfile | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/metadata.rb b/metadata.rb index a9ad5907..1990d7f4 100644 --- a/metadata.rb +++ b/metadata.rb @@ -5,7 +5,7 @@ description 'Resources for configuring and provisioning macOS' long_description 'Resources for configuring and provisioning macOS' chef_version '~> 13.0' if respond_to?(:chef_version) -version '0.8.2' +version '0.8.4' source_url 'https://github.com/Microsoft/macos-cookbook' issues_url 'https://github.com/Microsoft/macos-cookbook/issues' diff --git a/test/cookbooks/plistbuddy/Berksfile b/test/cookbooks/plistbuddy/Berksfile index cde259ef..0fac3b01 100644 --- a/test/cookbooks/plistbuddy/Berksfile +++ b/test/cookbooks/plistbuddy/Berksfile @@ -1 +1,5 @@ -cookbook 'macos', path: '../../../../macos/' \ No newline at end of file +source 'https://supermarket.chef.io' + +metadata + +cookbook 'macos', path: '../../../../macos/' From ec4b4897000502ef963995dfdfada1ce0eb569d8 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 16:13:11 -0700 Subject: [PATCH 15/83] move kitchen file --- .kitchen.yml => test/cookbooks/plistbuddy/.kitchen.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .kitchen.yml => test/cookbooks/plistbuddy/.kitchen.yml (100%) diff --git a/.kitchen.yml b/test/cookbooks/plistbuddy/.kitchen.yml similarity index 100% rename from .kitchen.yml rename to test/cookbooks/plistbuddy/.kitchen.yml From 532899501cbff02260dc4c01f9f5244d6eaecc45 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 16:26:35 -0700 Subject: [PATCH 16/83] Converge passing in test cookbook - Opportunistic cleanup of xcode test - some temp debugging info in resource definition - Rename name_property to command so as to not override action --- resources/plistbuddy.rb | 14 +++++++------- .../cookbooks/plistbuddy/recipes/customize_dock.rb | 2 +- test/smoke/default/xcode_test.rb | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/resources/plistbuddy.rb b/resources/plistbuddy.rb index 405611a7..da7a2cde 100644 --- a/resources/plistbuddy.rb +++ b/resources/plistbuddy.rb @@ -1,21 +1,21 @@ resource_name :plistbuddy -property :action, Symbol, name_property: true +property :command, String, name_property: true -property :name, String +property :path, String property :entry, String, required: true -property :value, [Hash, String, Array, TrueClass, FalseClass, Int, Float] +property :value, [Hash, String, Array, TrueClass, FalseClass, Integer, Float] action_class do - def entry_exists? + def entry_exist? command = format_plistbuddy_command(:print, new_resource.entry, new_resource.value) shell_out(command).error? end end action :execute do - if new_resource.action == :set && !entry_exist? - format_plistbuddy_command(:add, new_resource.entry) + if new_resource.command.to_s == 'set' && !entry_exist? + p format_plistbuddy_command(:add, new_resource.entry) end - format_plistbuddy_command(new_resource.action, new_resource.entry, new_resource.value) + p format_plistbuddy_command(new_resource.command, new_resource.entry, new_resource.value) end diff --git a/test/cookbooks/plistbuddy/recipes/customize_dock.rb b/test/cookbooks/plistbuddy/recipes/customize_dock.rb index b81f8452..8b224241 100644 --- a/test/cookbooks/plistbuddy/recipes/customize_dock.rb +++ b/test/cookbooks/plistbuddy/recipes/customize_dock.rb @@ -1,5 +1,5 @@ plistbuddy :set do - plist_path '/Users/vagrant/Library/Preferences/com.apple.dock.plist' + path '/Users/vagrant/Library/Preferences/com.apple.dock.plist' entry 'showMissionControlGestureEnabled' value false end diff --git a/test/smoke/default/xcode_test.rb b/test/smoke/default/xcode_test.rb index b34ada6a..e3b7cd61 100644 --- a/test/smoke/default/xcode_test.rb +++ b/test/smoke/default/xcode_test.rb @@ -11,6 +11,6 @@ end describe command('/usr/local/bin/xcversion simulators') do - its('stdout') { should match /iOS 10\.3\.1 Simulator \(installed\)/ } + its('stdout') { should match(/iOS 10\.3\.1 Simulator \(installed\)/) } end end From 55bed5dcc06993c74269b0c537e6c83595f0fcb5 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 18:45:51 -0700 Subject: [PATCH 17/83] Itempotence - Removed 'bool' prefix from boolean types, as that was somehow causing issues - Changed name_property to the path and removed that property - Use actual actions in the resource for the PlistBuddy commands --- libraries/plistbuddy.rb | 6 ++-- resources/plistbuddy.rb | 36 ++++++++++++++----- spec/unit/libraries/plistbuddy_spec.rb | 8 ++--- .../plistbuddy/recipes/customize_dock.rb | 3 +- .../plistbuddy/recipes/show_hidden_files.rb | 3 +- 5 files changed, 36 insertions(+), 20 deletions(-) diff --git a/libraries/plistbuddy.rb b/libraries/plistbuddy.rb index 041e03d9..cd1a7b1d 100644 --- a/libraries/plistbuddy.rb +++ b/libraries/plistbuddy.rb @@ -5,8 +5,8 @@ module PlistBuddyHelpers def convert_to_string_from_data_type(plist_entry) data_type_cases = { Array => "array #{plist_entry}", Integer => "int #{plist_entry}", - TrueClass => 'bool TRUE', - FalseClass => 'bool FALSE', + TrueClass => 'true', + FalseClass => 'false', Hash => "dict #{plist_entry}", String => "string #{plist_entry}", Float => "float #{plist_entry}" } @@ -15,7 +15,7 @@ def convert_to_string_from_data_type(plist_entry) def format_plistbuddy_command(action_property, plist_entry, plist_value = nil) value_with_data_type = convert_to_string_from_data_type plist_value - "/usr/libexec/Plistbuddy -c \'#{action_property.to_s.capitalize} :#{plist_entry} #{value_with_data_type}\'" + "/usr/libexec/Plistbuddy -c \'#{action_property.to_s.capitalize} :#{plist_entry} #{value_with_data_type}\'" # Add a space here for the plist path end end end diff --git a/resources/plistbuddy.rb b/resources/plistbuddy.rb index da7a2cde..b754e088 100644 --- a/resources/plistbuddy.rb +++ b/resources/plistbuddy.rb @@ -1,21 +1,39 @@ resource_name :plistbuddy -property :command, String, name_property: true - -property :path, String +property :path, String, name_property: true property :entry, String, required: true property :value, [Hash, String, Array, TrueClass, FalseClass, Integer, Float] +default_action :set + action_class do - def entry_exist? + def entry_missing? command = format_plistbuddy_command(:print, new_resource.entry, new_resource.value) - shell_out(command).error? + full_command = command + ' ' + new_resource.path + shell_out(full_command).error? + end + + def current_entry_value + command = format_plistbuddy_command(:print, new_resource.entry) + full_command = command + ' ' + new_resource.path + shell_out(full_command).stdout.chomp end end -action :execute do - if new_resource.command.to_s == 'set' && !entry_exist? - p format_plistbuddy_command(:add, new_resource.entry) +action :set do + puts "\n\n" + p "current_entry_value: #{current_entry_value}" + p "value: #{new_resource.value}" + puts "\n\n" + + if entry_missing? + execute format_plistbuddy_command(:add, new_resource.entry, new_resource.value) + ' ' + new_resource.path + execute format_plistbuddy_command(:set, new_resource.entry, new_resource.value) + ' ' + new_resource.path + elsif current_entry_value != new_resource.value.to_s + execute format_plistbuddy_command(:set, new_resource.entry, new_resource.value) + ' ' + new_resource.path end - p format_plistbuddy_command(new_resource.command, new_resource.entry, new_resource.value) +end + +action :delete do + execute format_plistbuddy_command(:delete, new_resource.entry, new_resource.value) + ' ' + new_resource.path end diff --git a/spec/unit/libraries/plistbuddy_spec.rb b/spec/unit/libraries/plistbuddy_spec.rb index 75d7434a..6fc6de47 100644 --- a/spec/unit/libraries/plistbuddy_spec.rb +++ b/spec/unit/libraries/plistbuddy_spec.rb @@ -5,7 +5,7 @@ describe MacOS::PlistBuddyHelpers, '#format_plistbuddy_command' do context 'When given some commands' do it 'the add command is formatted properly' do - expect(format_plistbuddy_command(:add, 'FooEntry', true)).to eq "/usr/libexec/Plistbuddy -c 'Add :FooEntry bool TRUE'" + expect(format_plistbuddy_command(:add, 'FooEntry', true)).to eq "/usr/libexec/Plistbuddy -c 'Add :FooEntry true'" end it 'the delete command is formatted properly' do @@ -13,11 +13,11 @@ end it 'the set command is formatted properly' do - expect(format_plistbuddy_command(:set, 'BazEntry', false)).to eq "/usr/libexec/Plistbuddy -c 'Set :BazEntry bool FALSE'" + expect(format_plistbuddy_command(:set, 'BazEntry', false)).to eq "/usr/libexec/Plistbuddy -c 'Set :BazEntry true'" end it 'the print command is formatted properly' do - expect(format_plistbuddy_command(:print, 'QuxEntry')).to eq "/usr/libexec/Plistbuddy -c 'Print :QuxEntry'" + expect(format_plistbuddy_command(:print, 'QuxEntry')).to eq "/usr/libexec/Plistbuddy -c 'Print :QuxEntry '" end end end @@ -25,7 +25,7 @@ describe MacOS::PlistBuddyHelpers, '#convert_to_string_from_data_type' do context 'When given a certain data type' do it 'returns the required PlistBuddy boolean entry' do - expect(convert_to_string_from_data_type(true)).to eq 'bool TRUE' + expect(convert_to_string_from_data_type(true)).to eq 'true' end xit 'returns the required PlistBuddy array entry' do # TODO: Implement proper plist array syntax (i.e. containers) diff --git a/test/cookbooks/plistbuddy/recipes/customize_dock.rb b/test/cookbooks/plistbuddy/recipes/customize_dock.rb index 8b224241..73f05800 100644 --- a/test/cookbooks/plistbuddy/recipes/customize_dock.rb +++ b/test/cookbooks/plistbuddy/recipes/customize_dock.rb @@ -1,5 +1,4 @@ -plistbuddy :set do - path '/Users/vagrant/Library/Preferences/com.apple.dock.plist' +plistbuddy '/Users/vagrant/Library/Preferences/com.apple.dock.plist' do entry 'showMissionControlGestureEnabled' value false end diff --git a/test/cookbooks/plistbuddy/recipes/show_hidden_files.rb b/test/cookbooks/plistbuddy/recipes/show_hidden_files.rb index 4926da21..5dcd3662 100644 --- a/test/cookbooks/plistbuddy/recipes/show_hidden_files.rb +++ b/test/cookbooks/plistbuddy/recipes/show_hidden_files.rb @@ -1,5 +1,4 @@ -plistbuddy :set do - path '~/Library/Preferences/com.apple.finder.plist' +plistbuddy '/Users/vagrant/Library/Preferences/com.apple.finder.plist' do entry 'AppleShowAllFiles' value true end From a493029a1c84826834b604ff35ca2feedb849788 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 18:47:49 -0700 Subject: [PATCH 18/83] Fix false positive? - Not sure how the previous test was passing previously, but I adjusted the boolean value for the BazEntry test so that the signature input matches the output --- spec/unit/libraries/plistbuddy_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/unit/libraries/plistbuddy_spec.rb b/spec/unit/libraries/plistbuddy_spec.rb index 6fc6de47..30bc59cf 100644 --- a/spec/unit/libraries/plistbuddy_spec.rb +++ b/spec/unit/libraries/plistbuddy_spec.rb @@ -13,7 +13,7 @@ end it 'the set command is formatted properly' do - expect(format_plistbuddy_command(:set, 'BazEntry', false)).to eq "/usr/libexec/Plistbuddy -c 'Set :BazEntry true'" + expect(format_plistbuddy_command(:set, 'BazEntry', false)).to eq "/usr/libexec/Plistbuddy -c 'Set :BazEntry false'" end it 'the print command is formatted properly' do From 92a5e41c92d3449b6c9d20c11d86fad7b5e91203 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 19:36:59 -0700 Subject: [PATCH 19/83] Add logic for adding a value - The data type should only be used when adding a value to a plist. Otherwise, we don't need to use the data type --- libraries/plistbuddy.rb | 30 ++++++++++++++++---------- spec/unit/libraries/plistbuddy_spec.rb | 12 +++++++---- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/libraries/plistbuddy.rb b/libraries/plistbuddy.rb index cd1a7b1d..88f40ff6 100644 --- a/libraries/plistbuddy.rb +++ b/libraries/plistbuddy.rb @@ -2,20 +2,28 @@ module MacOS module PlistBuddyHelpers - def convert_to_string_from_data_type(plist_entry) - data_type_cases = { Array => "array #{plist_entry}", - Integer => "int #{plist_entry}", - TrueClass => 'true', - FalseClass => 'false', - Hash => "dict #{plist_entry}", - String => "string #{plist_entry}", - Float => "float #{plist_entry}" } - data_type_cases[plist_entry.class] + def convert_to_string_from_data_type(value) + data_type_cases = { Array => "array #{value}", + Integer => "int #{value}", + TrueClass => "bool #{value}", + FalseClass => "bool #{value}", + Hash => "dict #{value}", + String => "string #{value}", + Float => "float #{value}" } + data_type_cases[value.class] end def format_plistbuddy_command(action_property, plist_entry, plist_value = nil) - value_with_data_type = convert_to_string_from_data_type plist_value - "/usr/libexec/Plistbuddy -c \'#{action_property.to_s.capitalize} :#{plist_entry} #{value_with_data_type}\'" # Add a space here for the plist path + plist_value = args_formatter(action_property, plist_value) + "/usr/libexec/Plistbuddy -c \'#{action_property.to_s.capitalize} :#{plist_entry} #{plist_value}\'" # Add a space here for the plist path + end + + def args_formatter(action_property, plist_value) + if action_property == :add + convert_to_string_from_data_type plist_value + else + plist_value + end end end end diff --git a/spec/unit/libraries/plistbuddy_spec.rb b/spec/unit/libraries/plistbuddy_spec.rb index 30bc59cf..ac11c30c 100644 --- a/spec/unit/libraries/plistbuddy_spec.rb +++ b/spec/unit/libraries/plistbuddy_spec.rb @@ -3,9 +3,13 @@ include MacOS::PlistBuddyHelpers describe MacOS::PlistBuddyHelpers, '#format_plistbuddy_command' do - context 'When given some commands' do - it 'the add command is formatted properly' do - expect(format_plistbuddy_command(:add, 'FooEntry', true)).to eq "/usr/libexec/Plistbuddy -c 'Add :FooEntry true'" + context 'Adding a value to a plist' do + it 'the bool arguments contain the data type' do + expect(format_plistbuddy_command(:add, 'FooEntry', true)).to eq "/usr/libexec/Plistbuddy -c 'Add :FooEntry bool true'" + end + + it 'the int arguments contain the data type' do + expect(format_plistbuddy_command(:add, 'QuuxEntry', 50)).to eq "/usr/libexec/Plistbuddy -c 'Add :QuuxEntry int 50'" end it 'the delete command is formatted properly' do @@ -25,7 +29,7 @@ describe MacOS::PlistBuddyHelpers, '#convert_to_string_from_data_type' do context 'When given a certain data type' do it 'returns the required PlistBuddy boolean entry' do - expect(convert_to_string_from_data_type(true)).to eq 'true' + expect(convert_to_string_from_data_type(true)).to eq 'bool true' end xit 'returns the required PlistBuddy array entry' do # TODO: Implement proper plist array syntax (i.e. containers) From a734d4af369b3c25770358fa0725d1319da4e5bb Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 26 Oct 2017 20:01:44 -0700 Subject: [PATCH 20/83] remove debugging; fix smoke tests --- libraries/plistbuddy.rb | 2 +- resources/plistbuddy.rb | 5 ----- test/cookbooks/plistbuddy/test/smoke/default/default_test.rb | 4 ++-- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/libraries/plistbuddy.rb b/libraries/plistbuddy.rb index 88f40ff6..e871c423 100644 --- a/libraries/plistbuddy.rb +++ b/libraries/plistbuddy.rb @@ -15,7 +15,7 @@ def convert_to_string_from_data_type(value) def format_plistbuddy_command(action_property, plist_entry, plist_value = nil) plist_value = args_formatter(action_property, plist_value) - "/usr/libexec/Plistbuddy -c \'#{action_property.to_s.capitalize} :#{plist_entry} #{plist_value}\'" # Add a space here for the plist path + "/usr/libexec/Plistbuddy -c \'#{action_property.to_s.capitalize} :#{plist_entry} #{plist_value}\'" end def args_formatter(action_property, plist_value) diff --git a/resources/plistbuddy.rb b/resources/plistbuddy.rb index b754e088..fa052905 100644 --- a/resources/plistbuddy.rb +++ b/resources/plistbuddy.rb @@ -21,11 +21,6 @@ def current_entry_value end action :set do - puts "\n\n" - p "current_entry_value: #{current_entry_value}" - p "value: #{new_resource.value}" - puts "\n\n" - if entry_missing? execute format_plistbuddy_command(:add, new_resource.entry, new_resource.value) + ' ' + new_resource.path execute format_plistbuddy_command(:set, new_resource.entry, new_resource.value) + ' ' + new_resource.path diff --git a/test/cookbooks/plistbuddy/test/smoke/default/default_test.rb b/test/cookbooks/plistbuddy/test/smoke/default/default_test.rb index 98a29aa9..c86f1025 100644 --- a/test/cookbooks/plistbuddy/test/smoke/default/default_test.rb +++ b/test/cookbooks/plistbuddy/test/smoke/default/default_test.rb @@ -1,7 +1,7 @@ describe command("/usr/libexec/PlistBuddy -c 'Print :showMissionControlGestureEnabled' /Users/vagrant/Library/Preferences/com.apple.dock.plist") do - its('stdout') { should be 'true' } + its('stdout') { should match 'false' } end describe command("/usr/libexec/PlistBuddy -c 'Print :AppleShowAllFiles' /Users/vagrant/Library/Preferences/com.apple.finder.plist") do - its('stdout') { should be 'true' } + its('stdout') { should match 'true' } end From f907c498bb491335c56b33fbbfbbf676d6ea5ae4 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Fri, 27 Oct 2017 00:10:24 -0700 Subject: [PATCH 21/83] remove .kitchen.yml --- test/cookbooks/plistbuddy/.gitignore | 103 +++++++++++++++++++++++++ test/cookbooks/plistbuddy/.kitchen.yml | 32 -------- 2 files changed, 103 insertions(+), 32 deletions(-) create mode 100644 test/cookbooks/plistbuddy/.gitignore delete mode 100644 test/cookbooks/plistbuddy/.kitchen.yml diff --git a/test/cookbooks/plistbuddy/.gitignore b/test/cookbooks/plistbuddy/.gitignore new file mode 100644 index 00000000..17de6c82 --- /dev/null +++ b/test/cookbooks/plistbuddy/.gitignore @@ -0,0 +1,103 @@ +*~ +*# +.#* +\#*# +.*.sw[a-z] +*.un~ + +# Bundler +Gemfile +Gemfile.lock +bin/* +.bundle/* + +# test kitchen +.kitchen/ +.kitchen.local.yml + +# Chef +Berksfile.lock +.zero-knife.rb +Policyfile.lock.json +.autotest +coverage +.DS_Store +pkg/* +tags +*/tags +.chef +results + +# You should check in your Gemfile.lock in applications, and not in gems +external_tests/*.lock +/Gemfile.local + +# ignore some common Bundler 'binstubs' directory names +# http://gembundler.com/man/bundle-exec.1.html +b/ +binstubs/ +.bundle +# RVM and RBENV ruby version files +.rbenv-version +.rvmrc +.ruby-version +.ruby-gemset + +# IDE files +.project + +# Documentation +_site/* +.yardoc/ +doc/ + +# Kitchen Tests Local Mode Data +kitchen-tests/nodes/* + +# Temporary files present during spec runs +spec/data/test-dir +spec/data/nodes +/config/ + +# acceptance binstubs +acceptance/bin/* + +vendor/ +acceptance/vendor +kitchen-tests/vendor + +# Visual Studio Code files +.vscode +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +.idea + +# CMake +cmake-build-debug/ + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Testing +*.box +berks-cookbooks +Vagrantfile +.rubocop.yml +.vagrant +data_bags diff --git a/test/cookbooks/plistbuddy/.kitchen.yml b/test/cookbooks/plistbuddy/.kitchen.yml deleted file mode 100644 index a7be1b91..00000000 --- a/test/cookbooks/plistbuddy/.kitchen.yml +++ /dev/null @@ -1,32 +0,0 @@ ---- -driver: - name: vagrant - provider: parallels - customize: - memory: 8192 - cpus: 2 - -provisioner: - name: chef_zero - -verifier: - name: inspec - -transport: - name: ssh - elevated: true - -platforms: - - name: apex/macos-10.12.6 - driver: - box: apex/macos-10.12.6 - box_url: http://imagr.corp.microsoft.com:8099/apex/macos-10.12.6 - box_check_update: true - -suites: - - name: plistbuddy - run_list: - - recipe[plistbuddy::default] - verifier: - inspec_tests: - - test/smoke/default From 43ea52b06d7942e0cf2ee19dde1d41ed0aaa0034 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Fri, 27 Oct 2017 18:40:23 -0700 Subject: [PATCH 22/83] bump version to 0.8.5 --- metadata.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metadata.rb b/metadata.rb index 1990d7f4..733d1c68 100644 --- a/metadata.rb +++ b/metadata.rb @@ -5,7 +5,7 @@ description 'Resources for configuring and provisioning macOS' long_description 'Resources for configuring and provisioning macOS' chef_version '~> 13.0' if respond_to?(:chef_version) -version '0.8.4' +version '0.8.5' source_url 'https://github.com/Microsoft/macos-cookbook' issues_url 'https://github.com/Microsoft/macos-cookbook/issues' From 07fcc08ca719c363abaf666cc5420c5bd2cc317e Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Sun, 29 Oct 2017 04:07:08 -0700 Subject: [PATCH 23/83] unskip ChefSpec tests - they're passing --- spec/unit/recipes/configurator.rb | 2 +- spec/unit/recipes/default_spec.rb | 2 +- spec/unit/recipes/keep_awake_spec.rb | 2 +- spec/unit/recipes/plistbuddy_spec.rb | 2 +- spec/unit/recipes/xcode_spec.rb | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/unit/recipes/configurator.rb b/spec/unit/recipes/configurator.rb index 21c21940..96969ac4 100644 --- a/spec/unit/recipes/configurator.rb +++ b/spec/unit/recipes/configurator.rb @@ -13,7 +13,7 @@ runner.converge(described_recipe) end - xit 'converges successfully' do + it 'converges successfully' do expect { chef_run }.to_not raise_error end end diff --git a/spec/unit/recipes/default_spec.rb b/spec/unit/recipes/default_spec.rb index e677b686..df3ad1c3 100644 --- a/spec/unit/recipes/default_spec.rb +++ b/spec/unit/recipes/default_spec.rb @@ -7,7 +7,7 @@ runner.converge(described_recipe) end - xit 'converges successfully' do + it 'converges successfully' do expect { chef_run }.to_not raise_error end end diff --git a/spec/unit/recipes/keep_awake_spec.rb b/spec/unit/recipes/keep_awake_spec.rb index 5f44447e..4e731e2e 100644 --- a/spec/unit/recipes/keep_awake_spec.rb +++ b/spec/unit/recipes/keep_awake_spec.rb @@ -7,7 +7,7 @@ runner.converge(described_recipe) end - xit 'converges successfully' do + it 'converges successfully' do expect { chef_run }.to_not raise_error end end diff --git a/spec/unit/recipes/plistbuddy_spec.rb b/spec/unit/recipes/plistbuddy_spec.rb index e677b686..df3ad1c3 100644 --- a/spec/unit/recipes/plistbuddy_spec.rb +++ b/spec/unit/recipes/plistbuddy_spec.rb @@ -7,7 +7,7 @@ runner.converge(described_recipe) end - xit 'converges successfully' do + it 'converges successfully' do expect { chef_run }.to_not raise_error end end diff --git a/spec/unit/recipes/xcode_spec.rb b/spec/unit/recipes/xcode_spec.rb index b8d8a17c..7f53222f 100644 --- a/spec/unit/recipes/xcode_spec.rb +++ b/spec/unit/recipes/xcode_spec.rb @@ -13,7 +13,7 @@ runner.converge(described_recipe) end - xit 'converges successfully' do + it 'converges successfully' do expect { chef_run }.to_not raise_error end end From 7297d6fee595a0809d078fe714cb2d6d9d20025f Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Sun, 29 Oct 2017 04:14:09 -0700 Subject: [PATCH 24/83] mark args_formatter as private method --- libraries/plistbuddy.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/plistbuddy.rb b/libraries/plistbuddy.rb index e871c423..e4fe683d 100644 --- a/libraries/plistbuddy.rb +++ b/libraries/plistbuddy.rb @@ -1,5 +1,3 @@ -include Chef::Mixin::ShellOut - module MacOS module PlistBuddyHelpers def convert_to_string_from_data_type(value) @@ -18,6 +16,8 @@ def format_plistbuddy_command(action_property, plist_entry, plist_value = nil) "/usr/libexec/Plistbuddy -c \'#{action_property.to_s.capitalize} :#{plist_entry} #{plist_value}\'" end + private + def args_formatter(action_property, plist_value) if action_property == :add convert_to_string_from_data_type plist_value From 3d2fdf5325cfccc79e3e011518834b2261a61d9e Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Thu, 30 Nov 2017 16:29:20 -0800 Subject: [PATCH 25/83] Feature/macos user (#14) * first commit add_user recipe * Testing Refactor & macos_user resource - Create new testing cookbook that contains tests for both plistbuddy and macos_user resources. The hope here is to have a single testing cookbook that contains multiple suites and suite testing variations - Create new macos_user resource - contains single boolean 'true' settings for autologin and admin user. Still work to be done for admin user and all steps that need to be taken to acheive the task. * fix method call * fix another method call * user native ruby File class and not overriden * fix some minor issues with resource; add kcpassword file * Add OG Ruby kcpassword file helper module * slightly different approach for Kcpassword module * passing test * Fix up kcpassword library module, smoke tests - Modify Kcpassword helper module to use a method for magic bits. This isn't ideal, but it works for now - Update smoke tests so that john_jr's group ID is 20. This may not be correct, but setting as 20 until it is further investigated * opportunistic refactor of keep_awake recipe * Refactor testing cookbook layout - Consolodate testing suites into single default suite - Add tests for keep_awake recipe - Use more common examples to test PlistBuddy resource * move xcode test to test cookbook * Opportunistic bug fix for plistbuddy resource - Previously, the plistbuddy resource did not allow any keys with spaces unless they were used in the value itself. Now, you can use keys with spaces in the value property without needing to double-quote it - Also, fix the PlistBuddy executable string to be correct * revert kcpassword.rb helper to a671164 * fix incorrect PlistBuddy data type name * Fix kcpassword.rb and update plistbuddy UTs * Extract disabling screen saver to plistbuddy - Also, skip Xcode test temporarily * PlistBuddy idempotence - Remove systemsetup and pmset resource calls in keep_awake until they are made idempotent * update test and plist name * Implement binary plist conversion - Changes to binary plists via PlistBuddy must be converted back to binary since the change implicitly converts the file to xml. This change contains logic to convert back to binary if the file is detected to be binary in the first place. * attempts at idempotence using chef helper methods * early commit to get it on the remote * implement logic for plist return type to ruby data type * Add floating type value support A wild FAILING TEST appeared! ... HANKO used TDD! It's super effective! * move function * real idempotence! * passing all unit tests * update test cookbook name * update new_users integration tests * systemsetup idempotence * all smoke and unit tests passing * quick fix for timezone bug * remove kcpassword file as it is no longer needed * update path for test cookbook to be default repo name * Rename keep_awake_spec.rb to keep_awake_test.rb * Rename preferences_spec.rb to preferences_test.rb * Rename new_users_spec.rb to new_users_test.rb * fix typo * Use relative path for macos cookbook source * Improve readability of relative path for macos cookbook source * Bump version * Addressing changes in Pull Request #14 - Fix bug where screensaver was not properly being disabled, update tests accordingly - Rename plistbuddy resource to plist, including all related files and callers - Rename kcpassword helper to macos_user to match helper -> resource convention; fix top level namespace to be MacOS - Correctly name recipe unit tests - Implement plist resource into disable_software_updates.rb recipe - Add disable_software_updates.rb recipe to default kitchen suite and appropriate smoke tests - Remove relatively useless logic in systemsetup value property coercion * Implement binary plist conversion * Fix unit test and apply the Law of Demeter --- .gitignore | 1 + attributes/default.rb | 3 + libraries/macos_user.rb | 36 +++++ libraries/plist.rb | 90 ++++++++++++ libraries/plistbuddy.rb | 32 ---- metadata.rb | 4 +- recipes/disable_software_updates.rb | 13 +- recipes/keep_awake.rb | 119 ++++++++++----- resources/macos_user.rb | 78 ++++++++++ resources/plist.rb | 39 +++++ resources/plistbuddy.rb | 34 ----- resources/systemsetup.rb | 40 ++--- spec/spec_helper.rb | 8 +- spec/unit/libraries/macos_user_spec.rb | 17 +++ spec/unit/libraries/plist_spec.rb | 139 ++++++++++++++++++ spec/unit/libraries/plistbuddy_spec.rb | 55 ------- .../{configurator.rb => configurator_spec.rb} | 10 +- spec/unit/recipes/default_spec.rb | 5 +- ...ec.rb => disable_software_updates_spec.rb} | 7 +- spec/unit/recipes/keep_awake_spec.rb | 5 +- .../{plistbuddy => macos_test}/.gitignore | 0 test/cookbooks/macos_test/.kitchen.yml | 28 ++++ .../{plistbuddy => macos_test}/Berksfile | 2 +- test/cookbooks/macos_test/metadata.rb | 4 + .../cookbooks/macos_test/recipes/new_users.rb | 11 ++ .../macos_test/recipes/preferences.rb | 17 +++ .../default/disable_software_updates_test.rb | 27 ++++ .../test/smoke/default/keep_awake_test.rb | 60 ++++++++ .../test/smoke/default/new_users_test.rb | 17 +++ .../test/smoke/default/preferences_test.rb | 15 ++ .../test}/smoke/default/xcode_test.rb | 6 +- test/cookbooks/plistbuddy/metadata.rb | 4 - .../plistbuddy/recipes/customize_dock.rb | 4 - test/cookbooks/plistbuddy/recipes/default.rb | 2 - .../plistbuddy/recipes/show_hidden_files.rb | 4 - .../test/smoke/default/default_test.rb | 7 - 36 files changed, 717 insertions(+), 226 deletions(-) create mode 100644 libraries/macos_user.rb create mode 100644 libraries/plist.rb delete mode 100644 libraries/plistbuddy.rb create mode 100644 resources/macos_user.rb create mode 100644 resources/plist.rb delete mode 100644 resources/plistbuddy.rb create mode 100644 spec/unit/libraries/macos_user_spec.rb create mode 100644 spec/unit/libraries/plist_spec.rb delete mode 100644 spec/unit/libraries/plistbuddy_spec.rb rename spec/unit/recipes/{configurator.rb => configurator_spec.rb} (56%) rename spec/unit/recipes/{plistbuddy_spec.rb => disable_software_updates_spec.rb} (50%) rename test/cookbooks/{plistbuddy => macos_test}/.gitignore (100%) create mode 100644 test/cookbooks/macos_test/.kitchen.yml rename test/cookbooks/{plistbuddy => macos_test}/Berksfile (51%) create mode 100644 test/cookbooks/macos_test/metadata.rb create mode 100644 test/cookbooks/macos_test/recipes/new_users.rb create mode 100644 test/cookbooks/macos_test/recipes/preferences.rb create mode 100644 test/cookbooks/macos_test/test/smoke/default/disable_software_updates_test.rb create mode 100644 test/cookbooks/macos_test/test/smoke/default/keep_awake_test.rb create mode 100644 test/cookbooks/macos_test/test/smoke/default/new_users_test.rb create mode 100644 test/cookbooks/macos_test/test/smoke/default/preferences_test.rb rename test/{ => cookbooks/macos_test/test}/smoke/default/xcode_test.rb (58%) delete mode 100644 test/cookbooks/plistbuddy/metadata.rb delete mode 100644 test/cookbooks/plistbuddy/recipes/customize_dock.rb delete mode 100644 test/cookbooks/plistbuddy/recipes/default.rb delete mode 100644 test/cookbooks/plistbuddy/recipes/show_hidden_files.rb delete mode 100644 test/cookbooks/plistbuddy/test/smoke/default/default_test.rb diff --git a/.gitignore b/.gitignore index 17de6c82..a7818a6b 100644 --- a/.gitignore +++ b/.gitignore @@ -68,6 +68,7 @@ kitchen-tests/vendor # Visual Studio Code files .vscode +*/**/*.code-workspace # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm .idea diff --git a/attributes/default.rb b/attributes/default.rb index e95ab281..224a3c7b 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -7,3 +7,6 @@ default['macos']['xcode']['version'] = '9.0' default['macos']['xcode']['simulator']['major_version'] = %w(11 10) + +default['macos']['network_time_server'] = 'time.windows.com' +default['macos']['time_zone'] = 'America/Los_Angeles' diff --git a/libraries/macos_user.rb b/libraries/macos_user.rb new file mode 100644 index 00000000..7d73a120 --- /dev/null +++ b/libraries/macos_user.rb @@ -0,0 +1,36 @@ +module MacOS + module MacOSUserHelpers + def kcpassword_hash(password) + bits = magic_bits + obfuscated = [] + padded(password).each do |char| + obfuscated.push(bits[0] ^ char) + bits.rotate! + end + obfuscated.pack('C*') + end + + private + + def magic_bits + [125, 137, 82, 35, 210, 188, 221, 234, 163, 185, 31] + end + + def magic_len + magic_bits.length + end + + def padded(password) + padding = magic_len - (password.length % magic_len) + padding_size = padding > 0 ? padding : 0 + translated(password) + ([0] * padding_size) + end + + def translated(password) + password.split('').map(&:ord) + end + end +end + +Chef::Recipe.include(MacOS::MacOSUserHelpers) +Chef::Resource.include(MacOS::MacOSUserHelpers) diff --git a/libraries/plist.rb b/libraries/plist.rb new file mode 100644 index 00000000..611f2730 --- /dev/null +++ b/libraries/plist.rb @@ -0,0 +1,90 @@ +module MacOS + module PlistHelpers + def convert_to_data_type_from_string(type, value) + case type + when 'boolean' + value.to_i == 1 + when 'integer' + value.to_i + when 'float' + value.to_f + when 'string' + value + else + raise "Unknown or unsupported data type: #{type.class}" + end + end + + def convert_to_string_from_data_type(value) + data_type_cases = { Array => "array #{value}", + Integer => "integer #{value}", + TrueClass => "bool #{value}", + FalseClass => "bool #{value}", + Hash => "dict #{value}", + String => "string #{value}", + Float => "float #{value}" } + data_type_cases[value.class] + 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 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) + arg = case subcommand.to_s + when 'add' + type_to_commandline_string(value) + when 'print' + '' + else + value + end + entry = "\"#{entry}\"" if entry.include?(' ') + entry_with_arg = [entry, arg].join(' ').strip + subcommand = "#{subcommand.capitalize} :#{entry_with_arg}" + [plistbuddy_executable, '-c', "\'#{subcommand}\'", path].join(' ') + end + + def system_preference(path, entry) + defaults_read_type_output = shell_out(defaults_executable, 'read-type', path, entry).stdout + defaults_read_output = shell_out(defaults_executable, 'read', path, entry).stdout + { key_type: defaults_read_type_output.split.last, key_value: defaults_read_output.strip } + end + + private + + def defaults_executable + '/usr/bin/defaults' + end + + def plistbuddy_executable + '/usr/libexec/PlistBuddy' + end + end +end + +Chef::Recipe.include(MacOS::PlistHelpers) +Chef::Resource.include(MacOS::PlistHelpers) diff --git a/libraries/plistbuddy.rb b/libraries/plistbuddy.rb deleted file mode 100644 index e4fe683d..00000000 --- a/libraries/plistbuddy.rb +++ /dev/null @@ -1,32 +0,0 @@ -module MacOS - module PlistBuddyHelpers - def convert_to_string_from_data_type(value) - data_type_cases = { Array => "array #{value}", - Integer => "int #{value}", - TrueClass => "bool #{value}", - FalseClass => "bool #{value}", - Hash => "dict #{value}", - String => "string #{value}", - Float => "float #{value}" } - data_type_cases[value.class] - end - - def format_plistbuddy_command(action_property, plist_entry, plist_value = nil) - plist_value = args_formatter(action_property, plist_value) - "/usr/libexec/Plistbuddy -c \'#{action_property.to_s.capitalize} :#{plist_entry} #{plist_value}\'" - end - - private - - def args_formatter(action_property, plist_value) - if action_property == :add - convert_to_string_from_data_type plist_value - else - plist_value - end - end - end -end - -Chef::Recipe.include(MacOS::PlistBuddyHelpers) -Chef::Resource.include(MacOS::PlistBuddyHelpers) diff --git a/metadata.rb b/metadata.rb index caba8a87..0889ed44 100644 --- a/metadata.rb +++ b/metadata.rb @@ -5,7 +5,7 @@ description 'Resources for configuring and provisioning macOS' long_description 'Resources for configuring and provisioning macOS' chef_version '~> 13.0' if respond_to?(:chef_version) -version '0.9.0' +version '0.10.0' source_url 'https://github.com/Microsoft/macos-cookbook' issues_url 'https://github.com/Microsoft/macos-cookbook/issues' @@ -13,3 +13,5 @@ supports 'mac_os_x' depends 'homebrew' + +gem 'colorize' diff --git a/recipes/disable_software_updates.rb b/recipes/disable_software_updates.rb index 7d6433c0..68a6fcd5 100644 --- a/recipes/disable_software_updates.rb +++ b/recipes/disable_software_updates.rb @@ -1,4 +1,11 @@ -defaults '/Library/Preferences/com.apple.SoftwareUpdate' do - settings 'AutomaticCheckEnabled' => false, - 'AutomaticDownload' => false +plist 'disable automatic software update check' do + path '/Library/Preferences/com.apple.SoftwareUpdate.plist' + entry 'AutomaticCheckEnabled' + value false +end + +plist 'disable automatic software update downloads' do + path '/Library/Preferences/com.apple.SoftwareUpdate.plist' + entry 'AutomaticDownload' + value false end diff --git a/recipes/keep_awake.rb b/recipes/keep_awake.rb index 162c6889..145abffe 100644 --- a/recipes/keep_awake.rb +++ b/recipes/keep_awake.rb @@ -1,41 +1,80 @@ -systemsetup 'keep awake and set time with systemsetup' do - set sleep: 0, - computersleep: 0, - displaysleep: 0, - harddisksleep: 0, - remoteappleevents: 'On', - allowpowerbuttontosleepcomputer: 'Off', - waitforstartupafterpowerfailure: 0, - restartfreeze: 'On', - networktimeserver: 'time.windows.com', - timezone: 'America/Los_Angeles' -end - -pmset 'keep awake with /usr/bin/pmset' do - settings sleep: 0, - hibernatemode: 0, - womp: 1, # wake on ethernet magic packet - hibernatefile: '/var/vm/sleepimage', - ttyskeepawake: 1 -end - -defaults '/Library/Preferences/com.apple.PowerManagement' do - settings 'DarkWakeBackgroundTasks' => false, # power nap - '"Automatic Restart On Power Loss"' => true, - '"Display Sleep Timer"' => 0, - '"Disk Sleep Timer"' => 0, - '"Wake On LAN"' => true, - '"System Sleep Timer"' => 0 -end - -ruby_block 'set power settings to autoLoginUser' do - block do - loginwindow_plist = '/Library/Preferences/com.apple.loginwindow' - auto_login_user = "defaults read #{loginwindow_plist} autoLoginUser" - node.default['macos']['power']['owner'] = shell_out!(auto_login_user).stdout.strip - end -end - -execute 'disable screensaver' do - command lazy { "sudo -u #{node['macos']['power']['owner']} defaults -currentHost write com.apple.screensaver idleTime 0" } +plist 'disable Power Nap' do + path '/Library/Preferences/com.apple.PowerManagement.plist' + entry 'DarkWakeBackgroundTasks' + value false +end + +plist 'enable automatic restart on power loss' do + path '/Library/Preferences/com.apple.PowerManagement.plist' + entry 'Automatic Restart On Power Loss' + value true +end + +plist 'set display sleep timer to zero' do + path '/Library/Preferences/com.apple.PowerManagement.plist' + entry 'Display Sleep Timer' + value 0 +end + +plist 'enable wake from sleep via network' do + path '/Library/Preferences/com.apple.PowerManagement.plist' + entry 'Wake On LAN' + value true +end + +plist 'set system sleep timer to zero' do + path '/Library/Preferences/com.apple.PowerManagement.plist' + entry 'System Sleep Timer' + value 0 +end + +plist 'disable screensaver' do + path "/Users/#{node['macos']['admin_user']}/Library/Preferences/ByHost/com.apple.screensaver.#{hardware_uuid}.plist" + entry 'idleTime' + value 0 +end + +systemsetup 'Set amount of idle time until computer sleeps to never' do + setting 'computersleep' + value 'Never' +end + +systemsetup 'set amount of idle time until display sleeps to never' do + setting 'displaysleep' + value 'Never' +end + +systemsetup 'set amount of idle time until hard disk sleeps to never' do + setting 'harddisksleep' + value 'Never' +end + +systemsetup 'set remote apple events to on' do + setting 'remoteappleevents' + value 'On' +end + +systemsetup 'disable the power button from being able to sleep the computer.' do + setting 'allowpowerbuttontosleepcomputer' + value 'Off' +end + +systemsetup 'set the number of seconds after which the computer will start up after a power failure to zero.' do + setting 'waitforstartupafterpowerfailure' + value 0 +end + +systemsetup 'set restart on freeze to on' do + setting 'restartfreeze' + value 'On' +end + +systemsetup "set network time server to #{node['macos']['network_time_server']}" do + setting 'networktimeserver' + value node['macos']['network_time_server'] +end + +systemsetup "set current time zone to #{node['macos']['time_zone']}" do + setting 'timezone' + value node['macos']['time_zone'] end diff --git a/resources/macos_user.rb b/resources/macos_user.rb new file mode 100644 index 00000000..75da963d --- /dev/null +++ b/resources/macos_user.rb @@ -0,0 +1,78 @@ +resource_name :macos_user +default_action :create + +property :username, String, name_property: true +property :password, String, default: 'password' +property :autologin, [TrueClass] +property :admin, [TrueClass] + +action_class do + def user_home + ::File.join('/Users', new_resource.username) + end + + def setup_assistant_plist + ::File.join(user_home, '/Library/Preferences/com.apple.SetupAssistant.plist') + end + + def setup_assistant_keypair_values + { 'DidSeeSiriSetup' => true, + 'DidSeeCloudSetup' => true, + 'LastSeenCloudProductVersion' => node['platform_version'] } + end + + def sysadminctl + '/usr/sbin/sysadminctl' + end + + def admin_user? + if property_is_set?(:admin) + '-admin' + else + '' + end + end +end + +action :create do + execute "add user #{new_resource.username}" do + command "#{sysadminctl} -addUser #{new_resource.username} -password #{new_resource.password} #{admin_user?}" + not_if { ::File.exist? user_home } + end + + if property_is_set?(:autologin) + setup_assistant_keypair_values.each do |key, setting| + plist "set #{setting} to #{key}" do + path setup_assistant_plist + entry key + value setting + end + end + + plist "set user \"#{new_resource.username}\" to login automatically" do + path '/Library/Preferences/com.apple.loginwindow.plist' + entry 'autoLoginUser' + value new_resource.username + end + + file '/etc/kcpassword' do + content kcpassword_hash(new_resource.password) + owner 'root' + group 'wheel' + mode '0600' + end + end +end + +action :delete do + directory user_home do + recursive true + action :delete + only_if { ::File.exist? user_home } + end + + execute "delete user: #{user}" do + command "#{sysadminctl} -deleteUser #{new_resource.username}" + only_if { "/usr/bin/dscl . -list /users | grep ^#{new_resource.username}$" } + end +end diff --git a/resources/plist.rb b/resources/plist.rb new file mode 100644 index 00000000..26764722 --- /dev/null +++ b/resources/plist.rb @@ -0,0 +1,39 @@ +resource_name :plist + +property :path, String, name_property: true +property :entry, String, desired_state: true +property :value, [TrueClass, FalseClass, String, Integer, Float], desired_state: true + +action_class do + def binary? + file_type_output = shell_out('/usr/bin/file', '--brief', '--mime-encoding', new_resource.path).stdout + file_type_output.strip == 'binary' + end +end + +load_current_value do |desired| + system_preference = system_preference(desired.path, desired.entry) + current_value_does_not_exist! if system_preference[:key_type].nil? + entry desired.entry unless system_preference[:key_type].nil? + value convert_to_data_type_from_string(system_preference[:key_type], system_preference[:key_value]) +end + +action :set do + converge_if_changed :entry do + converge_by "add \"#{new_resource.entry}\" to #{new_resource.path.split('/').last}" do + execute plistbuddy_command(:add, new_resource.entry, new_resource.path, new_resource.value) + end + end + + converge_if_changed :value do + converge_by "set \"#{new_resource.entry}\" to #{new_resource.value} at #{new_resource.path.split('/').last}" do + execute plistbuddy_command(:set, new_resource.entry, new_resource.path, new_resource.value) + end + end + + unless binary? + converge_by "convert \"#{new_resource.path.split('/').last}\" to binary" do + execute "/usr/bin/plutil -convert binary1 #{new_resource.path}" + end + end +end diff --git a/resources/plistbuddy.rb b/resources/plistbuddy.rb deleted file mode 100644 index fa052905..00000000 --- a/resources/plistbuddy.rb +++ /dev/null @@ -1,34 +0,0 @@ -resource_name :plistbuddy - -property :path, String, name_property: true -property :entry, String, required: true -property :value, [Hash, String, Array, TrueClass, FalseClass, Integer, Float] - -default_action :set - -action_class do - def entry_missing? - command = format_plistbuddy_command(:print, new_resource.entry, new_resource.value) - full_command = command + ' ' + new_resource.path - shell_out(full_command).error? - end - - def current_entry_value - command = format_plistbuddy_command(:print, new_resource.entry) - full_command = command + ' ' + new_resource.path - shell_out(full_command).stdout.chomp - end -end - -action :set do - if entry_missing? - execute format_plistbuddy_command(:add, new_resource.entry, new_resource.value) + ' ' + new_resource.path - execute format_plistbuddy_command(:set, new_resource.entry, new_resource.value) + ' ' + new_resource.path - elsif current_entry_value != new_resource.value.to_s - execute format_plistbuddy_command(:set, new_resource.entry, new_resource.value) + ' ' + new_resource.path - end -end - -action :delete do - execute format_plistbuddy_command(:delete, new_resource.entry, new_resource.value) + ' ' + new_resource.path -end diff --git a/resources/systemsetup.rb b/resources/systemsetup.rb index 278644da..f6bb4202 100644 --- a/resources/systemsetup.rb +++ b/resources/systemsetup.rb @@ -1,26 +1,32 @@ +require 'colorize' + resource_name :systemsetup -default_action :run -BASE_COMMAND = '/usr/sbin/systemsetup'.freeze +property :setting, desired_state: false +property :value, desired_state: true, coerce: proc { |m| m.to_s } -property :get, Array -property :set, Hash +default_action :set -action :run do - if new_resource.get - new_resource.get.each do |flag| - execute BASE_COMMAND do - command "#{BASE_COMMAND} -get#{flag}" - live_stream true - end - end +load_current_value do |desired| + command_output = shell_out('/usr/sbin/systemsetup', "-get#{desired.setting}").stdout.split(': ').last.strip + if command_output.include?('after') + value command_output.split[1] + elsif command_output.end_with?('seconds') + value command_output.split.first + elsif command_output.start_with?('Error') + puts "\n" + warn(command_output.to_s.colorize(:red).bold) + warn(desired.setting.to_s.colorize(:red)) + value desired.value + else + value command_output.split.last end +end - if new_resource.set - new_resource.set.each do |flag, setting| - execute BASE_COMMAND do - command "#{BASE_COMMAND} -set#{flag} #{setting}" - end +action :set do + converge_if_changed do + converge_by "set #{new_resource.setting} to #{new_resource.value}" do + execute "/usr/sbin/systemsetup -set#{new_resource.setting} #{new_resource.value}" end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 08509c91..6e059ed4 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,11 @@ require 'chefspec' require 'chefspec/berkshelf' -require_relative '../libraries/plistbuddy' +require_relative '../libraries/macos_user' +require_relative '../libraries/plist' require_relative '../libraries/xcode' + +RSpec.configure do |config| + config.platform = 'mac_os_x' + config.version = '10.12' +end diff --git a/spec/unit/libraries/macos_user_spec.rb b/spec/unit/libraries/macos_user_spec.rb new file mode 100644 index 00000000..a8d54843 --- /dev/null +++ b/spec/unit/libraries/macos_user_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +include MacOS::MacOSUserHelpers + +describe MacOS::MacOSUserHelpers, '#kcpassword_hash' do + context 'When calling the obfuscate method on a short password' do + it 'the password is obfuscated correctly' do + expect(kcpassword_hash('password')).to eq "\r\xE8!P\xA5\xD3\xAF\x8E\xA3\xB9\x1F".force_encoding('ASCII-8BIT') + end + end + + context 'When calling the obfuscate method on a long password' do + xit 'the password hash value matches the binary content of the file' do + expect(kcpassword_hash('correct-horse-battery-staple')).to eq "\x1E\xE6 Q\xB7\xDF\xA9\xC7\xCB\xD6m\x0E\xEC\x7FA\xB3\xC8\xA9\x8F\xD1\xC02\x0E\xFD3S\xBE\xD9\xAE\x9F\xC7\xD6\x1F".force_encoding('ASCII-8BIT') + end + end +end diff --git a/spec/unit/libraries/plist_spec.rb b/spec/unit/libraries/plist_spec.rb new file mode 100644 index 00000000..638357a4 --- /dev/null +++ b/spec/unit/libraries/plist_spec.rb @@ -0,0 +1,139 @@ +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 + 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 +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 'find the value from somewhere else' do + expect { convert_to_data_type_from_string(nil, '') }.to raise_error(RuntimeError) + 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(%w(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 + + # TODO: Skip until proper plist array syntax is implemented (i.e. containers) + xit 'returns the required array entry' do + expect(convert_to_string_from_data_type(%w(foo bar))).to eq 'array foo bar' + end + + # TODO: Skip until proper plist dict syntax is implemented (i.e. containers) + xit 'returns the required dictionary entry' do + expect(convert_to_string_from_data_type('baz' => 'qux')).to eq 'dict key value' + end + + it 'returns the required string entry' do + expect(convert_to_string_from_data_type('quux')).to eq 'string quux' + 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 + end +end diff --git a/spec/unit/libraries/plistbuddy_spec.rb b/spec/unit/libraries/plistbuddy_spec.rb deleted file mode 100644 index ac11c30c..00000000 --- a/spec/unit/libraries/plistbuddy_spec.rb +++ /dev/null @@ -1,55 +0,0 @@ -require 'spec_helper' - -include MacOS::PlistBuddyHelpers - -describe MacOS::PlistBuddyHelpers, '#format_plistbuddy_command' do - context 'Adding a value to a plist' do - it 'the bool arguments contain the data type' do - expect(format_plistbuddy_command(:add, 'FooEntry', true)).to eq "/usr/libexec/Plistbuddy -c 'Add :FooEntry bool true'" - end - - it 'the int arguments contain the data type' do - expect(format_plistbuddy_command(:add, 'QuuxEntry', 50)).to eq "/usr/libexec/Plistbuddy -c 'Add :QuuxEntry int 50'" - end - - it 'the delete command is formatted properly' do - expect(format_plistbuddy_command(:delete, 'BarEntry')).to eq "/usr/libexec/Plistbuddy -c 'Delete :BarEntry '" - end - - it 'the set command is formatted properly' do - expect(format_plistbuddy_command(:set, 'BazEntry', false)).to eq "/usr/libexec/Plistbuddy -c 'Set :BazEntry false'" - end - - it 'the print command is formatted properly' do - expect(format_plistbuddy_command(:print, 'QuxEntry')).to eq "/usr/libexec/Plistbuddy -c 'Print :QuxEntry '" - end - end -end - -describe MacOS::PlistBuddyHelpers, '#convert_to_string_from_data_type' do - context 'When given a certain data type' do - it 'returns the required PlistBuddy boolean entry' do - expect(convert_to_string_from_data_type(true)).to eq 'bool true' - end - - xit 'returns the required PlistBuddy array entry' do # TODO: Implement proper plist array syntax (i.e. containers) - expect(convert_to_string_from_data_type(%w(foo bar))).to eq 'array foo bar' - end - - xit 'returns the required PlistBuddy dictionary entry' do # TODO: Implement proper plist dict syntax (i.e. containers) - expect(convert_to_string_from_data_type('baz' => 'qux')).to eq 'dict key value' - end - - it 'returns the required PlistBuddy string entry' do - expect(convert_to_string_from_data_type('quux')).to eq 'string quux' - end - - it 'returns the required PlistBuddy int entry' do - expect(convert_to_string_from_data_type(1)).to eq 'int 1' - end - - it 'returns the required PlistBuddy float entry' do - expect(convert_to_string_from_data_type(1.0)).to eq 'float 1.0' - end - end -end diff --git a/spec/unit/recipes/configurator.rb b/spec/unit/recipes/configurator_spec.rb similarity index 56% rename from spec/unit/recipes/configurator.rb rename to spec/unit/recipes/configurator_spec.rb index 96969ac4..90c0a081 100644 --- a/spec/unit/recipes/configurator.rb +++ b/spec/unit/recipes/configurator_spec.rb @@ -5,13 +5,13 @@ before(:each) do stub_data_bag_item('credentials', 'apple_id').and_return( apple_id: 'developer@apple.com', - password: 'apple_id_password') + password: 'apple_id_password' + ) + stub_command('which git').and_return('/usr/local/bin/git') + stub_command('/usr/local/bin/mas account').and_return('developer@apple.com') end - let(:chef_run) do - runner = ChefSpec::SoloRunner.new(platform: 'mac_os_x', version: '10.12') - runner.converge(described_recipe) - end + let(:chef_run) { ChefSpec::SoloRunner.new.converge(described_recipe) } it 'converges successfully' do expect { chef_run }.to_not raise_error diff --git a/spec/unit/recipes/default_spec.rb b/spec/unit/recipes/default_spec.rb index df3ad1c3..87160d6e 100644 --- a/spec/unit/recipes/default_spec.rb +++ b/spec/unit/recipes/default_spec.rb @@ -2,10 +2,7 @@ describe 'macos::default' do context 'When all attributes are default, on macOS 10.12' do - let(:chef_run) do - runner = ChefSpec::ServerRunner.new(platform: 'mac_os_x', version: '10.12') - runner.converge(described_recipe) - end + let(:chef_run) { ChefSpec::SoloRunner.new.converge(described_recipe) } it 'converges successfully' do expect { chef_run }.to_not raise_error diff --git a/spec/unit/recipes/plistbuddy_spec.rb b/spec/unit/recipes/disable_software_updates_spec.rb similarity index 50% rename from spec/unit/recipes/plistbuddy_spec.rb rename to spec/unit/recipes/disable_software_updates_spec.rb index df3ad1c3..5a665277 100644 --- a/spec/unit/recipes/plistbuddy_spec.rb +++ b/spec/unit/recipes/disable_software_updates_spec.rb @@ -1,11 +1,8 @@ require 'spec_helper' -describe 'macos::default' do +describe 'macos::disable_software_updates' do context 'When all attributes are default, on macOS 10.12' do - let(:chef_run) do - runner = ChefSpec::ServerRunner.new(platform: 'mac_os_x', version: '10.12') - runner.converge(described_recipe) - end + let(:chef_run) { ChefSpec::SoloRunner.new.converge(described_recipe) } it 'converges successfully' do expect { chef_run }.to_not raise_error diff --git a/spec/unit/recipes/keep_awake_spec.rb b/spec/unit/recipes/keep_awake_spec.rb index 4e731e2e..3f7ed0fb 100644 --- a/spec/unit/recipes/keep_awake_spec.rb +++ b/spec/unit/recipes/keep_awake_spec.rb @@ -2,10 +2,7 @@ describe 'macos::keep_awake' do context 'When all attributes are default, on macOS 10.12' do - let(:chef_run) do - runner = ChefSpec::ServerRunner.new(platform: 'mac_os_x', version: '10.12') - runner.converge(described_recipe) - end + let(:chef_run) { ChefSpec::SoloRunner.new.converge(described_recipe) } it 'converges successfully' do expect { chef_run }.to_not raise_error diff --git a/test/cookbooks/plistbuddy/.gitignore b/test/cookbooks/macos_test/.gitignore similarity index 100% rename from test/cookbooks/plistbuddy/.gitignore rename to test/cookbooks/macos_test/.gitignore diff --git a/test/cookbooks/macos_test/.kitchen.yml b/test/cookbooks/macos_test/.kitchen.yml new file mode 100644 index 00000000..f1aff1fa --- /dev/null +++ b/test/cookbooks/macos_test/.kitchen.yml @@ -0,0 +1,28 @@ +--- +driver: + name: vagrant + provider: parallels + +provisioner: + name: chef_zero + always_update_cookbooks: true + +verifier: + name: inspec + sudo: true + +platforms: + - name: apex/macos-10.11.6 + - name: apex/macos-10.12.6 + - name: apex/macos-10.13 + +suites: + - name: default + run_list: + - recipe[macos::keep_awake] + - recipe[macos::disable_software_updates] + - recipe[macos_test::new_users] + - recipe[macos_test::preferences] + verifier: + inspec_tests: + - test/smoke/default diff --git a/test/cookbooks/plistbuddy/Berksfile b/test/cookbooks/macos_test/Berksfile similarity index 51% rename from test/cookbooks/plistbuddy/Berksfile rename to test/cookbooks/macos_test/Berksfile index 0fac3b01..18a2bfb2 100644 --- a/test/cookbooks/plistbuddy/Berksfile +++ b/test/cookbooks/macos_test/Berksfile @@ -2,4 +2,4 @@ source 'https://supermarket.chef.io' metadata -cookbook 'macos', path: '../../../../macos/' +cookbook 'macos', path: './../../../' diff --git a/test/cookbooks/macos_test/metadata.rb b/test/cookbooks/macos_test/metadata.rb new file mode 100644 index 00000000..e7873071 --- /dev/null +++ b/test/cookbooks/macos_test/metadata.rb @@ -0,0 +1,4 @@ +name 'macos_test' +version '1.0.0' + +depends 'macos' diff --git a/test/cookbooks/macos_test/recipes/new_users.rb b/test/cookbooks/macos_test/recipes/new_users.rb new file mode 100644 index 00000000..a12c4d6e --- /dev/null +++ b/test/cookbooks/macos_test/recipes/new_users.rb @@ -0,0 +1,11 @@ +macos_user 'create admin user randall and enable automatic login' do + username 'randall' + password 'correct-horse-battery-staple' + autologin true + admin true +end + +macos_user 'create non-admin user johnny' do + username 'johnny' + password 'yang-yolked-cordon-karate' +end diff --git a/test/cookbooks/macos_test/recipes/preferences.rb b/test/cookbooks/macos_test/recipes/preferences.rb new file mode 100644 index 00000000..66379db0 --- /dev/null +++ b/test/cookbooks/macos_test/recipes/preferences.rb @@ -0,0 +1,17 @@ +plist 'show hidden files' do + path '/Users/vagrant/Library/Preferences/com.apple.finder.plist' + entry 'AppleShowAllFiles' + value true +end + +plist 'put the Dock on the left side' do + path '/Users/vagrant/Library/Preferences/com.apple.dock.plist' + entry 'orientation' + value 'left' +end + +plist 'disable window animations and Get Info animations' do + path '/Users/vagrant/Library/Preferences/com.apple.dock.plist' + entry 'DisableAllAnimations' + value true +end diff --git a/test/cookbooks/macos_test/test/smoke/default/disable_software_updates_test.rb b/test/cookbooks/macos_test/test/smoke/default/disable_software_updates_test.rb new file mode 100644 index 00000000..28c88f19 --- /dev/null +++ b/test/cookbooks/macos_test/test/smoke/default/disable_software_updates_test.rb @@ -0,0 +1,27 @@ +software_update_plist = '/Library/Preferences/com.apple.SoftwareUpdate.plist' +automatic_check_enabled = 'AutomaticCheckEnabled' +automatic_download = 'AutomaticDownload' + +describe command("/usr/libexec/PlistBuddy -c 'Print :#{automatic_check_enabled}' #{software_update_plist}") do + its('stdout') { should match('false') } +end + +describe command("/usr/libexec/PlistBuddy -c 'Print :#{automatic_download}' #{software_update_plist}") do + its('stdout') { should match('false') } +end + +describe command("/usr/bin/defaults read-type #{software_update_plist} #{automatic_download}") do + its('stdout') { should match('boolean') } +end + +describe command("/usr/bin/defaults read-type #{software_update_plist} #{automatic_check_enabled}") do + its('stdout') { should match('boolean') } +end + +describe command("/usr/bin/defaults read #{software_update_plist} #{automatic_download}") do + its('stdout') { should match('0') } +end + +describe command("/usr/bin/defaults read #{software_update_plist} #{automatic_check_enabled}") do + its('stdout') { should match('0') } +end diff --git a/test/cookbooks/macos_test/test/smoke/default/keep_awake_test.rb b/test/cookbooks/macos_test/test/smoke/default/keep_awake_test.rb new file mode 100644 index 00000000..798b3cd0 --- /dev/null +++ b/test/cookbooks/macos_test/test/smoke/default/keep_awake_test.rb @@ -0,0 +1,60 @@ +control 'power' do + desc 'Display, machine and hard disk never sleep, the machine automatically restarts + after a freeze or power outage, and Power Nap' + + %w(sleep computersleep displaysleep harddisksleep).each do |setting| + describe command("systemsetup -get#{setting}") do + its('stdout') { should match('Never') } + end + end + + %w(restartfreeze remoteappleevents).each do |setting| + describe command("systemsetup -get#{setting}") do + its('stdout') { should match('On') } + end + end + + describe command('systemsetup -getwaitforstartupafterpowerfailure') do + its('stdout') { should match('0 seconds') } + end + + describe command('pmset -g') do + its('stdout') { should match(/sleep\s*0/) } + its('stdout') { should match(/hibernatemode\s*0$/) } + its('stdout') { should match(/ttyskeepawake\s*1/) } + its('stdout') { should match(%r{hibernatefile\s*\/var\/vm\/sleepimage}) } + its('stdout') { should match(/disksleep\s*0/) } + its('stdout') { should match(/displaysleep\s*0/) } + its('stdout') { should match(/ttyskeepawake\s*1/) } + end + + describe command("/usr/libexec/PlistBuddy -c 'Print :DarkWakeBackgroundTasks' '/Library/Preferences/com.apple.PowerManagement.plist'") do + its('stdout') { should match('false') } + end +end + +control 'screensaver' do + desc 'screensaver is disabled' + + def hardware_uuid + system_profiler_hardware_output = `system_profiler SPHardwareDataType` + hardware_overview = Psych.load(system_profiler_hardware_output)['Hardware']['Hardware Overview'] + hardware_overview['Hardware UUID'] + end + + describe command("/usr/libexec/PlistBuddy -c 'Print :idleTime' /Users/vagrant/Library/Preferences/ByHost/com.apple.screensaver.#{hardware_uuid}.plist"), :skip do + its('stdout') { should match(/0/) } + end + + describe command('su vagrant -c "/usr/bin/defaults -currentHost read com.apple.screensaver idleTime"') do + its('stdout') { should match(/0/) } + end + + describe command('su vagrant -c "/usr/bin/defaults -currentHost read-type com.apple.screensaver idleTime"') do + its('stdout') { should match(/integer/) } + end + + describe command("file --brief --mime /Users/vagrant/Library/Preferences/ByHost/com.apple.screensaver.#{hardware_uuid}.plist"), :skip do + its('stdout') { should match(/binary/) } + end +end diff --git a/test/cookbooks/macos_test/test/smoke/default/new_users_test.rb b/test/cookbooks/macos_test/test/smoke/default/new_users_test.rb new file mode 100644 index 00000000..4d6a0a53 --- /dev/null +++ b/test/cookbooks/macos_test/test/smoke/default/new_users_test.rb @@ -0,0 +1,17 @@ +control 'new macOS users' do + desc 'they exist with the expected characteristics' + + describe user('randall') do + it { should exist } + its('uid') { should eq 503 } + its('gid') { should eq 20 } + its('home') { should eq '/Users/randall' } + end + + describe user('johnny') do + it { should exist } + its('uid') { should eq 504 } + its('gid') { should eq 20 } + its('home') { should eq '/Users/johnny' } + end +end diff --git a/test/cookbooks/macos_test/test/smoke/default/preferences_test.rb b/test/cookbooks/macos_test/test/smoke/default/preferences_test.rb new file mode 100644 index 00000000..e82b509e --- /dev/null +++ b/test/cookbooks/macos_test/test/smoke/default/preferences_test.rb @@ -0,0 +1,15 @@ +control 'macOS user preferences' do + desc 'they are set to the correct values' + + describe command("/usr/libexec/PlistBuddy -c 'Print :orientation' /Users/vagrant/Library/Preferences/com.apple.dock.plist") do + its('stdout') { should match 'left' } + end + + describe command("/usr/libexec/PlistBuddy -c 'Print :AppleShowAllFiles' /Users/vagrant/Library/Preferences/com.apple.finder.plist") do + its('stdout') { should match 'true' } + end + + describe command("/usr/libexec/PlistBuddy -c 'Print :DisableAllAnimations' /Users/vagrant/Library/Preferences/com.apple.dock.plist") do + its('stdout') { should match 'true' } + end +end diff --git a/test/smoke/default/xcode_test.rb b/test/cookbooks/macos_test/test/smoke/default/xcode_test.rb similarity index 58% rename from test/smoke/default/xcode_test.rb rename to test/cookbooks/macos_test/test/smoke/default/xcode_test.rb index e3b7cd61..f55b36c6 100644 --- a/test/smoke/default/xcode_test.rb +++ b/test/cookbooks/macos_test/test/smoke/default/xcode_test.rb @@ -1,16 +1,16 @@ control 'xcode' do desc 'application Xcode exists and Developer mode is enabled' - describe file '/Applications/Xcode.app' do + describe file('/Applications/Xcode.app'), :skip do it { should exist } it { should be_symlink } end - describe directory '/Applications/Xcode-9.app' do + describe directory('/Applications/Xcode-9.app'), :skip do it { should exist } end - describe command('/usr/local/bin/xcversion simulators') do + describe command('/usr/local/bin/xcversion simulators'), :skip do its('stdout') { should match(/iOS 10\.3\.1 Simulator \(installed\)/) } end end diff --git a/test/cookbooks/plistbuddy/metadata.rb b/test/cookbooks/plistbuddy/metadata.rb deleted file mode 100644 index 21d229d5..00000000 --- a/test/cookbooks/plistbuddy/metadata.rb +++ /dev/null @@ -1,4 +0,0 @@ -name 'plistbuddy' -version '1.0.0' - -depends 'macos', '0.8.4' diff --git a/test/cookbooks/plistbuddy/recipes/customize_dock.rb b/test/cookbooks/plistbuddy/recipes/customize_dock.rb deleted file mode 100644 index 73f05800..00000000 --- a/test/cookbooks/plistbuddy/recipes/customize_dock.rb +++ /dev/null @@ -1,4 +0,0 @@ -plistbuddy '/Users/vagrant/Library/Preferences/com.apple.dock.plist' do - entry 'showMissionControlGestureEnabled' - value false -end diff --git a/test/cookbooks/plistbuddy/recipes/default.rb b/test/cookbooks/plistbuddy/recipes/default.rb deleted file mode 100644 index 0d12f25f..00000000 --- a/test/cookbooks/plistbuddy/recipes/default.rb +++ /dev/null @@ -1,2 +0,0 @@ -include_recipe 'plistbuddy::customize_dock' -include_recipe 'plistbuddy::show_hidden_files' diff --git a/test/cookbooks/plistbuddy/recipes/show_hidden_files.rb b/test/cookbooks/plistbuddy/recipes/show_hidden_files.rb deleted file mode 100644 index 5dcd3662..00000000 --- a/test/cookbooks/plistbuddy/recipes/show_hidden_files.rb +++ /dev/null @@ -1,4 +0,0 @@ -plistbuddy '/Users/vagrant/Library/Preferences/com.apple.finder.plist' do - entry 'AppleShowAllFiles' - value true -end diff --git a/test/cookbooks/plistbuddy/test/smoke/default/default_test.rb b/test/cookbooks/plistbuddy/test/smoke/default/default_test.rb deleted file mode 100644 index c86f1025..00000000 --- a/test/cookbooks/plistbuddy/test/smoke/default/default_test.rb +++ /dev/null @@ -1,7 +0,0 @@ -describe command("/usr/libexec/PlistBuddy -c 'Print :showMissionControlGestureEnabled' /Users/vagrant/Library/Preferences/com.apple.dock.plist") do - its('stdout') { should match 'false' } -end - -describe command("/usr/libexec/PlistBuddy -c 'Print :AppleShowAllFiles' /Users/vagrant/Library/Preferences/com.apple.finder.plist") do - its('stdout') { should match 'true' } -end From 174786ea0cc151d244e9c26aefeb2a42fa5f4537 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Tue, 5 Dec 2017 15:04:27 -0800 Subject: [PATCH 26/83] update helper pattern to match current standard; include everywhere --- libraries/xcode.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/xcode.rb b/libraries/xcode.rb index cdd7f8ca..ffcd718c 100644 --- a/libraries/xcode.rb +++ b/libraries/xcode.rb @@ -1,5 +1,5 @@ module Xcode - module Helper + module Helpers def xcversion_command '/opt/chef/embedded/bin/xcversion'.freeze end @@ -54,3 +54,6 @@ def available_simulator_versions end end end + +Chef::Recipe.include(Xcode::Helpers) +Chef::Resource.include(Xcode::Helpers) From 27bb087e54112c659df3dc1dbde676562af49ffe Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Tue, 5 Dec 2017 15:04:42 -0800 Subject: [PATCH 27/83] remove helper reference in Xcode resource --- resources/xcode.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/xcode.rb b/resources/xcode.rb index e7997c52..2d5fe7fe 100644 --- a/resources/xcode.rb +++ b/resources/xcode.rb @@ -1,5 +1,3 @@ -include Xcode::Helper - resource_name :xcode default_action %i(setup install_xcode install_simulators) From d85b9f0b45b7a8dca7f65c584e8f46fda5dc9c57 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Tue, 5 Dec 2017 15:04:51 -0800 Subject: [PATCH 28/83] bump version --- metadata.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metadata.rb b/metadata.rb index 0889ed44..c30c2fc6 100644 --- a/metadata.rb +++ b/metadata.rb @@ -5,7 +5,7 @@ description 'Resources for configuring and provisioning macOS' long_description 'Resources for configuring and provisioning macOS' chef_version '~> 13.0' if respond_to?(:chef_version) -version '0.10.0' +version '0.10.1' source_url 'https://github.com/Microsoft/macos-cookbook' issues_url 'https://github.com/Microsoft/macos-cookbook/issues' From 1a432107390893a240cdc357e4aaca435edec0ab Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Tue, 5 Dec 2017 15:05:35 -0800 Subject: [PATCH 29/83] update Xcode attribute to latest --- attributes/default.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/attributes/default.rb b/attributes/default.rb index 224a3c7b..fbaa5282 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -5,7 +5,7 @@ default['macos']['mono']['version'] = '4.4.2' default['macos']['mono']['checksum'] = 'd8bfbee7ae4d0d1facaf0ddfb70c0de4b1a3d94bb1b4c38e8fa4884539f54e23' -default['macos']['xcode']['version'] = '9.0' +default['macos']['xcode']['version'] = '9.1' default['macos']['xcode']['simulator']['major_version'] = %w(11 10) default['macos']['network_time_server'] = 'time.windows.com' From cfa82a798f9dc90365b140d65935bdc4e8e33c58 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Tue, 5 Dec 2017 15:14:21 -0800 Subject: [PATCH 30/83] extract xcode smoke tests to a different suite --- test/cookbooks/macos_test/.kitchen.yml | 9 +++++++++ .../test/smoke/{default => xcode}/xcode_test.rb | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) rename test/cookbooks/macos_test/test/smoke/{default => xcode}/xcode_test.rb (58%) diff --git a/test/cookbooks/macos_test/.kitchen.yml b/test/cookbooks/macos_test/.kitchen.yml index f1aff1fa..bba0d575 100644 --- a/test/cookbooks/macos_test/.kitchen.yml +++ b/test/cookbooks/macos_test/.kitchen.yml @@ -26,3 +26,12 @@ suites: verifier: inspec_tests: - test/smoke/default + + - name: xcode + run_list: + - recipe[macos::xcode] + excludes: + - apex/macos-10.11.6 + verifier: + inspec_tests: + - test/smoke/xcode diff --git a/test/cookbooks/macos_test/test/smoke/default/xcode_test.rb b/test/cookbooks/macos_test/test/smoke/xcode/xcode_test.rb similarity index 58% rename from test/cookbooks/macos_test/test/smoke/default/xcode_test.rb rename to test/cookbooks/macos_test/test/smoke/xcode/xcode_test.rb index f55b36c6..9c94816b 100644 --- a/test/cookbooks/macos_test/test/smoke/default/xcode_test.rb +++ b/test/cookbooks/macos_test/test/smoke/xcode/xcode_test.rb @@ -1,16 +1,16 @@ control 'xcode' do desc 'application Xcode exists and Developer mode is enabled' - describe file('/Applications/Xcode.app'), :skip do + describe file('/Applications/Xcode.app') do it { should exist } it { should be_symlink } end - describe directory('/Applications/Xcode-9.app'), :skip do + describe directory('/Applications/Xcode-9.1.app') do it { should exist } end - describe command('/usr/local/bin/xcversion simulators'), :skip do + describe command('/usr/local/bin/xcversion simulators') do its('stdout') { should match(/iOS 10\.3\.1 Simulator \(installed\)/) } end end From b4516ece3b1e45995ef2e8a049216396e7809692 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Tue, 5 Dec 2017 15:50:00 -0800 Subject: [PATCH 31/83] update xcversion path for simulators test --- test/cookbooks/macos_test/test/smoke/xcode/xcode_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cookbooks/macos_test/test/smoke/xcode/xcode_test.rb b/test/cookbooks/macos_test/test/smoke/xcode/xcode_test.rb index 9c94816b..25391e85 100644 --- a/test/cookbooks/macos_test/test/smoke/xcode/xcode_test.rb +++ b/test/cookbooks/macos_test/test/smoke/xcode/xcode_test.rb @@ -10,7 +10,7 @@ it { should exist } end - describe command('/usr/local/bin/xcversion simulators') do + describe command('/opt/chef/embedded/bin/xcversion simulators') do its('stdout') { should match(/iOS 10\.3\.1 Simulator \(installed\)/) } end end From 54618695621d93937b437e1e0a463acf4479d2d4 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Tue, 5 Dec 2017 17:13:45 -0800 Subject: [PATCH 32/83] update namespace again --- libraries/xcode.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/xcode.rb b/libraries/xcode.rb index ffcd718c..7df2f148 100644 --- a/libraries/xcode.rb +++ b/libraries/xcode.rb @@ -1,5 +1,5 @@ -module Xcode - module Helpers +module MacOS + module XcodeHelpers def xcversion_command '/opt/chef/embedded/bin/xcversion'.freeze end @@ -55,5 +55,5 @@ def available_simulator_versions end end -Chef::Recipe.include(Xcode::Helpers) -Chef::Resource.include(Xcode::Helpers) +Chef::Recipe.include(MacOS::XcodeHelpers) +Chef::Resource.include(MacOS::XcodeHelpers) From 302cc8af1107dd4befc1616421d4bc4b5b98758f Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Wed, 6 Dec 2017 13:44:45 -0800 Subject: [PATCH 33/83] refactor XcodeHelper modules in XCVersion, Xcode, and XCVersion modules updated methods to simplify site calls in resource --- libraries/xcode.rb | 100 +++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 44 deletions(-) diff --git a/libraries/xcode.rb b/libraries/xcode.rb index 7df2f148..22fca303 100644 --- a/libraries/xcode.rb +++ b/libraries/xcode.rb @@ -1,59 +1,71 @@ +include Chef::Mixin::ShellOut + module MacOS - module XcodeHelpers - def xcversion_command - '/opt/chef/embedded/bin/xcversion'.freeze - end + module XCVersion + class << self + def command + '/opt/chef/embedded/bin/xcversion'.freeze + end - def xcode_already_installed?(semantic_version) - xcversion_output = shell_out("#{xcversion_command} installed").stdout.split - installed_xcodes = xcversion_output.values_at(*xcversion_output.each_index.select(&:even?)) - installed_xcodes.include?(semantic_version) + def version(semantic_version) + split_version = semantic_version.split('.') + if split_version.length == 2 && split_version.last == '0' + split_version.first + else + semantic_version + end + end end + end - def xcversion_version(semantic_version) - split_version = semantic_version.split('.') - if split_version.length == 2 && split_version.last == '0' - split_version.first - else - semantic_version + module Xcode + class << self + def installed?(semantic_version) + xcversion_output = shell_out("#{XCVersion.command} installed").stdout.split + installed_xcodes = xcversion_output.values_at(*xcversion_output.each_index.select(&:even?)) + installed_xcodes.include?(semantic_version) end - end - def requested_xcode_not_at_path - xcode_version = '/Applications/Xcode.app/Contents/version.plist CFBundleShortVersionString' - node['macos']['xcode']['version'] != shell_out("defaults read #{xcode_version}").stdout.strip - end + def bundle_version_correct? + xcode_version = '/Applications/Xcode.app/Contents/version.plist CFBundleShortVersionString' + node['macos']['xcode']['version'] == shell_out("defaults read #{xcode_version}").stdout.strip + end - def simulator_already_installed?(semantic_version) - available_simulator_versions.include?("#{semantic_version} Simulator (installed)") - end + module Simulator + class << self + def installed?(semantic_version) + available_simulator_versions.include?("#{semantic_version} Simulator (installed)") + end - def highest_semantic_simulator_version(major_version, simulators) - requirement = Gem::Dependency.new('iOS', "~> #{major_version}") - highest = simulators.select { |name, vers| requirement.match?(name, vers) }.max - if highest.nil? - Chef::Application.fatal!("iOS #{major_version} Simulator no longer available from Apple!") - else - highest.join(' ') - end - end + def highest_semantic_version(major_version, simulators) + requirement = Gem::Dependency.new('iOS', "~> #{major_version}") + highest = simulators.select { |name, vers| requirement.match?(name, vers) }.max + if highest.nil? + Chef::Application.fatal!("iOS #{major_version} Simulator no longer available from Apple!") + else + highest.join(' ') + end + end - def included_simulator_major_version - version_matcher = /\d{1,2}\.\d{0,2}\.?\d{0,3}/ - sdks = shell_out!('/usr/bin/xcodebuild -showsdks').stdout - included_simulator = sdks.match(/Simulator - iOS (?#{version_matcher})/) - included_simulator[:version].split('.').first.to_i - end + def included_major_version + version_matcher = /\d{1,2}\.\d{0,2}\.?\d{0,3}/ + sdks = shell_out!('/usr/bin/xcodebuild -showsdks').stdout + included_simulator = sdks.match(/Simulator - iOS (?#{version_matcher})/) + included_simulator[:version].split('.').first.to_i + end - def simulator_list - available_simulator_versions.split(/\n/).map { |version| version.split[0...2] } - end + def list + available_simulator_versions.split(/\n/).map { |version| version.split[0...2] } + end - def available_simulator_versions - shell_out!("#{xcversion_command} simulators").stdout + def available_versions + shell_out!("#{XCVersion.command} simulators").stdout + end + end + end end end end -Chef::Recipe.include(MacOS::XcodeHelpers) -Chef::Resource.include(MacOS::XcodeHelpers) +Chef::Recipe.include(MacOS) +Chef::Resource.include(MacOS) From 4a135c3259c10479c9965d039ae9e62120726b10 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Wed, 6 Dec 2017 13:45:00 -0800 Subject: [PATCH 34/83] updated method calls for new modules --- resources/xcode.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/resources/xcode.rb b/resources/xcode.rb index 2d5fe7fe..de37ee94 100644 --- a/resources/xcode.rb +++ b/resources/xcode.rb @@ -21,26 +21,26 @@ execute 'update available Xcode versions' do environment DEVELOPER_CREDENTIALS - command "#{xcversion_command} update" + command "#{XCVersion.command} update" end execute "install Xcode #{new_resource.version}" do environment DEVELOPER_CREDENTIALS - command "#{xcversion_command} install '#{xcversion_version(new_resource.version)}'" - not_if { xcode_already_installed?(new_resource.version) } + command "#{XCVersion.command} install '#{XCVersion.version(new_resource.version)}'" + not_if { Xcode.installed?(new_resource.version) } end end action :install_simulators do if new_resource.ios_simulators new_resource.ios_simulators.each do |major_version| - next if major_version.to_i >= included_simulator_major_version - version = highest_semantic_simulator_version(major_version, simulator_list) + next if major_version.to_i >= Xcode::Simulator.included_major_version + version = Xcode::Simulator.highest_semantic_version(major_version, Xcode::Simulator.list) execute "install latest iOS #{major_version} Simulator" do environment DEVELOPER_CREDENTIALS - command "#{xcversion_command} simulators --install='#{version}'" - not_if { simulator_already_installed?(version) } + command "#{XCVersion.command} simulators --install='#{version}'" + not_if { Xcode::Simulator.installed?(version) } end end end From 4c68868d9e91808c4f1ca59f0f5805168ec6f7c5 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Wed, 6 Dec 2017 14:06:49 -0800 Subject: [PATCH 35/83] bump version --- metadata.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metadata.rb b/metadata.rb index c30c2fc6..0576e950 100644 --- a/metadata.rb +++ b/metadata.rb @@ -5,7 +5,7 @@ description 'Resources for configuring and provisioning macOS' long_description 'Resources for configuring and provisioning macOS' chef_version '~> 13.0' if respond_to?(:chef_version) -version '0.10.1' +version '0.12.0' source_url 'https://github.com/Microsoft/macos-cookbook' issues_url 'https://github.com/Microsoft/macos-cookbook/issues' From 9209e482de3e11a6e507686aacb68201d621d022 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Wed, 6 Dec 2017 14:11:13 -0800 Subject: [PATCH 36/83] extract xcversion module to separate library file --- libraries/xcode.rb | 91 +++++++++++++++++------------------------- libraries/xcversion.rb | 21 ++++++++++ 2 files changed, 57 insertions(+), 55 deletions(-) create mode 100644 libraries/xcversion.rb diff --git a/libraries/xcode.rb b/libraries/xcode.rb index 22fca303..8563b2f4 100644 --- a/libraries/xcode.rb +++ b/libraries/xcode.rb @@ -1,71 +1,52 @@ include Chef::Mixin::ShellOut -module MacOS - module XCVersion - class << self - def command - '/opt/chef/embedded/bin/xcversion'.freeze - end - - def version(semantic_version) - split_version = semantic_version.split('.') - if split_version.length == 2 && split_version.last == '0' - split_version.first - else - semantic_version - end - end +module Xcode + class << self + def installed?(semantic_version) + xcversion_output = shell_out("#{XCVersion.command} installed").stdout.split + installed_xcodes = xcversion_output.values_at(*xcversion_output.each_index.select(&:even?)) + installed_xcodes.include?(semantic_version) end - end - module Xcode - class << self - def installed?(semantic_version) - xcversion_output = shell_out("#{XCVersion.command} installed").stdout.split - installed_xcodes = xcversion_output.values_at(*xcversion_output.each_index.select(&:even?)) - installed_xcodes.include?(semantic_version) - end - - def bundle_version_correct? - xcode_version = '/Applications/Xcode.app/Contents/version.plist CFBundleShortVersionString' - node['macos']['xcode']['version'] == shell_out("defaults read #{xcode_version}").stdout.strip - end + def bundle_version_correct? + xcode_version = '/Applications/Xcode.app/Contents/version.plist CFBundleShortVersionString' + node['macos']['xcode']['version'] == shell_out("defaults read #{xcode_version}").stdout.strip + end - module Simulator - class << self - def installed?(semantic_version) - available_simulator_versions.include?("#{semantic_version} Simulator (installed)") - end + module Simulator + class << self + def installed?(semantic_version) + available_simulator_versions.include?("#{semantic_version} Simulator (installed)") + end - def highest_semantic_version(major_version, simulators) - requirement = Gem::Dependency.new('iOS', "~> #{major_version}") - highest = simulators.select { |name, vers| requirement.match?(name, vers) }.max - if highest.nil? - Chef::Application.fatal!("iOS #{major_version} Simulator no longer available from Apple!") - else - highest.join(' ') - end + def highest_semantic_version(major_version, simulators) + requirement = Gem::Dependency.new('iOS', "~> #{major_version}") + highest = simulators.select { |name, vers| requirement.match?(name, vers) }.max + if highest.nil? + Chef::Application.fatal!("iOS #{major_version} Simulator no longer available from Apple!") + else + highest.join(' ') end + end - def included_major_version - version_matcher = /\d{1,2}\.\d{0,2}\.?\d{0,3}/ - sdks = shell_out!('/usr/bin/xcodebuild -showsdks').stdout - included_simulator = sdks.match(/Simulator - iOS (?#{version_matcher})/) - included_simulator[:version].split('.').first.to_i - end + def included_major_version + version_matcher = /\d{1,2}\.\d{0,2}\.?\d{0,3}/ + sdks = shell_out!('/usr/bin/xcodebuild -showsdks').stdout + included_simulator = sdks.match(/Simulator - iOS (?#{version_matcher})/) + included_simulator[:version].split('.').first.to_i + end - def list - available_simulator_versions.split(/\n/).map { |version| version.split[0...2] } - end + def list + available_simulator_versions.split(/\n/).map { |version| version.split[0...2] } + end - def available_versions - shell_out!("#{XCVersion.command} simulators").stdout - end + def available_versions + shell_out!("#{XCVersion.command} simulators").stdout end end end end end -Chef::Recipe.include(MacOS) -Chef::Resource.include(MacOS) +Chef::Recipe.include(MacOS::Xcode) +Chef::Resource.include(MacOS::Xcode) diff --git a/libraries/xcversion.rb b/libraries/xcversion.rb new file mode 100644 index 00000000..4056a50c --- /dev/null +++ b/libraries/xcversion.rb @@ -0,0 +1,21 @@ +module MacOS + module XCVersion + class << self + def command + '/opt/chef/embedded/bin/xcversion'.freeze + end + + def version(semantic_version) + split_version = semantic_version.split('.') + if split_version.length == 2 && split_version.last == '0' + split_version.first + else + semantic_version + end + end + end + end +end + +Chef::Recipe.include(MacOS::XCVersion) +Chef::Resource.include(MacOS::XCVersion) From f4c456bef19718eda4fdd5f7d12720b2c5017277 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Wed, 6 Dec 2017 14:20:07 -0800 Subject: [PATCH 37/83] add missing macos module --- libraries/xcode.rb | 72 ++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/libraries/xcode.rb b/libraries/xcode.rb index 8563b2f4..6dfe36a4 100644 --- a/libraries/xcode.rb +++ b/libraries/xcode.rb @@ -1,47 +1,49 @@ include Chef::Mixin::ShellOut -module Xcode - class << self - def installed?(semantic_version) - xcversion_output = shell_out("#{XCVersion.command} installed").stdout.split - installed_xcodes = xcversion_output.values_at(*xcversion_output.each_index.select(&:even?)) - installed_xcodes.include?(semantic_version) - end +module MacOS + module Xcode + class << self + def installed?(semantic_version) + xcversion_output = shell_out("#{XCVersion.command} installed").stdout.split + installed_xcodes = xcversion_output.values_at(*xcversion_output.each_index.select(&:even?)) + installed_xcodes.include?(semantic_version) + end - def bundle_version_correct? - xcode_version = '/Applications/Xcode.app/Contents/version.plist CFBundleShortVersionString' - node['macos']['xcode']['version'] == shell_out("defaults read #{xcode_version}").stdout.strip - end + def bundle_version_correct? + xcode_version = '/Applications/Xcode.app/Contents/version.plist CFBundleShortVersionString' + node['macos']['xcode']['version'] == shell_out("defaults read #{xcode_version}").stdout.strip + end - module Simulator - class << self - def installed?(semantic_version) - available_simulator_versions.include?("#{semantic_version} Simulator (installed)") - end + module Simulator + class << self + def installed?(semantic_version) + available_simulator_versions.include?("#{semantic_version} Simulator (installed)") + end - def highest_semantic_version(major_version, simulators) - requirement = Gem::Dependency.new('iOS', "~> #{major_version}") - highest = simulators.select { |name, vers| requirement.match?(name, vers) }.max - if highest.nil? - Chef::Application.fatal!("iOS #{major_version} Simulator no longer available from Apple!") - else - highest.join(' ') + def highest_semantic_version(major_version, simulators) + requirement = Gem::Dependency.new('iOS', "~> #{major_version}") + highest = simulators.select { |name, vers| requirement.match?(name, vers) }.max + if highest.nil? + Chef::Application.fatal!("iOS #{major_version} Simulator no longer available from Apple!") + else + highest.join(' ') + end end - end - def included_major_version - version_matcher = /\d{1,2}\.\d{0,2}\.?\d{0,3}/ - sdks = shell_out!('/usr/bin/xcodebuild -showsdks').stdout - included_simulator = sdks.match(/Simulator - iOS (?#{version_matcher})/) - included_simulator[:version].split('.').first.to_i - end + def included_major_version + version_matcher = /\d{1,2}\.\d{0,2}\.?\d{0,3}/ + sdks = shell_out!('/usr/bin/xcodebuild -showsdks').stdout + included_simulator = sdks.match(/Simulator - iOS (?#{version_matcher})/) + included_simulator[:version].split('.').first.to_i + end - def list - available_simulator_versions.split(/\n/).map { |version| version.split[0...2] } - end + def list + available_simulator_versions.split(/\n/).map { |version| version.split[0...2] } + end - def available_versions - shell_out!("#{XCVersion.command} simulators").stdout + def available_versions + shell_out!("#{XCVersion.command} simulators").stdout + end end end end From cb4ea6977179a537b7acc890cc30e051ea7a9e10 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Wed, 6 Dec 2017 14:49:01 -0800 Subject: [PATCH 38/83] include parent module macos instead of child for xcode and xcversion --- libraries/xcode.rb | 54 +++++++++++++++++++++--------------------- libraries/xcversion.rb | 4 ++-- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/libraries/xcode.rb b/libraries/xcode.rb index 6dfe36a4..b1247501 100644 --- a/libraries/xcode.rb +++ b/libraries/xcode.rb @@ -13,42 +13,42 @@ def bundle_version_correct? xcode_version = '/Applications/Xcode.app/Contents/version.plist CFBundleShortVersionString' node['macos']['xcode']['version'] == shell_out("defaults read #{xcode_version}").stdout.strip end + end - module Simulator - class << self - def installed?(semantic_version) - available_simulator_versions.include?("#{semantic_version} Simulator (installed)") - end + module Simulator + class << self + def installed?(semantic_version) + available_simulator_versions.include?("#{semantic_version} Simulator (installed)") + end - def highest_semantic_version(major_version, simulators) - requirement = Gem::Dependency.new('iOS', "~> #{major_version}") - highest = simulators.select { |name, vers| requirement.match?(name, vers) }.max - if highest.nil? - Chef::Application.fatal!("iOS #{major_version} Simulator no longer available from Apple!") - else - highest.join(' ') - end + def highest_semantic_version(major_version, simulators) + requirement = Gem::Dependency.new('iOS', "~> #{major_version}") + highest = simulators.select { |name, vers| requirement.match?(name, vers) }.max + if highest.nil? + Chef::Application.fatal!("iOS #{major_version} Simulator no longer available from Apple!") + else + highest.join(' ') end + end - def included_major_version - version_matcher = /\d{1,2}\.\d{0,2}\.?\d{0,3}/ - sdks = shell_out!('/usr/bin/xcodebuild -showsdks').stdout - included_simulator = sdks.match(/Simulator - iOS (?#{version_matcher})/) - included_simulator[:version].split('.').first.to_i - end + def included_major_version + version_matcher = /\d{1,2}\.\d{0,2}\.?\d{0,3}/ + sdks = shell_out!('/usr/bin/xcodebuild -showsdks').stdout + included_simulator = sdks.match(/Simulator - iOS (?#{version_matcher})/) + included_simulator[:version].split('.').first.to_i + end - def list - available_simulator_versions.split(/\n/).map { |version| version.split[0...2] } - end + def list + available_simulator_versions.split(/\n/).map { |version| version.split[0...2] } + end - def available_versions - shell_out!("#{XCVersion.command} simulators").stdout - end + def available_versions + shell_out!("#{XCVersion.command} simulators").stdout end end end end end -Chef::Recipe.include(MacOS::Xcode) -Chef::Resource.include(MacOS::Xcode) +Chef::Recipe.include(MacOS) +Chef::Resource.include(MacOS) diff --git a/libraries/xcversion.rb b/libraries/xcversion.rb index 4056a50c..d6618ad8 100644 --- a/libraries/xcversion.rb +++ b/libraries/xcversion.rb @@ -17,5 +17,5 @@ def version(semantic_version) end end -Chef::Recipe.include(MacOS::XCVersion) -Chef::Resource.include(MacOS::XCVersion) +Chef::Recipe.include(MacOS) +Chef::Resource.include(MacOS) From 33fd038267dd5b076370cef298c7d096a4edbdc2 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Wed, 6 Dec 2017 15:09:56 -0800 Subject: [PATCH 39/83] update available_simulator_versions to new method --- libraries/xcode.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/xcode.rb b/libraries/xcode.rb index b1247501..d1d7ac38 100644 --- a/libraries/xcode.rb +++ b/libraries/xcode.rb @@ -18,7 +18,7 @@ def bundle_version_correct? module Simulator class << self def installed?(semantic_version) - available_simulator_versions.include?("#{semantic_version} Simulator (installed)") + available_versions.include?("#{semantic_version} Simulator (installed)") end def highest_semantic_version(major_version, simulators) @@ -39,7 +39,7 @@ def included_major_version end def list - available_simulator_versions.split(/\n/).map { |version| version.split[0...2] } + available_versions.split(/\n/).map { |version| version.split[0...2] } end def available_versions From 0baff896dbf4014ecfbcc1b29ad7b22dda28018a Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Fri, 8 Dec 2017 13:30:27 -0800 Subject: [PATCH 40/83] bump version --- metadata.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metadata.rb b/metadata.rb index 0576e950..f1427aa6 100644 --- a/metadata.rb +++ b/metadata.rb @@ -5,7 +5,7 @@ description 'Resources for configuring and provisioning macOS' long_description 'Resources for configuring and provisioning macOS' chef_version '~> 13.0' if respond_to?(:chef_version) -version '0.12.0' +version '0.12.1' source_url 'https://github.com/Microsoft/macos-cookbook' issues_url 'https://github.com/Microsoft/macos-cookbook/issues' From 417a9e6b8039ef9a3391f49c1e1ee965c61e6794 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Fri, 8 Dec 2017 13:31:02 -0800 Subject: [PATCH 41/83] add platform-specific smoke test for xcode --- .../macos_test/test/smoke/xcode/xcode_test.rb | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/test/cookbooks/macos_test/test/smoke/xcode/xcode_test.rb b/test/cookbooks/macos_test/test/smoke/xcode/xcode_test.rb index 25391e85..7f81d8eb 100644 --- a/test/cookbooks/macos_test/test/smoke/xcode/xcode_test.rb +++ b/test/cookbooks/macos_test/test/smoke/xcode/xcode_test.rb @@ -6,11 +6,22 @@ it { should be_symlink } end - describe directory('/Applications/Xcode-9.1.app') do - it { should exist } - end + if os[:release].match?(/10\.13/) || os[:release].match?(/10\.12/) + describe directory('/Applications/Xcode-9.2.app') do + it { should exist } + end + + describe command('/opt/chef/embedded/bin/xcversion simulators') do + its('stdout') { should match(/iOS 10\.3\.1 Simulator \(installed\)/) } + end + + elsif os[:release].match?(/10\.11/) + describe directory('/Applications/Xcode-8.2.1.app') do + it { should exist } + end - describe command('/opt/chef/embedded/bin/xcversion simulators') do - its('stdout') { should match(/iOS 10\.3\.1 Simulator \(installed\)/) } + describe command('/opt/chef/embedded/bin/xcversion simulators') do + its('stdout') { should match(/iOS 9\.3 Simulator \(installed\)/) } + end end end From c469799ca90b3d0cb41fe59fdcf9cafa7bfdc2e1 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Fri, 8 Dec 2017 13:31:11 -0800 Subject: [PATCH 42/83] add xcode test recipe --- test/cookbooks/macos_test/recipes/xcode.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 test/cookbooks/macos_test/recipes/xcode.rb diff --git a/test/cookbooks/macos_test/recipes/xcode.rb b/test/cookbooks/macos_test/recipes/xcode.rb new file mode 100644 index 00000000..197a4891 --- /dev/null +++ b/test/cookbooks/macos_test/recipes/xcode.rb @@ -0,0 +1,15 @@ +if node['platform_version'].match?(/10\.13/) || node['platform_version'].match?(/10\.12/) + execute 'Disable Gatekeeper' do + command 'spctl --master-disable' + end + + xcode '9.2' do + ios_simulators %w(11 10) + end + +elsif node['platform_version'].match?(/10\.11/) + + xcode '8.2.1' do + ios_simulators %w(10 9) + end +end From 1a4d685567725f284ab765322490812052041a5f Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Fri, 8 Dec 2017 13:31:52 -0800 Subject: [PATCH 43/83] update kitchen with xcode suite --- test/cookbooks/macos_test/.kitchen.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/cookbooks/macos_test/.kitchen.yml b/test/cookbooks/macos_test/.kitchen.yml index bba0d575..199f0791 100644 --- a/test/cookbooks/macos_test/.kitchen.yml +++ b/test/cookbooks/macos_test/.kitchen.yml @@ -2,6 +2,9 @@ driver: name: vagrant provider: parallels + customize: + memory: 10240 + cpus: 8 provisioner: name: chef_zero @@ -29,9 +32,7 @@ suites: - name: xcode run_list: - - recipe[macos::xcode] - excludes: - - apex/macos-10.11.6 + - recipe[macos_test::xcode] verifier: inspec_tests: - test/smoke/xcode From 34886e9f5f8bd9a14fca5cfe4ce6011313a4a8a1 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Fri, 8 Dec 2017 13:32:50 -0800 Subject: [PATCH 44/83] refactor simulator method to call it's own available list of simulators --- libraries/xcode.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/xcode.rb b/libraries/xcode.rb index d1d7ac38..b729d52f 100644 --- a/libraries/xcode.rb +++ b/libraries/xcode.rb @@ -21,9 +21,9 @@ def installed?(semantic_version) available_versions.include?("#{semantic_version} Simulator (installed)") end - def highest_semantic_version(major_version, simulators) + def highest_semantic_version(major_version) requirement = Gem::Dependency.new('iOS', "~> #{major_version}") - highest = simulators.select { |name, vers| requirement.match?(name, vers) }.max + highest = available_list.select { |name, vers| requirement.match?(name, vers) }.max if highest.nil? Chef::Application.fatal!("iOS #{major_version} Simulator no longer available from Apple!") else @@ -38,7 +38,7 @@ def included_major_version included_simulator[:version].split('.').first.to_i end - def list + def available_list available_versions.split(/\n/).map { |version| version.split[0...2] } end From 46aff7d2408e30ed0f38be82011d29b2254eb636 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Fri, 8 Dec 2017 13:33:31 -0800 Subject: [PATCH 45/83] use new simulator method to find highest available version --- resources/xcode.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/xcode.rb b/resources/xcode.rb index de37ee94..33c6e1f6 100644 --- a/resources/xcode.rb +++ b/resources/xcode.rb @@ -35,7 +35,7 @@ if new_resource.ios_simulators new_resource.ios_simulators.each do |major_version| next if major_version.to_i >= Xcode::Simulator.included_major_version - version = Xcode::Simulator.highest_semantic_version(major_version, Xcode::Simulator.list) + version = Xcode::Simulator.highest_semantic_version(major_version) execute "install latest iOS #{major_version} Simulator" do environment DEVELOPER_CREDENTIALS From c353211b8baace07157cc7a20193e1e34173a43e Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Fri, 8 Dec 2017 13:34:02 -0800 Subject: [PATCH 46/83] move xcode prep work into the setup action --- resources/xcode.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/xcode.rb b/resources/xcode.rb index 33c6e1f6..5450d828 100644 --- a/resources/xcode.rb +++ b/resources/xcode.rb @@ -9,9 +9,7 @@ chef_gem 'xcode-install' do options('--no-document') end -end -action :install_xcode do CREDENTIALS_DATA_BAG = data_bag_item(:credentials, :apple_id) DEVELOPER_CREDENTIALS = { @@ -23,7 +21,9 @@ environment DEVELOPER_CREDENTIALS command "#{XCVersion.command} update" end +end +action :install_xcode do execute "install Xcode #{new_resource.version}" do environment DEVELOPER_CREDENTIALS command "#{XCVersion.command} install '#{XCVersion.version(new_resource.version)}'" From ada8f54b3aa081a96273df7418c91068b568b749 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Fri, 8 Dec 2017 16:28:32 -0800 Subject: [PATCH 47/83] clear kitchen customizations --- test/cookbooks/macos_test/.kitchen.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/cookbooks/macos_test/.kitchen.yml b/test/cookbooks/macos_test/.kitchen.yml index 199f0791..1fd2484a 100644 --- a/test/cookbooks/macos_test/.kitchen.yml +++ b/test/cookbooks/macos_test/.kitchen.yml @@ -2,9 +2,6 @@ driver: name: vagrant provider: parallels - customize: - memory: 10240 - cpus: 8 provisioner: name: chef_zero From 0d23c1f531d49ab762d4a3dea39f570990c8b2aa Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Fri, 8 Dec 2017 16:28:49 -0800 Subject: [PATCH 48/83] lazily evalutate ios simulator property --- test/cookbooks/macos_test/recipes/xcode.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cookbooks/macos_test/recipes/xcode.rb b/test/cookbooks/macos_test/recipes/xcode.rb index 197a4891..126a3fdb 100644 --- a/test/cookbooks/macos_test/recipes/xcode.rb +++ b/test/cookbooks/macos_test/recipes/xcode.rb @@ -4,12 +4,12 @@ end xcode '9.2' do - ios_simulators %w(11 10) + ios_simulators lazy { %w(11 10) } end elsif node['platform_version'].match?(/10\.11/) xcode '8.2.1' do - ios_simulators %w(10 9) + ios_simulators lazy { %w(10 9) } end end From 572a7e1b434a224fd6e012eb731cceead5323f96 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Fri, 8 Dec 2017 16:57:38 -0800 Subject: [PATCH 49/83] move lazy evaluation to simulator action in xcode resource --- resources/xcode.rb | 4 +--- test/cookbooks/macos_test/recipes/xcode.rb | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/resources/xcode.rb b/resources/xcode.rb index 5450d828..15dc5487 100644 --- a/resources/xcode.rb +++ b/resources/xcode.rb @@ -35,11 +35,9 @@ if new_resource.ios_simulators new_resource.ios_simulators.each do |major_version| next if major_version.to_i >= Xcode::Simulator.included_major_version - version = Xcode::Simulator.highest_semantic_version(major_version) - execute "install latest iOS #{major_version} Simulator" do environment DEVELOPER_CREDENTIALS - command "#{XCVersion.command} simulators --install='#{version}'" + command lazy { "#{XCVersion.command} simulators --install='#{Xcode::Simulator.highest_semantic_version(major_version)}'" } not_if { Xcode::Simulator.installed?(version) } end end diff --git a/test/cookbooks/macos_test/recipes/xcode.rb b/test/cookbooks/macos_test/recipes/xcode.rb index 126a3fdb..197a4891 100644 --- a/test/cookbooks/macos_test/recipes/xcode.rb +++ b/test/cookbooks/macos_test/recipes/xcode.rb @@ -4,12 +4,12 @@ end xcode '9.2' do - ios_simulators lazy { %w(11 10) } + ios_simulators %w(11 10) end elsif node['platform_version'].match?(/10\.11/) xcode '8.2.1' do - ios_simulators lazy { %w(10 9) } + ios_simulators %w(10 9) end end From d1e442a8da2026d7a1293df99fd34fbfae3a2447 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Sat, 9 Dec 2017 04:39:14 -0800 Subject: [PATCH 50/83] revert lazy execution --- resources/xcode.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/xcode.rb b/resources/xcode.rb index 15dc5487..74154412 100644 --- a/resources/xcode.rb +++ b/resources/xcode.rb @@ -35,9 +35,10 @@ if new_resource.ios_simulators new_resource.ios_simulators.each do |major_version| next if major_version.to_i >= Xcode::Simulator.included_major_version + version = Xcode::Simulator.highest_semantic_version(major_version) execute "install latest iOS #{major_version} Simulator" do environment DEVELOPER_CREDENTIALS - command lazy { "#{XCVersion.command} simulators --install='#{Xcode::Simulator.highest_semantic_version(major_version)}'" } + command "#{XCVersion.command} simulators --install='#{version}'" not_if { Xcode::Simulator.installed?(version) } end end From eae24ccd76ba7cf1ddb5e520480518340ff0c420 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Sat, 9 Dec 2017 04:39:46 -0800 Subject: [PATCH 51/83] warn and retry if simulator list is empty --- libraries/xcode.rb | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libraries/xcode.rb b/libraries/xcode.rb index b729d52f..80fab54b 100644 --- a/libraries/xcode.rb +++ b/libraries/xcode.rb @@ -23,11 +23,17 @@ def installed?(semantic_version) def highest_semantic_version(major_version) requirement = Gem::Dependency.new('iOS', "~> #{major_version}") - highest = available_list.select { |name, vers| requirement.match?(name, vers) }.max - if highest.nil? - Chef::Application.fatal!("iOS #{major_version} Simulator no longer available from Apple!") + if available_list.empty? + Chef::Log.error('iOS simulator list not populated yet, refreshing...') + shell_out('sleep 20') + highest_semantic_version(major_version) else - highest.join(' ') + highest = available_list.select { |name, vers| requirement.match?(name, vers) }.max + if highest.nil? + Chef::Application.fatal!("iOS #{major_version} Simulator no longer available from Apple!") + else + highest.join(' ') + end end end From 66434f3ac96ebbd6fdefbec6a0be0e1c896b5717 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Sat, 9 Dec 2017 12:45:58 -0800 Subject: [PATCH 52/83] restore spacing --- resources/xcode.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/xcode.rb b/resources/xcode.rb index 74154412..87cecfb0 100644 --- a/resources/xcode.rb +++ b/resources/xcode.rb @@ -36,6 +36,7 @@ new_resource.ios_simulators.each do |major_version| next if major_version.to_i >= Xcode::Simulator.included_major_version version = Xcode::Simulator.highest_semantic_version(major_version) + execute "install latest iOS #{major_version} Simulator" do environment DEVELOPER_CREDENTIALS command "#{XCVersion.command} simulators --install='#{version}'" From 4c33b962f8b89779388343342099d674e691ce87 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Sat, 9 Dec 2017 12:46:50 -0800 Subject: [PATCH 53/83] more whitespace --- resources/xcode.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/xcode.rb b/resources/xcode.rb index 87cecfb0..5450d828 100644 --- a/resources/xcode.rb +++ b/resources/xcode.rb @@ -36,7 +36,7 @@ new_resource.ios_simulators.each do |major_version| next if major_version.to_i >= Xcode::Simulator.included_major_version version = Xcode::Simulator.highest_semantic_version(major_version) - + execute "install latest iOS #{major_version} Simulator" do environment DEVELOPER_CREDENTIALS command "#{XCVersion.command} simulators --install='#{version}'" From baf7ff3ebf9ab2c8652be716b48148f645faf43f Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Mon, 11 Dec 2017 13:29:48 -0800 Subject: [PATCH 54/83] refactor highest_semantic_simulator method into class, smaller methods --- libraries/xcode.rb | 55 ++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/libraries/xcode.rb b/libraries/xcode.rb index 80fab54b..7d2a876f 100644 --- a/libraries/xcode.rb +++ b/libraries/xcode.rb @@ -15,26 +15,37 @@ def bundle_version_correct? end end - module Simulator - class << self - def installed?(semantic_version) - available_versions.include?("#{semantic_version} Simulator (installed)") + class Simulator + attr_reader :version + + def initialize(major_version) + while available_list.empty? + Chef::Log.warn('iOS Simulator list not populated yet') + sleep 10 end + if latest_semantic_version(major_version).nil? + Chef::Application.fatal!("iOS #{major_version} Simulator no longer available from Apple!") + else + @version = latest_semantic_version(major_version).join(' ') + end + end + + def available_versions + shell_out!("#{XCVersion.command} simulators").stdout + end + + def available_list + available_versions.split(/\n/).map { |version| version.split[0...2] } + end - def highest_semantic_version(major_version) - requirement = Gem::Dependency.new('iOS', "~> #{major_version}") - if available_list.empty? - Chef::Log.error('iOS simulator list not populated yet, refreshing...') - shell_out('sleep 20') - highest_semantic_version(major_version) - else - highest = available_list.select { |name, vers| requirement.match?(name, vers) }.max - if highest.nil? - Chef::Application.fatal!("iOS #{major_version} Simulator no longer available from Apple!") - else - highest.join(' ') - end - end + def latest_semantic_version(major_version) + requirement = Gem::Dependency.new('iOS', "~> #{major_version}") + available_list.select { |platform, version| requirement.match?(platform, version) }.max + end + + class << self + def installed?(semantic_version) + shell_out!("#{XCVersion.command} simulators").stdout.include?("#{semantic_version} Simulator (installed)") end def included_major_version @@ -43,14 +54,6 @@ def included_major_version included_simulator = sdks.match(/Simulator - iOS (?#{version_matcher})/) included_simulator[:version].split('.').first.to_i end - - def available_list - available_versions.split(/\n/).map { |version| version.split[0...2] } - end - - def available_versions - shell_out!("#{XCVersion.command} simulators").stdout - end end end end From 54a546471b27f100aeb3186503a82ee70fcc61c6 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Mon, 11 Dec 2017 13:30:01 -0800 Subject: [PATCH 55/83] implement simulator class --- resources/xcode.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/xcode.rb b/resources/xcode.rb index 5450d828..647ff555 100644 --- a/resources/xcode.rb +++ b/resources/xcode.rb @@ -35,7 +35,7 @@ if new_resource.ios_simulators new_resource.ios_simulators.each do |major_version| next if major_version.to_i >= Xcode::Simulator.included_major_version - version = Xcode::Simulator.highest_semantic_version(major_version) + version = Xcode::Simulator.new(major_version).version execute "install latest iOS #{major_version} Simulator" do environment DEVELOPER_CREDENTIALS From 35f6caad87a617e5b4a7108c8c47c8c026fbe7f8 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Mon, 11 Dec 2017 13:47:20 -0800 Subject: [PATCH 56/83] add more xcversion command methods --- libraries/xcversion.rb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libraries/xcversion.rb b/libraries/xcversion.rb index d6618ad8..7a90f1ba 100644 --- a/libraries/xcversion.rb +++ b/libraries/xcversion.rb @@ -5,7 +5,19 @@ def command '/opt/chef/embedded/bin/xcversion'.freeze end - def version(semantic_version) + def update + command + ' update' + end + + def install_simulator(version) + command + " simulators --install='#{version}'" + end + + def install_xcode(version) + command + " install '#{apple_pseudosemantic_version(version)}'" + end + + def apple_pseudosemantic_version(semantic_version) split_version = semantic_version.split('.') if split_version.length == 2 && split_version.last == '0' split_version.first From eeeb24de387ec790c7618701ce27b679ec970f88 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Mon, 11 Dec 2017 13:47:33 -0800 Subject: [PATCH 57/83] implement xcversion command methods --- resources/xcode.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/xcode.rb b/resources/xcode.rb index 647ff555..9825452a 100644 --- a/resources/xcode.rb +++ b/resources/xcode.rb @@ -19,14 +19,14 @@ execute 'update available Xcode versions' do environment DEVELOPER_CREDENTIALS - command "#{XCVersion.command} update" + command XCVersion.command.update end end action :install_xcode do execute "install Xcode #{new_resource.version}" do environment DEVELOPER_CREDENTIALS - command "#{XCVersion.command} install '#{XCVersion.version(new_resource.version)}'" + command XCVersion.command.install_xcode not_if { Xcode.installed?(new_resource.version) } end end @@ -39,7 +39,7 @@ execute "install latest iOS #{major_version} Simulator" do environment DEVELOPER_CREDENTIALS - command "#{XCVersion.command} simulators --install='#{version}'" + command XCVersion.install_simulator(version) not_if { Xcode::Simulator.installed?(version) } end end From 3412dce405d9616e51a7d139e62db570337ef640 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Mon, 11 Dec 2017 13:48:50 -0800 Subject: [PATCH 58/83] implement command methods correctly --- resources/xcode.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/xcode.rb b/resources/xcode.rb index 9825452a..5349af6d 100644 --- a/resources/xcode.rb +++ b/resources/xcode.rb @@ -19,14 +19,14 @@ execute 'update available Xcode versions' do environment DEVELOPER_CREDENTIALS - command XCVersion.command.update + command XCVersion.update end end action :install_xcode do execute "install Xcode #{new_resource.version}" do environment DEVELOPER_CREDENTIALS - command XCVersion.command.install_xcode + command XCVersion.install_xcode not_if { Xcode.installed?(new_resource.version) } end end From 64f710bfab228052b29f570ae9747fcf7070443d Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Mon, 11 Dec 2017 13:56:44 -0800 Subject: [PATCH 59/83] add list methods for xcversion --- libraries/xcversion.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libraries/xcversion.rb b/libraries/xcversion.rb index 7a90f1ba..2d430319 100644 --- a/libraries/xcversion.rb +++ b/libraries/xcversion.rb @@ -9,10 +9,18 @@ def update command + ' update' end + def list_simulators + command + ' simulators' + end + def install_simulator(version) command + " simulators --install='#{version}'" end + def list_xcodes + command + ' list' + end + def install_xcode(version) command + " install '#{apple_pseudosemantic_version(version)}'" end From a6b4e2e1e7d9e5c11390885412692c3312e88234 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Mon, 11 Dec 2017 13:57:04 -0800 Subject: [PATCH 60/83] implement xcversion list methods --- libraries/xcode.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/xcode.rb b/libraries/xcode.rb index 7d2a876f..6a3bdf19 100644 --- a/libraries/xcode.rb +++ b/libraries/xcode.rb @@ -31,11 +31,11 @@ def initialize(major_version) end def available_versions - shell_out!("#{XCVersion.command} simulators").stdout + shell_out!(XCVersion.list_simulators).stdout end def available_list - available_versions.split(/\n/).map { |version| version.split[0...2] } + available_versions.split(/\n/).map { |version| version.split[0..1] } end def latest_semantic_version(major_version) @@ -45,7 +45,8 @@ def latest_semantic_version(major_version) class << self def installed?(semantic_version) - shell_out!("#{XCVersion.command} simulators").stdout.include?("#{semantic_version} Simulator (installed)") + shell_out!(XCVersion.list_simulators) + .stdout.include?("#{semantic_version} Simulator (installed)") end def included_major_version From 79a1150ccdf712348dd1163542e6b13e67f372c7 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Mon, 11 Dec 2017 13:59:04 -0800 Subject: [PATCH 61/83] implement install xcode correctly --- resources/xcode.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/xcode.rb b/resources/xcode.rb index 5349af6d..575076e9 100644 --- a/resources/xcode.rb +++ b/resources/xcode.rb @@ -26,7 +26,7 @@ action :install_xcode do execute "install Xcode #{new_resource.version}" do environment DEVELOPER_CREDENTIALS - command XCVersion.install_xcode + command XCVersion.install_xcode(new_resource.version) not_if { Xcode.installed?(new_resource.version) } end end From b10adfbf36f9e062c7d008a4d504e320b608b28a Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Mon, 11 Dec 2017 14:04:02 -0800 Subject: [PATCH 62/83] reorder methods --- libraries/xcode.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/xcode.rb b/libraries/xcode.rb index 6a3bdf19..32b2a7fc 100644 --- a/libraries/xcode.rb +++ b/libraries/xcode.rb @@ -30,17 +30,17 @@ def initialize(major_version) end end - def available_versions - shell_out!(XCVersion.list_simulators).stdout + def latest_semantic_version(major_version) + requirement = Gem::Dependency.new('iOS', "~> #{major_version}") + available_list.select { |platform, version| requirement.match?(platform, version) }.max end def available_list available_versions.split(/\n/).map { |version| version.split[0..1] } end - def latest_semantic_version(major_version) - requirement = Gem::Dependency.new('iOS', "~> #{major_version}") - available_list.select { |platform, version| requirement.match?(platform, version) }.max + def available_versions + shell_out!(XCVersion.list_simulators).stdout end class << self From 54f2e4619008dff9bfd9bf67825ea062efb81923 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Mon, 11 Dec 2017 14:06:29 -0800 Subject: [PATCH 63/83] add method to list installed xcodes --- libraries/xcversion.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/xcversion.rb b/libraries/xcversion.rb index 2d430319..4f7e7c85 100644 --- a/libraries/xcversion.rb +++ b/libraries/xcversion.rb @@ -23,6 +23,8 @@ def list_xcodes def install_xcode(version) command + " install '#{apple_pseudosemantic_version(version)}'" + def installed_xcodes + xcversion + ' installed' end def apple_pseudosemantic_version(semantic_version) From 890c71009279f90efed609d0cf5c48b661ce520b Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Mon, 11 Dec 2017 14:06:44 -0800 Subject: [PATCH 64/83] use more descriptive name for 'command' method --- libraries/xcversion.rb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libraries/xcversion.rb b/libraries/xcversion.rb index 4f7e7c85..8098a218 100644 --- a/libraries/xcversion.rb +++ b/libraries/xcversion.rb @@ -1,28 +1,30 @@ module MacOS module XCVersion class << self - def command + def xcversion '/opt/chef/embedded/bin/xcversion'.freeze end def update - command + ' update' + xcversion + ' update' end def list_simulators - command + ' simulators' + xcversion + ' simulators' end def install_simulator(version) - command + " simulators --install='#{version}'" + xcversion + " simulators --install='#{version}'" end def list_xcodes - command + ' list' + xcversion + ' list' end def install_xcode(version) - command + " install '#{apple_pseudosemantic_version(version)}'" + xcversion + " install '#{apple_pseudosemantic_version(version)}'" + end + def installed_xcodes xcversion + ' installed' end From 14f87381c71874539f0004d4ab35160ecb862a2f Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Mon, 11 Dec 2017 14:07:26 -0800 Subject: [PATCH 65/83] move where the space lives --- libraries/xcversion.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libraries/xcversion.rb b/libraries/xcversion.rb index 8098a218..58d9762d 100644 --- a/libraries/xcversion.rb +++ b/libraries/xcversion.rb @@ -2,31 +2,31 @@ module MacOS module XCVersion class << self def xcversion - '/opt/chef/embedded/bin/xcversion'.freeze + '/opt/chef/embedded/bin/xcversion '.freeze end def update - xcversion + ' update' + xcversion + 'update' end def list_simulators - xcversion + ' simulators' + xcversion + 'simulators' end def install_simulator(version) - xcversion + " simulators --install='#{version}'" + xcversion + "simulators --install='#{version}'" end def list_xcodes - xcversion + ' list' + xcversion + 'list' end def install_xcode(version) - xcversion + " install '#{apple_pseudosemantic_version(version)}'" + xcversion + "install '#{apple_pseudosemantic_version(version)}'" end def installed_xcodes - xcversion + ' installed' + xcversion + 'installed' end def apple_pseudosemantic_version(semantic_version) From 393923a2002aea141b68b16d6d59ccf0e7c1f4f9 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Mon, 11 Dec 2017 14:13:04 -0800 Subject: [PATCH 66/83] implement installed xcodes command --- libraries/xcode.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/xcode.rb b/libraries/xcode.rb index 32b2a7fc..35b5ff10 100644 --- a/libraries/xcode.rb +++ b/libraries/xcode.rb @@ -4,7 +4,7 @@ module MacOS module Xcode class << self def installed?(semantic_version) - xcversion_output = shell_out("#{XCVersion.command} installed").stdout.split + xcversion_output = shell_out(XCVersion.installed).stdout.split installed_xcodes = xcversion_output.values_at(*xcversion_output.each_index.select(&:even?)) installed_xcodes.include?(semantic_version) end From 947502080871de26e11665fe82be46f6f31bfdbc Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Mon, 11 Dec 2017 14:22:39 -0800 Subject: [PATCH 67/83] implement install xcodes correctly --- libraries/xcode.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/xcode.rb b/libraries/xcode.rb index 35b5ff10..1fb86794 100644 --- a/libraries/xcode.rb +++ b/libraries/xcode.rb @@ -4,7 +4,7 @@ module MacOS module Xcode class << self def installed?(semantic_version) - xcversion_output = shell_out(XCVersion.installed).stdout.split + xcversion_output = shell_out(XCVersion.installed_xcodes).stdout.split installed_xcodes = xcversion_output.values_at(*xcversion_output.each_index.select(&:even?)) installed_xcodes.include?(semantic_version) end From 4c797a2bef5b82c04eac8246bbe36f571eaec2d6 Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Tue, 12 Dec 2017 10:36:44 -0800 Subject: [PATCH 68/83] disable downloads prior to disabling software update check --- recipes/disable_software_updates.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/recipes/disable_software_updates.rb b/recipes/disable_software_updates.rb index 68a6fcd5..d8711060 100644 --- a/recipes/disable_software_updates.rb +++ b/recipes/disable_software_updates.rb @@ -1,11 +1,11 @@ -plist 'disable automatic software update check' do +plist 'disable automatic software update downloads' do path '/Library/Preferences/com.apple.SoftwareUpdate.plist' - entry 'AutomaticCheckEnabled' + entry 'AutomaticDownload' value false end -plist 'disable automatic software update downloads' do +plist 'disable automatic software update check' do path '/Library/Preferences/com.apple.SoftwareUpdate.plist' - entry 'AutomaticDownload' + entry 'AutomaticCheckEnabled' value false end From e91ddbbd2aa6241bb1446d913e21cd9065a16e57 Mon Sep 17 00:00:00 2001 From: Mark John Merin Date: Tue, 12 Dec 2017 10:44:37 -0800 Subject: [PATCH 69/83] Renamed name to device_name --- resources/name.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/name.rb b/resources/name.rb index 93061497..3d30ed3e 100644 --- a/resources/name.rb +++ b/resources/name.rb @@ -1,24 +1,24 @@ -resource_name :name +resource_name :device_name default_action :run BASE_COMMAND = '/usr/sbin/scutil'.freeze SMB_SERVER_PLIST = '/Library/Preferences/SystemConfiguration/com.apple.smb.server'.freeze -property :name, String, name_property: true +property :device_name, String, name_property: true # We cannot set the LocalHostName here because it does not conform to # the DNS standards outlined in RFC 1034 (section 3.5) action :run do execute BASE_COMMAND do - command "#{BASE_COMMAND} --set HostName '#{new_resource.name}'" + command "#{BASE_COMMAND} --set HostName '#{new_resource.device_name}'" end execute BASE_COMMAND do - command "#{BASE_COMMAND} --set ComputerName '#{new_resource.name}'" + command "#{BASE_COMMAND} --set ComputerName '#{new_resource.device_name}'" end defaults SMB_SERVER_PLIST do - settings 'NetBIOSName' => new_resource.name + settings 'NetBIOSName' => new_resource.device_name end end From 0dc51376d7dc9df43e7546a79df6f676ce32f39b Mon Sep 17 00:00:00 2001 From: Mark John Merin Date: Tue, 12 Dec 2017 12:54:03 -0800 Subject: [PATCH 70/83] Change name.rb to machine_name.rb to be similar with the apex automation cookbook. Instances of name are also all changed to machine_name. --- resources/{name.rb => machine_name.rb} | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) rename resources/{name.rb => machine_name.rb} (67%) diff --git a/resources/name.rb b/resources/machine_name.rb similarity index 67% rename from resources/name.rb rename to resources/machine_name.rb index 3d30ed3e..1b52d47b 100644 --- a/resources/name.rb +++ b/resources/machine_name.rb @@ -1,24 +1,24 @@ -resource_name :device_name +resource_name :machine_name default_action :run BASE_COMMAND = '/usr/sbin/scutil'.freeze SMB_SERVER_PLIST = '/Library/Preferences/SystemConfiguration/com.apple.smb.server'.freeze -property :device_name, String, name_property: true +property :machine_name, String, name_property: true # We cannot set the LocalHostName here because it does not conform to # the DNS standards outlined in RFC 1034 (section 3.5) action :run do execute BASE_COMMAND do - command "#{BASE_COMMAND} --set HostName '#{new_resource.device_name}'" + command "#{BASE_COMMAND} --set HostName '#{new_resource.machine_name}'" end execute BASE_COMMAND do - command "#{BASE_COMMAND} --set ComputerName '#{new_resource.device_name}'" + command "#{BASE_COMMAND} --set ComputerName '#{new_resource.machine_name}'" end defaults SMB_SERVER_PLIST do - settings 'NetBIOSName' => new_resource.device_name + settings 'NetBIOSName' => new_resource.machine_name end end From f42c1d78e10f313fee8f1168f44f9165b5cf3b08 Mon Sep 17 00:00:00 2001 From: Mark John Merin Date: Tue, 12 Dec 2017 15:54:56 -0800 Subject: [PATCH 71/83] Add new test recipe and smoke test for machine_name. --- test/cookbooks/macos_test/.kitchen.yml | 1 + .../cookbooks/macos_test/recipes/machine_name.rb | 1 + .../test/smoke/default/machine_name_test.rb | 16 ++++++++++++++++ 3 files changed, 18 insertions(+) create mode 100644 test/cookbooks/macos_test/recipes/machine_name.rb create mode 100644 test/cookbooks/macos_test/test/smoke/default/machine_name_test.rb diff --git a/test/cookbooks/macos_test/.kitchen.yml b/test/cookbooks/macos_test/.kitchen.yml index 1fd2484a..951fabb0 100644 --- a/test/cookbooks/macos_test/.kitchen.yml +++ b/test/cookbooks/macos_test/.kitchen.yml @@ -23,6 +23,7 @@ suites: - recipe[macos::disable_software_updates] - recipe[macos_test::new_users] - recipe[macos_test::preferences] + - recipe[macos_test::machine_name] verifier: inspec_tests: - test/smoke/default diff --git a/test/cookbooks/macos_test/recipes/machine_name.rb b/test/cookbooks/macos_test/recipes/machine_name.rb new file mode 100644 index 00000000..cce79fa7 --- /dev/null +++ b/test/cookbooks/macos_test/recipes/machine_name.rb @@ -0,0 +1 @@ +machine_name "New#{node['platform_version']}_Washing_Machine" diff --git a/test/cookbooks/macos_test/test/smoke/default/machine_name_test.rb b/test/cookbooks/macos_test/test/smoke/default/machine_name_test.rb new file mode 100644 index 00000000..f215c295 --- /dev/null +++ b/test/cookbooks/macos_test/test/smoke/default/machine_name_test.rb @@ -0,0 +1,16 @@ +control 'machine name' do + desc 'machine name is set to the format "New#{macos_semantic_version}_Washing_Machine"' + + macos_semantic_version = command('sw_vers -productVersion').stdout.strip + hostname_pattern = /New#{macos_semantic_version}_Washing_Machine/ + + hostname_commands = ['hostname', + 'scutil --get ComputerName', + 'scutil --get HostName'] + + hostname_commands.each do |hostname_command| + describe command(hostname_command) do + its('stdout') { should match hostname_pattern } + end + end +end From cc9085d7d5e1745a6234b0ba90f0145b8cc8be3a Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Tue, 12 Dec 2017 16:00:24 -0800 Subject: [PATCH 72/83] add disable-swu test suite --- test/cookbooks/macos_test/.kitchen.yml | 7 +++++ .../disable_software_updates_test.rb | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 test/cookbooks/macos_test/test/smoke/disable_swu/disable_software_updates_test.rb diff --git a/test/cookbooks/macos_test/.kitchen.yml b/test/cookbooks/macos_test/.kitchen.yml index 1fd2484a..a680d305 100644 --- a/test/cookbooks/macos_test/.kitchen.yml +++ b/test/cookbooks/macos_test/.kitchen.yml @@ -33,3 +33,10 @@ suites: verifier: inspec_tests: - test/smoke/xcode + + - name: disable-swu + run_list: + - recipe[macos::disable_software_updates] + verifier: + inspec_tests: + - test/smoke/disable_swu diff --git a/test/cookbooks/macos_test/test/smoke/disable_swu/disable_software_updates_test.rb b/test/cookbooks/macos_test/test/smoke/disable_swu/disable_software_updates_test.rb new file mode 100644 index 00000000..28c88f19 --- /dev/null +++ b/test/cookbooks/macos_test/test/smoke/disable_swu/disable_software_updates_test.rb @@ -0,0 +1,27 @@ +software_update_plist = '/Library/Preferences/com.apple.SoftwareUpdate.plist' +automatic_check_enabled = 'AutomaticCheckEnabled' +automatic_download = 'AutomaticDownload' + +describe command("/usr/libexec/PlistBuddy -c 'Print :#{automatic_check_enabled}' #{software_update_plist}") do + its('stdout') { should match('false') } +end + +describe command("/usr/libexec/PlistBuddy -c 'Print :#{automatic_download}' #{software_update_plist}") do + its('stdout') { should match('false') } +end + +describe command("/usr/bin/defaults read-type #{software_update_plist} #{automatic_download}") do + its('stdout') { should match('boolean') } +end + +describe command("/usr/bin/defaults read-type #{software_update_plist} #{automatic_check_enabled}") do + its('stdout') { should match('boolean') } +end + +describe command("/usr/bin/defaults read #{software_update_plist} #{automatic_download}") do + its('stdout') { should match('0') } +end + +describe command("/usr/bin/defaults read #{software_update_plist} #{automatic_check_enabled}") do + its('stdout') { should match('0') } +end From b1486629eed1bafab6534cb26fdfbb8f77dfdc6f Mon Sep 17 00:00:00 2001 From: Mark John Merin Date: Wed, 13 Dec 2017 10:01:07 -0800 Subject: [PATCH 73/83] Bump up cookbook version numbers. --- metadata.rb | 2 +- test/cookbooks/macos_test/metadata.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/metadata.rb b/metadata.rb index f1427aa6..d1581ab3 100644 --- a/metadata.rb +++ b/metadata.rb @@ -5,7 +5,7 @@ description 'Resources for configuring and provisioning macOS' long_description 'Resources for configuring and provisioning macOS' chef_version '~> 13.0' if respond_to?(:chef_version) -version '0.12.1' +version '0.12.2' source_url 'https://github.com/Microsoft/macos-cookbook' issues_url 'https://github.com/Microsoft/macos-cookbook/issues' diff --git a/test/cookbooks/macos_test/metadata.rb b/test/cookbooks/macos_test/metadata.rb index e7873071..bc2cd37a 100644 --- a/test/cookbooks/macos_test/metadata.rb +++ b/test/cookbooks/macos_test/metadata.rb @@ -1,4 +1,4 @@ name 'macos_test' -version '1.0.0' +version '1.0.1' depends 'macos' From cdcc0155a6f873139bd005a46f08795aba1c091e Mon Sep 17 00:00:00 2001 From: Jacob Zaval Date: Wed, 13 Dec 2017 14:50:36 -0800 Subject: [PATCH 74/83] update kitchen test suite order, remove standalone swu testing --- test/cookbooks/macos_test/.kitchen.yml | 9 +------ .../disable_software_updates_test.rb | 27 ------------------- 2 files changed, 1 insertion(+), 35 deletions(-) delete mode 100644 test/cookbooks/macos_test/test/smoke/disable_swu/disable_software_updates_test.rb diff --git a/test/cookbooks/macos_test/.kitchen.yml b/test/cookbooks/macos_test/.kitchen.yml index 524259dc..91711293 100644 --- a/test/cookbooks/macos_test/.kitchen.yml +++ b/test/cookbooks/macos_test/.kitchen.yml @@ -20,8 +20,8 @@ suites: - name: default run_list: - recipe[macos::keep_awake] - - recipe[macos::disable_software_updates] - recipe[macos_test::new_users] + - recipe[macos::disable_software_updates] - recipe[macos_test::preferences] - recipe[macos_test::machine_name] verifier: @@ -34,10 +34,3 @@ suites: verifier: inspec_tests: - test/smoke/xcode - - - name: disable-swu - run_list: - - recipe[macos::disable_software_updates] - verifier: - inspec_tests: - - test/smoke/disable_swu diff --git a/test/cookbooks/macos_test/test/smoke/disable_swu/disable_software_updates_test.rb b/test/cookbooks/macos_test/test/smoke/disable_swu/disable_software_updates_test.rb deleted file mode 100644 index 28c88f19..00000000 --- a/test/cookbooks/macos_test/test/smoke/disable_swu/disable_software_updates_test.rb +++ /dev/null @@ -1,27 +0,0 @@ -software_update_plist = '/Library/Preferences/com.apple.SoftwareUpdate.plist' -automatic_check_enabled = 'AutomaticCheckEnabled' -automatic_download = 'AutomaticDownload' - -describe command("/usr/libexec/PlistBuddy -c 'Print :#{automatic_check_enabled}' #{software_update_plist}") do - its('stdout') { should match('false') } -end - -describe command("/usr/libexec/PlistBuddy -c 'Print :#{automatic_download}' #{software_update_plist}") do - its('stdout') { should match('false') } -end - -describe command("/usr/bin/defaults read-type #{software_update_plist} #{automatic_download}") do - its('stdout') { should match('boolean') } -end - -describe command("/usr/bin/defaults read-type #{software_update_plist} #{automatic_check_enabled}") do - its('stdout') { should match('boolean') } -end - -describe command("/usr/bin/defaults read #{software_update_plist} #{automatic_download}") do - its('stdout') { should match('0') } -end - -describe command("/usr/bin/defaults read #{software_update_plist} #{automatic_check_enabled}") do - its('stdout') { should match('0') } -end From f2fb70ec4c0ff90938752becc204123e0a1599ea Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Wed, 13 Dec 2017 17:33:07 -0800 Subject: [PATCH 75/83] implement build definition badge and minor tweaks --- README.md | 55 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 208cc4df..8b01de5c 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,20 @@ -# macOS Cookbook +macOS Cookbook +============== -This cookbook provides: -- Resources for configuring and provisioning macOS. -- Recipes that implement common use-cases of the macOS cookbook's recources. +![build-status](https://office.visualstudio.com/_apis/public/build/definitions/59d72877-1cea-4eb6-9d06-66716573631a/2140/badge) -## Platforms +The macOS cookbook is a Chef library cookbook that provides resources for configuring +and provisioning macOS. Additionally, it provides recipes that implement common +use-cases of the macOS cookbook's recources. -- macOS - -## Chef +Requirements +------------ - Chef 13+ +- macOS -## Attributes +Attributes +---------- ### Admin User and Password @@ -25,30 +27,31 @@ Each of these attributes defaults to vagrant since our resources are developed with the Vagrant paradigm. In other words, the use and password declared here should be an admin user. -### Mono +### Xcode + +```ruby +node['macos']['xcode']['version'] = '9.2' +``` -_TODO_ +Recipes +------- ---- +- `disable_software_updates` +- `keep_awake` +- `mono` +- `xcode` +- `configurator` -## Resources +Resources +--------- - `ard` -- `name` +- `machine_name` - `defaults` - `pmset` - `systemsetup` - `xcode` +- `plist` -Checkout the [Wiki](https://github.com/Microsoft/macos-cookbook/wiki) for details about the macOS Cookbook resources. - ---- - -## Recipes - -- `disable_software_updates` -- `keep_awake` -- `mono` -- `configurator` - - +Checkout the [Wiki](https://github.com/Microsoft/macos-cookbook/wiki) for details +about the macOS Cookbook resources. From 3c66d4b194da53c9ea3edc60c30585415e3f1526 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Wed, 13 Dec 2017 21:17:48 -0800 Subject: [PATCH 76/83] Add descriptions and attribute lists for recipes --- .gitignore | 1 + README.md | 86 +++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 73 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index a7818a6b..de71f3ba 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,4 @@ Vagrantfile .rubocop.yml .vagrant data_bags +*.code-workspace diff --git a/README.md b/README.md index 8b01de5c..d74028d6 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,15 @@ use-cases of the macOS cookbook's recources. Requirements ------------ -- Chef 13+ -- macOS +- Only tested on Chef 13 +- Surprisingly, this cookbook is only compatible with macOS + +Supported OS X/macOS versions +----------------------------- + +- OS X El Capitan 10.11 +- macOS Sierra 10.12 +- macOS High Sierra 10.13 Attributes ---------- @@ -24,23 +31,74 @@ node['macos']['admin_password'] = 'vagrant' ``` Each of these attributes defaults to vagrant since our resources are developed -with the Vagrant paradigm. In other words, the use and password declared here -should be an admin user. +with the Vagrant paradigm. In other words, the user and password declared here +should be an admin user with passwordless super-user rights. + +Recipes +------- + +### Disable Software Updates + +**Usage:** `include_recipe macos::disable_software_updates` +**Description:** Disables automatic checking and downloading of software updates. + +No attributes used in this recipe. + +### Keep Awake + +**Usage:** `include_recipe macos::keep_awake` +**Description:** Prevent macOS from falling asleep, disable the screensaver, and +several other settings to always keep macOS on. Uses the `plistbuddy` and `pmset` +resources. + +| Attribute used | Default value | +|---------------------------------------|-------------------------| +| `node['macos']['network_time_server']`| `'time.windows.com'` | +| `node['macos']['time_zone']` | `'America/Los_Angeles'` | + +### Mono + +**Usage:** `include_recipe macos::mono` +**Description:** Installs [Mono](http://www.mono-project.com/docs/about-mono/). +Version 4.4.2 by default. + +| Attribute used | Default value | +|-------------------------------------|----------------------------------------| +| `node['macos']['mono']['package']` | `'MonoFramework-MDK-4.4.2.11.macos10.xamarin.universal.pkg'` | +| `node['macos']['mono']['version']` | `'4.4.2'` | +| `node['macos']['mono']['checksum']` | `'d8bfbee7ae4d0d1facaf0ddfb70c0de4b1a3d94bb1b4c38e8fa4884539f54e23'` | ### Xcode -```ruby -node['macos']['xcode']['version'] = '9.2' -``` +**Usage:** `include_recipe::xcode` +**Description:** Installs Xcode 9.2 and simulators for iOS 10 and iOS 11. Uses the +`xcode-install` gem. -Recipes -------- +| Attribute Used | Default value | +|---------------------------------------------------------------|---------------| +| `node['macos']['xcode']['version']` | `'9.1'` | +| `node['macos']['xcode']['simulator']['major_version']` | `%w(11 10)` | -- `disable_software_updates` -- `keep_awake` -- `mono` -- `xcode` -- `configurator` +### Apple Configurator 2 + +**Usage:** `include_recipe::configurator` + +**Description:** Installs Apple Configurator 2 using `mas` and links `cfgutil` to +`/usr/local/bin`. Requires a `data_bag_item` containing valid App Store credentials. + +**Attributes**: No attributes used in this recipe. + +#### Required Data Bag Items + +**Example:** + +```json +{ + "id": "apple_id" + "apple_id": "farva@spurbury.gov", + "password": "0k@yN0cR34m" +} +``` Resources --------- From bf664a67bcc16dafe5c2c1abc062e4e788e752de Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Wed, 13 Dec 2017 21:25:53 -0800 Subject: [PATCH 77/83] Remove 'description' label from recipe names --- README.md | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index d74028d6..2ec14c98 100644 --- a/README.md +++ b/README.md @@ -39,18 +39,20 @@ Recipes ### Disable Software Updates +Disables automatic checking and downloading of software updates. + **Usage:** `include_recipe macos::disable_software_updates` -**Description:** Disables automatic checking and downloading of software updates. No attributes used in this recipe. ### Keep Awake -**Usage:** `include_recipe macos::keep_awake` -**Description:** Prevent macOS from falling asleep, disable the screensaver, and +Prevent macOS from falling asleep, disable the screensaver, and several other settings to always keep macOS on. Uses the `plistbuddy` and `pmset` resources. +**Usage:** `include_recipe macos::keep_awake` + | Attribute used | Default value | |---------------------------------------|-------------------------| | `node['macos']['network_time_server']`| `'time.windows.com'` | @@ -58,9 +60,10 @@ resources. ### Mono +Installs [Mono](http://www.mono-project.com/docs/about-mono/). Requires package +name, version number, and checksum in order to override. + **Usage:** `include_recipe macos::mono` -**Description:** Installs [Mono](http://www.mono-project.com/docs/about-mono/). -Version 4.4.2 by default. | Attribute used | Default value | |-------------------------------------|----------------------------------------| @@ -70,9 +73,10 @@ Version 4.4.2 by default. ### Xcode +Installs Xcode 9.1 and simulators for iOS 10 and iOS 11. Check out +the documentation for the Xcode resource if you need more flexibility. + **Usage:** `include_recipe::xcode` -**Description:** Installs Xcode 9.2 and simulators for iOS 10 and iOS 11. Uses the -`xcode-install` gem. | Attribute Used | Default value | |---------------------------------------------------------------|---------------| @@ -81,11 +85,11 @@ Version 4.4.2 by default. ### Apple Configurator 2 -**Usage:** `include_recipe::configurator` - -**Description:** Installs Apple Configurator 2 using `mas` and links `cfgutil` to +Installs Apple Configurator 2 using `mas` and links `cfgutil` to `/usr/local/bin`. Requires a `data_bag_item` containing valid App Store credentials. +**Usage:** `include_recipe::configurator` + **Attributes**: No attributes used in this recipe. #### Required Data Bag Items @@ -94,7 +98,7 @@ Version 4.4.2 by default. ```json { - "id": "apple_id" + "id": "apple_id", "apple_id": "farva@spurbury.gov", "password": "0k@yN0cR34m" } From 1b64101ae543bba4b69740c417dafbef7415b03b Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Wed, 13 Dec 2017 22:16:17 -0800 Subject: [PATCH 78/83] Bump version, add documentation dir --- README.md | 61 ++++++++++++++++ documentation/ard.md | 46 ++++++++++++ documentation/resource_ard.md | 131 ++++++++++++++++++++++++++++++++++ metadata.rb | 2 +- 4 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 documentation/ard.md create mode 100644 documentation/resource_ard.md diff --git a/README.md b/README.md index 2ec14c98..c8944a98 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,67 @@ Installs Apple Configurator 2 using `mas` and links `cfgutil` to Resources --------- +### Apple Remote Desktop + +===================================================== +gem_package +===================================================== +`[edit on GitHub] `__ + +.. warning:: .. tag notes_chef_gem_vs_gem_package + + The **chef_gem** and **gem_package** resources are both used to install Ruby gems. For any machine on which the chef-client is installed, there are two instances of Ruby. One is the standard, system-wide instance of Ruby and the other is a dedicated instance that is available only to the chef-client. Use the **chef_gem** resource to install gems into the instance of Ruby that is dedicated to the chef-client. Use the **gem_package** resource to install all other gems (i.e. install gems system-wide). + + .. end_tag + +.. tag resource_package_gem + +Use the **gem_package** resource to manage gem packages that are only included in recipes. When a package is installed from a local file, it must be added to the node using the **remote_file** or **cookbook_file** resources. + +.. end_tag + +.. note:: .. tag notes_resource_gem_package + + The **gem_package** resource must be specified as ``gem_package`` and cannot be shortened to ``package`` in a recipe. + + .. end_tag + +Syntax +===================================================== +A **gem_package** resource block manages a package on a node, typically by installing it. The simplest use of the **gem_package** resource is: + +.. code-block:: ruby + + gem_package 'package_name' + +which will install the named package using all of the default options and the default action (``:install``). + +The full syntax for all of the properties that are available to the **gem_package** resource is: + +.. code-block:: ruby + + gem_package 'name' do + clear_sources TrueClass, FalseClass + include_default_source TrueClass, FalseClass + gem_binary String + notifies # see description + options String + package_name String, Array # defaults to 'name' if not specified + provider Chef::Provider::Package::Rubygems + source String, Array + subscribes # see description + timeout String, Integer + version String, Array + action Symbol # defaults to :install if not specified + end + +where + +* ``gem_package`` tells the chef-client to manage a package +* ``'name'`` is the name of the package +* ``action`` identifies which steps the chef-client will take to bring the node into the desired state +* ``clear_sources``, ``include_default_source``, ``gem_binary``, ``options``, ``package_name``, ``provider``, ``source``, ``timeout``, and ``version`` are properties of this resource, with the Ruby type shown. See "Properties" section below for more information about all of the properties that may be used with this resource. + - `ard` - `machine_name` - `defaults` diff --git a/documentation/ard.md b/documentation/ard.md new file mode 100644 index 00000000..10c44989 --- /dev/null +++ b/documentation/ard.md @@ -0,0 +1,46 @@ +ard +=== + +`[edit on GitHub] `__ + +The `ard` resource represents the current state of the "Remote Management" settings. +It uses the kickstart command with command line arguments based on the properties +set in an `ard` resource. + +Syntax +------ + +An `ard` resource block manages a package on a node, typically by +installing it. The simplest use of the **gem_package** resource is: + +.. code-block:: ruby + +ard 'enable' + +which will install the named package using all of the default options and the default action (``:install``). + +The full syntax for all of the properties that are available to the **gem_package** resource is: + +.. code-block:: ruby + + gem_package 'name' do + clear_sources TrueClass, FalseClass + include_default_source TrueClass, FalseClass + gem_binary String + notifies # see description + options String + package_name String, Array # defaults to 'name' if not specified + provider Chef::Provider::Package::Rubygems + source String, Array + subscribes # see description + timeout String, Integer + version String, Array + action Symbol # defaults to :install if not specified + end + +where + +* ``gem_package`` tells the chef-client to manage a package +* ``'name'`` is the name of the package +* ``action`` identifies which steps the chef-client will take to bring the node into the desired state +* ``clear_sources``, ``include_default_source``, ``gem_binary``, ``options``, ``package_name``, ``provider``, ``source``, ``timeout``, and ``version`` are properties of this resource, with the Ruby type shown. See "Properties" section below for more information about all of the properties that may be used with this resource. \ No newline at end of file diff --git a/documentation/resource_ard.md b/documentation/resource_ard.md new file mode 100644 index 00000000..2ac8e3c3 --- /dev/null +++ b/documentation/resource_ard.md @@ -0,0 +1,131 @@ +ard +=== + +Use the **ard** resource to manage Remote Desktop settings and preferences. +Under the hood, an **ard** resource executes the `kickstart` command, located +in ARDAgent.app (one of the CoreServices of macOS). It has some basic actions, +which pertain to the simple `kickstart` subcommands. It also has the more +complicated `:configure` action, which requires some familiarity with +`kickstart`. You can learn more about the `kickstart` command [here](https://support.apple.com/en-us/HT201710). + +Syntax +------ + +A **ard** resource block declares a basic description of the command configuration +and a set of properties depending on the actions executed. For example: + +```ruby +ard 'activate and configure ard' do + action [:activate, :configure] +end +``` + +where + +- `:activate` activates the ARD agent +- `:configure` configures the agent using the `kickstart` defaut commandline arguments. + +The full syntax for all of the properties that are available to the **ard** +resource is: + +```ruby +ard 'description' do + install_package String + uninstall_options Array, default: ['-files', '-settings', '-prefs'] + restart_options Array, default: ['-agent', '-console', '-menu'] + users Array + privs Array, default: ['-all'] + access String, default: '-on' + allow_access_for String, default: '-allUsers' + computerinfo Array + clientopts Array + action Symbol +end +``` + +**Note:** Not all properties are compatible with each action. + +Actions +------- + +This resource has the following actions: + +`:activate` + +      Activate the remote desktop agent. + +`:deactivate` + +      Deactivate the remote desktop agent. + +`:uninstall` + +      Uninstall a package from another remotely +managed mac. + +`:stop` + +      Stop the agent. + +`:restart` + +      Restart the remote desktop agent. + +`:configure` + +      Configure the setup of the remote desktop +agent using the default options. If you were to configure the default options, +your settings would look like this in the GUI: + +Properties +---------- + +`install_package` + +      **Ruby Type:** `String` + +`uninstall_options` + +      **Ruby type:** `Array` + +      default options: `['-files', '-settings', '-prefs']` + +`restart_options` + +      **Ruby type:** `Array` + +      default options: `['-agent', '-console', '-menu']` + +`users` + +      **Ruby type:** `Array` + +`privs` + +      **Ruby type:** `Array` + +      default: `['-all']` + +`access` + +      **Ruby type:** `String` + +      default: `'-on'` + +`allow_access_for` + +      **Ruby type:** `String` + +      default: `'-allUsers'` + +`computerinfo` + +      **Ruby type:** `Array` + +`clientopts` + +      **Ruby type:** `Array` + +`action` + +      **Ruby type:** `Symbol` diff --git a/metadata.rb b/metadata.rb index d1581ab3..bde1aa31 100644 --- a/metadata.rb +++ b/metadata.rb @@ -5,7 +5,7 @@ description 'Resources for configuring and provisioning macOS' long_description 'Resources for configuring and provisioning macOS' chef_version '~> 13.0' if respond_to?(:chef_version) -version '0.12.2' +version '0.12.3' source_url 'https://github.com/Microsoft/macos-cookbook' issues_url 'https://github.com/Microsoft/macos-cookbook/issues' From 742e731b9273e61f763eb7b70b8d870ec221b9a7 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Wed, 13 Dec 2017 22:22:26 -0800 Subject: [PATCH 79/83] Fix up the last commit --- README.md | 72 +------------------------------------------- documentation/ard.md | 46 ---------------------------- 2 files changed, 1 insertion(+), 117 deletions(-) delete mode 100644 documentation/ard.md diff --git a/README.md b/README.md index c8944a98..6b47c225 100644 --- a/README.md +++ b/README.md @@ -107,74 +107,4 @@ Installs Apple Configurator 2 using `mas` and links `cfgutil` to Resources --------- -### Apple Remote Desktop - -===================================================== -gem_package -===================================================== -`[edit on GitHub] `__ - -.. warning:: .. tag notes_chef_gem_vs_gem_package - - The **chef_gem** and **gem_package** resources are both used to install Ruby gems. For any machine on which the chef-client is installed, there are two instances of Ruby. One is the standard, system-wide instance of Ruby and the other is a dedicated instance that is available only to the chef-client. Use the **chef_gem** resource to install gems into the instance of Ruby that is dedicated to the chef-client. Use the **gem_package** resource to install all other gems (i.e. install gems system-wide). - - .. end_tag - -.. tag resource_package_gem - -Use the **gem_package** resource to manage gem packages that are only included in recipes. When a package is installed from a local file, it must be added to the node using the **remote_file** or **cookbook_file** resources. - -.. end_tag - -.. note:: .. tag notes_resource_gem_package - - The **gem_package** resource must be specified as ``gem_package`` and cannot be shortened to ``package`` in a recipe. - - .. end_tag - -Syntax -===================================================== -A **gem_package** resource block manages a package on a node, typically by installing it. The simplest use of the **gem_package** resource is: - -.. code-block:: ruby - - gem_package 'package_name' - -which will install the named package using all of the default options and the default action (``:install``). - -The full syntax for all of the properties that are available to the **gem_package** resource is: - -.. code-block:: ruby - - gem_package 'name' do - clear_sources TrueClass, FalseClass - include_default_source TrueClass, FalseClass - gem_binary String - notifies # see description - options String - package_name String, Array # defaults to 'name' if not specified - provider Chef::Provider::Package::Rubygems - source String, Array - subscribes # see description - timeout String, Integer - version String, Array - action Symbol # defaults to :install if not specified - end - -where - -* ``gem_package`` tells the chef-client to manage a package -* ``'name'`` is the name of the package -* ``action`` identifies which steps the chef-client will take to bring the node into the desired state -* ``clear_sources``, ``include_default_source``, ``gem_binary``, ``options``, ``package_name``, ``provider``, ``source``, ``timeout``, and ``version`` are properties of this resource, with the Ruby type shown. See "Properties" section below for more information about all of the properties that may be used with this resource. - -- `ard` -- `machine_name` -- `defaults` -- `pmset` -- `systemsetup` -- `xcode` -- `plist` - -Checkout the [Wiki](https://github.com/Microsoft/macos-cookbook/wiki) for details -about the macOS Cookbook resources. +- [ARD (Apple Remote Desktop)](https://github.com/Microsoft/macos-cookbook/blob/feature/documentation/documentation/resource_ard.md) diff --git a/documentation/ard.md b/documentation/ard.md deleted file mode 100644 index 10c44989..00000000 --- a/documentation/ard.md +++ /dev/null @@ -1,46 +0,0 @@ -ard -=== - -`[edit on GitHub] `__ - -The `ard` resource represents the current state of the "Remote Management" settings. -It uses the kickstart command with command line arguments based on the properties -set in an `ard` resource. - -Syntax ------- - -An `ard` resource block manages a package on a node, typically by -installing it. The simplest use of the **gem_package** resource is: - -.. code-block:: ruby - -ard 'enable' - -which will install the named package using all of the default options and the default action (``:install``). - -The full syntax for all of the properties that are available to the **gem_package** resource is: - -.. code-block:: ruby - - gem_package 'name' do - clear_sources TrueClass, FalseClass - include_default_source TrueClass, FalseClass - gem_binary String - notifies # see description - options String - package_name String, Array # defaults to 'name' if not specified - provider Chef::Provider::Package::Rubygems - source String, Array - subscribes # see description - timeout String, Integer - version String, Array - action Symbol # defaults to :install if not specified - end - -where - -* ``gem_package`` tells the chef-client to manage a package -* ``'name'`` is the name of the package -* ``action`` identifies which steps the chef-client will take to bring the node into the desired state -* ``clear_sources``, ``include_default_source``, ``gem_binary``, ``options``, ``package_name``, ``provider``, ``source``, ``timeout``, and ``version`` are properties of this resource, with the Ruby type shown. See "Properties" section below for more information about all of the properties that may be used with this resource. \ No newline at end of file From 92b1283661b979df89f615396c0874bb01c81246 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Wed, 13 Dec 2017 22:39:26 -0800 Subject: [PATCH 80/83] Separate 10.12 and 10.13 build status --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6b47c225..133b0b31 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ macOS Cookbook ============== -![build-status](https://office.visualstudio.com/_apis/public/build/definitions/59d72877-1cea-4eb6-9d06-66716573631a/2140/badge) +macOS Sierra 10.12 ![build-status-1012](https://office.visualstudio.com/_apis/public/build/definitions/59d72877-1cea-4eb6-9d06-66716573631a/2143/badge) +macOS High Sierra 10.13 ![build-status-1013](https://office.visualstudio.com/_apis/public/build/definitions/59d72877-1cea-4eb6-9d06-66716573631a/2140/badge) The macOS cookbook is a Chef library cookbook that provides resources for configuring and provisioning macOS. Additionally, it provides recipes that implement common From 2e6a0591668037e65584d6854083f2d3c4cab91f Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Wed, 13 Dec 2017 22:44:58 -0800 Subject: [PATCH 81/83] Add table for build status --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 133b0b31..cfd494c3 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,16 @@ macOS Cookbook ============== -macOS Sierra 10.12 ![build-status-1012](https://office.visualstudio.com/_apis/public/build/definitions/59d72877-1cea-4eb6-9d06-66716573631a/2143/badge) -macOS High Sierra 10.13 ![build-status-1013](https://office.visualstudio.com/_apis/public/build/definitions/59d72877-1cea-4eb6-9d06-66716573631a/2140/badge) - The macOS cookbook is a Chef library cookbook that provides resources for configuring and provisioning macOS. Additionally, it provides recipes that implement common use-cases of the macOS cookbook's recources. +||| +|-|-| +| macOS Sierra 10.12 | ![build-status-1012](https://office.visualstudio.com/_apis/public/build/definitions/59d72877-1cea-4eb6-9d06-66716573631a/2143/badge) | +| macOS High Sierra 10.13 | ![build-status-1013](https://office.visualstudio.com/_apis/public/build/definitions/59d72877-1cea-4eb6-9d06-66716573631a/2140/badge) | +||| + Requirements ------------ From 01432c67fb040b4a70e83295f226525abec0a6cd Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Wed, 13 Dec 2017 23:20:19 -0800 Subject: [PATCH 82/83] Add plist resource documentation --- README.md | 1 + documentation/resource_ard.md | 4 ++- documentation/resource_plist.md | 62 +++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 documentation/resource_plist.md diff --git a/README.md b/README.md index cfd494c3..c287f4ca 100644 --- a/README.md +++ b/README.md @@ -112,3 +112,4 @@ Resources --------- - [ARD (Apple Remote Desktop)](https://github.com/Microsoft/macos-cookbook/blob/feature/documentation/documentation/resource_ard.md) +- [Plist](https://github.com/Microsoft/macos-cookbook/blob/feature/documentation/documentation/resource_plist.md) diff --git a/documentation/resource_ard.md b/documentation/resource_ard.md index 2ac8e3c3..e6ed8ba7 100644 --- a/documentation/resource_ard.md +++ b/documentation/resource_ard.md @@ -6,7 +6,9 @@ Under the hood, an **ard** resource executes the `kickstart` command, located in ARDAgent.app (one of the CoreServices of macOS). It has some basic actions, which pertain to the simple `kickstart` subcommands. It also has the more complicated `:configure` action, which requires some familiarity with -`kickstart`. You can learn more about the `kickstart` command [here](https://support.apple.com/en-us/HT201710). +`kickstart`. + +[Learn more about the `kickstart` command](https://support.apple.com/en-us/HT201710). Syntax ------ diff --git a/documentation/resource_plist.md b/documentation/resource_plist.md new file mode 100644 index 00000000..95d63cf3 --- /dev/null +++ b/documentation/resource_plist.md @@ -0,0 +1,62 @@ +plist +===== + +Use the **plist** resource to manage property list files (plists) and their content. +A **plist** resource instance represents the state of a single key-value pair in +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 `/usr/bin/defaults` +and `/usr/libexec/PlistBuddy` will be useful when implementing the +**plist** resource. + +[Learn more about property lists.](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/PropertyLists/QuickStartPlist/QuickStartPlist.html#//apple_ref/doc/uid/10000048i-CH4-SW5) + +Syntax +------ + +The full syntax for all of the properties that are available to the **plist** +resource is: + +```ruby +plist 'description' do + path String + entry String + value TrueClass, FalseClass, String, Integer, Float + action Symbol +end +``` + +Actions +------- + +This resource has the following actions: + +`:set` + +      Set `entry` to `value` in `path` + +Examples +-------- + +Enabling the setting to show both visible and 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` From f4d252be4b345a3706d02fad1139073b0b1a2418 Mon Sep 17 00:00:00 2001 From: Eric Hanko Date: Wed, 13 Dec 2017 23:53:09 -0800 Subject: [PATCH 83/83] Add Xcode documentation --- README.md | 24 ++++++++---- documentation/resource_ard.md | 12 +++--- documentation/resource_plist.md | 6 ++- documentation/resource_xcode.md | 69 +++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 16 deletions(-) create mode 100644 documentation/resource_xcode.md diff --git a/README.md b/README.md index c287f4ca..229fcd91 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@ Requirements - Only tested on Chef 13 - Surprisingly, this cookbook is only compatible with macOS -Supported OS X/macOS versions ------------------------------ +Supported OS Versions +--------------------- - OS X El Capitan 10.11 - macOS Sierra 10.12 @@ -80,7 +80,9 @@ name, version number, and checksum in order to override. Installs Xcode 9.1 and simulators for iOS 10 and iOS 11. Check out the documentation for the Xcode resource if you need more flexibility. -**Usage:** `include_recipe::xcode` +:large_orange_diamond: Requires an `apple_id` data bag item. + +**Usage:** `include_recipe macos::xcode` | Attribute Used | Default value | |---------------------------------------------------------------|---------------| @@ -90,13 +92,18 @@ the documentation for the Xcode resource if you need more flexibility. ### Apple Configurator 2 Installs Apple Configurator 2 using `mas` and links `cfgutil` to -`/usr/local/bin`. Requires a `data_bag_item` containing valid App Store credentials. +`/usr/local/bin`. + +:large_orange_diamond: Requires an `apple_id` data bag item. -**Usage:** `include_recipe::configurator` +**Usage:** `include_recipe macos::configurator` **Attributes**: No attributes used in this recipe. -#### Required Data Bag Items +#### Data Bags + +Both the `macos::xcode` and `macos::configurator` recipes require a data bag +item named `apple_id` containing valid Apple ID credentials. For example: **Example:** @@ -111,5 +118,6 @@ Installs Apple Configurator 2 using `mas` and links `cfgutil` to Resources --------- -- [ARD (Apple Remote Desktop)](https://github.com/Microsoft/macos-cookbook/blob/feature/documentation/documentation/resource_ard.md) -- [Plist](https://github.com/Microsoft/macos-cookbook/blob/feature/documentation/documentation/resource_plist.md) +- [ARD (Apple Remote Desktop)](./documentation/resource_ard.md) +- [Plist](./documentation/resource_plist.md) +- [Xcode](./documentation/resource_xcode.md) diff --git a/documentation/resource_ard.md b/documentation/resource_ard.md index e6ed8ba7..0f92074a 100644 --- a/documentation/resource_ard.md +++ b/documentation/resource_ard.md @@ -33,15 +33,15 @@ resource is: ```ruby ard 'description' do install_package String - uninstall_options Array, default: ['-files', '-settings', '-prefs'] - restart_options Array, default: ['-agent', '-console', '-menu'] + uninstall_options Array, # defaults to ['-files', '-settings', '-prefs'] if not specified + restart_options Array, # defaults to ['-agent', '-console', '-menu'] if not specified users Array - privs Array, default: ['-all'] - access String, default: '-on' - allow_access_for String, default: '-allUsers' + privs Array, # defaults to ['-all'] if not specified + access String, # defaults to '-on' if not specified + allow_access_for String, # defaults to '-allUsers' if not specified computerinfo Array clientopts Array - action Symbol + action Symbol # defaults to [:activate, :configure] if not specified end ``` diff --git a/documentation/resource_plist.md b/documentation/resource_plist.md index 95d63cf3..cdceb3f8 100644 --- a/documentation/resource_plist.md +++ b/documentation/resource_plist.md @@ -26,10 +26,10 @@ resource is: ```ruby plist 'description' do - path String + path String # defaults to 'description' if not specified entry String value TrueClass, FalseClass, String, Integer, Float - action Symbol + action Symbol # defaults to :set if not specified end ``` @@ -58,5 +58,7 @@ 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` diff --git a/documentation/resource_xcode.md b/documentation/resource_xcode.md new file mode 100644 index 00000000..3d267b45 --- /dev/null +++ b/documentation/resource_xcode.md @@ -0,0 +1,69 @@ +xcode +===== + +Use the **xcode** resource to manage a single installation of Apple's Xcode IDE. +An **xcode** resource instance represents the state of a single Xcode installation +and any simulators that are declared using the `ios_simulators` property. The latest +version of iOS simulators are always installed with Xcode. + +Syntax +------ + +The full syntax for all of the properties that are available to the **xcode** +resource is: + +```ruby +xcode 'description' do + version String # defaults to 'description' if not specified + path String # defaults to '/Applications/Xcode.app' if not specified + ios_simulators Array # defaults to [10, 11] if not specified + action Symbol # defaults to [:install_xcode, :install_simulators] if not specified +end +``` + +Actions +------- + +This resource has the following actions: + +`:install_xcode` + +      Set `entry` to `value` in `path` + +`:install_simulators` + +      Along with a `version` of Xcode, +install the declared array of the major versions of `ios_simulators`. + +Examples +-------- + +### Basic usage + +The **xcode** resource in its simplest form: + +```ruby +xcode '9.2' +``` + +### Using with node attributes + +Install different versions of Xcode based on the macOS version: + +```ruby +if node['platform_version'].match?(/10\.13/) || node['platform_version'].match?(/10\.12/) + execute 'Disable Gatekeeper' do + command 'spctl --master-disable' + end + + xcode '9.2' do + ios_simulators %w(11 10) + end + +elsif node['platform_version'].match?(/10\.11/) + + xcode '8.2.1' do + ios_simulators %w(10 9) + end +end +```