0

私は最新のものを使用しますか?ファイルを再コンパイル/再リンク/再生成する必要があるかどうかを判断するためのRubyのメソッド。これらのステップで使用するビルドフレームワークが非常に高速であるため、出力ファイルと前提条件ファイルのファイル変更タイムスタンプがまったく同じになる場合があります。 。これにより、ビルドフレームワークがファイルを不必要に再コンパイル/再リンクします。

私はそのように構築するためのタイムスタンプを比較します-

compile_file(file) unless uptodate?(file, %W(#{dependencies}))

ソースを調べて最新のものを探しましたか?ここから、このように見えます-

def uptodate?(new, old_list, options = nil)
  raise ArgumentError, 'uptodate? does not accept any option' if options
  return false unless File.exist?(new)
  new_time = File.mtime(new)
  old_list.each do |old|
    if File.exist?(old)
      return false unless new_time > File.mtime(old)
    end
  end
  true
end

疑われるように、タイムスタンプが等しい場合はfalseを返します。この問題を回避するための最もエレガントな方法は何ですか?LinuxとWindowsでフレームワークを実行しようとしましたが、同じ問題が発生します。私がここで読んだことから、ファイルシステム固有のファイル変更時間の解決の問題である可能性は低いです(ext4の解像度は1マイクロ秒であるため)。

4

2 に答える 2

2

基盤となるファイルシステムがサポートしている場合でも、 RubyのFileオブジェクトはファイル変更タイムスタンプのサブセカンド解決をサポートしていないようです。1つの解決策は、Rubyを使用して結果をシェルアウトしls --full-time、解析することDateTimeです。これは、数分の1秒をサポートします。

module FileUtilsPlus
  def self.uptodate?(new, old_list, options = nil)
    return true if FileUtils.uptodate?(new, old_list, options)
    return false unless File.exist?(new)
    new_time = filemtime(new)
    old_list.each do |old|
      if File.exist?(old)
        return false unless new_time > filemtime(old)
      end
    end
  end

  def self.filemtime(path)
    DateTime.parse(`ls --full-time foo | awk '{ print $6 " " $7 }'`)
  end
end

これはRubyのネイティブファイル操作よりもはるかに遅くなるため、FileUtils::uptodate?falseが返された場合にのみこの魔法を実行することに注意してください。

于 2012-08-17T04:21:10.843 に答える
1

uptodate?正しいようです。タイムスタンプが等しい場合、ファイルは最新である場合とそうでない場合があります。したがって、それは安全側で誤りを犯し、それが古くなっていると宣言します。

ファイルをビルドする手順で、依存関係の時間と等しい場合は、ビルドされたファイルの時間を1秒進めるロジックを追加します。はい、それはハックですが、その状況下でできる最善の方法かもしれません。

一部のファイルシステム(ext4など)は、1秒未満の解像度でタイムスタンプを保存できるため、一見の価値があります。

上記のいずれかを除けば、モンキーパッチを最新のものにすることができますか?または、タイムスタンプが等しい場合にビルドしない側でエラーが発生する独自のファイルを作成します。

于 2012-08-17T04:17:56.033 に答える