From 169837fbeaf507ee6ed5f358e698edbf7dde14ac Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Tue, 25 Apr 2017 14:19:22 +0100 Subject: [PATCH 01/38] If resource source is set to nil then assume that we are doing a network or local install. This means we don't want to extract or clean Visual Studio ISO. --- providers/edition.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/providers/edition.rb b/providers/edition.rb index b2d4e56..0364e7b 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -41,6 +41,7 @@ def whyrun_supported? source new_resource.source overwrite true checksum new_resource.checksum + not_if new_resource.source = nil end # Ensure the target directory exists so logging doesn't fail on VS 2010 @@ -65,7 +66,7 @@ def whyrun_supported? path extracted_iso_dir action :delete recursive true - not_if { new_resource.preserve_extracted_files } + not_if { new_resource.source = nil or new_resource.preserve_extracted_files } end end new_resource.updated_by_last_action(true) @@ -137,7 +138,8 @@ def install_log_file def installer_exe installer = new_resource.installer_file || "vs_#{new_resource.edition}.exe" - ::File.join(extracted_iso_dir, installer) + installer = ::File.join(extracted_iso_dir, installer) unless new_resource.source = nil + installer end def extracted_iso_dir From 508333f474a4d842bf4c7cf2c05e344d45ed5395 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Tue, 25 Apr 2017 14:54:24 +0100 Subject: [PATCH 02/38] Only throw an exception when src is nil if we have not specified an installer_file. The installer_file could be the path the full path to the network install --- libraries/helper.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/helper.rb b/libraries/helper.rb index e798fbb..838623b 100644 --- a/libraries/helper.rb +++ b/libraries/helper.rb @@ -29,8 +29,10 @@ def versions # Gets the version/edition ISO download URL or raises an error def source_download_url(version, edition) src = iso_source(version, edition) - assert_src_is_not_nil(src, version, edition) - ::File.join(src, node['visualstudio'][version][edition]['filename']) + assert_src_is_not_nil(src, version, edition) if node['visualstudio'][version][edition]['installer_file'] = nil + url = nil + url = ::File.join(src, node['visualstudio'][version][edition]['filename']) if src != nil + url end private From 3ab9f4623448d8acdd813b030d93737b6f744e7a Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Tue, 25 Apr 2017 15:15:14 +0100 Subject: [PATCH 03/38] Chef windows_package uses returns instead of success_code --- providers/edition.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/edition.rb b/providers/edition.rb index 0364e7b..694726a 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -58,7 +58,7 @@ def whyrun_supported? installer_type :custom options setup_options timeout 3600 # 1hour - success_codes [0, 127, 3010] + returns [0, 127, 3010] end # Cleanup extracted ISO files from tmp dir From cd15ecddf9464bc424191df293b442ef601c3df3 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Tue, 25 Apr 2017 15:39:05 +0100 Subject: [PATCH 04/38] Comparing values. Not setting them. --- libraries/helper.rb | 2 +- providers/edition.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/helper.rb b/libraries/helper.rb index 838623b..31774d2 100644 --- a/libraries/helper.rb +++ b/libraries/helper.rb @@ -29,7 +29,7 @@ def versions # Gets the version/edition ISO download URL or raises an error def source_download_url(version, edition) src = iso_source(version, edition) - assert_src_is_not_nil(src, version, edition) if node['visualstudio'][version][edition]['installer_file'] = nil + assert_src_is_not_nil(src, version, edition) if node['visualstudio'][version][edition]['installer_file'] == nil url = nil url = ::File.join(src, node['visualstudio'][version][edition]['filename']) if src != nil url diff --git a/providers/edition.rb b/providers/edition.rb index 694726a..3ab7f23 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -41,7 +41,7 @@ def whyrun_supported? source new_resource.source overwrite true checksum new_resource.checksum - not_if new_resource.source = nil + not_if new_resource.source == nil end # Ensure the target directory exists so logging doesn't fail on VS 2010 @@ -66,7 +66,7 @@ def whyrun_supported? path extracted_iso_dir action :delete recursive true - not_if { new_resource.source = nil or new_resource.preserve_extracted_files } + not_if { new_resource.source == nil or new_resource.preserve_extracted_files } end end new_resource.updated_by_last_action(true) @@ -138,7 +138,7 @@ def install_log_file def installer_exe installer = new_resource.installer_file || "vs_#{new_resource.edition}.exe" - installer = ::File.join(extracted_iso_dir, installer) unless new_resource.source = nil + installer = ::File.join(extracted_iso_dir, installer) unless new_resource.source == nil installer end From 8946cbf4bd0f538b7e769f0879d1f8461d2532ac Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Tue, 25 Apr 2017 15:56:25 +0100 Subject: [PATCH 05/38] If a value is nil or empty we should consider it to be overridden and use the installer_exe path only --- libraries/helper.rb | 4 ++-- providers/edition.rb | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/helper.rb b/libraries/helper.rb index 31774d2..34a8574 100644 --- a/libraries/helper.rb +++ b/libraries/helper.rb @@ -29,9 +29,9 @@ def versions # Gets the version/edition ISO download URL or raises an error def source_download_url(version, edition) src = iso_source(version, edition) - assert_src_is_not_nil(src, version, edition) if node['visualstudio'][version][edition]['installer_file'] == nil + assert_src_is_not_nil(src, version, edition) if node['visualstudio'][version][edition]['installer_file'] url = nil - url = ::File.join(src, node['visualstudio'][version][edition]['filename']) if src != nil + url = ::File.join(src, node['visualstudio'][version][edition]['filename']) if !src url end diff --git a/providers/edition.rb b/providers/edition.rb index 3ab7f23..4dafd5e 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -41,7 +41,7 @@ def whyrun_supported? source new_resource.source overwrite true checksum new_resource.checksum - not_if new_resource.source == nil + only_if new_resource.source end # Ensure the target directory exists so logging doesn't fail on VS 2010 @@ -66,7 +66,7 @@ def whyrun_supported? path extracted_iso_dir action :delete recursive true - not_if { new_resource.source == nil or new_resource.preserve_extracted_files } + not_if { !new_resource.source or new_resource.preserve_extracted_files } end end new_resource.updated_by_last_action(true) @@ -138,7 +138,7 @@ def install_log_file def installer_exe installer = new_resource.installer_file || "vs_#{new_resource.edition}.exe" - installer = ::File.join(extracted_iso_dir, installer) unless new_resource.source == nil + installer = ::File.join(extracted_iso_dir, installer) if new_resource.source installer end From f01608a261546c685ffcfa696c56c0ad6cdadc26 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Tue, 25 Apr 2017 16:13:34 +0100 Subject: [PATCH 06/38] Use empty? rather --- libraries/helper.rb | 4 ++-- providers/edition.rb | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/helper.rb b/libraries/helper.rb index 34a8574..cae167f 100644 --- a/libraries/helper.rb +++ b/libraries/helper.rb @@ -29,9 +29,9 @@ def versions # Gets the version/edition ISO download URL or raises an error def source_download_url(version, edition) src = iso_source(version, edition) - assert_src_is_not_nil(src, version, edition) if node['visualstudio'][version][edition]['installer_file'] + assert_src_is_not_nil(src, version, edition) unless node['visualstudio'][version][edition]['installer_file'].empty? url = nil - url = ::File.join(src, node['visualstudio'][version][edition]['filename']) if !src + url = ::File.join(src, node['visualstudio'][version][edition]['filename']) unless src.empty? url end diff --git a/providers/edition.rb b/providers/edition.rb index 4dafd5e..ca9332d 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -41,7 +41,7 @@ def whyrun_supported? source new_resource.source overwrite true checksum new_resource.checksum - only_if new_resource.source + not_if new_resource.source.empty? end # Ensure the target directory exists so logging doesn't fail on VS 2010 @@ -66,7 +66,7 @@ def whyrun_supported? path extracted_iso_dir action :delete recursive true - not_if { !new_resource.source or new_resource.preserve_extracted_files } + not_if { new_resource.source.empty? or new_resource.preserve_extracted_files } end end new_resource.updated_by_last_action(true) @@ -138,7 +138,7 @@ def install_log_file def installer_exe installer = new_resource.installer_file || "vs_#{new_resource.edition}.exe" - installer = ::File.join(extracted_iso_dir, installer) if new_resource.source + installer = ::File.join(extracted_iso_dir, installer) unless new_resource.source.empty? installer end From be9be710ccb74a85f86f1cf5215d6ee5904b5715 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Tue, 25 Apr 2017 16:26:22 +0100 Subject: [PATCH 07/38] source attribute is now optional --- resources/edition.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/edition.rb b/resources/edition.rb index a6e8d09..6fce824 100644 --- a/resources/edition.rb +++ b/resources/edition.rb @@ -32,7 +32,7 @@ attribute :install_dir, kind_of: String, required: true # The ISO full source URL -attribute :source, kind_of: String, required: true +attribute :source, kind_of: String, required: false # The installed MSI package name attribute :package_name, kind_of: String, required: true From 959d08df48d5be3d533c2f4e7cd08dc9c6c6d09b Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Tue, 25 Apr 2017 16:35:38 +0100 Subject: [PATCH 08/38] replace empty with blank --- providers/edition.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/providers/edition.rb b/providers/edition.rb index ca9332d..ccf5c59 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -41,7 +41,7 @@ def whyrun_supported? source new_resource.source overwrite true checksum new_resource.checksum - not_if new_resource.source.empty? + not_if new_resource.source.blank? end # Ensure the target directory exists so logging doesn't fail on VS 2010 @@ -66,7 +66,7 @@ def whyrun_supported? path extracted_iso_dir action :delete recursive true - not_if { new_resource.source.empty? or new_resource.preserve_extracted_files } + not_if { new_resource.source.blank? or new_resource.preserve_extracted_files } end end new_resource.updated_by_last_action(true) @@ -138,7 +138,7 @@ def install_log_file def installer_exe installer = new_resource.installer_file || "vs_#{new_resource.edition}.exe" - installer = ::File.join(extracted_iso_dir, installer) unless new_resource.source.empty? + installer = ::File.join(extracted_iso_dir, installer) unless new_resource.source.blank? installer end From acff8a426b955cf6d22080fbb5621c41df7ae332 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Tue, 25 Apr 2017 16:45:02 +0100 Subject: [PATCH 09/38] remove blank --- providers/edition.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/providers/edition.rb b/providers/edition.rb index ccf5c59..3ab7f23 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -41,7 +41,7 @@ def whyrun_supported? source new_resource.source overwrite true checksum new_resource.checksum - not_if new_resource.source.blank? + not_if new_resource.source == nil end # Ensure the target directory exists so logging doesn't fail on VS 2010 @@ -66,7 +66,7 @@ def whyrun_supported? path extracted_iso_dir action :delete recursive true - not_if { new_resource.source.blank? or new_resource.preserve_extracted_files } + not_if { new_resource.source == nil or new_resource.preserve_extracted_files } end end new_resource.updated_by_last_action(true) @@ -138,7 +138,7 @@ def install_log_file def installer_exe installer = new_resource.installer_file || "vs_#{new_resource.edition}.exe" - installer = ::File.join(extracted_iso_dir, installer) unless new_resource.source.blank? + installer = ::File.join(extracted_iso_dir, installer) unless new_resource.source == nil installer end From 291c331c38aeea83727595b5adf45127ffa88dce Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Tue, 25 Apr 2017 16:53:52 +0100 Subject: [PATCH 10/38] Make it a function --- providers/edition.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/edition.rb b/providers/edition.rb index 3ab7f23..97b393d 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -41,7 +41,7 @@ def whyrun_supported? source new_resource.source overwrite true checksum new_resource.checksum - not_if new_resource.source == nil + not_if { new_resource.source == nil } end # Ensure the target directory exists so logging doesn't fail on VS 2010 From d8fe130335e1eb89ed56b85de4f410860a3bf531 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Wed, 26 Apr 2017 17:56:13 +0100 Subject: [PATCH 11/38] Add Visual Studio 2017 Add ability to install via web installer --- attributes/default.rb | 1 + attributes/vs2017.rb | 148 ++++++++++++++++++++++++++++++++++++++++++ providers/edition.rb | 50 ++++++++++++-- 3 files changed, 192 insertions(+), 7 deletions(-) create mode 100644 attributes/vs2017.rb diff --git a/attributes/default.rb b/attributes/default.rb index 6cde6b6..26900bf 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -40,3 +40,4 @@ include_attribute 'visualstudio::vs2012' include_attribute 'visualstudio::vs2013' include_attribute 'visualstudio::vs2015' +include_attribute 'visualstudio::vs2017' diff --git a/attributes/vs2017.rb b/attributes/vs2017.rb new file mode 100644 index 0000000..19a41d2 --- /dev/null +++ b/attributes/vs2017.rb @@ -0,0 +1,148 @@ + +# +# Author:: Shawn Neal () +# Cookbook Name:: visualstudio +# Attribute:: vs2017 +# +# Copyright 2015, Shawn Neal +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Currently you cannot change this, doing so will break the cookbook +default['visualstudio']['2017']['install_dir'] = (ENV['ProgramFiles(x86)'] || 'C:\Program Files (x86)') + '\Microsoft Visual Studio 16.0' + +# Test Professional w/Update1 https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-test-professional +default['visualstudio']['2017']['testprofessional']['installer_file'] = 'vs_testprofessional.exe' +default['visualstudio']['2017']['testprofessional']['filename'] = 'vs_testprofessional.exe' +default['visualstudio']['2017']['testprofessional']['package_name'] = 'Microsoft Visual Studio Test Professional 2017' +default['visualstudio']['2017']['testprofessional']['checksum'] = '' +default['visualstudio']['2017']['testprofessional']['default_source'] = 'https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=TestProfessional&rel=15' + +# Professional w/Update1 +default['visualstudio']['2017']['professional']['installer_file'] = 'vs_professional.exe' +default['visualstudio']['2017']['professional']['filename'] = 'vs_professional.exe' +default['visualstudio']['2017']['professional']['package_name'] = 'Microsoft Visual Studio Professional 2017' +default['visualstudio']['2017']['professional']['checksum'] = '' +default['visualstudio']['2017']['professional']['default_source'] = 'https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=Professional&rel=15' + +# Defaults for https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-professional +default['visualstudio']['2017']['professional']['default_install_items'].tap do |h| + h['Microsoft.VisualStudio.Workload.CoreEditor']['selected'] = true + h['Microsoft.VisualStudio.Workload.Azure']['selected'] = true + h['Microsoft.VisualStudio.Workload.Data']['selected'] = true + h['Microsoft.VisualStudio.Workload.ManagedDesktop']['selected'] = true + h['Microsoft.VisualStudio.Workload.ManagedGame']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeCrossPlat']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeDesktop']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeGame']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeMobile']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetCoreTools']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetCrossPlat']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetWeb']['selected'] = true + h['Microsoft.VisualStudio.Workload.Node']['selected'] = true + h['Microsoft.VisualStudio.Workload.Office']['selected'] = true + h['Microsoft.VisualStudio.Workload.Universal']['selected'] = true + h['Microsoft.VisualStudio.Workload.VisualStudioExtension']['selected'] = true + h['Microsoft.VisualStudio.Workload.WebCrossPlat']['selected'] = true + h['Component.Android.Emulator']['selected'] = true + h['Component.GitHub.VisualStudio']['selected'] = true + h['Microsoft.Component.Blend.SDK.WPF']['selected'] = true + h['Microsoft.Component.HelpViewer']['selected'] = true + h['Microsoft.Net.Component.3.5.DeveloperTools']['selected'] = true + h['Microsoft.VisualStudio.Component.DependencyValidation.Community']['selected'] = true + h['Microsoft.VisualStudio.Component.LinqToSql']['selected'] = true + h['Microsoft.VisualStudio.Component.Phone.Emulator']['selected'] = true + h['Microsoft.VisualStudio.Component.TestTools.Core']['selected'] = true + h['Microsoft.VisualStudio.Component.TypeScript.2.0']['selected'] = true +end + +# Community w/Update 3 +default['visualstudio']['2017']['community']['installer_file'] = 'vs_community.exe' +default['visualstudio']['2017']['community']['filename'] = 'vs_community.exe' +default['visualstudio']['2017']['community']['package_name'] = 'Microsoft Visual Studio Community 2017' +default['visualstudio']['2017']['community']['checksum'] = '' +default['visualstudio']['2017']['community']['default_source'] = 'https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=Community&rel=15' + +# Defaults for https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-community +default['visualstudio']['2017']['community']['default_install_items'].tap do |h| + h['Microsoft.VisualStudio.Workload.CoreEditor']['selected'] = true + h['Microsoft.VisualStudio.Workload.Azure']['selected'] = true + h['Microsoft.VisualStudio.Workload.Data']['selected'] = true + h['Microsoft.VisualStudio.Workload.ManagedDesktop']['selected'] = true + h['Microsoft.VisualStudio.Workload.ManagedGame']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeCrossPlat']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeDesktop']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeGame']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeMobile']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetCoreTools']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetCrossPlat']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetWeb']['selected'] = true + h['Microsoft.VisualStudio.Workload.Node']['selected'] = true + h['Microsoft.VisualStudio.Workload.Office']['selected'] = true + h['Microsoft.VisualStudio.Workload.Universal']['selected'] = true + h['Microsoft.VisualStudio.Workload.VisualStudioExtension']['selected'] = true + h['Microsoft.VisualStudio.Workload.WebCrossPlat']['selected'] = true + h['Component.Android.Emulator']['selected'] = true + h['Component.GitHub.VisualStudio']['selected'] = true + h['Microsoft.Component.Blend.SDK.WPF']['selected'] = true + h['Microsoft.Component.HelpViewer']['selected'] = true + h['Microsoft.Net.Component.3.5.DeveloperTools']['selected'] = true + h['Microsoft.VisualStudio.Component.DependencyValidation.Community']['selected'] = true + h['Microsoft.VisualStudio.Component.LinqToSql']['selected'] = true + h['Microsoft.VisualStudio.Component.Phone.Emulator']['selected'] = true + h['Microsoft.VisualStudio.Component.TestTools.Core']['selected'] = true + h['Microsoft.VisualStudio.Component.TypeScript.2.0']['selected'] = true +end + +# Enterprise w/Update1 +default['visualstudio']['2017']['enterprise']['installer_file'] = 'vs_enterprise.exe' +default['visualstudio']['2017']['enterprise']['filename'] = 'vs_enterprise.exe' +default['visualstudio']['2017']['enterprise']['package_name'] = 'Microsoft Visual Studio Enterprise 2017' +default['visualstudio']['2017']['enterprise']['checksum'] = '' +default['visualstudio']['2017']['enterprise']['default_source'] = 'https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=Enterprise&rel=15' + +# Defaults for the https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-enterprise +default['visualstudio']['2017']['enterprise']['default_install_items'].tap do |h| + h['Microsoft.VisualStudio.Workload.CoreEditor']['selected'] = true + h['Microsoft.VisualStudio.Workload.Azure']['selected'] = true + h['Microsoft.VisualStudio.Workload.Data']['selected'] = true + h['Microsoft.VisualStudio.Workload.ManagedDesktop']['selected'] = true + h['Microsoft.VisualStudio.Workload.ManagedGame']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeCrossPlat']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeDesktop']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeGame']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeMobile']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetCoreTools']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetCrossPlat']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetWeb']['selected'] = true + h['Microsoft.VisualStudio.Workload.Node']['selected'] = true + h['Microsoft.VisualStudio.Workload.Office']['selected'] = true + h['Microsoft.VisualStudio.Workload.Universal']['selected'] = true + h['Microsoft.VisualStudio.Workload.VisualStudioExtension']['selected'] = true + h['Microsoft.VisualStudio.Workload.WebCrossPlat']['selected'] = true + h['Component.Android.Emulator']['selected'] = true + h['Component.GitHub.VisualStudio']['selected'] = true + h['Microsoft.Component.Blend.SDK.WPF']['selected'] = true + h['Microsoft.Component.HelpViewer']['selected'] = true + h['Microsoft.Net.Component.3.5.DeveloperTools']['selected'] = true + h['Microsoft.VisualStudio.Component.LinqToSql']['selected'] = true + h['Microsoft.VisualStudio.Component.Phone.Emulator']['selected'] = true + h['Microsoft.VisualStudio.Component.TestTools.CodedUITest']['selected'] = true + h['Microsoft.VisualStudio.Component.TestTools.Core']['selected'] = true + h['Microsoft.VisualStudio.Component.TestTools.FeedbackClient']['selected'] = true + h['Microsoft.VisualStudio.Component.TestTools.MicrosoftTestManager']['selected'] = true + h['Microsoft.VisualStudio.Component.TestTools.WebLoadTest']['selected'] = true + h['Microsoft.VisualStudio.Component.TestTools.Core']['selected'] = true + h['Microsoft.VisualStudio.Component.TypeScript.2.0']['selected'] = true +end diff --git a/providers/edition.rb b/providers/edition.rb index 97b393d..856bf0b 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -41,7 +41,16 @@ def whyrun_supported? source new_resource.source overwrite true checksum new_resource.checksum - not_if { new_resource.source == nil } + only_if { new_resource.source != nil and extractable_download } + end + + # Not an ISO but the web install + remote_file "download__#{new_resource.version}_#{new_resource.edition}" do + path installer_exe + source new_resource.source + overwrite true + checksum new_resource.checksum + only_if { new_resource.source != nil and !extractable_download } end # Ensure the target directory exists so logging doesn't fail on VS 2010 @@ -49,14 +58,11 @@ def whyrun_supported? path new_resource.install_dir recursive true end - - # Install Visual Studio - setup_options = new_resource.version == '2010' ? prepare_vs2010_options : prepare_vs_options - + windows_package new_resource.package_name do source installer_exe installer_type :custom - options setup_options + options visual_studio_options timeout 3600 # 1hour returns [0, 127, 3010] end @@ -66,13 +72,17 @@ def whyrun_supported? path extracted_iso_dir action :delete recursive true - not_if { new_resource.source == nil or new_resource.preserve_extracted_files } + only_if { new_resource.source != nil and !new_resource.preserve_extracted_files } end end new_resource.updated_by_last_action(true) end end +def extractable_download + ::File.extname(new_resource.source).downcase == '.iso' or ::File.extname(new_resource.source).downcase == '.zip' ::File.extname(new_resource.source).downcase == '.7z') +end + def prepare_vs_options config_path = create_vs_admin_deployment_file setup_options = "/Q /norestart /noweb /log \"#{install_log_file}\" /adminfile \"#{config_path}\"" @@ -124,6 +134,28 @@ def create_vs2010_unattend_file config_path end +def prepare_vs2017_options + # Merge the VS version and edition default AdminDeploymentFile.xml item's with customized install_items + install_items = deep_merge(node['visualstudio'][new_resource.version.to_s][new_resource.edition.to_s]['default_install_items'], Mash.new) + workloads_and_components_to_install = '' + + install_items.each do |key, attributes| + if attributes.has_key?('selected') + should_install = attributes['selected'] ? 'yes' : 'no' + if (should_install) + workloads_and_components_to_install << " --add #{key}" + end + end + end + workloads_and_components_to_install = ' --all' if workloads_and_components_to_install.blank? + + setup_options = '--norestart --quiet --wait' + setup_options << " --installPath \"#{new_resource.install_dir}\"" unless new_resource.install_dir.blank? + setup_options << workloads_and_components_to_install + + setup_options +end + def utf8_to_unicode(file_path) powershell_script "convert #{file_path} to unicode" do code( @@ -136,6 +168,10 @@ def install_log_file win_friendly_path(::File.join(new_resource.install_dir, 'vsinstall.log')) end +def visual_studio_options + new_resource.version == '2010' ? prepare_vs2010_options : new_resource.version == '2017' ? prepare_vs2017_options : prepare_vs_options +end + def installer_exe installer = new_resource.installer_file || "vs_#{new_resource.edition}.exe" installer = ::File.join(extracted_iso_dir, installer) unless new_resource.source == nil From 623e5c75df4f3c5507937828f90a480701fea13e Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Thu, 27 Apr 2017 09:13:57 +0100 Subject: [PATCH 12/38] Better to use casecmp instead of downcase == --- providers/edition.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/edition.rb b/providers/edition.rb index 856bf0b..bb596fa 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -80,7 +80,7 @@ def whyrun_supported? end def extractable_download - ::File.extname(new_resource.source).downcase == '.iso' or ::File.extname(new_resource.source).downcase == '.zip' ::File.extname(new_resource.source).downcase == '.7z') + (::File.extname(new_resource.source).casecmp(".iso")) == 0 or (::File.extname(new_resource.source).casecmp(".zip")) == 0 or (::File.extname(new_resource.source).casecmp(".7z")) == 0 end def prepare_vs_options From a96ccea74ec03f6062a4021f7f1216ca51951f35 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Thu, 27 Apr 2017 09:32:31 +0100 Subject: [PATCH 13/38] Source is a required parameter, so only evaluate when we know its not null --- providers/edition.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/edition.rb b/providers/edition.rb index bb596fa..c4d8d39 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -47,7 +47,7 @@ def whyrun_supported? # Not an ISO but the web install remote_file "download__#{new_resource.version}_#{new_resource.edition}" do path installer_exe - source new_resource.source + source lazy { new_resource.source } overwrite true checksum new_resource.checksum only_if { new_resource.source != nil and !extractable_download } From 5e74354af1dfb7f26a69b8e65551412b3f7e9fe0 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Thu, 27 Apr 2017 09:37:32 +0100 Subject: [PATCH 14/38] Use preferred ruby style for checking if nil --- providers/edition.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/providers/edition.rb b/providers/edition.rb index c4d8d39..78b6a08 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -41,7 +41,7 @@ def whyrun_supported? source new_resource.source overwrite true checksum new_resource.checksum - only_if { new_resource.source != nil and extractable_download } + only_if { (!new_resource.source.nil?) and extractable_download } end # Not an ISO but the web install @@ -50,7 +50,7 @@ def whyrun_supported? source lazy { new_resource.source } overwrite true checksum new_resource.checksum - only_if { new_resource.source != nil and !extractable_download } + only_if { (!new_resource.source.nil?) and (!extractable_download) } end # Ensure the target directory exists so logging doesn't fail on VS 2010 @@ -72,7 +72,7 @@ def whyrun_supported? path extracted_iso_dir action :delete recursive true - only_if { new_resource.source != nil and !new_resource.preserve_extracted_files } + only_if { (!new_resource.source.nil?) and (!new_resource.preserve_extracted_files) } end end new_resource.updated_by_last_action(true) @@ -174,7 +174,7 @@ def visual_studio_options def installer_exe installer = new_resource.installer_file || "vs_#{new_resource.edition}.exe" - installer = ::File.join(extracted_iso_dir, installer) unless new_resource.source == nil + installer = ::File.join(extracted_iso_dir, installer) unless new_resource.source.nil? installer end From 0dcb25d60c9034747896cd91d2ff932c468c15c3 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Thu, 27 Apr 2017 09:44:33 +0100 Subject: [PATCH 15/38] Property does not exist (copied over from seven_zip extract) --- providers/edition.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/providers/edition.rb b/providers/edition.rb index 78b6a08..07a0a9a 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -48,7 +48,6 @@ def whyrun_supported? remote_file "download__#{new_resource.version}_#{new_resource.edition}" do path installer_exe source lazy { new_resource.source } - overwrite true checksum new_resource.checksum only_if { (!new_resource.source.nil?) and (!extractable_download) } end From ac05ea97737b68f13a4d7558ab44252c83280a58 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Thu, 27 Apr 2017 09:52:39 +0100 Subject: [PATCH 16/38] Use empty instead of blank --- providers/edition.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/providers/edition.rb b/providers/edition.rb index 07a0a9a..926640b 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -146,10 +146,10 @@ def prepare_vs2017_options end end end - workloads_and_components_to_install = ' --all' if workloads_and_components_to_install.blank? + workloads_and_components_to_install = ' --all' if workloads_and_components_to_install.empty? setup_options = '--norestart --quiet --wait' - setup_options << " --installPath \"#{new_resource.install_dir}\"" unless new_resource.install_dir.blank? + setup_options << " --installPath \"#{new_resource.install_dir}\"" unless new_resource.install_dir.empty? setup_options << workloads_and_components_to_install setup_options From f0589bf533063a7c581903e9aa5c9bcab00b3bed Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Thu, 27 Apr 2017 11:38:56 +0100 Subject: [PATCH 17/38] Display whats going on for debug purposes --- providers/edition.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/edition.rb b/providers/edition.rb index 926640b..b649652 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -148,7 +148,7 @@ def prepare_vs2017_options end workloads_and_components_to_install = ' --all' if workloads_and_components_to_install.empty? - setup_options = '--norestart --quiet --wait' + setup_options = '--norestart --passive --wait' setup_options << " --installPath \"#{new_resource.install_dir}\"" unless new_resource.install_dir.empty? setup_options << workloads_and_components_to_install From a9af16ab3e77506d8a919738184d875c7b283b43 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Fri, 28 Apr 2017 09:25:44 +0100 Subject: [PATCH 18/38] Deal with the following installation options: --all Optional: Whether to install all workloads and components for a product. --allWorkloads Optional: Installs all workloads and their required components, no recommended or optional components. --includeRecommended Optional: Includes the recommended components for any workloads that are installed, but not the optional components. The workloads are specified either with --allWorkloads or --add. --includeOptional Optional: Includes the optional components for any workloads that are installed, but not the recommended components. The workloads are specified either with --allWorkloads or --add. --- attributes/vs2017.rb | 4 ++++ providers/edition.rb | 20 ++++++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/attributes/vs2017.rb b/attributes/vs2017.rb index 19a41d2..6fe567d 100644 --- a/attributes/vs2017.rb +++ b/attributes/vs2017.rb @@ -21,6 +21,10 @@ # Currently you cannot change this, doing so will break the cookbook default['visualstudio']['2017']['install_dir'] = (ENV['ProgramFiles(x86)'] || 'C:\Program Files (x86)') + '\Microsoft Visual Studio 16.0' +default['visualstudio']['2017']['all'] = false +default['visualstudio']['2017']['allWorkloads'] = false +default['visualstudio']['2017']['includeRecommended'] = true +default['visualstudio']['2017']['includeOptional'] = false # Test Professional w/Update1 https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-test-professional default['visualstudio']['2017']['testprofessional']['installer_file'] = 'vs_testprofessional.exe' diff --git a/providers/edition.rb b/providers/edition.rb index b649652..356c1bb 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -134,23 +134,31 @@ def create_vs2010_unattend_file end def prepare_vs2017_options + + option_all = node['visualstudio'][new_resource.version.to_s]['all'] + option_allWorkloads = node['visualstudio'][new_resource.version.to_s]['allWorkloads'] + option_includeRecommended = node['visualstudio'][new_resource.version.to_s]['includeRecommended'] + option_include_optional = node['visualstudio'][new_resource.version.to_s]['includeOptional'] + options_components_to_install = '' + # Merge the VS version and edition default AdminDeploymentFile.xml item's with customized install_items install_items = deep_merge(node['visualstudio'][new_resource.version.to_s][new_resource.edition.to_s]['default_install_items'], Mash.new) - workloads_and_components_to_install = '' - install_items.each do |key, attributes| if attributes.has_key?('selected') should_install = attributes['selected'] ? 'yes' : 'no' if (should_install) - workloads_and_components_to_install << " --add #{key}" + options_components_to_install << " --add #{key}" end end end - workloads_and_components_to_install = ' --all' if workloads_and_components_to_install.empty? - setup_options = '--norestart --passive --wait' + setup_options = '--norestart --quiet --wait' setup_options << " --installPath \"#{new_resource.install_dir}\"" unless new_resource.install_dir.empty? - setup_options << workloads_and_components_to_install + setup_options << " --all" if option_all + setup_options << " --allWorkloads" if option_allWorkloads && !option_all + setup_options << " --includeRecommended" if option_includeRecommended && !option_all + setup_options << " --includeOptional" if option_include_optional && !option_all + setup_options << options_components_to_install unless options_components_to_install.empty? || option_all || option_allWorkloads setup_options end From 6905bdd98dc0e844f9ce0ef53f2720d4687a3dea Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Fri, 28 Apr 2017 11:01:25 +0100 Subject: [PATCH 19/38] Takes a long time, lets see what the progress is --- providers/edition.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/edition.rb b/providers/edition.rb index 356c1bb..4bf6d11 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -152,7 +152,7 @@ def prepare_vs2017_options end end - setup_options = '--norestart --quiet --wait' + setup_options = '--norestart --passive --wait' setup_options << " --installPath \"#{new_resource.install_dir}\"" unless new_resource.install_dir.empty? setup_options << " --all" if option_all setup_options << " --allWorkloads" if option_allWorkloads && !option_all From e0c2a03ef9ea990be4b86b338735c2baeee155bd Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Fri, 28 Apr 2017 12:14:36 +0100 Subject: [PATCH 20/38] At the moment Visual Studio is waiting on user input if its run from commandline and its already installed. Perhaps passing in all the options will stop that. --- providers/edition.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/providers/edition.rb b/providers/edition.rb index 4bf6d11..8b7724b 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -155,10 +155,10 @@ def prepare_vs2017_options setup_options = '--norestart --passive --wait' setup_options << " --installPath \"#{new_resource.install_dir}\"" unless new_resource.install_dir.empty? setup_options << " --all" if option_all - setup_options << " --allWorkloads" if option_allWorkloads && !option_all - setup_options << " --includeRecommended" if option_includeRecommended && !option_all - setup_options << " --includeOptional" if option_include_optional && !option_all - setup_options << options_components_to_install unless options_components_to_install.empty? || option_all || option_allWorkloads + setup_options << " --allWorkloads" if option_allWorkloads + setup_options << " --includeRecommended" if option_includeRecommended + setup_options << " --includeOptional" if option_include_optional + setup_options << options_components_to_install unless options_components_to_install.empty? setup_options end From aaeb2d937947216d36485676c2d1273b39e2b70a Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Tue, 2 May 2017 13:24:13 +0100 Subject: [PATCH 21/38] Just enumerate attributes directly. --- providers/edition.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/providers/edition.rb b/providers/edition.rb index 8b7724b..35552e0 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -141,12 +141,10 @@ def prepare_vs2017_options option_include_optional = node['visualstudio'][new_resource.version.to_s]['includeOptional'] options_components_to_install = '' - # Merge the VS version and edition default AdminDeploymentFile.xml item's with customized install_items - install_items = deep_merge(node['visualstudio'][new_resource.version.to_s][new_resource.edition.to_s]['default_install_items'], Mash.new) - install_items.each do |key, attributes| + # Merge the VS version and edition default AdminDeploymentFile.xml item's with customized install_items + node['visualstudio'][new_resource.version.to_s][new_resource.edition.to_s]['default_install_items'].each do |key, attributes| if attributes.has_key?('selected') - should_install = attributes['selected'] ? 'yes' : 'no' - if (should_install) + if (attributes['selected') options_components_to_install << " --add #{key}" end end From a5950026222f471beb358f4f275dda04931e7e26 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Tue, 2 May 2017 13:27:55 +0100 Subject: [PATCH 22/38] Added missing square bracket --- providers/edition.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/edition.rb b/providers/edition.rb index 35552e0..cdea239 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -144,7 +144,7 @@ def prepare_vs2017_options # Merge the VS version and edition default AdminDeploymentFile.xml item's with customized install_items node['visualstudio'][new_resource.version.to_s][new_resource.edition.to_s]['default_install_items'].each do |key, attributes| if attributes.has_key?('selected') - if (attributes['selected') + if (attributes['selected']) options_components_to_install << " --add #{key}" end end From 19bd9d7c55efd142da41653e99568828829beae9 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Tue, 2 May 2017 16:46:22 +0100 Subject: [PATCH 23/38] Update documentation for Visual Studio 2017 and network installs --- README.md | 47 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index eef127f..1f2b92f 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,14 @@ [![Build status](https://ci.appveyor.com/api/projects/status/ttumjhmmxjo5j7gv/branch/master?svg=true)](https://ci.appveyor.com/project/ChefWindowsCookbooks65871/visualstudio/branch/master) # VisualStudio Cookbook -This Chef cookbook installs Visual Studio 2010, 2012, 2013, 2015 from an ISO. +This Chef cookbook installs Visual Studio 2010, 2012, 2013, 2015, 2017 from an ISO or folder/network location. # Requirements This cookbook assumes the appropriate version of the .NET framework has already been installed before running the VisualStudio cookbook. To install .NET you can use the [dotnetframework cookbook](https://supermarket.chef.io/cookbooks/dotnetframework). You must reboot the system after the .NET installation and before the VisualStudio installation. - VisualStudio 2010, 2012, and 2013 require .NET 4.5.x. -- VisualStudio 2015 requires .NET 4.6. +- VisualStudio 2015, 2017 requires .NET 4.6. This cookbook requires 7-zip to be installed so it can extract the ISO. To ensure this happens this cookbook includes the [seven_zip](https://supermarket.chef.io/cookbooks/seven_zip) default recipe. @@ -30,6 +30,10 @@ NOTE - This cookbook cannot be installed over naked WinRM, i.e. knife-winrm with - 2015 Professional - 2015 Test Professional - 2015 Community +- 2017 Enterprise +- 2017 Professional +- 2017 Test Professional +- 2017 Community ## Supported OSs - Windows 7 @@ -87,7 +91,7 @@ If you _really_ want to install VS 2015 on Windows Server 2012R2 over naked WinR ['visualstudio']['version'] Integer - The VisualStudio version to install, i.e. 2010, 2012, 2013, 2015. + The VisualStudio version to install, i.e. 2010, 2012, 2013, 2015, 2017. 2015 @@ -118,7 +122,7 @@ If you _really_ want to install VS 2015 on Windows Server 2012R2 over naked WinR # Usage -Add `'visualstudio::default'` to your runlist. This will install VS 2015 Community Edition from the publicly available ISO. If you'd like to install another edition set the 'edition' attribute to: 'community', 'professional', 'premium', or 'testprofessional'. If you'd like to install a different version set the 'version' attribute to: '2010', '2012', '2013', '2015'. +Add `'visualstudio::default'` to your runlist. This will install VS 2015 Community Edition from the publicly available ISO. If you'd like to install another edition set the 'edition' attribute to: 'community', 'professional', 'premium', or 'testprofessional'. If you'd like to install a different version set the 'version' attribute to: '2010', '2012', '2013', '2015', '2017'. If you need to install multiple different versions/editions of VisualStudio on the same node you must instead set the 'installs' attribute. If the installs attribute is set then the version and edition attributes are ignored. @@ -142,10 +146,41 @@ node.override['visualstudio']['2013']['professional']['source'] = 'https://myart VisualStudio 2013 and newer have default public download links for all their ISOs. If you're using an older version (2010, 2012) you must first set a download source. Either set the global `node['visualstudio']['source']` download URL or the version/edition specific download source, e.g. `node['visualstudio']['2012']['professional']['source']`. You can also use these same attributes to override the ISO location for newer VS versions. +VisualStudio 2017 does not have an ISO installer. You have to use web installer. For faster installs you can cache the Visual Studio installation files on a network share using the offline install cache. + +To run an installation from a network share, set the following: + +```ruby +node.override['visualstudio']['version'] = '2017' +node.override['visualstudio']['edition'] = 'professional' +node.override['visualstudio']['source'] = '' +node.override['visualstudio']['2017']['professional']['default_source'] = '' +node.override['visualstudio']['2017']['professional']['source'] = '' +node.override['visualstudio']['2017']['professional']['filename'] = '' +node.override['visualstudio']['2017']['professional']['checksum'] = nil +node.override['visualstudio']['2017']['professional']['installer_file'] = '//myartifactrepo/visualstudio/vs_professional.exe' +``` + ## Customizing Installed Features -### VS 2012 and Newer +### VS 2017 or newer + +To customize the command line install options for adding workloads for an unattended install in Visual Studio 2017 or newer edit the node attribute `node['visualstudio']['2017']['professional']['default_install_items']` +adding the 'id' of the workload you want to install. The attribute 'Selected' can be set to a boolean value. + +For example: +`node['visualstudio']['2017']['professional']['default_install_items']['Microsoft.VisualStudio.Workload.CoreEditor']['selected']= true` + +There are also 4 additional command line arguments that can be set: +```ruby +node.override['visualstudio']['2017']['all'] = true +node.override['visualstudio']['2017']['allWorkloads'] = true +node.override['visualstudio']['2017']['includeRecommended'] = true +node.override['visualstudio']['2017']['includeOptional'] = true +``` + +### VS 2012 to VS 2015 -To customize the AdminDeployment.xml file for adding features to an unattended install in VisualStudio 2012 and newer edit the node attribute `node['visualstudio']['install_items']` +To customize the AdminDeployment.xml file for adding features to an unattended install in VisualStudio 2012 to Visual Studio 2015 edit the node attribute `node['visualstudio']['install_items']` adding the 'id' of the `` you want to install, it's 'Selected', 'Hidden', and 'FriendlyName' can then be set assuming the item has the attribute(s). For example: From 93ac50d5627f2dc6251998f91bb84d69ac2c0940 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Tue, 2 May 2017 17:59:35 +0100 Subject: [PATCH 24/38] Rubocop suggestions --- attributes/vs2017.rb | 170 +++++++++++++++++++++---------------------- providers/edition.rb | 35 +++++---- 2 files changed, 105 insertions(+), 100 deletions(-) diff --git a/attributes/vs2017.rb b/attributes/vs2017.rb index 6fe567d..0d375aa 100644 --- a/attributes/vs2017.rb +++ b/attributes/vs2017.rb @@ -42,33 +42,33 @@ # Defaults for https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-professional default['visualstudio']['2017']['professional']['default_install_items'].tap do |h| - h['Microsoft.VisualStudio.Workload.CoreEditor']['selected'] = true - h['Microsoft.VisualStudio.Workload.Azure']['selected'] = true - h['Microsoft.VisualStudio.Workload.Data']['selected'] = true - h['Microsoft.VisualStudio.Workload.ManagedDesktop']['selected'] = true - h['Microsoft.VisualStudio.Workload.ManagedGame']['selected'] = true - h['Microsoft.VisualStudio.Workload.NativeCrossPlat']['selected'] = true - h['Microsoft.VisualStudio.Workload.NativeDesktop']['selected'] = true - h['Microsoft.VisualStudio.Workload.NativeGame']['selected'] = true - h['Microsoft.VisualStudio.Workload.NativeMobile']['selected'] = true - h['Microsoft.VisualStudio.Workload.NetCoreTools']['selected'] = true - h['Microsoft.VisualStudio.Workload.NetCrossPlat']['selected'] = true - h['Microsoft.VisualStudio.Workload.NetWeb']['selected'] = true - h['Microsoft.VisualStudio.Workload.Node']['selected'] = true - h['Microsoft.VisualStudio.Workload.Office']['selected'] = true - h['Microsoft.VisualStudio.Workload.Universal']['selected'] = true - h['Microsoft.VisualStudio.Workload.VisualStudioExtension']['selected'] = true - h['Microsoft.VisualStudio.Workload.WebCrossPlat']['selected'] = true - h['Component.Android.Emulator']['selected'] = true - h['Component.GitHub.VisualStudio']['selected'] = true - h['Microsoft.Component.Blend.SDK.WPF']['selected'] = true - h['Microsoft.Component.HelpViewer']['selected'] = true - h['Microsoft.Net.Component.3.5.DeveloperTools']['selected'] = true - h['Microsoft.VisualStudio.Component.DependencyValidation.Community']['selected'] = true - h['Microsoft.VisualStudio.Component.LinqToSql']['selected'] = true - h['Microsoft.VisualStudio.Component.Phone.Emulator']['selected'] = true - h['Microsoft.VisualStudio.Component.TestTools.Core']['selected'] = true - h['Microsoft.VisualStudio.Component.TypeScript.2.0']['selected'] = true + h['Microsoft.VisualStudio.Workload.CoreEditor']['selected'] = true + h['Microsoft.VisualStudio.Workload.Azure']['selected'] = true + h['Microsoft.VisualStudio.Workload.Data']['selected'] = true + h['Microsoft.VisualStudio.Workload.ManagedDesktop']['selected'] = true + h['Microsoft.VisualStudio.Workload.ManagedGame']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeCrossPlat']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeDesktop']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeGame']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeMobile']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetCoreTools']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetCrossPlat']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetWeb']['selected'] = true + h['Microsoft.VisualStudio.Workload.Node']['selected'] = true + h['Microsoft.VisualStudio.Workload.Office']['selected'] = true + h['Microsoft.VisualStudio.Workload.Universal']['selected'] = true + h['Microsoft.VisualStudio.Workload.VisualStudioExtension']['selected'] = true + h['Microsoft.VisualStudio.Workload.WebCrossPlat']['selected'] = true + h['Component.Android.Emulator']['selected'] = true + h['Component.GitHub.VisualStudio']['selected'] = true + h['Microsoft.Component.Blend.SDK.WPF']['selected'] = true + h['Microsoft.Component.HelpViewer']['selected'] = true + h['Microsoft.Net.Component.3.5.DeveloperTools']['selected'] = true + h['Microsoft.VisualStudio.Component.DependencyValidation.Community']['selected'] = true + h['Microsoft.VisualStudio.Component.LinqToSql']['selected'] = true + h['Microsoft.VisualStudio.Component.Phone.Emulator']['selected'] = true + h['Microsoft.VisualStudio.Component.TestTools.Core']['selected'] = true + h['Microsoft.VisualStudio.Component.TypeScript.2.0']['selected'] = true end # Community w/Update 3 @@ -80,33 +80,33 @@ # Defaults for https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-community default['visualstudio']['2017']['community']['default_install_items'].tap do |h| - h['Microsoft.VisualStudio.Workload.CoreEditor']['selected'] = true - h['Microsoft.VisualStudio.Workload.Azure']['selected'] = true - h['Microsoft.VisualStudio.Workload.Data']['selected'] = true - h['Microsoft.VisualStudio.Workload.ManagedDesktop']['selected'] = true - h['Microsoft.VisualStudio.Workload.ManagedGame']['selected'] = true - h['Microsoft.VisualStudio.Workload.NativeCrossPlat']['selected'] = true - h['Microsoft.VisualStudio.Workload.NativeDesktop']['selected'] = true - h['Microsoft.VisualStudio.Workload.NativeGame']['selected'] = true - h['Microsoft.VisualStudio.Workload.NativeMobile']['selected'] = true - h['Microsoft.VisualStudio.Workload.NetCoreTools']['selected'] = true - h['Microsoft.VisualStudio.Workload.NetCrossPlat']['selected'] = true - h['Microsoft.VisualStudio.Workload.NetWeb']['selected'] = true - h['Microsoft.VisualStudio.Workload.Node']['selected'] = true - h['Microsoft.VisualStudio.Workload.Office']['selected'] = true - h['Microsoft.VisualStudio.Workload.Universal']['selected'] = true - h['Microsoft.VisualStudio.Workload.VisualStudioExtension']['selected'] = true - h['Microsoft.VisualStudio.Workload.WebCrossPlat']['selected'] = true - h['Component.Android.Emulator']['selected'] = true - h['Component.GitHub.VisualStudio']['selected'] = true - h['Microsoft.Component.Blend.SDK.WPF']['selected'] = true - h['Microsoft.Component.HelpViewer']['selected'] = true - h['Microsoft.Net.Component.3.5.DeveloperTools']['selected'] = true - h['Microsoft.VisualStudio.Component.DependencyValidation.Community']['selected'] = true - h['Microsoft.VisualStudio.Component.LinqToSql']['selected'] = true - h['Microsoft.VisualStudio.Component.Phone.Emulator']['selected'] = true - h['Microsoft.VisualStudio.Component.TestTools.Core']['selected'] = true - h['Microsoft.VisualStudio.Component.TypeScript.2.0']['selected'] = true + h['Microsoft.VisualStudio.Workload.CoreEditor']['selected'] = true + h['Microsoft.VisualStudio.Workload.Azure']['selected'] = true + h['Microsoft.VisualStudio.Workload.Data']['selected'] = true + h['Microsoft.VisualStudio.Workload.ManagedDesktop']['selected'] = true + h['Microsoft.VisualStudio.Workload.ManagedGame']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeCrossPlat']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeDesktop']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeGame']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeMobile']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetCoreTools']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetCrossPlat']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetWeb']['selected'] = true + h['Microsoft.VisualStudio.Workload.Node']['selected'] = true + h['Microsoft.VisualStudio.Workload.Office']['selected'] = true + h['Microsoft.VisualStudio.Workload.Universal']['selected'] = true + h['Microsoft.VisualStudio.Workload.VisualStudioExtension']['selected'] = true + h['Microsoft.VisualStudio.Workload.WebCrossPlat']['selected'] = true + h['Component.Android.Emulator']['selected'] = true + h['Component.GitHub.VisualStudio']['selected'] = true + h['Microsoft.Component.Blend.SDK.WPF']['selected'] = true + h['Microsoft.Component.HelpViewer']['selected'] = true + h['Microsoft.Net.Component.3.5.DeveloperTools']['selected'] = true + h['Microsoft.VisualStudio.Component.DependencyValidation.Community']['selected'] = true + h['Microsoft.VisualStudio.Component.LinqToSql']['selected'] = true + h['Microsoft.VisualStudio.Component.Phone.Emulator']['selected'] = true + h['Microsoft.VisualStudio.Component.TestTools.Core']['selected'] = true + h['Microsoft.VisualStudio.Component.TypeScript.2.0']['selected'] = true end # Enterprise w/Update1 @@ -118,35 +118,35 @@ # Defaults for the https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-enterprise default['visualstudio']['2017']['enterprise']['default_install_items'].tap do |h| - h['Microsoft.VisualStudio.Workload.CoreEditor']['selected'] = true - h['Microsoft.VisualStudio.Workload.Azure']['selected'] = true - h['Microsoft.VisualStudio.Workload.Data']['selected'] = true - h['Microsoft.VisualStudio.Workload.ManagedDesktop']['selected'] = true - h['Microsoft.VisualStudio.Workload.ManagedGame']['selected'] = true - h['Microsoft.VisualStudio.Workload.NativeCrossPlat']['selected'] = true - h['Microsoft.VisualStudio.Workload.NativeDesktop']['selected'] = true - h['Microsoft.VisualStudio.Workload.NativeGame']['selected'] = true - h['Microsoft.VisualStudio.Workload.NativeMobile']['selected'] = true - h['Microsoft.VisualStudio.Workload.NetCoreTools']['selected'] = true - h['Microsoft.VisualStudio.Workload.NetCrossPlat']['selected'] = true - h['Microsoft.VisualStudio.Workload.NetWeb']['selected'] = true - h['Microsoft.VisualStudio.Workload.Node']['selected'] = true - h['Microsoft.VisualStudio.Workload.Office']['selected'] = true - h['Microsoft.VisualStudio.Workload.Universal']['selected'] = true - h['Microsoft.VisualStudio.Workload.VisualStudioExtension']['selected'] = true - h['Microsoft.VisualStudio.Workload.WebCrossPlat']['selected'] = true - h['Component.Android.Emulator']['selected'] = true - h['Component.GitHub.VisualStudio']['selected'] = true - h['Microsoft.Component.Blend.SDK.WPF']['selected'] = true - h['Microsoft.Component.HelpViewer']['selected'] = true - h['Microsoft.Net.Component.3.5.DeveloperTools']['selected'] = true - h['Microsoft.VisualStudio.Component.LinqToSql']['selected'] = true - h['Microsoft.VisualStudio.Component.Phone.Emulator']['selected'] = true - h['Microsoft.VisualStudio.Component.TestTools.CodedUITest']['selected'] = true - h['Microsoft.VisualStudio.Component.TestTools.Core']['selected'] = true - h['Microsoft.VisualStudio.Component.TestTools.FeedbackClient']['selected'] = true - h['Microsoft.VisualStudio.Component.TestTools.MicrosoftTestManager']['selected'] = true - h['Microsoft.VisualStudio.Component.TestTools.WebLoadTest']['selected'] = true - h['Microsoft.VisualStudio.Component.TestTools.Core']['selected'] = true - h['Microsoft.VisualStudio.Component.TypeScript.2.0']['selected'] = true + h['Microsoft.VisualStudio.Workload.CoreEditor']['selected'] = true + h['Microsoft.VisualStudio.Workload.Azure']['selected'] = true + h['Microsoft.VisualStudio.Workload.Data']['selected'] = true + h['Microsoft.VisualStudio.Workload.ManagedDesktop']['selected'] = true + h['Microsoft.VisualStudio.Workload.ManagedGame']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeCrossPlat']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeDesktop']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeGame']['selected'] = true + h['Microsoft.VisualStudio.Workload.NativeMobile']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetCoreTools']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetCrossPlat']['selected'] = true + h['Microsoft.VisualStudio.Workload.NetWeb']['selected'] = true + h['Microsoft.VisualStudio.Workload.Node']['selected'] = true + h['Microsoft.VisualStudio.Workload.Office']['selected'] = true + h['Microsoft.VisualStudio.Workload.Universal']['selected'] = true + h['Microsoft.VisualStudio.Workload.VisualStudioExtension']['selected'] = true + h['Microsoft.VisualStudio.Workload.WebCrossPlat']['selected'] = true + h['Component.Android.Emulator']['selected'] = true + h['Component.GitHub.VisualStudio']['selected'] = true + h['Microsoft.Component.Blend.SDK.WPF']['selected'] = true + h['Microsoft.Component.HelpViewer']['selected'] = true + h['Microsoft.Net.Component.3.5.DeveloperTools']['selected'] = true + h['Microsoft.VisualStudio.Component.LinqToSql']['selected'] = true + h['Microsoft.VisualStudio.Component.Phone.Emulator']['selected'] = true + h['Microsoft.VisualStudio.Component.TestTools.CodedUITest']['selected'] = true + h['Microsoft.VisualStudio.Component.TestTools.Core']['selected'] = true + h['Microsoft.VisualStudio.Component.TestTools.FeedbackClient']['selected'] = true + h['Microsoft.VisualStudio.Component.TestTools.MicrosoftTestManager']['selected'] = true + h['Microsoft.VisualStudio.Component.TestTools.WebLoadTest']['selected'] = true + h['Microsoft.VisualStudio.Component.TestTools.Core']['selected'] = true + h['Microsoft.VisualStudio.Component.TypeScript.2.0']['selected'] = true end diff --git a/providers/edition.rb b/providers/edition.rb index cdea239..8e0efa7 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -41,7 +41,7 @@ def whyrun_supported? source new_resource.source overwrite true checksum new_resource.checksum - only_if { (!new_resource.source.nil?) and extractable_download } + only_if { !new_resource.source.nil? and extractable_download } end # Not an ISO but the web install @@ -49,7 +49,7 @@ def whyrun_supported? path installer_exe source lazy { new_resource.source } checksum new_resource.checksum - only_if { (!new_resource.source.nil?) and (!extractable_download) } + only_if { !new_resource.source.nil? and !extractable_download } end # Ensure the target directory exists so logging doesn't fail on VS 2010 @@ -57,7 +57,7 @@ def whyrun_supported? path new_resource.install_dir recursive true end - + windows_package new_resource.package_name do source installer_exe installer_type :custom @@ -71,7 +71,7 @@ def whyrun_supported? path extracted_iso_dir action :delete recursive true - only_if { (!new_resource.source.nil?) and (!new_resource.preserve_extracted_files) } + only_if { !new_resource.source.nil? and !new_resource.preserve_extracted_files } end end new_resource.updated_by_last_action(true) @@ -79,7 +79,7 @@ def whyrun_supported? end def extractable_download - (::File.extname(new_resource.source).casecmp(".iso")) == 0 or (::File.extname(new_resource.source).casecmp(".zip")) == 0 or (::File.extname(new_resource.source).casecmp(".7z")) == 0 + ::File.extname(new_resource.source).casecmp('.iso').zero? || ::File.extname(new_resource.source).casecmp('.zip').zero? || ::File.extname(new_resource.source).casecmp('.7z').zero? end def prepare_vs_options @@ -134,28 +134,27 @@ def create_vs2010_unattend_file end def prepare_vs2017_options - option_all = node['visualstudio'][new_resource.version.to_s]['all'] - option_allWorkloads = node['visualstudio'][new_resource.version.to_s]['allWorkloads'] - option_includeRecommended = node['visualstudio'][new_resource.version.to_s]['includeRecommended'] + option_all_workloads = node['visualstudio'][new_resource.version.to_s]['allWorkloads'] + option_include_recommended = node['visualstudio'][new_resource.version.to_s]['includeRecommended'] option_include_optional = node['visualstudio'][new_resource.version.to_s]['includeOptional'] options_components_to_install = '' # Merge the VS version and edition default AdminDeploymentFile.xml item's with customized install_items node['visualstudio'][new_resource.version.to_s][new_resource.edition.to_s]['default_install_items'].each do |key, attributes| if attributes.has_key?('selected') - if (attributes['selected']) - options_components_to_install << " --add #{key}" + if attributes['selected'] + options_components_to_install << " --add #{key}" end end end setup_options = '--norestart --passive --wait' setup_options << " --installPath \"#{new_resource.install_dir}\"" unless new_resource.install_dir.empty? - setup_options << " --all" if option_all - setup_options << " --allWorkloads" if option_allWorkloads - setup_options << " --includeRecommended" if option_includeRecommended - setup_options << " --includeOptional" if option_include_optional + setup_options << ' --all' if option_all + setup_options << ' --allWorkloads' if option_all_workloads + setup_options << ' --includeRecommended' if option_include_recommended + setup_options << ' --includeOptional' if option_include_optional setup_options << options_components_to_install unless options_components_to_install.empty? setup_options @@ -174,7 +173,13 @@ def install_log_file end def visual_studio_options - new_resource.version == '2010' ? prepare_vs2010_options : new_resource.version == '2017' ? prepare_vs2017_options : prepare_vs_options + if new_resource.version == '2010' + return prepare_vs2010_options + elsif new_resource.version == '2017' + return prepare_vs2017_options + else + return prepare_vs_options + end end def installer_exe From bd0ee8410d2f44171a4709159d2cba15a1f71ae7 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Tue, 2 May 2017 18:18:01 +0100 Subject: [PATCH 25/38] More rubocop suggestions --- providers/edition.rb | 50 ++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/providers/edition.rb b/providers/edition.rb index 8e0efa7..f7e0f7e 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -41,7 +41,7 @@ def whyrun_supported? source new_resource.source overwrite true checksum new_resource.checksum - only_if { !new_resource.source.nil? and extractable_download } + only_if { !new_resource.source.nil? && extractable_download } end # Not an ISO but the web install @@ -49,7 +49,7 @@ def whyrun_supported? path installer_exe source lazy { new_resource.source } checksum new_resource.checksum - only_if { !new_resource.source.nil? and !extractable_download } + only_if { !new_resource.source.nil? && !extractable_download } end # Ensure the target directory exists so logging doesn't fail on VS 2010 @@ -71,7 +71,7 @@ def whyrun_supported? path extracted_iso_dir action :delete recursive true - only_if { !new_resource.source.nil? and !new_resource.preserve_extracted_files } + only_if { !new_resource.source.nil? && !new_resource.preserve_extracted_files } end end new_resource.updated_by_last_action(true) @@ -79,7 +79,8 @@ def whyrun_supported? end def extractable_download - ::File.extname(new_resource.source).casecmp('.iso').zero? || ::File.extname(new_resource.source).casecmp('.zip').zero? || ::File.extname(new_resource.source).casecmp('.7z').zero? + extension = ::File.extname(new_resource.source) + extension.casecmp('.iso').zero? || extension.casecmp('.zip').zero? || extension.casecmp('.7z').zero? end def prepare_vs_options @@ -134,28 +135,19 @@ def create_vs2010_unattend_file end def prepare_vs2017_options - option_all = node['visualstudio'][new_resource.version.to_s]['all'] - option_all_workloads = node['visualstudio'][new_resource.version.to_s]['allWorkloads'] - option_include_recommended = node['visualstudio'][new_resource.version.to_s]['includeRecommended'] - option_include_optional = node['visualstudio'][new_resource.version.to_s]['includeOptional'] - options_components_to_install = '' - - # Merge the VS version and edition default AdminDeploymentFile.xml item's with customized install_items - node['visualstudio'][new_resource.version.to_s][new_resource.edition.to_s]['default_install_items'].each do |key, attributes| - if attributes.has_key?('selected') - if attributes['selected'] - options_components_to_install << " --add #{key}" - end - end - end + visual_studio_attributes = node['visualstudio'][new_resource.version.to_s] setup_options = '--norestart --passive --wait' setup_options << " --installPath \"#{new_resource.install_dir}\"" unless new_resource.install_dir.empty? - setup_options << ' --all' if option_all - setup_options << ' --allWorkloads' if option_all_workloads - setup_options << ' --includeRecommended' if option_include_recommended - setup_options << ' --includeOptional' if option_include_optional - setup_options << options_components_to_install unless options_components_to_install.empty? + setup_options << ' --all' if visual_studio_attributes['all'] + setup_options << ' --allWorkloads' if visual_studio_attributes['allWorkloads'] + setup_options << ' --includeRecommended' if visual_studio_attributes['includeRecommended'] + setup_options << ' --includeOptional' if visual_studio_attributes['includeOptional'] + + visual_studio_attributes[new_resource.edition.to_s]['default_install_items'].each do |key, attributes| + next unless attributes['selected'] + setup_options << " --add #{key}" + end setup_options end @@ -173,13 +165,11 @@ def install_log_file end def visual_studio_options - if new_resource.version == '2010' - return prepare_vs2010_options - elsif new_resource.version == '2017' - return prepare_vs2017_options - else - return prepare_vs_options - end + options = prepare_vs2010_options if new_resource.version == '2010' + options = prepare_vs2017_options if new_resource.version == '2017' + options = prepare_vs_options unless new_resource.version == '2010' || new_resource.version == '2017' + + options end def installer_exe From 4533909060c6c1ce47b54b7f4e6b08e5c97f53f8 Mon Sep 17 00:00:00 2001 From: Ryan Gribble Date: Fri, 14 Jul 2017 11:46:14 +1000 Subject: [PATCH 26/38] Ignores rubocop BlockLength cop for all spec and attributes files --- .rubocop.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index f4acc5c..c8fb12b 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -14,3 +14,8 @@ Metrics/LineLength: Metrics/AbcSize: Max: 25 + +Metrics/BlockLength: + Exclude: + - 'spec/**/*.rb' + - 'attributes/**/*.rb' From 45f0a1b201d22e2d844d700aeefba8f6c249eaaf Mon Sep 17 00:00:00 2001 From: Ryan Gribble Date: Fri, 14 Jul 2017 11:46:39 +1000 Subject: [PATCH 27/38] Ignores rubocop BlockLength cop for action and converge_by methods --- .rubocop.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index c8fb12b..0da8d41 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -19,3 +19,6 @@ Metrics/BlockLength: Exclude: - 'spec/**/*.rb' - 'attributes/**/*.rb' + ExcludedMethods: + - action + - converge_by \ No newline at end of file From 16e520787bb9179041f8610794331e0c3cfbf6d7 Mon Sep 17 00:00:00 2001 From: Ryan Gribble Date: Fri, 14 Jul 2017 11:47:39 +1000 Subject: [PATCH 28/38] Fixes LineLength violation --- attributes/vs2017.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/attributes/vs2017.rb b/attributes/vs2017.rb index 0d375aa..e0f5503 100644 --- a/attributes/vs2017.rb +++ b/attributes/vs2017.rb @@ -20,7 +20,8 @@ # # Currently you cannot change this, doing so will break the cookbook -default['visualstudio']['2017']['install_dir'] = (ENV['ProgramFiles(x86)'] || 'C:\Program Files (x86)') + '\Microsoft Visual Studio 16.0' +default['visualstudio']['2017']['install_dir'] = + (ENV['ProgramFiles(x86)'] || 'C:\Program Files (x86)') + '\Microsoft Visual Studio 16.0' default['visualstudio']['2017']['all'] = false default['visualstudio']['2017']['allWorkloads'] = false default['visualstudio']['2017']['includeRecommended'] = true @@ -117,7 +118,7 @@ default['visualstudio']['2017']['enterprise']['default_source'] = 'https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=Enterprise&rel=15' # Defaults for the https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-enterprise -default['visualstudio']['2017']['enterprise']['default_install_items'].tap do |h| +default['visualstudio']['2017']['enterprise']['default_install_items'].tap do |h| h['Microsoft.VisualStudio.Workload.CoreEditor']['selected'] = true h['Microsoft.VisualStudio.Workload.Azure']['selected'] = true h['Microsoft.VisualStudio.Workload.Data']['selected'] = true From cee77c90a41ac29c0f33989677c7dfef7adb7006 Mon Sep 17 00:00:00 2001 From: Ryan Gribble Date: Fri, 14 Jul 2017 11:48:01 +1000 Subject: [PATCH 29/38] Fixes LineLength violation --- libraries/helper.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/helper.rb b/libraries/helper.rb index cae167f..cfc1f35 100644 --- a/libraries/helper.rb +++ b/libraries/helper.rb @@ -29,7 +29,8 @@ def versions # Gets the version/edition ISO download URL or raises an error def source_download_url(version, edition) src = iso_source(version, edition) - assert_src_is_not_nil(src, version, edition) unless node['visualstudio'][version][edition]['installer_file'].empty? + assert_src_is_not_nil(src, version, edition) \ + unless node['visualstudio'][version][edition]['installer_file'].empty? url = nil url = ::File.join(src, node['visualstudio'][version][edition]['filename']) unless src.empty? url @@ -47,11 +48,10 @@ def iso_source(version, edition) # Fails the Chef run if the visualstudio download source is not set def assert_src_is_not_nil(src, version, edition) - if src.nil? - raise 'The ISO download source is empty! '\ - "Set the node['visualstudio']['#{version}']['#{edition}']['source'] " \ - 'or node[\'visualstudio\'][\'source\'] attribute and run again!' - end + return unless src.nil? + raise 'The ISO download source is empty! '\ + "Set the node['visualstudio']['#{version}']['#{edition}']['source'] " \ + 'or node[\'visualstudio\'][\'source\'] attribute and run again!' end def windows_package_is_installed?(package_name) From 84eb80bb5c58ecb1654d08d6fa76da6b403b7066 Mon Sep 17 00:00:00 2001 From: Ryan Gribble Date: Fri, 14 Jul 2017 11:48:49 +1000 Subject: [PATCH 30/38] Fixes cyclomatic complexity violation by splitting prepare_vs2017_options function into sub functions --- providers/edition.rb | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/providers/edition.rb b/providers/edition.rb index f7e0f7e..74fe6f5 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -135,15 +135,11 @@ def create_vs2010_unattend_file end def prepare_vs2017_options - visual_studio_attributes = node['visualstudio'][new_resource.version.to_s] - setup_options = '--norestart --passive --wait' - setup_options << " --installPath \"#{new_resource.install_dir}\"" unless new_resource.install_dir.empty? - setup_options << ' --all' if visual_studio_attributes['all'] - setup_options << ' --allWorkloads' if visual_studio_attributes['allWorkloads'] - setup_options << ' --includeRecommended' if visual_studio_attributes['includeRecommended'] - setup_options << ' --includeOptional' if visual_studio_attributes['includeOptional'] + setup_options << prepare_vs2017_options_installpath + setup_options << prepare_vs2017_options_global + visual_studio_attributes = node['visualstudio'][new_resource.version.to_s] visual_studio_attributes[new_resource.edition.to_s]['default_install_items'].each do |key, attributes| next unless attributes['selected'] setup_options << " --add #{key}" @@ -152,6 +148,25 @@ def prepare_vs2017_options setup_options end +def prepare_vs2017_options_installpath + path_option = '' + path_option = " --installPath \"#{new_resource.install_dir}\"" unless new_resource.install_dir.empty? + + path_option +end + +def prepare_vs2017_options_global + visual_studio_attributes = node['visualstudio'][new_resource.version.to_s] + + global_options = '' + global_options << ' --all' if visual_studio_attributes['all'] + global_options << ' --allWorkloads' if visual_studio_attributes['allWorkloads'] + global_options << ' --includeRecommended' if visual_studio_attributes['includeRecommended'] + global_options << ' --includeOptional' if visual_studio_attributes['includeOptional'] + + global_options +end + def utf8_to_unicode(file_path) powershell_script "convert #{file_path} to unicode" do code( From be4bb974a7790b070b4387b84e79dc28f74b13a3 Mon Sep 17 00:00:00 2001 From: Ryan Gribble Date: Fri, 14 Jul 2017 11:49:33 +1000 Subject: [PATCH 31/38] Fixes Gemfile ordering violation --- Gemfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 743d303..6733101 100644 --- a/Gemfile +++ b/Gemfile @@ -2,14 +2,14 @@ source 'http://rubygems.org' +gem 'berkshelf' +gem 'chef' gem 'chefspec' +gem 'foodcritic' +gem 'rake' gem 'rspec' gem 'rspec-core' gem 'rspec-expectations' gem 'rspec-mocks' -gem 'chef' -gem 'foodcritic' gem 'rubocop' -gem 'rake' -gem 'berkshelf' gem 'stove' From 757149ce04f6daad42b897ba8671003ab682282f Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Thu, 10 Aug 2017 08:23:59 +0100 Subject: [PATCH 32/38] Fix lint suggestions --- appveyor.yml | 2 +- libraries/helper.rb | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 2ac5c95..397a30e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -22,7 +22,7 @@ clone_depth: 1 install: - ps: net user /add $env:winrm_user $env:winrm_pass - ps: net localgroup administrators $env:winrm_user /add - - ps: Invoke-WebRequest -Uri https://packages.chef.io/stable/windows/2008r2/chefdk-0.17.17-1-x86.msi -OutFile c:\projects\chefdk.msi + - ps: Invoke-WebRequest -Uri https://packages.chef.io/files/stable/chefdk/2.0.28/windows/2016/chefdk-2.0.28-1-x86.msi -OutFile c:\projects\chefdk.msi - ps: Start-Process C:\Windows\System32\msiexec.exe -ArgumentList "/qb /i c:\projects\chefdk.msi" -wait - ps: $env:PATH="C:\Ruby$env:ruby_version\bin;$env:PATH" - bundle config --local path c:\projects\bundle diff --git a/libraries/helper.rb b/libraries/helper.rb index cfc1f35..6d2f9b1 100644 --- a/libraries/helper.rb +++ b/libraries/helper.rb @@ -28,11 +28,12 @@ def versions # Gets the version/edition ISO download URL or raises an error def source_download_url(version, edition) - src = iso_source(version, edition) - assert_src_is_not_nil(src, version, edition) \ - unless node['visualstudio'][version][edition]['installer_file'].empty? url = nil - url = ::File.join(src, node['visualstudio'][version][edition]['filename']) unless src.empty? + edition_node = node['visualstudio'][version][edition] + return url if edition_node.nil? || !edition_node['installer_file'] + src = iso_source(version, edition) + assert_src_is_not_nil(src, version, edition) + url = ::File.join(src, edition_node['filename']) if src url end From ecbaeae82d1c59822e7ea49b3097cd0db477dac7 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Thu, 10 Aug 2017 15:08:25 +0100 Subject: [PATCH 33/38] Add support for updates via network share --- attributes/vs2010.rb | 1 + attributes/vs2012.rb | 1 + attributes/vs2013.rb | 1 + libraries/helper.rb | 8 +++--- providers/update.rb | 56 ++++++++++++++++++++++++++++++++------- recipes/install_update.rb | 2 ++ resources/update.rb | 6 +++++ 7 files changed, 62 insertions(+), 13 deletions(-) diff --git a/attributes/vs2010.rb b/attributes/vs2010.rb index 37a7873..df9857e 100644 --- a/attributes/vs2010.rb +++ b/attributes/vs2010.rb @@ -51,3 +51,4 @@ 'Microsoft Visual Studio 2010 Service Pack 1' default['visualstudio']['2010']['update']['default_source'] = 'http://download.microsoft.com/download/E/B/A/EBA0A152-F426-47E6-9E3F-EFB686E3CA20' +default['visualstudio']['2010']['update']['installer_file'] = nil diff --git a/attributes/vs2012.rb b/attributes/vs2012.rb index d32e015..fc90df5 100644 --- a/attributes/vs2012.rb +++ b/attributes/vs2012.rb @@ -226,6 +226,7 @@ 'Visual Studio 2012 Update 5 (KB2707250)' default['visualstudio']['2012']['update']['default_source'] = 'https://download.microsoft.com/download/1/7/A/17A8493D-BB25-4811-8242-CCCB74EF982E' +default['visualstudio']['2012']['update']['installer_file'] = nil # VS 2012 Office developer tools default['visualstudio']['2012']['vsto']['installer_file'] = 'officetools_bundle.exe' diff --git a/attributes/vs2013.rb b/attributes/vs2013.rb index 3338a3f..c5212f5 100644 --- a/attributes/vs2013.rb +++ b/attributes/vs2013.rb @@ -281,3 +281,4 @@ 'Visual Studio 2013 Update 5 (KB3021976)' default['visualstudio']['2013']['update']['default_source'] = 'http://download.microsoft.com/download/A/F/9/AF95E6F8-2E6E-49D0-A48A-8E918D7FD768' +default['visualstudio']['2013']['update']['installer_file'] = nil diff --git a/libraries/helper.rb b/libraries/helper.rb index 6d2f9b1..cf81fbd 100644 --- a/libraries/helper.rb +++ b/libraries/helper.rb @@ -30,8 +30,8 @@ def versions def source_download_url(version, edition) url = nil edition_node = node['visualstudio'][version][edition] - return url if edition_node.nil? || !edition_node['installer_file'] src = iso_source(version, edition) + return url if src.nil? && edition_node['installer_file'] assert_src_is_not_nil(src, version, edition) url = ::File.join(src, edition_node['filename']) if src url @@ -41,9 +41,11 @@ def source_download_url(version, edition) # Gets the version/edition ISO download root URL def iso_source(version, edition) - src = node['visualstudio'][version][edition]['default_source'] + edition_node = node['visualstudio'][version][edition] + + src = edition_node['default_source'] src = node['visualstudio']['source'] if node['visualstudio']['source'] - src = node['visualstudio'][version][edition]['source'] if node['visualstudio'][version][edition]['source'] + src = edition_node['source'] if edition_node['source'] src end diff --git a/providers/update.rb b/providers/update.rb index decb933..f597ec1 100644 --- a/providers/update.rb +++ b/providers/update.rb @@ -40,29 +40,49 @@ def whyrun_supported? source new_resource.source overwrite true checksum new_resource.checksum + only_if { !new_resource.source.nil? && extractable_download } + end + + # Not an ISO but the web install + remote_file "download__#{setup_basename}" do + path installer_exe + source lazy { new_resource.source } + checksum new_resource.checksum + only_if { !new_resource.source.nil? && !extractable_download } + end + + # Ensure the target directory exists so logging doesn't fail on VS 2010 + directory "create_#{new_resource.install_dir}" do + path new_resource.install_dir + recursive true end # Install Visual Studio Update windows_package new_resource.package_name do - source setup_exe + source installer_exe installer_type :custom - options "/Q /norestart /noweb /Log \"#{install_log_file}\"" + options visual_studio_options timeout 3600 # 1 hour success_codes [0, 127, 3010] end - # Cleanup extracted ISO files + # Cleanup extracted ISO files from tmp dir directory "remove_#{new_resource.package_name}" do path extracted_iso_dir action :delete recursive true - not_if { new_resource.preserve_extracted_files } + only_if { !new_resource.source.nil? && !new_resource.preserve_extracted_files } end end new_resource.updated_by_last_action(true) end end +def extractable_download + extension = ::File.extname(new_resource.source) + extension.casecmp('.iso').zero? || extension.casecmp('.zip').zero? || extension.casecmp('.7z').zero? +end + def extracted_iso_dir default_path = ::File.join( Chef::Config[:file_cache_path], @@ -78,12 +98,28 @@ def install_log_file # only base file name of source, e.g. VS2013.5 def setup_basename - ::File.basename(new_resource.source, '.iso') + ::File.basename(new_resource.source, '.*') +end + +def installer_exe + installer = new_resource.installer_file || new_resource.version == '2010' ? 'setup.exe' : "#{setup_basename}.exe" + installer = ::File.join(extracted_iso_dir, installer) unless new_resource.source.nil? + installer +end + +def visual_studio_options + options = prepare_vs2017_options if new_resource.version == '2017' + options = prepare_vs_options unless new_resource.version == '2017' + + options +end + +def prepare_vs_options + setup_options = "/Q /norestart /noweb /log \"#{install_log_file}\"" + setup_options end -# setup executable path, by convention the exe has the same name as the iso -# except VS 2010 which just uses setup.exe -def setup_exe - setup_file = new_resource.package_name.include?('2010') ? 'setup.exe' : "#{setup_basename}.exe" - ::File.join(extracted_iso_dir, setup_file) +def prepare_vs2017_options + setup_options = '--norestart --passive --wait' + setup_options end diff --git a/recipes/install_update.rb b/recipes/install_update.rb index b771665..4c83419 100644 --- a/recipes/install_update.rb +++ b/recipes/install_update.rb @@ -28,10 +28,12 @@ versions_with_updates.each do |version| url = source_download_url(version, 'update') visualstudio_update "visualstudio_#{version}_update" do + version version install_dir node['visualstudio'][version]['install_dir'] source url package_name node['visualstudio'][version]['update']['package_name'] checksum node['visualstudio'][version]['update']['checksum'] preserve_extracted_files node['visualstudio']['preserve_extracted_files'] + installer_file installer_file node['visualstudio'][version]['update']['installer_file'] end end diff --git a/resources/update.rb b/resources/update.rb index 60b990d..da3992e 100644 --- a/resources/update.rb +++ b/resources/update.rb @@ -22,6 +22,9 @@ actions :install default_action :install +# The VS version: 2010, 2012 etc +attribute :version, kind_of: String, required: true + # The VS installation directory attribute :install_dir, kind_of: String, required: true @@ -36,3 +39,6 @@ # Should the extracted ISO files be preserved after installation? attribute :preserve_extracted_files, kind_of: [TrueClass, FalseClass], default: false + +# The installer filename specific to the edition, defaults to vs_.exe +attribute :installer_file, kind_of: String, required: false From 60baa38487f56f521ed964b3d6069c86a4e21892 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Fri, 11 Aug 2017 14:40:29 +0100 Subject: [PATCH 34/38] if we are specifying a blackslash or forward slash we are point to a path somewhere to install this remotely from --- libraries/helper.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/helper.rb b/libraries/helper.rb index cf81fbd..2b66731 100644 --- a/libraries/helper.rb +++ b/libraries/helper.rb @@ -31,7 +31,10 @@ def source_download_url(version, edition) url = nil edition_node = node['visualstudio'][version][edition] src = iso_source(version, edition) - return url if src.nil? && edition_node['installer_file'] + return url if src.nil? && (\ + edition_node['installer_file'].include?('/') \ + || edition_node['installer_file'].include?('\\') \ + ) assert_src_is_not_nil(src, version, edition) url = ::File.join(src, edition_node['filename']) if src url From e98dbd0079c8933ed492c99d1f9e0283b4a0bea0 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Fri, 11 Aug 2017 15:44:18 +0100 Subject: [PATCH 35/38] These references are not used --- providers/update.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/providers/update.rb b/providers/update.rb index f597ec1..fad82e5 100644 --- a/providers/update.rb +++ b/providers/update.rb @@ -19,9 +19,6 @@ # limitations under the License. # -require 'digest/md5' -require 'chef/shell_out' - include Windows::Helper include Visualstudio::Helper From 92e52a568324ecbb0d8e76b2a1385000a2f78bc9 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Mon, 14 Aug 2017 16:57:35 +0100 Subject: [PATCH 36/38] Handle empty string and nil strings --- libraries/helper.rb | 2 +- providers/edition.rb | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/helper.rb b/libraries/helper.rb index 2b66731..f0047bc 100644 --- a/libraries/helper.rb +++ b/libraries/helper.rb @@ -31,7 +31,7 @@ def source_download_url(version, edition) url = nil edition_node = node['visualstudio'][version][edition] src = iso_source(version, edition) - return url if src.nil? && (\ + return url if (src == "" || src.nil?) && (\ edition_node['installer_file'].include?('/') \ || edition_node['installer_file'].include?('\\') \ ) diff --git a/providers/edition.rb b/providers/edition.rb index 74fe6f5..e88b9f7 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -41,7 +41,7 @@ def whyrun_supported? source new_resource.source overwrite true checksum new_resource.checksum - only_if { !new_resource.source.nil? && extractable_download } + only_if { !(new_resource.source == "" || new_resource.source.nil?) && extractable_download } end # Not an ISO but the web install @@ -49,7 +49,7 @@ def whyrun_supported? path installer_exe source lazy { new_resource.source } checksum new_resource.checksum - only_if { !new_resource.source.nil? && !extractable_download } + only_if { !(new_resource.source == "" || new_resource.source.nil?) && !extractable_download } end # Ensure the target directory exists so logging doesn't fail on VS 2010 @@ -71,7 +71,7 @@ def whyrun_supported? path extracted_iso_dir action :delete recursive true - only_if { !new_resource.source.nil? && !new_resource.preserve_extracted_files } + only_if { !(new_resource.source == "" || new_resource.source.nil?) && extractable_download && !new_resource.preserve_extracted_files } end end new_resource.updated_by_last_action(true) @@ -79,6 +79,7 @@ def whyrun_supported? end def extractable_download + return false if new_resource.source == "" || new_resource.source.nil? extension = ::File.extname(new_resource.source) extension.casecmp('.iso').zero? || extension.casecmp('.zip').zero? || extension.casecmp('.7z').zero? end From 155b178828fded04d8de2962dffaf0535815ef0f Mon Sep 17 00:00:00 2001 From: Bruce Emehiser Date: Tue, 15 Aug 2017 14:10:55 -0700 Subject: [PATCH 37/38] Fixed RuboCop errors. --- Rakefile | 2 +- libraries/helper.rb | 2 +- providers/edition.rb | 13 ++++++++----- providers/update.rb | 2 +- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Rakefile b/Rakefile index a552925..370bf70 100644 --- a/Rakefile +++ b/Rakefile @@ -5,7 +5,7 @@ require 'foodcritic' require 'rspec/core/rake_task' require 'stove/rake_task' -task default: [:rubocop, :foodcritic, :spec] +task default: %i[rubocop foodcritic spec] FoodCritic::Rake::LintTask.new do |t| t.options = { diff --git a/libraries/helper.rb b/libraries/helper.rb index f0047bc..5583c5a 100644 --- a/libraries/helper.rb +++ b/libraries/helper.rb @@ -31,7 +31,7 @@ def source_download_url(version, edition) url = nil edition_node = node['visualstudio'][version][edition] src = iso_source(version, edition) - return url if (src == "" || src.nil?) && (\ + return url if (src == '' || src.nil?) && (\ edition_node['installer_file'].include?('/') \ || edition_node['installer_file'].include?('\\') \ ) diff --git a/providers/edition.rb b/providers/edition.rb index e88b9f7..3b59fb9 100644 --- a/providers/edition.rb +++ b/providers/edition.rb @@ -41,15 +41,15 @@ def whyrun_supported? source new_resource.source overwrite true checksum new_resource.checksum - only_if { !(new_resource.source == "" || new_resource.source.nil?) && extractable_download } + only_if { !(new_resource.source == '' || new_resource.source.nil?) && extractable_download } end # Not an ISO but the web install remote_file "download__#{new_resource.version}_#{new_resource.edition}" do path installer_exe - source lazy { new_resource.source } + source { lazy { new_resource.source } } checksum new_resource.checksum - only_if { !(new_resource.source == "" || new_resource.source.nil?) && !extractable_download } + only_if { !(new_resource.source == '' || new_resource.source.nil?) && !extractable_download } end # Ensure the target directory exists so logging doesn't fail on VS 2010 @@ -71,7 +71,10 @@ def whyrun_supported? path extracted_iso_dir action :delete recursive true - only_if { !(new_resource.source == "" || new_resource.source.nil?) && extractable_download && !new_resource.preserve_extracted_files } + only_if do + !(new_resource.source == '' || new_resource.source.nil?) \ + && extractable_download && !new_resource.preserve_extracted_files + end end end new_resource.updated_by_last_action(true) @@ -79,7 +82,7 @@ def whyrun_supported? end def extractable_download - return false if new_resource.source == "" || new_resource.source.nil? + return false if new_resource.source == '' || new_resource.source.nil? extension = ::File.extname(new_resource.source) extension.casecmp('.iso').zero? || extension.casecmp('.zip').zero? || extension.casecmp('.7z').zero? end diff --git a/providers/update.rb b/providers/update.rb index fad82e5..608ec87 100644 --- a/providers/update.rb +++ b/providers/update.rb @@ -43,7 +43,7 @@ def whyrun_supported? # Not an ISO but the web install remote_file "download__#{setup_basename}" do path installer_exe - source lazy { new_resource.source } + source { lazy { new_resource.source } } checksum new_resource.checksum only_if { !new_resource.source.nil? && !extractable_download } end From e9ac772ef0b0408950501a95eee14c744615989d Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Wed, 16 Aug 2017 08:04:32 +0100 Subject: [PATCH 38/38] array literals should use round brackets --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 370bf70..89ab9b6 100644 --- a/Rakefile +++ b/Rakefile @@ -5,7 +5,7 @@ require 'foodcritic' require 'rspec/core/rake_task' require 'stove/rake_task' -task default: %i[rubocop foodcritic spec] +task default: %i(rubocop foodcritic spec) FoodCritic::Rake::LintTask.new do |t| t.options = {