覆盖ENV [' HOME']以开发Ruby命令行应用程序

时间:2014-05-26 14:27:53

标签: ruby command-line-interface

我正在构建一个具有以下特征的Ruby命令行应用程序:

  • 它使用GLI框架。
  • 该应用程序使用ENV['HOME']变量作为用户主目录的路径。
  • 配置文件存储在用户的主目录下。
  • 该应用程序将作为Gem部署到生产中。
  • 开发是在生产中使用该应用程序的同一台计算机上完成的。
  • Cucumber,RSpec和通过bundle exec bin/app_name运行应用程序的组合用于测试开发中的脚本。

该应用程序操纵文件。我的目标是确保开发实例仅在其自己的开发/测试环境中运行。我相信一个好方法是在运行脚本进行开发时覆盖ENV['HOME']

有没有办法覆盖ENV['HOME']变量,这样无论如何,只要脚本在其开发目录中运行,它就不会使用实际的ENV['HOME']路径?

1 个答案:

答案 0 :(得分:1)

我这样做的方法是将任何开发特定的东西保留在实际的应用程序代码之外,但是要在开发期间使用Rakefile进行测试。在那里你可以确保环境设置得恰当,如:

desc "Run the app"
task :exec do
  ENV['HOME']= "somewhere else"
  exec "./bin/your_binary"
end

然后,您可以运行rake exec(或赋予任务更好的名称)来运行开发版本,同时仍然可以运行真实版本。如果您保留bin的开发PATH目录,则应该没有机会混淆这两个命令。

如果您希望能够直接运行开发版本,则可以使用以下事实:当您运行gems二进制文件时,执行的实际文件是Rubygems创建的包装器文件。您可以使用可执行文件顶部的__FILE__ == $0惯用语来检查:

if __FILE == $0
  # executing directly, probably in dev environment
  ENV['HOME'] = "somewhere else"
end

当直接调用您的文件时,将替换环境,当调用已安装的gem $0时将是包装文件,因此将使用原始环境。

执行此操作的“正常”方法是仅从shell设置环境,例如在巴什:

$ HOME='somewhere else' ./bin/the_executable

这里的危险当然是你可能忘记设置环境,导致你丢弃一些文件。您可以通过为整个视野设置新环境来解决这个问题:

$ export HOME='somewhere else'
$ ./bin/the_executable

但这可能会影响使用HOME的其他工具,因此不建议这样做。

我的建议是选择Rakefile选项,将__FILE == $0选项作为第二选择。