从rake任务中运行foreman

11

我有如下的Rake任务:

namespace :foreman do
  task :dev do
    `foreman start -f Procfile.dev`
  end
end

desc "Run Foreman using Procfile.dev"
task :foreman => 'foreman:dev'

在shell中,forman命令能够正常工作,但是当我运行rake foreman时,出现了以下错误:

/Users/me/.gem/ruby/2.0.0/gems/bundler-1.5.2/lib/bundler/rubygems_integration.rb:240:in `block in replace_gem': foreman is not part of the bundle. Add it to Gemfile. (Gem::LoadError)
    from /Users/me/.gem/ruby/2.0.0/bin/foreman:22:in `<main>'

福尔曼明确表示:

Ruby users should take care not to install foreman in their project's Gemfile

那么我应该如何运行这个任务呢?

4个回答

3
如果必须通过rake来实现,请尝试更改通过反引号的外壳输出,以使用系统范围内foreman二进制文件的硬编码路径。
`/global/path/to/foreman start -f Procfile.dev`

您只需要使用“which”或“locate”或类似的工具来确定在捆绑器上下文之外有效的路径。如果您正在使用rbenv,则可能足够:

$ rbenv which rake
/home/name/.rbenv/versions/1.9.3-p448/bin/rake

我希望这能帮助你前进。

2

不确定是否可行,但您可以显式导出与您的shell关联的环境变量,然后调用foreman。就我所知,我认为这并不推荐,建议使用@dax提出的bash脚本。

步骤

  1. Get the $PATH and other environment variables from your shell

    printenv >> shell.env
    
  2. Get the environment variables from the rails environment

    namespace :foreman_test do
      task :dev do
        `printenv >> rails.env`
      end
    end
    
  3. Compare the two and find out the changed environment variables, and set them up in your rake task in the system call

    namespace :foreman do
      task :dev do
        `export PATH=/original/path:/value && GEM_DIR=/some/folder && foreman start -f Procfile.dev`
      end
    end
    

谢谢您的回答。请问您能否解释一下为什么从rake任务运行它会失败?考虑到该任务不依赖于:environment,为什么它确切地要经过bundle呢? - Undistraction
@Pedr 一个可能的解释是你使用了 --binstubs 初始化了你的 repo,所以当你执行 rake taskname 的时候,实际上是在使用 bin/rake,并且默认选择了你的 GEMFILE。不管怎样,我的解决方案有效吗? - Anshul Goyal
我不使用binstubs。我使用be别名代替。我尝试运行rakebe rakebin/rake。所有的结果都导致了我上面描述的相同错误。我现在无法进行测试,但我会尽快尝试。 - Undistraction
@Pedr 如果你将其作为 be rake 运行,那么已经调用了bundler,这意味着项目的Gemfile会被引用。由于你提到使用 bin/rake,我认为可以安全地假设 rake 也将引用 bin/rake。因此,在任何情况下,你的Gemfile都将被引用。由于系统调用会启动一个新的子进程,在子进程中导出变量/重置它们是安全的。 - Anshul Goyal

1
如果必须使用rake任务,请尝试以下方法(来自this answer):
namespace :foreman do
  task :dev do
    sh "foreman start -f Procfile.dev"
  end
end

如果不一定需要使用 rake 任务,我有一个简单的 bash 脚本可以为特定项目启动,并且效果很好:
#!/bin/bash

export PROJECT_DIR=`pwd`
export PORT=$1

source "$HOME/.rvm/scripts/rvm"

unset BUNDLE_GEMFILE
unset BUNDLE_BIN_PATH
unset RUBYOPT
unset GEM_HOME
unset GEM_PATH

(cd <project full path> && exec foreman start -p $PORT)

谢谢,我想我更喜欢把所有东西都放在任务中(已经有很多了)。不幸的是,在任务中使用 shsystem 会给我带来相同的错误。 - Undistraction
也许那个警告是不要在项目的Gemfile中安装 - 你是否已经安装或尝试在全局的Gemfile中安装它? - dax
它肯定对系统可用。我可以运行 foreman start -f Procfile.dev 而不需要 bundle exec,它可以正常运行。 - Undistraction

0
一段时间过去了,这是我使用chruby的方法:
namespace :foreman do
  task :dev do
    # 1. Load .bash_profile to ensure chruby is available
    # 2. Switch the ruby version to the one defined in .ruby-version
    # 3. Start foreman
    system %(
      source ~/.bash_profile
      chruby "$(cat .ruby-version)"
      foreman start --procfile Procfile.dev
    )
  end
end

desc "Run Foreman using Procfile.dev"
task :foreman => 'foreman:dev'

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