如果已使用CRLF行结尾检出模板文件,请让Vagrant + Chef运行保释

时间:2015-07-23 18:29:32

标签: ruby vagrant chef line-endings

当Windows开发人员从我的Git仓库with Git's autocrlf set to true查看食谱时,我会不断发现烦人的问题。当他们运行vagrant up以启动Linux VM时,将菜谱文件映射到具有CRLF行结尾的VM,这会导致在shell和其他POSIX实用程序尝试时出现模糊错误操作已复制到VM中的(现在无效的)模板文件。

对此的修复非常简单:将autocrlf设置更改为inputfalse后重新克隆存储库。

我的问题是,当你有错误的行结尾时,唯一的症状是在奇怪的地方出现错误,这些错误绝不会导致行结尾出现问题。

我怎样才能让厨师†检查菜谱模板文件中的错误行结尾,如果发现错误,则会抛出错误?我认为这是一个简单的Ruby片段,可以对其进行断言我可以放在配方顶部的给定文件中的行结尾可以正常工作。

注意:在我的repo的特定情况下,步骤顺序为:

  1. 开发人员检出仓库
  2. 开发人员运行vagrant up
  3. Vagrant开始在VM中运行一名厨师
  4. 最后,repo的构建脚本在VM中运行
  5. †或者其他任何包含在回购中的内容

2 个答案:

答案 0 :(得分:2)

Rubocop可用于强制执行unix style line endingsmany other things之内)。

例如(从命令行,来宾中的):

gem install rubocop
rubocop --only Style/EndOfLine  # only check line endings

或者可以在厨师本身的背景下完成,例如以下食谱:

chef_gem 'rubocop'

ruby_block 'check line endings' do
  block do
    # It's probably better to call rubo cop code directly, rather than
    # shelling out, but that can be an exercise for the reader ;-)
    rubocop_cmd = Mixlib::ShellOut.new(
      'rubocop --only Style/EndOfLine',
      :cwd => 'dir_to_check'
    )
    rubocop_cmd.run_command

    # Raise an exception if it didn't exit with 0.
    rubocop_cmd.error!
  end
end

未被捕获的例外将导致厨师逃跑。

答案 1 :(得分:0)

这是一个Ruby片段,您可以将其放入任何Chef配方中:

def cookbook_supporting_files(*cookbooks)
  cookbooks = cookbooks.map {|name| run_context.cookbook_collection[name]}

  cookbooks.flat_map do |cb|
    (cb.manifest[:files] + cb.manifest[:templates]) \
      .map {|f| ::File.join(cb.root_dir, f['path']) }
  end
end

def dos_eol?(f)
  ::File.open(f, 'rb').read(4096).include? "\r\n"
end

cookbook_supporting_files(cookbook_name).each do |f|
  if dos_eol? f
    raise "Cookbook template '#{f}' contains CRLF line endings"
  end
end

这将检查上面代码片段中存在的任何食谱中存在的cookbook文件和模板的行结尾。

如果您想要使用相同的代码段检查其他食谱,只需替换:

cookbook_supporting_files(cookbook_name)

使用您要检查的食谱清单:

cookbook_supporting_files('some_cookbook', 'another_cookbook')