class Bundler::CompactIndexClient::CacheFile

以一种对并发修改具有鲁棒性的方式写入缓存文件,如果提供了摘要,则将验证校验和

常量

DEFAULT_FILE_MODE

属性

original_path[R]
path[R]

公共类方法

copy(path) { |file| ... } 点击切换源代码

使用原始文件的副本初始化,然后 yield 实例。

# File bundler/compact_index_client/cache_file.rb, line 24
def self.copy(path, &block)
  new(path) do |file|
    file.initialize_digests

    SharedHelpers.filesystem_access(path, :read) do
      path.open("rb") do |s|
        file.open {|f| IO.copy_stream(s, f) }
      end
    end

    yield file
  end
end
new(original_path) { |self| ... } 点击切换源代码
# File bundler/compact_index_client/cache_file.rb, line 49
def initialize(original_path, &block)
  @original_path = original_path
  @perm = original_path.file? ? original_path.stat.mode : DEFAULT_FILE_MODE
  @path = original_path.sub(/$/, ".#{$$}.tmp")
  return unless block_given?
  begin
    yield self
  ensure
    close
  end
end
write(path, data, digests = nil) 点击切换源代码

将数据写入临时文件,然后替换原始文件,如果提供了摘要,则验证摘要。

# File bundler/compact_index_client/cache_file.rb, line 39
def self.write(path, data, digests = nil)
  return unless data
  new(path) do |file|
    file.digests = digests
    file.write(data)
  end
end

公共实例方法

append(data) 点击切换源代码

当没有摘要时,返回 false 并且不追加,因为在没有摘要的情况下追加太容易出错。

# File bundler/compact_index_client/cache_file.rb, line 104
def append(data)
  return false unless digests?
  open("a") {|f| f.write data }
  verify && commit
end
close() 点击切换源代码

删除临时文件,而不替换原始文件。 该文件已永久关闭。

# File bundler/compact_index_client/cache_file.rb, line 141
def close
  return if @closed
  FileUtils.remove_file(path) if @path&.file?
  @closed = true
end
commit() 点击切换源代码

使用临时文件替换原始文件,而不验证摘要。 该文件已永久关闭。

# File bundler/compact_index_client/cache_file.rb, line 131
def commit
  raise ClosedError, "Cannot commit closed file" if @closed
  SharedHelpers.filesystem_access(original_path, :write) do
    FileUtils.mv(path, original_path)
  end
  @closed = true
end
commit!() 点击切换源代码
# File bundler/compact_index_client/cache_file.rb, line 116
def commit!
  verify || raise(DigestMismatchError.new(@base64digests, @expected_digests))
  commit
end
digests=(expected_digests) 点击切换源代码

设置将在最后验证的摘要

# File bundler/compact_index_client/cache_file.rb, line 77
def digests=(expected_digests)
  @expected_digests = expected_digests

  if @expected_digests.nil?
    @digests = nil
  elsif @digests
    @digests = @digests.slice(*@expected_digests.keys)
  else
    initialize_digests(@expected_digests.keys)
  end
end
digests?() 点击切换源代码
# File bundler/compact_index_client/cache_file.rb, line 89
def digests?
  @digests&.any?
end
initialize_digests(keys = nil) 点击切换源代码

使用 CompactIndexClient::SUPPORTED_DIGESTS 初始化摘要,或基于键的子集。

# File bundler/compact_index_client/cache_file.rb, line 66
def initialize_digests(keys = nil)
  @digests = keys ? SUPPORTED_DIGESTS.slice(*keys) : SUPPORTED_DIGESTS.dup
  @digests.transform_values! {|algo_class| SharedHelpers.digest(algo_class).new }
end
open(write_mode = "wb", perm = @perm) { |digests? ? digest_io: f| ... } 点击切换源代码

打开临时文件以进行写入,重用原始权限,并 yield IO 对象。

# File bundler/compact_index_client/cache_file.rb, line 94
def open(write_mode = "wb", perm = @perm, &block)
  raise ClosedError, "Cannot reopen closed file" if @closed
  SharedHelpers.filesystem_access(path, :write) do
    path.open(write_mode, perm) do |f|
      yield digests? ? Gem::Package::DigestIO.new(f, @digests) : f
    end
  end
end
reset_digests() 点击切换源代码

重置摘要,使其不包含任何以前读取的数据

# File bundler/compact_index_client/cache_file.rb, line 72
def reset_digests
  @digests&.each_value(&:reset)
end
size() 点击切换源代码
# File bundler/compact_index_client/cache_file.rb, line 61
def size
  path.size
end
verify() 点击切换源代码

验证摘要,匹配时返回 true,不匹配时返回 false。

# File bundler/compact_index_client/cache_file.rb, line 122
def verify
  return true unless @expected_digests && digests?
  @base64digests = @digests.transform_values!(&:base64digest)
  @digests = nil
  @base64digests.all? {|algo, digest| @expected_digests[algo] == digest }
end
write(data) 点击切换源代码
# File bundler/compact_index_client/cache_file.rb, line 110
def write(data)
  reset_digests
  open {|f| f.write data }
  commit!
end