File indexing completed on 2024-04-14 05:02:33

0001 # Debian changelog.
0002 class Changelog
0003   # This is a simplified parser that only reads the first line (latest entry)
0004   # to get version and name of the package. It is used because parsechangelog
0005   # has been observed to be incredibly slow at what it does, while it in fact
0006   # provides more information than we need. So here's the super optimized
0007   # version for us.
0008 
0009   attr_reader :name
0010 
0011   EPOCH      = 0b1
0012   BASE       = 0b10
0013   BASESUFFIX = 0b100
0014   REVISION   = 0b1000
0015   ALL        = 0b1111
0016 
0017   def initialize(pwd = Dir.pwd)
0018     line = File.open("#{pwd}/debian/changelog", &:gets)
0019     # plasma-framework (5.3.0-0ubuntu1) utopic; urgency=medium
0020     match = line.match(/^(.*) \((.*)\) (.+); urgency=(\w+)/)
0021     # Need a  match and 5 elements.
0022     # 0: full match
0023     # 1: source name
0024     # 2: version
0025     # 3: distribution series
0026     # 4: urgency
0027     raise 'E: Cannot read debian/changelog' if match.nil? || match.size != 5
0028     @name = match[1]
0029     @version = match[2]
0030     # Don't even bother with the rest, we don't care right now.
0031 
0032     fill_comps(@version.dup)
0033   end
0034 
0035   def version(flags = ALL)
0036     ret = ''
0037     ret += @comps[:epoch] if flagged?(flags, EPOCH)
0038     ret += @comps[:base] if flagged?(flags, BASE)
0039     ret += @comps[:base_suffix] if flagged?(flags, BASESUFFIX)
0040     ret += @comps[:revision] if flagged?(flags, REVISION)
0041     ret
0042   end
0043 
0044   private
0045 
0046   def flagged?(flags, type)
0047     flags & type > 0
0048   end
0049 
0050   # right parition
0051   # @return [Array] of size 2 with the remainder of str as first and the right
0052   #   sub-string as last.
0053   # @note The sub-string always contains the separator itself as well.
0054   def rpart(str, sep)
0055     first, second, third = str.rpartition(sep)
0056     return [third, ''] if first.empty? && second.empty?
0057     [first, [second, third].join]
0058   end
0059 
0060   def fill_comps(version)
0061     # Split the entire thing.
0062     @comps = {}
0063     # For reasons beyond my apprehension the original behavior is to retain
0064     # the separators in the results, which requires somewhat acrobatic
0065     # partitioning to keep them around for compatibility.
0066     version, @comps[:revision] = rpart(version, '-')
0067     git_seperator = version.include?('~git') ? '~git' : '+git'
0068     version, @comps[:base_suffix] = rpart(version, git_seperator)
0069     @comps[:epoch], _, @comps[:base] = version.rpartition(':')
0070     @comps[:epoch] += ':' unless @comps[:epoch].empty?
0071   end
0072 end