# Copyright (C) 2011 Cornelius Schumacher # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. class RpmManifestizer attr_accessor :dry_run def initialize settings @settings = settings @cut_off_exceptions = [ "qt4-x11" ] @source_rpms = Hash.new end def create_manifest name, rpm_name qf = 'version:%{VERSION}\n' qf += 'summary:%{SUMMARY}\n' qf += 'homepage:%{URL}\n' qf += 'license:%{LICENSE}\n' qf += 'sourcerpm:%{SOURCERPM}\n' header = `rpm -q --queryformat '#{qf}' #{rpm_name}` header_strings = header.split "\n" headers = Hash.new header_strings.each do |header_string| header_string =~ /^(.*?):(.*)$/ headers[$1] = $2 end source_rpm = headers["sourcerpm"] @source_rpms[source_rpm] = Array.new raw = `rpm -q --queryformat '%{DESCRIPTION}' #{rpm_name}` parse_authors = false description = "" authors = Array.new raw.each_line do |line3| if line3 =~ /^Authors:/ parse_authors = true next end if parse_authors if line3 =~ /^---/ next end authors.push "\"#{line3.strip}\"" else description += line3.chomp + "\\n" end end description.gsub! /"/, "\\\"" description.strip! release_date = Date.parse "1970-01-01" licenses = Array.new headers["license"].split(";").each do |l| licenses.push "\"#{l.strip}\"" end licenses_string = licenses.join "," manifest_path = "#{@settings.manifest_path}/#{name}" if !File.exists? manifest_path Dir.mkdir manifest_path end filename = "#{manifest_path}/#{name}.#{release_date}.manifest" File.open( filename, "w") do |f2| f2.puts '{'; f2.puts ' "schema_version": 1,' f2.puts " \"name\": \"#{name}\"," f2.puts " \"release_date\": \"#{release_date}\"," [ "version", "summary", "homepage" ].each do |key| f2.puts " \"#{key}\": \"#{headers[key]}\"," end f2.puts " \"licenses\": [#{licenses_string}]," f2.puts " \"description\": \"#{description}\"," f2.puts ' "authors": [' + authors.join(",") + '],' f2.puts ' "maturity": "stable",' f2.puts ' "packages": {' f2.puts ' "openSUSE": {' f2.puts ' "11.4": {' f2.puts " \"package_name\": \"#{rpm_name}\"," f2.puts ' "repository": {' f2.puts ' "url": "http://download.opensuse.org/distribution/11.4/repo/oss/",' f2.puts ' "name": "openSUSE-11.4-Oss"' f2.puts ' },' f2.puts " \"source_rpm\": \"#{source_rpm}\"" f2.puts ' }' f2.puts ' }' f2.puts ' }' f2.puts '}' end end def requires_qt? rpm_name IO.popen "rpm -q --requires #{rpm_name}" do |f2| while line2 = f2.gets do if line2 =~ /Qt/ return true end end end false end def is_library? rpm_name rpm_name =~ /^lib/ end def is_32bit? rpm_name rpm_name =~ /\-32bit/ end def cut_off_number_suffix name if @cut_off_exceptions.include? name return name end i = name.length - 1 while i > 0 if name[i].chr !~ /[\-_0-9]/ break end i -= 1 end if i > 0 return name[0..i] end name end def process_all_rpms if !File.exist? @settings.cache_dir + "/qt_source.json" create_qt_source_cache end qt_sources = Hash.new File.open @settings.cache_dir + "/qt_source.json" do |file| qt_sources = JSON file.read end qt_sources.each do |source,sections| sections["all"].each do |rpm| if rpm =~ /(.*)-devel$/ name = $1 if name =~ /^lib(.*)/ name = $1 end lib_rpm = "" sections["lib"].each do |lib| if lib !~ /\-devel$/ lib_rpm = lib break end end if lib_rpm.empty? lib_rpm = rpm end puts "Identified manifest: #{name} (Library RPM: #{lib_rpm})" if !dry_run create_manifest name, lib_rpm end end end end if !dry_run patch = @settings.data_path + "/manifest.patch" cmd = "cd #{@settings.manifest_path}; patch -p1 <#{patch}"; puts "Patching manifests with #{patch}" system cmd end end def read_source_cache if !File.exist? @settings.cache_dir + "/source.json" create_source_cache end sources = Hash.new File.open @settings.cache_dir + "/source.json" do |file| sources = JSON file.read end sources end def create_source_cache puts "Creating cache of RPM meta data" Upstream.get_involved "Create more friendly progress display for cache creation", 3 sources = Hash.new IO.popen "rpmqpack" do |f| while line = f.gets do rpm_name = line.chomp puts "SCAN #{rpm_name}" source_rpm = `rpm -q --queryformat '%{SOURCERPM}' #{rpm_name}` sources[rpm_name] = source_rpm end end File.open @settings.cache_dir + "/source.json", "w" do |f| f.puts sources.to_json end end def create_qt_source_cache puts "Creating cache of Qt library RPMs" sources = read_source_cache rpms = Hash.new sources.each do |rpm,source| if rpms.has_key? source rpms[source] = rpms[source].push rpm else rpms[source] = Array.new.push rpm end end qt_sources = Hash.new sources.each do |rpm,source| next unless requires_qt? rpm next unless is_library? rpm next if is_32bit? rpm if !qt_sources.has_key? source sections = Hash.new sections[:all] = Array.new sections[:lib] = Array.new qt_sources[source] = sections end qt_sources[source][:all] = rpms[source] qt_sources[source][:lib] = qt_sources[source][:lib].push rpm puts "Found RPM #{rpm} (#{source})" end File.open @settings.cache_dir + "/qt_source.json", "w" do |f| f.puts JSON.pretty_generate qt_sources end end end