diff options
author | Lamont Granquist <lamont@scriptkiddie.org> | 2018-04-02 13:27:14 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-02 13:27:14 -0700 |
commit | 90abfe5ddb1728952df4dd21f55012f29002b737 (patch) | |
tree | 054d99df0d1985fc4a897bd682803f8a78a21b25 | |
parent | 387908ee27f14b18ff7bfdb19158e690ec5415c6 (diff) | |
parent | 68d5b2ea2f1c540307ce0e14387f2924aefe4950 (diff) | |
download | chef-90abfe5ddb1728952df4dd21f55012f29002b737.tar.gz |
Merge pull request #7027 from gengor/CHEF-7026
[CHEF-7026] Rewrite portage package provider candidate_version determination and fix tests
-rw-r--r-- | lib/chef/provider/package/portage.rb | 58 | ||||
-rw-r--r-- | spec/unit/provider/package/portage_spec.rb | 158 |
2 files changed, 37 insertions, 179 deletions
diff --git a/lib/chef/provider/package/portage.rb b/lib/chef/provider/package/portage.rb index 016008c339..fecbba9dc9 100644 --- a/lib/chef/provider/package/portage.rb +++ b/lib/chef/provider/package/portage.rb @@ -59,46 +59,40 @@ class Chef current_resource end - def parse_emerge(package, txt) - availables = {} - found_package_name = nil - - txt.each_line do |line| - if line =~ /\*\s+#{PACKAGE_NAME_PATTERN}/ - found_package_name = $&.delete("*").strip - if package =~ /\// # the category is specified - if found_package_name == package - availables[found_package_name] = nil - end - else # the category is not specified - if found_package_name.split("/").last == package - availables[found_package_name] = nil - end + def raise_error_for_query(msg) + raise Chef::Exceptions::Package, "Query for '#{new_resource.package_name}' #{msg}" + end + + def candidate_version + return @candidate_version if @candidate_version + + pkginfo = shell_out_compact("portageq", "best_visible", "/", new_resource.package_name) + + if pkginfo.exitstatus != 0 + pkginfo.stderr.each_line do |line| + if line =~ /[Uu]nqualified atom .*match.* multiple/ + raise_error_for_query("matched multiple packages (please specify a category):\n#{pkginfo.inspect}") end end - if line =~ /Latest version available: (.*)/ && availables.key?(found_package_name) - availables[found_package_name] = $1.strip + if pkginfo.stdout.strip.empty? + raise_error_for_query("did not find a matching package:\n#{pkginfo.inspect}") end - end - if availables.size > 1 - # shouldn't happen if a category is specified so just use `package` - raise Chef::Exceptions::Package, "Multiple emerge results found for #{package}: #{availables.keys.join(' ')}. Specify a category." + raise_error_for_query("resulted in an unknown error:\n#{pkginfo.inspect}") end - availables.values.first - end - - def candidate_version - return @candidate_version if @candidate_version - - status = shell_out_compact("emerge", "--color", "n", "--nospinner", "--search", new_resource.package_name.split("/").last) - available, installed = parse_emerge(new_resource.package_name, status.stdout) - @candidate_version = available + if pkginfo.stdout.lines.count > 1 + raise_error_for_query("produced unexpected output (multiple lines):\n#{pkginfo.inspect}") + end - unless status.exitstatus == 0 - raise Chef::Exceptions::Package, "emerge --search failed - #{status.inspect}!" + pkginfo.stdout.chomp! + if pkginfo.stdout =~ /-r\d+$/ + # Latest/Best version of the package is a revision (-rX). + @candidate_version = pkginfo.stdout.split(/(?<=-)/).last(2).join + else + # Latest/Best version of the package is NOT a revision (-rX). + @candidate_version = pkginfo.stdout.split("-").last end @candidate_version diff --git a/spec/unit/provider/package/portage_spec.rb b/spec/unit/provider/package/portage_spec.rb index d77e180181..40dc44b113 100644 --- a/spec/unit/provider/package/portage_spec.rb +++ b/spec/unit/provider/package/portage_spec.rb @@ -113,173 +113,37 @@ describe Chef::Provider::Package::Portage, "load_current_resource" do end it "should throw an exception if the exitstatus is not 0" do - status = double(:stdout => "", :exitstatus => 1) + status = double(:stdout => "", :stderr => "", :exitstatus => 1) allow(@provider).to receive(:shell_out).and_return(status) expect { @provider.candidate_version }.to raise_error(Chef::Exceptions::Package) end it "should find the candidate_version if a category is specifed and there are no duplicates" do - output = <<EOF -Searching... -[ Results for search key : git ] -[ Applications found : 14 ] - -* app-misc/digitemp [ Masked ] - Latest version available: 3.5.0 - Latest version installed: [ Not Installed ] - Size of files: 261 kB - Homepage: http://www.digitemp.com/ http://www.ibutton.com/ - Description: Temperature logging and reporting using Dallas Semiconductor's iButtons and 1-Wire protocol - License: GPL-2 - -* dev-util/git - Latest version available: 1.6.0.6 - Latest version installed: ignore - Size of files: 2,725 kB - Homepage: http://git.or.cz/ - Description: GIT - the stupid content tracker, the revision control system heavily used by the Linux kernel team - License: GPL-2 - -* dev-util/gitosis [ Masked ] - Latest version available: 0.2_p20080825 - Latest version installed: [ Not Installed ] - Size of files: 31 kB - Homepage: http://eagain.net/gitweb/?p=gitosis.git;a=summary - Description: gitosis -- software for hosting git repositories - License: GPL-2 -EOF - - status = double(:stdout => output, :exitstatus => 0) + status = double(:stdout => "dev-vcs/git-2.16.2", :exitstatus => 0) expect(@provider).to receive(:shell_out).and_return(status) - expect(@provider.candidate_version).to eq("1.6.0.6") + expect(@provider.candidate_version).to eq("2.16.2") end it "should find the candidate_version if a category is not specifed and there are no duplicates" do - output = <<EOF -Searching... -[ Results for search key : git ] -[ Applications found : 14 ] - -* app-misc/digitemp [ Masked ] - Latest version available: 3.5.0 - Latest version installed: [ Not Installed ] - Size of files: 261 kB - Homepage: http://www.digitemp.com/ http://www.ibutton.com/ - Description: Temperature logging and reporting using Dallas Semiconductor's iButtons and 1-Wire protocol - License: GPL-2 - -* dev-util/git - Latest version available: 1.6.0.6 - Latest version installed: ignore - Size of files: 2,725 kB - Homepage: http://git.or.cz/ - Description: GIT - the stupid content tracker, the revision control system heavily used by the Linux kernel team - License: GPL-2 - -* dev-util/gitosis [ Masked ] - Latest version available: 0.2_p20080825 - Latest version installed: [ Not Installed ] - Size of files: 31 kB - Homepage: http://eagain.net/gitweb/?p=gitosis.git;a=summary - Description: gitosis -- software for hosting git repositories - License: GPL-2 -EOF - - status = double(:stdout => output, :exitstatus => 0) + status = double(:stdout => "dev-vcs/git-2.16.2", :exitstatus => 0) @provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context) expect(@provider).to receive(:shell_out).and_return(status) - expect(@provider.candidate_version).to eq("1.6.0.6") + expect(@provider.candidate_version).to eq("2.16.2") end it "should throw an exception if a category is not specified and there are duplicates" do - output = <<EOF -Searching... -[ Results for search key : git ] -[ Applications found : 14 ] - -* app-misc/digitemp [ Masked ] - Latest version available: 3.5.0 - Latest version installed: [ Not Installed ] - Size of files: 261 kB - Homepage: http://www.digitemp.com/ http://www.ibutton.com/ - Description: Temperature logging and reporting using Dallas Semiconductor's iButtons and 1-Wire protocol - License: GPL-2 - -* app-misc/git - Latest version available: 4.3.20 - Latest version installed: [ Not Installed ] - Size of files: 416 kB - Homepage: http://www.gnu.org/software/git/ - Description: GNU Interactive Tools - increase speed and efficiency of most daily task - License: GPL-2 + stderr_output = <<EOF +You specified an unqualified atom that matched multiple packages: +* app-misc/sphinx +* dev-python/sphinx -* dev-util/git - Latest version available: 1.6.0.6 - Latest version installed: ignore - Size of files: 2,725 kB - Homepage: http://git.or.cz/ - Description: GIT - the stupid content tracker, the revision control system heavily used by the Linux kernel team - License: GPL-2 - -* dev-util/gitosis [ Masked ] - Latest version available: 0.2_p20080825 - Latest version installed: [ Not Installed ] - Size of files: 31 kB - Homepage: http://eagain.net/gitweb/?p=gitosis.git;a=summary - Description: gitosis -- software for hosting git repositories - License: GPL-2 +Please use a more specific atom. EOF - - status = double(:stdout => output, :exitstatus => 0) + status = double(:stdout => "", :stderr => stderr_output, :exitstatus => 1) @provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context) expect(@provider).to receive(:shell_out).and_return(status) expect { @provider.candidate_version }.to raise_error(Chef::Exceptions::Package) end - - it "should find the candidate_version if a category is specifed and there are category duplicates" do - output = <<EOF -Searching... -[ Results for search key : git ] -[ Applications found : 14 ] - -* app-misc/digitemp [ Masked ] - Latest version available: 3.5.0 - Latest version installed: [ Not Installed ] - Size of files: 261 kB - Homepage: http://www.digitemp.com/ http://www.ibutton.com/ - Description: Temperature logging and reporting using Dallas Semiconductor's iButtons and 1-Wire protocol - License: GPL-2 - -* app-misc/git - Latest version available: 4.3.20 - Latest version installed: [ Not Installed ] - Size of files: 416 kB - Homepage: http://www.gnu.org/software/git/ - Description: GNU Interactive Tools - increase speed and efficiency of most daily task - License: GPL-2 - -* dev-util/git - Latest version available: 1.6.0.6 - Latest version installed: ignore - Size of files: 2,725 kB - Homepage: http://git.or.cz/ - Description: GIT - the stupid content tracker, the revision control system heavily used by the Linux kernel team - License: GPL-2 - -* dev-util/gitosis [ Masked ] - Latest version available: 0.2_p20080825 - Latest version installed: [ Not Installed ] - Size of files: 31 kB - Homepage: http://eagain.net/gitweb/?p=gitosis.git;a=summary - Description: gitosis -- software for hosting git repositories - License: GPL-2 -EOF - - status = double(:stdout => output, :exitstatus => 0) - @provider = Chef::Provider::Package::Portage.new(@new_resource, @run_context) - expect(@provider).to receive(:shell_out).and_return(status) - expect(@provider.candidate_version).to eq("1.6.0.6") - end end describe Chef::Provider::Package::Portage, "install_package" do |