什么是用于分层和可继承配置的最佳Perl模块?

5
如果我有一个全新的项目,使用基于Perl的哪个配置模块最佳实践?
将会有一个 Catalyst 应用程序和一些命令行脚本。它们应该共享相同的配置。
我认为需要一些功能...
分层配置以清晰地维护不同的开发和生产设置。
我想定义“全局”配置一次(例如,results_per_page => 20),并且可以被我的开发/生产配置继承但又可以覆盖。
Global:
  results_per_page: 20
  db_dsn: DBI:mysql;
  db_name: my_app
Dev:
  inherit_from: Global
  db_user: dev
  db_pass: dev
Dev_New_Feature_Branch:
  inherit_from: Dev
  db_name: my_app_new_feature
Live:
  inherit_from: Global
  db_user: live
  db_pass: secure

当我将项目部署到新服务器或者分支/复制到其他地方(例如,新的开发实例)时,我希望能(仅一次)设置使用哪个配置集/文件,然后所有未来的更新都是自动的。

我想这可以通过符号链接来实现:

git clone example.com:/var/git/my_project . # or any equiv vcs
cd my_project/etc
ln -s live.config to_use.config

未来,随着科技的发展,IT技术将会变得越来越重要。
git pull # or any equiv vcs

我还希望有类似于FindBin的东西,这样我的配置文件就可以使用绝对路径或相对于当前部署的路径。鉴于此:

/home/me/development/project/
  bin
  lib
  etc/config

其中/home/me/development/project/etc/config包含以下内容:

tmpl_dir: templates/

当我的Perl代码查找tmpl_dir配置时,它会得到:
/home/me/development/project/templates/

但是在实际部署中:
/var/www/project/
  bin
  lib
  etc/config

同样的代码会神奇地返回相同的结果。
/var/www/project/templates/

在配置中应该尊重绝对值,以便:

apache_config: /etc/apache2/httpd.conf

无论如何,都会返回“/etc/apache2/httpd.conf”。

与FindBin风格的方法不同,另一种选择是允许以其他配置值为基础定义配置值。

tmpl_dir: $base_dir/templates

我也想要一匹小马 ;)

3个回答

9

Catalyst::Plugin::ConfigLoader支持多个覆盖配置文件。如果你的Catalyst应用程序叫做MyApp,那么它有三个级别的覆盖:1)MyApp.pm可以有一个__PACKAGE__->config(...)指令,2)它接下来会在应用程序的主目录中查找MyApp.yml,3)它会查找MyApp_local.yml。每个级别都可以覆盖其他级别中的设置。

在我构建的Catalyst应用程序中,我将所有不可变的设置放在MyApp.pm中,将调试设置放在MyApp.yml中,将生产设置放在MyApp_<servertype>.yml中,然后在每个部署的服务器上将MyApp_local.yml链接到指向MyApp_<servertype>.yml(它们都有一点不同...)。

这样,我的所有配置都在SVN中,我只需要一个ln -s步骤来手动配置服务器。


6

Perl最佳实践警告您不要做您想要的事情。它指出配置文件应该简单,避免您所需的复杂特性。它建议使用三个模块(都不是核心Perl):Config::GeneralConfig::StdConfig::Tiny

这样做的一般理由是,配置文件的编辑往往是由非程序员完成的,您使配置文件更加复杂,他们就越容易搞砸它们。

所有这些话说完了,您可能会看一下YAML。它提供了一个功能齐全、易于阅读的序列化格式。我相信Perl中目前推荐的解析器是YAML::XS。如果您选择这条路,我建议编写一个配置工具供最终用户使用,而不是让他们直接编辑文件。

ETA:根据Chris Dolan的回答,似乎对您来说YAML是正确的选择,因为Catalyst已经在使用它(.yml是YAML文件的事实标准扩展名)。

*我听说盲人可能会有困难


2
YAML对于配置来说很讨厌 - 它不太友好于非程序员,部分原因是yaml在pod中的定义本身就是错误的,因为它们都依赖于不同的空格方式。这个链接解决了Config::General的主要问题。我以前用C::G编写过一些相当复杂的配置文件,它确实不会干扰你的语法要求等方面。除此之外,Chris的建议似乎是正确的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接