summaryrefslogtreecommitdiff
path: root/lib/chef/provider/package/winget.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chef/provider/package/winget.rb')
-rw-r--r--lib/chef/provider/package/winget.rb219
1 files changed, 219 insertions, 0 deletions
diff --git a/lib/chef/provider/package/winget.rb b/lib/chef/provider/package/winget.rb
new file mode 100644
index 0000000000..453730a04d
--- /dev/null
+++ b/lib/chef/provider/package/winget.rb
@@ -0,0 +1,219 @@
+#
+# Authors:: Adam Jacob (<adam@chef.io>)
+# Ionuț Arțăriși (<iartarisi@suse.cz>)
+# Copyright:: Copyright (c) Chef Software Inc.
+# Copyright:: 2013-2016, SUSE Linux GmbH
+# License:: Apache License, Version 2.0
+#
+# 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.
+#
+
+require_relative "../package"
+require_relative "../../resource/winget_package"
+
+class Chef
+ class Provider
+ class Package
+ class Winget < Chef::Provider::Package
+ use_multipackage_api
+ allow_nils
+
+ provides :package, platform_family: "windows"
+ provides :winget_package
+
+ def load_current_resource
+ @current_resource = Chef::Resource::WingetPackage.new(new_resource.name)
+ current_resource.package_name(new_resource.package_name)
+ current_resource.version(get_current_versions)
+ current_resource
+ end
+
+ def install_package(name, version)
+ puts "here is the version string I was passed by install_package : #{version}"
+ actual_version = version
+ arguments = build_argument_string
+ winget_package("install", name, "--version #{version}", arguments )
+ end
+
+ def upgrade_package(name, version)
+ # `zypper install` upgrades packages, we rely on the idempotency checks to get action :install behavior
+ install_package(name, version)
+ end
+
+ private
+
+ def build_argument_string
+ build_arguments = ""
+ build_arguments << " --source #{new_resource.source_name}" if new_resource.source_name
+ build_arguments << " --scope #{new_resource.scope}" if new_resource.scope
+ build_arguments << " --override:#{new_resource.options}" if new_resource.options
+ build_arguments << " --location #{new_resource.location}" if new_resource.location
+ build_arguments << " --force" if new_resource.force
+ build_arguments
+ end
+
+ def get_current_versions
+ puts "The installed version and index are : "
+ package_name_array.each_with_index.map { |pkg, i| installed_version(i) }
+ end
+
+ def candidate_version
+ @candidate_version ||= package_name_array.each_with_index.map { |pkg, i| available_version(i) }
+ end
+
+ def is_installed?(package_name)
+ ps_results = powershell_exec!("winget list #{package_name}").result
+ ps_results.each do |line|
+ if line =~ /No installed/
+ puts "returning false"
+ return false
+ elsif line =~ /\d+\.\d+\.\d+\.\d+|\d+\.\d+\.\d+/
+ current_version = line.split(' ')
+ puts "I think I found this version : #{current_version[-1]}"
+ return current_version[-1]
+ end
+ end
+ end
+
+ def get_latest_version(package_name)
+ # return a version number
+ end
+
+ def resolve_current_version(package_name)
+ puts "resolving current version for : #{package_name}"
+ latest_version = current_version = nil
+ is_installed = false
+ # latest version is the one on the Internet
+ # current version is the one installed
+ # is the damned thing installed locally? If yes, gimme the version from the Internet
+ #
+ logger.trace("#{new_resource} checking winget")
+ status = is_installed?(package_name)
+ if status != false
+ is_installed = true
+ current_version = status
+ puts "current version is : #{current_version}"
+ end
+
+ latest_version = get_latest_version
+
+ # status = shell_out!("winget", "list", package_name)
+ # puts "What is my status : #{status.stdout}"
+ # status.stdout.each_line do |line|
+ # if line =~ /^No installed package *: (.+) *$/
+
+ # # installed_version = $1.strip
+ # # logger.trace("#{new_resource} version #{installed_version}")
+ # # is_installed = true
+ # elsif line =~ /^Name *: (.+) *$/
+ # end
+ puts "Is #{package_name} installed? : #{is_installed}"
+ current_version ||= latest_version if is_installed
+ current_version
+ end
+
+ # def resolve_current_version(package_name)
+ # latest_version = current_version = nil
+ # is_installed = false
+ # logger.trace("#{new_resource} checking zypper")
+ # status = shell_out!("zypper", "--non-interactive", "info", package_name)
+ # status.stdout.each_line do |line|
+ # case line
+ # when /^Version *: (.+) *$/
+ # latest_version = $1.strip
+ # logger.trace("#{new_resource} version #{latest_version}")
+ # when /^Installed *: Yes.*$/ # http://rubular.com/r/9StcAMjOn6
+ # is_installed = true
+ # logger.trace("#{new_resource} is installed")
+ # when /^Status *: out-of-date \(version (.+) installed\) *$/
+ # current_version = $1.strip
+ # logger.trace("#{new_resource} out of date version #{current_version}")
+ # end
+ # end
+ # current_version ||= latest_version if is_installed
+ # current_version
+ # end
+
+
+
+ def resolve_available_version(package_name, new_version)
+ puts "checking available versions for #{package_name}"
+ search_string = new_version.nil? ? package_name : "#{package_name}=#{new_version}"
+ so = shell_out!("winget", "search", search_string)
+ so.stdout.each_line do |line|
+ if line =~ /#{search_string}\s+\w+\.\w+\s+\d+\.\d+\.\d+/
+ version = line.split(" ")[2]
+ return version
+ end
+ end
+ nil
+ end
+
+ def available_version(index)
+ @available_version ||= []
+ @available_version[index] ||= resolve_available_version(package_name_array[index], safe_version_array[index])
+ @available_version[index]
+ end
+
+ def installed_version(index)
+ puts "here is the installed version #{resolve_current_version(package_name_array[index])} "
+ @installed_version ||= []
+ @installed_version[index] ||= resolve_current_version(package_name_array[index])
+ @installed_version[index]
+ end
+
+ def zip(names, versions)
+ names.zip(versions).map do |n, v|
+ (v.nil? || v.empty?) ? n : "#{n}=#{v}"
+ end.compact
+ end
+
+ def winget_version
+ @winget_version ||=
+ `winget --version`.scan(/\d+/).join(".").to_f
+ end
+
+ def winget_package(command, name, version, arguments)
+ # zipped_names = zip(names, versions)
+ # shell_out!("winget", global_options, "--non-interactive", gpg_checks, command, *options, zipped_names)
+ shell_out!("winget", command, name, version, arguments)
+ end
+
+ # def global_options
+ # new_resource.global_options
+ # end
+
+ # def locked_packages
+ # @locked_packages ||=
+ # begin
+ # locked = shell_out!("zypper", "locks")
+ # locked.stdout.each_line.map do |line|
+ # line.split("|").shift(2).last.strip
+ # end
+ # end
+ # end
+
+ def safe_version_array
+ if new_resource.version.is_a?(Array)
+ new_resource.version
+ elsif new_resource.version.nil?
+ package_name_array.map { nil }
+ else
+ [ new_resource.version ]
+ end
+ end
+
+ end
+ end
+ end
+end