Skip to content

Commit 15d5223

Browse files
committed
Merge remote-tracking branch 'origin/maint-desc-docs-fallback-1.6.x' into maint-desc-docs-fallback
2 parents d249941 + 988491b commit 15d5223

File tree

8 files changed

+111
-44
lines changed

8 files changed

+111
-44
lines changed

lib/puppet/resource_api.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ def register_type(definition)
3535
end
3636

3737
Puppet::Type.newtype(definition[:name].to_sym) do
38-
@docs = definition[:docs]
3938
@type_definition = type_def
39+
@docs = type_def.desc
4040

4141
# Keeps a copy of the provider around. Weird naming to avoid clashes with puppet's own `provider` member
4242
define_singleton_method(:my_provider) do

lib/puppet/resource_api/transport.rb

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,16 @@ module Puppet::ResourceApi; end # rubocop:disable Style/Documentation
33
# Remote target transport API
44
module Puppet::ResourceApi::Transport
55
def register(schema)
6-
raise Puppet::DevError, 'requires a hash as schema, not `%{other_type}`' % { other_type: schema.class } unless schema.is_a? Hash
7-
raise Puppet::DevError, 'requires a `:name`' unless schema.key? :name
8-
raise Puppet::DevError, 'requires `:desc`' unless schema.key? :desc
9-
raise Puppet::DevError, 'requires `:connection_info`' unless schema.key? :connection_info
10-
raise Puppet::DevError, '`:connection_info` must be a hash, not `%{other_type}`' % { other_type: schema[:connection_info].class } unless schema[:connection_info].is_a?(Hash)
6+
definition = Puppet::ResourceApi::TransportSchemaDef.new(schema)
117

12-
unless transports[schema[:name]].nil?
8+
unless transports[definition.name].nil?
139
raise Puppet::DevError, 'Transport `%{name}` is already registered for `%{environment}`' % {
14-
name: schema[:name],
10+
name: definition.name,
1511
environment: current_environment,
1612
}
1713
end
18-
transports[schema[:name]] = Puppet::ResourceApi::TransportSchemaDef.new(schema)
14+
15+
transports[schema[:name]] = definition
1916
end
2017
module_function :register # rubocop:disable Style/AccessModifierDeclarations
2118

lib/puppet/resource_api/type_definition.rb

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,27 @@ def namevars
9090
}.keys
9191
end
9292

