File indexing completed on 2024-04-14 15:22:19

0001 # frozen_string_literal: true
0002 #
0003 # Copyright (C) 2015-2016 Harald Sitter <sitter@kde.org>
0004 #
0005 # This library is free software; you can redistribute it and/or
0006 # modify it under the terms of the GNU Lesser General Public
0007 # License as published by the Free Software Foundation; either
0008 # version 2.1 of the License, or (at your option) version 3, or any
0009 # later version accepted by the membership of KDE e.V. (or its
0010 # successor approved by the membership of KDE e.V.), which shall
0011 # act as a proxy defined in Section 6 of version 3 of the license.
0012 #
0013 # This library is distributed in the hope that it will be useful,
0014 # but WITHOUT ANY WARRANTY; without even the implied warranty of
0015 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016 # Lesser General Public License for more details.
0017 #
0018 # You should have received a copy of the GNU Lesser General Public
0019 # License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0020 
0021 module Debian
0022   # A debian policy version handling class.
0023   class Version
0024     attr_accessor :epoch
0025     attr_accessor :upstream
0026     attr_accessor :revision
0027 
0028     def initialize(string)
0029       @epoch = nil
0030       @upstream = nil
0031       @revision = nil
0032       parse(string)
0033     end
0034 
0035     def full
0036       comps = []
0037       comps << "#{epoch}:" if epoch
0038       comps << upstream
0039       comps << "-#{revision}" if revision
0040       comps.join
0041     end
0042 
0043     def to_s
0044       full
0045     end
0046 
0047     # We could easily reimplement version comparision from Version.pm, but
0048     # it's mighty ugh because of string components, so in order to not run into
0049     # problems down the line, let's just consult with dpkg for now.
0050     def <=>(other)
0051       return 0 if full == other.full
0052       return 1 if compare_version(full, 'gt', other.full)
0053       return -1 if compare_version(full, 'lt', other.full)
0054       # A version can be stringwise different but have the same weight.
0055       # Make sure we cover that.
0056       return 0 if compare_version(full, 'eq', other.full)
0057     end
0058 
0059     private
0060 
0061     def compare_version(ours, op, theirs)
0062       run('--compare-versions', ours, op, theirs)
0063     end
0064 
0065     def run(*args)
0066       system('dpkg', *args)
0067     end
0068 
0069     def parse(string)
0070       regex = /^(?:(?<epoch>\d+):)?
0071                 (?<upstream>[A-Za-z0-9.+:~-]+?)
0072                 (?:-(?<revision>[A-Za-z0-9.~+]+))?$/x
0073       match = string.match(regex)
0074       @epoch = match[:epoch]
0075       @upstream = match[:upstream]
0076       @revision = match[:revision]
0077     end
0078   end
0079 end