我还没有看到任何关于如何覆盖包装食谱中的属性的正式最佳实践,我认为必须选择一种风格,只要您的所有食谱在您的组织内保持一致,您就应该很好。以下是我个人的看法。
属性文件
我们最初遵循类似的分隔属性文件的风格attributes/customize.rb
您描述的格式。但是,我们发现将所有属性保留在中要简单得多attributes/default.rb
,特别是因为我们的属性代码少于 50 行。
覆盖优先级
我们总是使用最低属性优先级当覆盖我们的包装器说明书中的属性时。我们坚持default
只要有可能,因为优先顺序决定了你的食谱default
胜过包装好的食谱default
.
属性访问方式
您看到的大多数食谱都使用字符串访问格式。
default['foo']['bar'] = 42
事实上有一个美食评论家规则特别不鼓励使用符号访问。 Foodcritic 还鼓励使用访问属性的一致风格。如果您正在决定一种样式,请记住社区几乎已经决定了字符串访问格式。
然而,还有另一种方法。 Chef 中的属性不是Hash
,他们实际上是一个Mash. Mash
恰好支持将属性作为方法访问,因此:
default.foo.bar = 42
我们更喜欢这种语法,因为它更紧凑。
不过,请务必小心,因为特贾伊·卡登指出, Chef 实现了这个method_missing
,因此如果属性名称与当前(或将来)的属性名称相同,您可能会遇到问题node
对象方法。我们用我们的组织名称作为所有食谱的序言,因此不太可能发生冲突,但是当我们覆盖社区食谱时,我们可能会遇到问题。值得庆幸的是,测试应该可以发现任何此类错误。
注意事项
重写包装器说明书中的属性不会以令人惊讶的方式工作,特别是在涉及字符串插值时。这在中得到了很好的解释这篇博文。主要要点是食谱是否将属性定义为:
default['version'] = '1.0'
default['url'] = "http://example.com/#{node['version']}.zip"
在你的包装食谱中你重写version
:
default['version'] = '2.0'
The default['url']
仍会决心http://example.com/1.0.zip
, not http://example.com/2.0.zip
正如你所期望的那样。发生这种情况是因为 url 属性被插值before你的覆盖发生了。这篇博文更深入地讨论并提供了一个潜在的解决方案。
Wrap Up
归根结底,Chef 中有多种做事的方法,而且社区仍在成熟。有一些关于编写可重复使用的食谱等的最佳实践,但这些实践仍在不断发展。
您能做的最好的事情就是尝试各种风格,找出最适合您和您的团队的风格。一旦你决定了一种风格,我建议整理一份风格指南(我用过这个 Angular 风格指南作为灵感)。您还可以通过以下方式强制执行您的风格指南定制美食评论家规则。我们通过这种方法取得了成功。