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

0001 require_relative '../kci'
0002 
0003 module Debian
0004   # Mangle dsc to not do ARM builds unless explicitly enabled.
0005   # With hundreds of distinct sources on CI, building all of them on three
0006   # architectures, of which one is not too commonly used, is extremly excessive.
0007   # Instead, by default we only build on the common architectures with extra
0008   # architectures needing to be enabled explicitly.
0009   # To achieve this mangle the Architecture field in the control file.
0010   # If it contains an uncommon arch -> remove it -> if it is empty now, abort
0011   # If it contains any -> replace with !uncommon
0012   # This is a cheapster hack implementation to avoid having to implement write
0013   # support in Debian::Control|DSC.
0014   class DSCArch
0015     class Error < Exception; end
0016     class EmptyError < Error; end
0017     class CountError < Error; end
0018     class MultilineError < Error; end
0019 
0020     def self.enabled_architectures
0021       enabled_architectures = KCI.architectures.dup
0022       extras = KCI.extra_architectures
0023       env_extras = ENV.fetch('ENABLED_EXTRA_ARCHITECTURES') { nil }
0024       extras.each do |extra|
0025         next unless env_extras && !env_extras.empty?
0026         next unless env_extras.split(' ').include?(extra)
0027         enabled_architectures << extra
0028       end
0029       enabled_architectures
0030     end
0031 
0032     # Twiddles the Architecture field of a DSC file to only list enabled arches.
0033     def self.twiddle!(directory_with_dsc)
0034       dsc = nil
0035       Dir.chdir(directory_with_dsc) do
0036         dsc = Dir.glob('*.dsc')
0037         unless dsc.size == 1
0038           raise CountError, "Not exactly one dsc WTF -> #{dsc}"
0039         end
0040         dsc = File.expand_path(dsc[0])
0041       end
0042 
0043       enabled_arches = enabled_architectures
0044 
0045       saw_architecture = false
0046       line_after = false
0047       lines = File.read(dsc).lines
0048       lines.collect! do |line|
0049         if line_after && line.start_with?(' ')
0050           raise MultilineError, 'Line after Architecture starts with space.'
0051         end
0052         line_after = false
0053 
0054         match = line.match(/^Architecture: (.*)$/)
0055         next line unless match
0056         arches = match[1].split(' ')
0057         arches.collect! do |arch|
0058           next enabled_arches if arch == 'any' || arch == 'linux-any'
0059           next arch if arch == 'all'
0060           next nil unless enabled_arches.include?(arch)
0061           arch
0062         end
0063         arches.flatten!
0064         arches.compact!
0065         arches.uniq!
0066         raise EmptyError, "Ripped all arches out of '#{line}'" if arches.empty?
0067         saw_architecture = true
0068         line_after = true
0069         "Architecture: #{arches.join(' ')}\n"
0070       end
0071       File.write(dsc, lines.join)
0072       return if saw_architecture
0073       raise EmptyError, 'There apparently was no Architecture field!'
0074     end
0075   end
0076 end