Commit 53d2babb authored by Robin H. Johnson's avatar Robin H. Johnson Committed by GitHub
Browse files

Merge pull request #152 from gentoo/accept-keywords

implement package.accept_keywords.
parents 0d31af50 bedb3113
File.expand_path('../..', File.dirname(__FILE__)).tap { |dir| $:.unshift(dir) unless $:.include?(dir) }
require 'puppet/provider/portagefile'
require 'puppet/util/portage'
Puppet::Type.type(:package_accept_keywords).provide(:parsed,
:parent => Puppet::Provider::PortageFile,
:default_target => "/etc/portage/package.accept_keywords/default",
:filetype => :flat
) do
desc "The package_accept_keywords provider that uses the ParsedFile class"
text_line :comment, :match => /^\s*#/
text_line :blank, :match => /^\s*$/
record_line :parsed, :fields => %w{name keywords}, :joiner => ' ', :rts => true do |line|
Puppet::Provider::PortageFile.process_line(line, :keywords)
end
# Define the ParsedFile format hook
#
# @param [Hash] hash
#
# @return [String]
def self.to_line(hash)
return super unless hash[:record_type] == :parsed
build_line(hash, :keywords)
end
end
File.expand_path('../..', File.dirname(__FILE__)).tap { |dir| $:.unshift(dir) unless $:.include?(dir) }
require 'puppet/property/portage_version'
require 'puppet/property/portage_slot'
require 'puppet/parameter/portage_name'
require 'puppet/util/portage'
Puppet::Type.newtype(:package_accept_keywords) do
@doc = "Set accept_keywords for a package.
package_accept_keywords { 'app-admin/puppet':
accept_keywords => ['~x86', '-hppa'],
target => 'puppet',
}"
ensurable do
defaultvalues
defaultto :present
end
newparam(:name, :namevar => true, :parent => Puppet::Parameter::PortageName)
newproperty(:version, :parent => Puppet::Property::PortageVersion)
newproperty(:slot, :parent => Puppet::Property::PortageSlot)
newproperty(:accept_keywords) do
desc "The accept_keywords(s) to use"
defaultto []
validate do |value|
raise ArgumentError, "Keyword cannot contain whitespace" if value =~ /\s/
end
def insync?(is)
is == should
end
def should
if defined? @should
flattened = @should.flatten
if flattened == [:absent]
return :absent
else
return flattened.select { |s| !s.empty? }
end
else
return nil
end
end
def should_to_s(newvalue = @should)
newvalue.join(" ")
end
def is_to_s(currentvalue = @is)
currentvalue = [currentvalue] unless currentvalue.is_a? Array
currentvalue.join(" ")
end
end
newproperty(:target) do
desc "The location of the package.accept_keywords file"
defaultto do
if @resource.class.defaultprovider.ancestors.include?(Puppet::Provider::ParsedFile)
@resource.class.defaultprovider.default_target
else
nil
end
end
# Allow us to not have to specify an absolute path unless we really want to
munge do |value|
if !value.match(/\//)
value = "/etc/portage/package.accept_keywords/" + value
end
value
end
end
end
...@@ -16,6 +16,10 @@ ...@@ -16,6 +16,10 @@
# #
# Portage keywords for the package. # Portage keywords for the package.
# #
# [*accept_keywords*]
#
# Portage accept_keywords for the package.
#
# [*target*] # [*target*]
# #
# A default value for package.* targets # A default value for package.* targets
...@@ -28,6 +32,10 @@ ...@@ -28,6 +32,10 @@
# #
# An optional custom target for package keywords # An optional custom target for package keywords
# #
# [*accept_keywords_target*]
#
# An optional custom target for package accept_keywords
#
# [*mask_target*] # [*mask_target*]
# #
# An optional custom target for package masks # An optional custom target for package masks
...@@ -52,6 +60,14 @@ ...@@ -52,6 +60,14 @@
# #
# An optional slot specification for package keywords # An optional slot specification for package keywords
# #
# [*accept_keywords_version*]
#
# An optional version specification for package accept_keywords
#
# [*accept_keywords_slot*]
#
# An optional slot specification for package accept_keywords
#
# [*mask_version*] # [*mask_version*]
# #
# An optional version specification for package mask # An optional version specification for package mask
...@@ -73,7 +89,7 @@ ...@@ -73,7 +89,7 @@
# portage::package { 'app-admin/puppet': # portage::package { 'app-admin/puppet':
# ensure => '3.0.1', # ensure => '3.0.1',
# use => ['augeas', '-rrdtool'], # use => ['augeas', '-rrdtool'],
# keywords => '~amd64', # accept_keywords => '~amd64',
# target => 'puppet', # target => 'puppet',
# mask_version => '<=2.7.18', # mask_version => '<=2.7.18',
# } # }
...@@ -82,6 +98,7 @@ ...@@ -82,6 +98,7 @@
# #
# * `puppet describe package_use` # * `puppet describe package_use`
# * `puppet describe package_keywords` # * `puppet describe package_keywords`
# * `puppet describe package_accept_keywords`
# * `puppet describe package_mask` # * `puppet describe package_mask`
# * `puppet describe package_unmask` # * `puppet describe package_unmask`
# #
...@@ -93,6 +110,9 @@ define portage::package ( ...@@ -93,6 +110,9 @@ define portage::package (
$keywords = undef, $keywords = undef,
$keywords_version = undef, $keywords_version = undef,
$keywords_slot = undef, $keywords_slot = undef,
$accept_keywords = undef,
$accept_keywords_version = undef,
$accept_keywords_slot = undef,
$mask_version = undef, $mask_version = undef,
$mask_slot = undef, $mask_slot = undef,
$unmask_version = undef, $unmask_version = undef,
...@@ -100,6 +120,7 @@ define portage::package ( ...@@ -100,6 +120,7 @@ define portage::package (
$target = undef, $target = undef,
$use_target = undef, $use_target = undef,
$keywords_target = undef, $keywords_target = undef,
$accept_keywords_target = undef,
$mask_target = undef, $mask_target = undef,
$unmask_target = undef, $unmask_target = undef,
) { ) {
...@@ -124,6 +145,13 @@ define portage::package ( ...@@ -124,6 +145,13 @@ define portage::package (
$assigned_keywords_target = $target $assigned_keywords_target = $target
} }
if $accept_keywords_target {
$assigned_accept_keywords_target = $accept_keywords_target
}
else {
$assigned_accept_keywords_target = $target
}
if $mask_target { if $mask_target {
$assigned_mask_target = $mask_target $assigned_mask_target = $mask_target
} }
...@@ -177,6 +205,28 @@ define portage::package ( ...@@ -177,6 +205,28 @@ define portage::package (
notify => [Exec["rebuild_${atom}"], Package[$name]], notify => [Exec["rebuild_${atom}"], Package[$name]],
} }
} }
if $accept_keywords or $accept_keywords_version {
if $accept_keywords == 'all' {
$assigned_accept_keywords = undef
}
else {
$assigned_accept_keywords = $accept_keywords
}
package_accept_keywords { $name:
accept_keywords => $assigned_accept_keywords,
version => $accept_keywords_version,
slot => $accept_keywords_slot,
target => $assigned_accept_keywords_target,
notify => [Exec["rebuild_${atom}"], Package[$name]],
}
}
else {
package_accept_keywords { $name:
ensure => absent,
target => $assigned_accept_keywords_target,
notify => [Exec["rebuild_${atom}"], Package[$name]],
}
}
if $mask_version or $mask_slot { if $mask_version or $mask_slot {
if $mask_version == 'all' { if $mask_version == 'all' {
......
require 'spec_helper'
require 'support/integration/provider/shared_contexts'
describe Puppet::Type.type(:package_accept_keywords).provider(:parsed) do
include_context "portagefile integration runner"
subject { File.read(path) }
describe "with a single instance" do
describe "without a version or slot" do
describe "without a keyword" do
let(:resources) do
r = []
r << type_class.new(
:name => 'app-admin/dummy',
:target => path,
:provider => :parsed
)
r
end
it { should have(1).lines }
it { should match %r[^app-admin/dummy $] }
end
describe "with a single keyword" do
let(:resources) do
r = []
r << type_class.new(
:name => 'app-admin/dummy',
:accept_keywords => '~amd64',
:target => path,
:provider => :parsed
)
r
end
it { should have(1).lines }
it { should match %r[^app-admin/dummy ~amd64$] }
end
describe "with multiple accept_keywords" do
let(:resources) do
r = []
r << type_class.new(
:name => 'app-admin/dummy',
:accept_keywords => ['~amd64', '~x86'],
:target => path,
:provider => :parsed
)
r
end
it { should have(1).lines }
it { should match %r[^app-admin/dummy ~amd64 ~x86$] }
end
end
describe "with a version and slot" do
describe "without a keyword" do
let(:resources) do
r = []
r << type_class.new(
:name => 'app-admin/dummy',
:target => path,
:version => '>=2.3.4_alpha1',
:slot => '2',
:provider => :parsed
)
r
end
it { should have(1).lines }
it { should match %r[^>=app-admin/dummy-2\.3\.4_alpha1:2 $] }
end
describe "with a single keyword" do
let(:resources) do
r = []
r << type_class.new(
:name => 'app-admin/dummy',
:accept_keywords => '~amd64',
:target => path,
:version => '>=2.3.4_alpha1',
:slot => '2',
:provider => :parsed
)
r
end
it { should have(1).lines }
it { should match %r[^>=app-admin/dummy-2\.3\.4_alpha1:2 ~amd64$] }
end
describe "with multiple accept_keywords" do
let(:resources) do
r = []
r << type_class.new(
:name => 'app-admin/dummy',
:accept_keywords => ['~amd64', '~x86'],
:target => path,
:version => '>=2.3.4_alpha1',
:slot => '2',
:provider => :parsed
)
r
end
it { should have(1).lines }
it { should match %r[^>=app-admin/dummy-2\.3\.4_alpha1:2 ~amd64 ~x86$] }
end
end
end
end
require 'spec_helper'
describe Puppet::Type.type(:package_accept_keywords).provider(:parsed) do
before do
described_class.stubs(:filetype).returns(Puppet::Util::FileType::FileTypeRam)
described_class.stubs(:filetype=)
@default_target = described_class.default_target
end
it "should have a default target of /etc/portage/package.accept_keywords/default" do
described_class.default_target.should == "/etc/portage/package.accept_keywords/default"
end
describe "when parsing" do
it "should parse out the package name" do
line = "app-admin/tree ~amd64"
described_class.parse_line(line)[:name].should == "app-admin/tree"
end
it "should parse out the package name with version" do
line = ">=app-admin/tree-2.0-r1 ~amd64"
described_class.parse_line(line)[:name].should == "app-admin/tree"
end
it "should parse out the package name with slot" do
line = "app-admin/tree:2 ~amd64"
described_class.parse_line(line)[:name].should == "app-admin/tree"
end
it "should not raise an error if no accept_keywords are given for a package" do
line = "app-admin/tree"
lambda { described_class.parse_line(line) }.should_not raise_error
end
it "should parse out a single accept_keywords" do
line = "app-admin/tree ~amd64"
described_class.parse_line(line)[:accept_keywords].should == %w{~amd64}
end
it "should parse out multiple accept_keywords into an array" do
line = "app-admin/tree -amd64 ~amd64"
described_class.parse_line(line)[:accept_keywords].should == %w{-amd64 ~amd64}
end
end
describe "when flushing" do
before :each do
@ramfile = Puppet::Util::FileType::FileTypeRam.new(@default_target)
File.stubs(:exist?).with('/etc/portage/package.accept_keywords').returns(true)
described_class.any_instance.stubs(:target_object).returns(@ramfile)
resource = Puppet::Type::Package_accept_keywords.new(:name => 'app-admin/tree', :ensure => :present)
resource.stubs(:should).with(:target).returns(@default_target)
@providerinstance = described_class.new(resource)
@providerinstance.ensure = :present
end
after :each do
described_class.clear
end
it "should write an atom name to disk" do
@providerinstance.flush
@ramfile.read.should == "app-admin/tree\n"
end
it "should write a single keyword to disk" do
@providerinstance.accept_keywords = "~amd64"
@providerinstance.flush
@ramfile.read.should == "app-admin/tree ~amd64\n"
end
it "should write an array of accept_keywords to disk" do
@providerinstance.accept_keywords = %w{~amd64 ~x86}
@providerinstance.flush
@ramfile.read.should == "app-admin/tree ~amd64 ~x86\n"
end
end
end
require 'spec_helper'
describe Puppet::Type.type(:package_accept_keywords) do
before do
@provider = stub 'provider'
@provider.stubs(:name).returns(:parsed)
@provider.stubs(:ancestors).returns([Puppet::Provider::ParsedFile])
@provider.stubs(:default_target).returns("defaulttarget")
described_class.stubs(:defaultprovider).returns(@provider)
end
describe "when validating attributes" do
params = [:name]
properties = [:accept_keywords, :keywords, :target, :ensure, :version, :slot]
params.each do |param|
it "should have the #{param} param" do
described_class.attrtype(param).should == :param
end
end
properties.each do |property|
it "should have the #{property} property" do
described_class.attrtype(property).should == :property
end
end
end
it "should have name as the namevar" do
described_class.key_attributes.should == [:name]
end
describe "when validating the accept_keywords property" do
it "should accept a string for accept_keywords" do
expect { described_class.new(:name => "sys-devel/gcc", :accept_keywords => "~amd64") }.to_not raise_error
end
it "should reject accept_keywords with a space" do
expect { described_class.new(:name => "sys-devel/gcc", :accept_keywords => "~amd 64") }.to raise_error
end
it "should accept an array for accept_keywords" do
expect { described_class.new(:name => "sys-devel/gcc", :accept_keywords => ["~amd64", "~x86"]) }.to_not raise_error
end
end
describe "when validating the target property" do
it "should default to the provider's default target" do
described_class.new(:name => "sys-devel/gcc").should(:target).should == "/etc/portage/package.accept_keywords/defaulttarget"
end
it "should munge targets that do not specify a fully qualified path" do
described_class.new(:name => "sys-devel/gcc", :target => "gcc").should(:target).should == "/etc/portage/package.accept_keywords/gcc"
end
it "should not munge fully qualified targets" do
described_class.new(:name => "sys-devel/gcc", :target => "/tmp/gcc").should(:target).should == "/tmp/gcc"
end
end
describe "when validating the accept_keywords property" do
it "should default to an empty list" do
described_class.new(:name => "sys-devel/gcc").should(:accept_keywords).should == []
end
it "should properly handle nested arrays" do
described_class.new(:name => "sys-devel/gcc", :accept_keywords => ["foo",["bar"]]).property(:accept_keywords).insync?(["foo","bar"]).should eq true
end
end
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment