require 'digest' module RIM # RimInfo is RIM's per module information written to project gits. # The user is not meant to modify these files directly: # Files are protected by a checksum an will become invalid if modified. # # Example: # # 4759302048574720930432049375757593827561 # remote_url: ssh://some/url/to/git/repo # revision_sha1: 8347982374198379842984562095637243593092 # target_revision: trunk # ignores: CMakeLists.txt,*.arxml # checksum: 9584872389474857324485873627894494726222 # # rev_name is a symbolic name for revision # # ignores is a comma separated list of file patterns to be ignored # class RimInfo InfoFileName = ".riminfo" AttrsDef = [ :remote_url, :revision_sha1, :target_revision, :ignores, :checksum, :subdir ] AttrsDef.each do |d| attr_accessor d end @@git_infos = { :committer_date => "%ci" } attr_accessor :infos def self.exists?(dir) File.exist?(info_file(dir)) end def self.from_dir(dir) mi = self.new mi.from_dir(dir) mi end def self.from_s(content) mi = self.new mi.from_s(content) mi end def self.git_infos @@git_infos end def dirty? @dirty end def from_s(content) attrs = {} # normalize line endings # this way riminfo files will be valid even if line endings are changed content = content.gsub("\r\n", "\n") checksum = content[0..39] # exclude \n after checksum content = content[41..-1] if content content.split("\n").each do |l| col = l.index(":") if col name, value = l[0..col-1], l[col+1..-1] if name && value attrs[name.strip.to_sym] = value.strip end end end if attrs[:subdir] == "" attrs[:subdir] = nil end else return true end AttrsDef.each do |a| send("#{a}=".to_sym, attrs[a]) end @@git_infos.each_pair do |key, value| if attrs.has_key?(key) @infos ||= {} @infos[key] = attrs[key] end end @dirty = checksum != calc_sha1(content) end def from_dir(dir) file = RimInfo.info_file(dir) if File.exist?(file) content = nil File.open(file, "rb") do |f| content = f.read end from_s(content) end end def to_dir(dir) file = RimInfo.info_file(dir) content = "\n" content << "RIM Info file. You're welcome to read but don't write it.\n" content << "Instead, use RIM commands to do the things you want to do.\n" content << "BEWARE: Any manual modification will invalidate the file!\n" content << "\n" content << "#{to_s}\n" File.open(file, "wb") do |f| f.write(calc_sha1(content)+"\n") f.write(content) end end def to_s i = @infos || {} max_len = (AttrsDef + i.keys).collect{|a| a.size}.max s = AttrsDef.collect { |a| "#{a.to_s.ljust(max_len)}: #{send(a)}" }.join("\n") if !i.empty? s << "\n\n" i.each_pair { |key, value| s << "#{key.to_s.ljust(max_len)}: #{value.to_s}\n" } end s end private def calc_sha1(content) sha1 = Digest::SHA1.new sha1.update(content) sha1.hexdigest end def self.info_file(dir) dir + "/" + InfoFileName end end end