93+
def desc
94+
definition[:desc]
95+
end
96+
9397
def validate_schema(definition, attr_key)
9498
raise Puppet::DevError, '%{type_class} must be a Hash, not `%{other_type}`' % { type_class: self.class.name, other_type: definition.class } unless definition.is_a?(Hash)
95-
@attributes = definition[attr_key]
9699
raise Puppet::DevError, '%{type_class} must have a name' % { type_class: self.class.name } unless definition.key? :name
97-
raise Puppet::DevError, '%{type_class} must have `%{attr_key}`' % { type_class: self.class.name, attrs: attr_key } unless definition.key? attr_key
100+
raise Puppet::DevError, '`%{name}` must have `%{attrs}`' % { name: definition[:name], attrs: attr_key } unless definition.key? attr_key
101+
102+
# fixup desc/docs backwards compatibility
103+
if definition.key? :docs
104+
if definition[:desc]
105+
raise Puppet::DevError, '`%{name}` has both `desc` and `docs`, prefer using `desc`' % { name: definition[:name] }
106+
end
107+
definition[:desc] = definition[:docs]
108+
definition.delete(:docs)
109+
end
110+
111+
Puppet.warning('`%{name}` has no documentation, add it using a `desc` key' % { name: definition[:name] }) unless definition.key? :desc
112+
113+
@attributes = definition[attr_key]
98114
unless attributes.is_a?(Hash)
99115
raise Puppet::DevError, '`%{name}.%{attrs}` must be a hash, not `%{other_type}`' % {
100116
name: definition[:name], attrs: attr_key, other_type: attributes.class
@@ -104,7 +120,7 @@ def validate_schema(definition, attr_key)
104120
attributes.each do |key, attr|
105121
raise Puppet::DevError, "`#{definition[:name]}.#{key}` must be a Hash, not a #{attr.class}" unless attr.is_a? Hash
106122
raise Puppet::DevError, "`#{definition[:name]}.#{key}` has no type" unless attr.key? :type
107-
Puppet.warning("`#{definition[:name]}.#{key}` has no docs") unless attr.key? :desc
123+
Puppet.warning("`#{definition[:name]}.#{key}` has no documentation, add it using a `desc` key") unless attr.key? :desc
108124

109125
# validate the type by attempting to parse into a puppet type
110126
@data_type_cache[attributes[key][:type]] ||=

spec/puppet/resource_api/base_context_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def send_log(log, msg)
1313
TestContext.new(definition)
1414
end
1515

16-
let(:definition_hash) { { name: 'some_resource', attributes: { name: { type: 'String', desc: 'message' } }, features: feature_support } }
16+
let(:definition_hash) { { name: 'some_resource', desc: 'a test resource', attributes: { name: { type: 'String', desc: 'message' } }, features: feature_support } }
1717
let(:definition) { Puppet::ResourceApi::TypeDefinition.new(definition_hash) }
1818
let(:feature_support) { [] }
1919

spec/puppet/resource_api/base_type_definition_spec.rb

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,25 @@
44
subject(:type) { described_class.new(definition, :attributes) }
55

66
let(:definition) do
7-
{ name: 'some_resource', attributes: {
8-
ensure: {
9-
type: 'Enum[present, absent]',
10-
desc: 'Whether this resource should be present or absent on the target system.',
11-
default: 'present',
7+
{ name: 'some_resource',
8+
desc: 'a test type',
9+
attributes: {
10+
ensure: {
11+
type: 'Enum[present, absent]',
12+
desc: 'Whether this resource should be present or absent on the target system.',
13+
default: 'present',
14+
},
15+
name: {
16+
type: 'String',
17+
desc: 'The name of the resource you want to manage.',
18+
behaviour: :namevar,
19+
},
20+
prop: {
21+
type: 'Integer',
22+
desc: 'A mandatory property, that MUST NOT be validated on deleting.',
23+
},
1224
},
13-
name: {
14-
type: 'String',
15-
desc: 'The name of the resource you want to manage.',
16-
behaviour: :namevar,
17-
},
18-
prop: {
19-
type: 'Integer',
20-
desc: 'A mandatory property, that MUST NOT be validated on deleting.',
21-
},
22-
}, features: feature_support }
25+
features: feature_support }
2326
end
2427
let(:feature_support) { [] }
2528

@@ -76,6 +79,7 @@
7679
let(:definition) do
7780
{
7881
name: 'some_transport',
82+
desc: 'a test transport',
7983
connection_info: {
8084
username: {
8185
type: 'String',
@@ -191,49 +195,80 @@
191195
end
192196

193197
describe '#validate_schema' do
198+
let(:definition) { { name: 'some_resource', desc: 'a test resource', attributes: attributes } }
199+
194200
context 'when the type definition does not have a name' do
195-
let(:definition) { { attributes: 'some_string' } }
201+
let(:definition) { { desc: 'a test resource', attributes: {} } }
196202

197203
it { expect { type }.to raise_error Puppet::DevError, %r{must have a name} }
198204
end
199205

206+
context 'when the type definition does not have a desc' do
207+
let(:definition) { { name: 'some_resource', attributes: {} } }
208+
209+
it {
210+
expect(Puppet).to receive(:warning).with('`some_resource` has no documentation, add it using a `desc` key')
211+
type
212+
}
213+
end
214+
200215
context 'when attributes is not a hash' do
201-
let(:definition) { { name: 'some_resource', attributes: 'some_string' } }
216+
let(:attributes) { 'some_string' }
202217

203218
it { expect { type }.to raise_error Puppet::DevError, %r{`some_resource.attributes` must be a hash} }
204219
end
205220

206221
context 'when an attribute is not a hash' do
207-
let(:definition) { { name: 'some_resource', attributes: { name: 'some_string' } } }
222+
let(:attributes) { { name: 'some_string' } }
208223

209224
it { expect { type }.to raise_error Puppet::DevError, %r{`some_resource.name` must be a Hash} }
210225
end
211226

212227
context 'when an attribute has no type' do
213-
let(:definition) { { name: 'some_resource', attributes: { name: { desc: 'message' } } } }
228+
let(:attributes) { { name: { desc: 'message' } } }
214229

215230
it { expect { type }.to raise_error Puppet::DevError, %r{has no type} }
216231
end
217232

218-
context 'when an attribute has no descrption' do
219-
let(:definition) { { name: 'some_resource', attributes: { name: { type: 'String' } } } }
233+
context 'when an attribute has no description' do
234+
let(:attributes) { { name: { type: 'String' } } }
220235

221-
it 'Raises a warning message' do
222-
expect(Puppet).to receive(:warning).with('`some_resource.name` has no docs')
236+
it 'raises a warning message' do
237+
expect(Puppet).to receive(:warning).with('`some_resource.name` has no documentation, add it using a `desc` key')
223238
type
224239
end
225240
end
226241

227242
context 'when an attribute has an unsupported type' do
228-
let(:definition) { { name: 'some_resource', attributes: { name: { type: 'basic' } } } }
243+
let(:definition) { { name: 'some_resource', desc: 'a test resource', attributes: { name: { type: 'basic' } } } }
229244

230245
it { expect { type }.to raise_error %r{<basic> is not a valid type specification} }
231246
end
232247

248+
context 'with deprecated `docs` key' do
249+
let(:definition) { { name: 'some_resource', docs: 'a test resource', attributes: {} } }
250+
251+
it 'does not raise a warning message' do
252+
expect(Puppet).not_to receive(:warning)
253+
type
254+
end
255+
256+
it 'exposes the documentation as `desc`' do
257+
expect(type.desc).to eq 'a test resource'
258+
end
259+
end
260+
261+
context 'with both `docs` and `desc` key' do
262+
let(:definition) { { name: 'some_resource', desc: 'the real description', docs: 'an oversight', attributes: {} } }
263+
264+
it { expect { type }.to raise_error Puppet::DevError, %r{`some_resource` has both `desc` and `docs`, prefer using `desc`} }
265+
end
266+
233267
context 'with both behavior and behaviour' do
234268
let(:definition) do
235269
{
236270
name: 'bad_behaviour',
271+
desc: 'a test type',
237272
attributes: {
238273
name: {
239274
type: 'String',
@@ -251,6 +286,7 @@
251286
let(:definition) do
252287
{
253288
name: 'bad_syntax',
289+
desc: 'a test type',
254290
attributes: {
255291
name: {
256292
type: 'Optional[String',

spec/puppet/resource_api/puppet_context_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
RSpec.describe Puppet::ResourceApi::PuppetContext do
44
subject(:context) { described_class.new(definition) }
55

6-
let(:definition) { { name: 'some_resource', attributes: {} } }
6+
let(:definition) { { name: 'some_resource', desc: 'a test resource', attributes: {} } }
77

88
describe '#device' do
99
context 'when a NetworkDevice is configured' do

spec/puppet/resource_api/transport_spec.rb

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,18 @@ def change_environment(name = nil)
3636

3737
describe '#register(schema)' do
3838
context 'when registering a schema with missing keys' do
39-
it { expect { described_class.register([]) }.to raise_error(Puppet::DevError, %r{requires a hash as schema}) }
40-
it { expect { described_class.register({}) }.to raise_error(Puppet::DevError, %r{requires a `:name`}) }
41-
it { expect { described_class.register(name: 'no connection info', desc: 'some description') }.to raise_error(Puppet::DevError, %r{requires `:connection_info`}) }
42-
it { expect { described_class.register(name: 'no description') }.to raise_error(Puppet::DevError, %r{requires `:desc`}) }
43-
it { expect { described_class.register(name: 'no hash attributes', desc: 'some description', connection_info: []) }.to raise_error(Puppet::DevError, %r{`:connection_info` must be a hash, not}) }
39+
it { expect { described_class.register([]) }.to raise_error(Puppet::DevError, %r{must be a Hash, not `Array`}) }
40+
it { expect { described_class.register({}) }.to raise_error(Puppet::DevError, %r{must have a name}) }
41+
it { expect { described_class.register(name: 'no connection info', desc: 'some description') }.to raise_error(Puppet::DevError, %r{`no connection info` must have `connection_info`}) }
42+
it do
43+
expect {
44+
described_class.register(name: 'no hash attributes', desc: 'some description', connection_info: [])
45+
}.to raise_error(Puppet::DevError, %r{`no hash attributes.connection_info` must be a hash, not `Array})
46+
end
47+
it 'warns if there is no documentation ' do
48+
expect(Puppet).to receive(:warning).with(%r{has no documentation, add it using a `desc` key})
49+
described_class.register(name: 'no description', connection_info: {})
50+
end
4451
end
4552

4653
context 'when registering a minimal transport' do
@@ -300,6 +307,7 @@ class Wibble; end
300307

301308
it 'validates the connection_info' do
302309
allow(Puppet::ResourceApi::TransportSchemaDef).to receive(:new).with(schema).and_return(schema_def)
310+
allow(schema_def).to receive(:name).with(no_args).and_return('validate')
303311

304312
described_class.register(schema)
305313

@@ -330,6 +338,7 @@ class Wibble; end
330338

331339
before(:each) do
332340
allow(Puppet::ResourceApi::TransportSchemaDef).to receive(:new).with(schema).and_return(schema_def)
341+
allow(schema_def).to receive(:name).with(no_args).and_return('sensitive_transport')
333342
described_class.register(schema)
334343
end
335344

spec/puppet/resource_api_spec.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
after(:each) do
1818
Puppet::Util::Log.close_all
19+
Puppet::Util::NetworkDevice.teardown
1920
end
2021

2122
it 'has a version number' do
@@ -44,6 +45,7 @@
4445
let(:definition) do
4546
{
4647
name: type_name,
48+
desc: 'a test resource',
4749
attributes: {
4850
name: {
4951
type: 'String',
@@ -747,6 +749,7 @@ def set(_context, _changes); end
747749
let(:definition) do
748750
{
749751
name: 'init_behaviour',
752+
desc: 'a test resource',
750753
attributes: {
751754
ensure: {
752755
type: 'Enum[present, absent]',
@@ -1172,7 +1175,7 @@ def set(_context, _changes); end
11721175
context 'when loading a provider that doesn\'t create the correct class' do
11731176
let(:definition) { { name: 'no_class', attributes: {} } }
11741177

1175-
it { expect { described_class.load_provider('no_class') }.to raise_error Puppet::DevError, %r{Puppet::Provider::NoClass::NoClass} }
1178+
it { expect { described_class.load_provider('no_class') }.to raise_error Puppet::DevError, %r{provider class Puppet::Provider::NoClass::NoClass not found} }
11761179
end
11771180

11781181
context 'when loading a provider that creates the correct class' do
@@ -1792,6 +1795,7 @@ def set(_context, changes) end
17921795
let(:definition) do
17931796
{
17941797
name: 'test_noop_support',
1798+
desc: 'a test resource',
17951799
features: ['no such feature'],
17961800
attributes: {},
17971801
}
@@ -1808,6 +1812,7 @@ def set(_context, changes) end
18081812
let(:definition) do
18091813
{
18101814
name: 'test_behaviour',
1815+
desc: 'a test resource',
18111816
attributes: {
18121817
id: {
18131818
type: 'String',
@@ -1824,6 +1829,7 @@ def set(_context, changes) end
18241829
let(:definition) do
18251830
{
18261831
name: 'test_behaviour',
1832+
desc: 'a test resource',
18271833
attributes: {
18281834
param: {
18291835
type: 'String',
@@ -1840,6 +1846,7 @@ def set(_context, changes) end
18401846
let(:definition) do
18411847
{
18421848
name: 'test_behaviour',
1849+
desc: 'a test resource',
18431850
attributes: {
18441851
param_ro: {
18451852
type: 'String',
@@ -1856,6 +1863,7 @@ def set(_context, changes) end
18561863
let(:definition) do
18571864
{
18581865
name: 'test_behaviour',
1866+
desc: 'a test resource',
18591867
attributes: {
18601868
param_ro: {
18611869
type: 'String',
@@ -1872,6 +1880,7 @@ def set(_context, changes) end
18721880
let(:definition) do
18731881
{
18741882
name: 'test_behaviour',
1883+
desc: 'a test resource',
18751884
attributes: {
18761885
source: {
18771886
type: 'String',

0 commit comments

Comments
 (0)