{"action":"created","comment":{"url":"https://api.github.com/repos/chef/chef/pulls/comments/43588208","id":43588208,"diff_hunk":"@@ -0,0 +1,220 @@\n+#\n+# Copyright:: Copyright (c) 2015 Chef Software, Inc.\n+# License:: Apache License, Version 2.0\n+#\n+# Licensed under the Apache License, Version 2.0 (the \"License\");\n+# you may not use this file except in compliance with the License.\n+# You may obtain a copy of the License at\n+#\n+#     http://www.apache.org/licenses/LICENSE-2.0\n+#\n+# Unless required by applicable law or agreed to in writing, software\n+# distributed under the License is distributed on an \"AS IS\" BASIS,\n+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+# See the License for the specific language governing permissions and\n+# limitations under the License.\n+#\n+\n+require 'chef/provider/package'\n+require 'chef/resource/chocolatey_package'\n+require 'chef/mixin/powershell_out'\n+\n+class Chef\n+  class Provider\n+    class Package\n+      class Chocolatey < Chef::Provider::Package\n+        include Chef::Mixin::PowershellOut\n+\n+        provides :chocolatey_package, os: \"windows\"\n+\n+        # Declare that our arguments should be arrays\n+        package_class_supports_arrays\n+\n+        # Responsible for building the current_resource.\n+        #\n+        # @return [Chef::Resource::ChocolateyPackage] the current_resource\n+        def load_current_resource\n+          @current_resource = Chef::Resource::ChocolateyPackage.new(new_resource.name)\n+          current_resource.package_name(new_resource.package_name)\n+          current_resource.version(build_current_versions)\n+          current_resource\n+        end\n+\n+        # Lazy initializer for candidate_version.  A nil value means that there is no candidate\n+        # version and the package is not installable (generally an error).\n+        #\n+        # @return [Array] list of candidate_versions indexed same as new_resource.package_name/version\n+        def candidate_version\n+          @candidate_version ||= build_candidate_versions\n+        end\n+\n+        # Install multiple packages via choco.exe\n+        #\n+        # @param names [Array<String>] array of package names to install\n+        # @param versions [Array<String>] array of versions to install\n+        def install_package(names, versions)\n+          name_versions_to_install = desired_name_versions.select { |n, v| names.include?(n) }\n+\n+          name_nil_versions = name_versions_to_install.select { |n,v| v.nil? }\n+          name_has_versions = name_versions_to_install.reject { |n,v| v.nil? }\n+\n+          # choco does not support installing multiple packages with version pins\n+          name_has_versions.each do |name, version|\n+            choco_command(\"install -y -version\", version, cmd_args, name)\n+          end\n+\n+          # but we can do all the ones without version pins at once\n+          unless name_nil_versions.empty?\n+            cmd_names = name_nil_versions.keys\n+            choco_command(\"install -y\", cmd_args, *cmd_names)\n+          end\n+        end\n+\n+        # Upgrade multiple packages via choco.exe\n+        #\n+        # @param names [Array<String>] array of package names to install\n+        # @param versions [Array<String>] array of versions to install\n+        def upgrade_package(names, versions)\n+          unless desired_name_versions.select { |n, v| names.include?(n) }.all? { |n,v| v.nil? }\n+            raise Chef::Exceptions::Package, \"Chocolatey Provider does not support version pins on upgrade command, use install instead\"\n+          end\n+\n+          choco_command(\"upgrade -y\", cmd_args, *names)\n+        end\n+\n+        # Remove multiple packages via choco.exe\n+        #\n+        # @param names [Array<String>] array of package names to install\n+        # @param versions [Array<String>] array of versions to install\n+        def remove_package(names, versions)\n+          choco_command(\"uninstall -y\", cmd_args, *names)\n+        end\n+\n+        # Support :uninstall as an action in order for users to easily convert\n+        # from the `chocolatey` provider in the cookbook.  It is, however,\n+        # already deprecated.\n+        def action_uninstall\n+          Chef::Log.deprecation \"The use of action :uninstall on the chocolatey_package provider is deprecated, please use :remove\"\n+          action_remove\n+        end\n+\n+        # Choco does not have dpkg's distinction between purge and remove\n+        alias_method :purge_package, :remove_package\n+\n+        # Override the superclass check.  The semantics for our new_resource.source is not files to\n+        # install from, but like the rubygem provider's sources which are more like repos.\n+        def check_resource_semantics!\n+        end\n+\n+        private\n+\n+        # Magic to find where chocolatey is installed in the system, and to\n+        # return the full path of choco.exe\n+        #\n+        # @return [String] full path of choco.exe\n+        def choco_exe\n+          @choco_exe ||=\n+            ::File.join(\n+              powershell_out!(\n+                \"[System.Environment]::GetEnvironmentVariable('ChocolateyInstall', 'MACHINE')\"\n+              ).stdout.chomp,\n+              'bin',\n+              'choco.exe'\n+          )\n+        end\n+\n+        # Helper to dispatch a choco command through shell_out using the timeout\n+        # set on the new resource, with nice command formatting.\n+        #\n+        # @param args [String] variable number of string arguments\n+        # @return [Mixlib::ShellOut] object returned from shell_out!\n+        def choco_command(*args)\n+          shell_out_with_timeout!(args_to_string(choco_exe, *args))\n+        end\n+\n+        # Use the available_packages Hash helper to create an array suitable for\n+        # using in candidate_version\n+        #\n+        # @return [Array] list of candidate_version, same index as new_resource.package_name/version\n+        def build_candidate_versions\n+          new_resource.package_name.map do |package_name|\n+            available_packages[package_name.downcase]\n+          end\n+        end\n+\n+        # Use the installed_packages Hash helper to create an array suitable for\n+        # using in current_resource.version\n+        #\n+        # @return [Array] list of candidate_version, same index as new_resource.package_name/version\n+        def build_current_versions\n+          new_resource.package_name.map do |package_name|\n+            installed_packages[package_name.downcase]\n+          end\n+        end\n+\n+        # Helper to construct Hash of names-to-versions, requested on the new_resource.\n+        # If new_resource.version is nil, then all values will be nil.\n+        #\n+        # @return [Hash] Mapping of requested names to versions\n+        def desired_name_versions\n+          desired_versions = new_resource.version || new_resource.package_name.map { nil }\n+          Hash[*new_resource.package_name.zip(desired_versions).flatten]\n+        end\n+\n+        # Helper to construct optional args out of new_resource\n+        #\n+        # @return [String] options from new_resource or empty string\n+        def cmd_args\n+          cmd_args = [ new_resource.options ]\n+          cmd_args.push( \"-source #{new_resource.source}\" ) if new_resource.source\n+          args_to_string(*cmd_args)\n+        end\n+\n+        # Helper to nicely convert variable string args into a single command line.  It\n+        # will compact nulls or empty strings and join arguments with single spaces, without\n+        # introducing any double-spaces for missing args.\n+        #\n+        # @param args [String] variable number of string arguments\n+        # @return [String] nicely concatenated string or empty string\n+        def args_to_string(*args)\n+          args.reject {|i| i.nil? || i == \"\" }.join(\" \")\n+        end\n+\n+        # Available packages in chocolatey as a Hash of names mapped to versions\n+        # (names are downcased for case-insensitive matching)\n+        #\n+        # @return [Hash] name-to-version mapping of available packages\n+        def available_packages","path":"lib/chef/provider/package/chocolatey.rb","position":187,"original_position":187,"commit_id":"6feef55a3055d30ac77d39e22390dcce660ce03a","original_commit_id":"6feef55a3055d30ac77d39e22390dcce660ce03a","user":{"login":"mwrock","id":655165,"avatar_url":"https://avatars.githubusercontent.com/u/655165?v=3","gravatar_id":"","url":"https://api.github.com/users/mwrock","html_url":"https://github.com/mwrock","followers_url":"https://api.github.com/users/mwrock/followers","following_url":"https://api.github.com/users/mwrock/following{/other_user}","gists_url":"https://api.github.com/users/mwrock/gists{/gist_id}","starred_url":"https://api.github.com/users/mwrock/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mwrock/subscriptions","organizations_url":"https://api.github.com/users/mwrock/orgs","repos_url":"https://api.github.com/users/mwrock/repos","events_url":"https://api.github.com/users/mwrock/events{/privacy}","received_events_url":"https://api.github.com/users/mwrock/received_events","type":"User","site_admin":false},"body":"Consider taking a `package_name` parameter and then calling `choco #{package_name} -r` which will be much faster. Otherwise this returns thousands of results.","created_at":"2015-11-01T21:54:37Z","updated_at":"2015-11-01T21:54:37Z","html_url":"https://github.com/chef/chef/pull/4106#discussion_r43588208","pull_request_url":"https://api.github.com/repos/chef/chef/pulls/4106","_links":{"self":{"href":"https://api.github.com/repos/chef/chef/pulls/comments/43588208"},"html":{"href":"https://github.com/chef/chef/pull/4106#discussion_r43588208"},"pull_request":{"href":"https://api.github.com/repos/chef/chef/pulls/4106"}}},"pull_request":{"url":"https://api.github.com/repos/chef/chef/pulls/4106","id":48759304,"html_url":"https://github.com/chef/chef/pull/4106","diff_url":"https://github.com/chef/chef/pull/4106.diff","patch_url":"https://github.com/chef/chef/pull/4106.patch","issue_url":"https://api.github.com/repos/chef/chef/issues/4106","number":4106,"state":"open","locked":false,"title":"add chocolatey_package to core chef","user":{"login":"lamont-granquist","id":454857,"avatar_url":"https://avatars.githubusercontent.com/u/454857?v=3","gravatar_id":"","url":"https://api.github.com/users/lamont-granquist","html_url":"https://github.com/lamont-granquist","followers_url":"https://api.github.com/users/lamont-granquist/followers","following_url":"https://api.github.com/users/lamont-granquist/following{/other_user}","gists_url":"https://api.github.com/users/lamont-granquist/gists{/gist_id}","starred_url":"https://api.github.com/users/lamont-granquist/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lamont-granquist/subscriptions","organizations_url":"https://api.github.com/users/lamont-granquist/orgs","repos_url":"https://api.github.com/users/lamont-granquist/repos","events_url":"https://api.github.com/users/lamont-granquist/events{/privacy}","received_events_url":"https://api.github.com/users/lamont-granquist/received_events","type":"User","site_admin":false},"body":"\r\n* Adds `chocolatey_package` as a core-chef resource\r\n* Does not conflict with the `chocolatey` provider in the cookbook\r\n* Uses the semantics of the core-chef package resource instead of chocolately (:remove instead of :uninstall)\r\n* Implements multipackage install/remove/upgrade to the extent possible\r\n\r\nBonus is that it adds features to the core package provider to make it much easier to write multipackage-enabled subclasses.\r\n\r\nOne difference between this provider and the chocolatey provider in the cookbook is that we only take a string of options not a hash, again for consistency with the base package provider code in core chef.","created_at":"2015-10-26T16:04:14Z","updated_at":"2015-11-01T21:54:37Z","closed_at":null,"merged_at":null,"merge_commit_sha":"79d3d919d667bca1ddd0351bfa1704a8f4ad7ebe","assignee":{"login":"lamont-granquist","id":454857,"avatar_url":"https://avatars.githubusercontent.com/u/454857?v=3","gravatar_id":"","url":"https://api.github.com/users/lamont-granquist","html_url":"https://github.com/lamont-granquist","followers_url":"https://api.github.com/users/lamont-granquist/followers","following_url":"https://api.github.com/users/lamont-granquist/following{/other_user}","gists_url":"https://api.github.com/users/lamont-granquist/gists{/gist_id}","starred_url":"https://api.github.com/users/lamont-granquist/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lamont-granquist/subscriptions","organizations_url":"https://api.github.com/users/lamont-granquist/orgs","repos_url":"https://api.github.com/users/lamont-granquist/repos","events_url":"https://api.github.com/users/lamont-granquist/events{/privacy}","received_events_url":"https://api.github.com/users/lamont-granquist/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/chef/chef/pulls/4106/commits","review_comments_url":"https://api.github.com/repos/chef/chef/pulls/4106/comments","review_comment_url":"https://api.github.com/repos/chef/chef/pulls/comments{/number}","comments_url":"https://api.github.com/repos/chef/chef/issues/4106/comments","statuses_url":"https://api.github.com/repos/chef/chef/statuses/6feef55a3055d30ac77d39e22390dcce660ce03a","head":{"label":"chef:lcg/chocolatey-package","ref":"lcg/chocolatey-package","sha":"6feef55a3055d30ac77d39e22390dcce660ce03a","user":{"login":"chef","id":29740,"avatar_url":"https://avatars.githubusercontent.com/u/29740?v=3","gravatar_id":"","url":"https://api.github.com/users/chef","html_url":"https://github.com/chef","followers_url":"https://api.github.com/users/chef/followers","following_url":"https://api.github.com/users/chef/following{/other_user}","gists_url":"https://api.github.com/users/chef/gists{/gist_id}","starred_url":"https://api.github.com/users/chef/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chef/subscriptions","organizations_url":"https://api.github.com/users/chef/orgs","repos_url":"https://api.github.com/users/chef/repos","events_url":"https://api.github.com/users/chef/events{/privacy}","received_events_url":"https://api.github.com/users/chef/received_events","type":"Organization","site_admin":false},"repo":{"id":108278,"name":"chef","full_name":"chef/chef","owner":{"login":"chef","id":29740,"avatar_url":"https://avatars.githubusercontent.com/u/29740?v=3","gravatar_id":"","url":"https://api.github.com/users/chef","html_url":"https://github.com/chef","followers_url":"https://api.github.com/users/chef/followers","following_url":"https://api.github.com/users/chef/following{/other_user}","gists_url":"https://api.github.com/users/chef/gists{/gist_id}","starred_url":"https://api.github.com/users/chef/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chef/subscriptions","organizations_url":"https://api.github.com/users/chef/orgs","repos_url":"https://api.github.com/users/chef/repos","events_url":"https://api.github.com/users/chef/events{/privacy}","received_events_url":"https://api.github.com/users/chef/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/chef/chef","description":"A systems integration framework, built to bring the benefits of configuration management to your entire infrastructure.","fork":false,"url":"https://api.github.com/repos/chef/chef","forks_url":"https://api.github.com/repos/chef/chef/forks","keys_url":"https://api.github.com/repos/chef/chef/keys{/key_id}","collaborators_url":"https://api.github.com/repos/chef/chef/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/chef/chef/teams","hooks_url":"https://api.github.com/repos/chef/chef/hooks","issue_events_url":"https://api.github.com/repos/chef/chef/issues/events{/number}","events_url":"https://api.github.com/repos/chef/chef/events","assignees_url":"https://api.github.com/repos/chef/chef/assignees{/user}","branches_url":"https://api.github.com/repos/chef/chef/branches{/branch}","tags_url":"https://api.github.com/repos/chef/chef/tags","blobs_url":"https://api.github.com/repos/chef/chef/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/chef/chef/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/chef/chef/git/refs{/sha}","trees_url":"https://api.github.com/repos/chef/chef/git/trees{/sha}","statuses_url":"https://api.github.com/repos/chef/chef/statuses/{sha}","languages_url":"https://api.github.com/repos/chef/chef/languages","stargazers_url":"https://api.github.com/repos/chef/chef/stargazers","contributors_url":"https://api.github.com/repos/chef/chef/contributors","subscribers_url":"https://api.github.com/repos/chef/chef/subscribers","subscription_url":"https://api.github.com/repos/chef/chef/subscription","commits_url":"https://api.github.com/repos/chef/chef/commits{/sha}","git_commits_url":"https://api.github.com/repos/chef/chef/git/commits{/sha}","comments_url":"https://api.github.com/repos/chef/chef/comments{/number}","issue_comment_url":"https://api.github.com/repos/chef/chef/issues/comments{/number}","contents_url":"https://api.github.com/repos/chef/chef/contents/{+path}","compare_url":"https://api.github.com/repos/chef/chef/compare/{base}...{head}","merges_url":"https://api.github.com/repos/chef/chef/merges","archive_url":"https://api.github.com/repos/chef/chef/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/chef/chef/downloads","issues_url":"https://api.github.com/repos/chef/chef/issues{/number}","pulls_url":"https://api.github.com/repos/chef/chef/pulls{/number}","milestones_url":"https://api.github.com/repos/chef/chef/milestones{/number}","notifications_url":"https://api.github.com/repos/chef/chef/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/chef/chef/labels{/name}","releases_url":"https://api.github.com/repos/chef/chef/releases{/id}","created_at":"2009-01-15T20:40:48Z","updated_at":"2015-11-01T17:45:08Z","pushed_at":"2015-10-31T02:18:51Z","git_url":"git://github.com/chef/chef.git","ssh_url":"git@github.com:chef/chef.git","clone_url":"https://github.com/chef/chef.git","svn_url":"https://github.com/chef/chef","homepage":"http://www.chef.io/chef/","size":186698,"stargazers_count":3890,"watchers_count":3890,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1595,"mirror_url":null,"open_issues_count":415,"forks":1595,"open_issues":415,"watchers":3890,"default_branch":"master"}},"base":{"label":"chef:master","ref":"master","sha":"474dedbd2f47f79c8fcc24a2cb02f82fc234d6dd","user":{"login":"chef","id":29740,"avatar_url":"https://avatars.githubusercontent.com/u/29740?v=3","gravatar_id":"","url":"https://api.github.com/users/chef","html_url":"https://github.com/chef","followers_url":"https://api.github.com/users/chef/followers","following_url":"https://api.github.com/users/chef/following{/other_user}","gists_url":"https://api.github.com/users/chef/gists{/gist_id}","starred_url":"https://api.github.com/users/chef/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chef/subscriptions","organizations_url":"https://api.github.com/users/chef/orgs","repos_url":"https://api.github.com/users/chef/repos","events_url":"https://api.github.com/users/chef/events{/privacy}","received_events_url":"https://api.github.com/users/chef/received_events","type":"Organization","site_admin":false},"repo":{"id":108278,"name":"chef","full_name":"chef/chef","owner":{"login":"chef","id":29740,"avatar_url":"https://avatars.githubusercontent.com/u/29740?v=3","gravatar_id":"","url":"https://api.github.com/users/chef","html_url":"https://github.com/chef","followers_url":"https://api.github.com/users/chef/followers","following_url":"https://api.github.com/users/chef/following{/other_user}","gists_url":"https://api.github.com/users/chef/gists{/gist_id}","starred_url":"https://api.github.com/users/chef/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chef/subscriptions","organizations_url":"https://api.github.com/users/chef/orgs","repos_url":"https://api.github.com/users/chef/repos","events_url":"https://api.github.com/users/chef/events{/privacy}","received_events_url":"https://api.github.com/users/chef/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/chef/chef","description":"A systems integration framework, built to bring the benefits of configuration management to your entire infrastructure.","fork":false,"url":"https://api.github.com/repos/chef/chef","forks_url":"https://api.github.com/repos/chef/chef/forks","keys_url":"https://api.github.com/repos/chef/chef/keys{/key_id}","collaborators_url":"https://api.github.com/repos/chef/chef/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/chef/chef/teams","hooks_url":"https://api.github.com/repos/chef/chef/hooks","issue_events_url":"https://api.github.com/repos/chef/chef/issues/events{/number}","events_url":"https://api.github.com/repos/chef/chef/events","assignees_url":"https://api.github.com/repos/chef/chef/assignees{/user}","branches_url":"https://api.github.com/repos/chef/chef/branches{/branch}","tags_url":"https://api.github.com/repos/chef/chef/tags","blobs_url":"https://api.github.com/repos/chef/chef/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/chef/chef/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/chef/chef/git/refs{/sha}","trees_url":"https://api.github.com/repos/chef/chef/git/trees{/sha}","statuses_url":"https://api.github.com/repos/chef/chef/statuses/{sha}","languages_url":"https://api.github.com/repos/chef/chef/languages","stargazers_url":"https://api.github.com/repos/chef/chef/stargazers","contributors_url":"https://api.github.com/repos/chef/chef/contributors","subscribers_url":"https://api.github.com/repos/chef/chef/subscribers","subscription_url":"https://api.github.com/repos/chef/chef/subscription","commits_url":"https://api.github.com/repos/chef/chef/commits{/sha}","git_commits_url":"https://api.github.com/repos/chef/chef/git/commits{/sha}","comments_url":"https://api.github.com/repos/chef/chef/comments{/number}","issue_comment_url":"https://api.github.com/repos/chef/chef/issues/comments{/number}","contents_url":"https://api.github.com/repos/chef/chef/contents/{+path}","compare_url":"https://api.github.com/repos/chef/chef/compare/{base}...{head}","merges_url":"https://api.github.com/repos/chef/chef/merges","archive_url":"https://api.github.com/repos/chef/chef/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/chef/chef/downloads","issues_url":"https://api.github.com/repos/chef/chef/issues{/number}","pulls_url":"https://api.github.com/repos/chef/chef/pulls{/number}","milestones_url":"https://api.github.com/repos/chef/chef/milestones{/number}","notifications_url":"https://api.github.com/repos/chef/chef/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/chef/chef/labels{/name}","releases_url":"https://api.github.com/repos/chef/chef/releases{/id}","created_at":"2009-01-15T20:40:48Z","updated_at":"2015-11-01T17:45:08Z","pushed_at":"2015-10-31T02:18:51Z","git_url":"git://github.com/chef/chef.git","ssh_url":"git@github.com:chef/chef.git","clone_url":"https://github.com/chef/chef.git","svn_url":"https://github.com/chef/chef","homepage":"http://www.chef.io/chef/","size":186698,"stargazers_count":3890,"watchers_count":3890,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1595,"mirror_url":null,"open_issues_count":415,"forks":1595,"open_issues":415,"watchers":3890,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/chef/chef/pulls/4106"},"html":{"href":"https://github.com/chef/chef/pull/4106"},"issue":{"href":"https://api.github.com/repos/chef/chef/issues/4106"},"comments":{"href":"https://api.github.com/repos/chef/chef/issues/4106/comments"},"review_comments":{"href":"https://api.github.com/repos/chef/chef/pulls/4106/comments"},"review_comment":{"href":"https://api.github.com/repos/chef/chef/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/chef/chef/pulls/4106/commits"},"statuses":{"href":"https://api.github.com/repos/chef/chef/statuses/6feef55a3055d30ac77d39e22390dcce660ce03a"}}}}