lib/pkg-wizard/rpm.rb in pkg-wizard-0.1.27 vs lib/pkg-wizard/rpm.rb in pkg-wizard-0.1.28

- old
+ new

@@ -1,27 +1,179 @@ require 'fileutils' +require 'pkg-wizard/streaming_downloader' +require 'uri' module PKGWizard class NoSpecFound < Exception; end class RPMBuildError < Exception; end class RPM + + def initialize(pkg) + @pkg = pkg.strip.chomp + raise ArgumentError.new("Invalid package.") if pkg !~ /.*\.rpm$/ + raise ArgumentError.new("Invalid package.") if not File.exist?(pkg) + end + + def source_package_name + info = `rpm -qi -qp #{@pkg} 2>/dev/null`.lines + info.find do |s| + s =~ /^Source RPM\s*:(.*)$/ + end + $1.strip.chomp + end + end class SpecFile - attr_accessor :name, :release, :version + attr_accessor :spec def self.parse(file) - f = File.read(file) + f = '' + if File.exist?(file) + f = File.read(file) + else + f = file + end spec = SpecFile.new - spec.name = f.match(/Name:(.*?)$/)[1].strip.chomp - spec.version = f.match(/Version:(.*?)$/)[1].strip.chomp - spec.release = f.match(/Release:(.*?)$/)[1].strip.chomp.gsub(/%\{\?.*\}/, '') + spec.spec = f spec end + def files + buf = [] + in_files = false + @spec.each_line do |l| + if l =~ /^\s*%files/ + in_files = true + next + end + if l =~ /^\s*%(changelog|pre|pro|prep|preun|postun|post|install|clean|build|define)/ and in_files + break + end + if in_files + buf << l.strip.chomp if not l.strip.chomp.empty? + end + end + buf + end + + def release + @spec.match(/Release:(.*?)$/i)[1].strip.chomp.gsub(/%\{\?.*\}/, '') rescue nil + end + + def name + @spec.match(/Name:(.*?)$/i)[1].strip.chomp rescue nil + end + + def version + @spec.match(/Version:(.*?)$/i)[1].strip.chomp rescue nil + end + + def sources + s = [] + @spec.each_line do |line| + if line =~ /^\s*Source\d*:(.*)$/i + s << $1.strip.chomp + end + end + s + end + + def build_requires + build_requires = [] + @spec.each_line do |l| + if l =~ /^\s*buildrequires:(.*)$/i + build_requires = $1.split + build_requires.reject! { |i| i !~ /^[a-zA-Z0-9]/ } + end + end + build_requires + end + + def requires + requires = [] + @spec.each_line do |l| + if l =~ /^\s*requires:(.*)$/i + requires = $1.split + requires.reject! { |i| i !~ /^[a-zA-Z0-9]/ } + end + end + requires + end + + def changelog + buf = "" + in_changelog = false + @spec.each_line do |l| + if l =~ /%changelog/ + in_changelog = true + next + end + if in_changelog + buf += l + end + end + return buf + end + + def changelog_entries + entries = [] + cursor = -1 + changelog.each_line do |l| + if l =~ /^\*/ + cursor += 1 + entries[cursor] = l + else + entries[cursor] += l if not l.strip.chomp.empty? + end + end + entries + end + + def download_source_files(defines = [], dest_dir = '.') + define = '' + if defines.is_a? Array and defines.size >= 1 + define = defines[0] + elsif defines.is_a? String + define = defines + else + define = nil + end + if define + if define !~ /\w\s+\w/ + raise ArgumentError.new "Invalid --define syntax. Use 'macro_name macro_value'" + else + new_sources = [] + def_tokens = define.split + sources.each do |s| + new_sources << s.gsub(/%\{\??#{def_tokens[0]}\}/, def_tokens[1]) + end + end + else + new_sources = sources + end + new_sources.each do |s| + next if s !~ /http:\/\// + yield s if block_given? + download_from_url s, dest_dir + end + end + def pkgname "#{name}-#{version}-#{release}" + end + + private + def download_from_url(url, tmpdir = '.') + uri = URI.parse(url) + remote_pkg = uri.path.split('/').last + d = StreamingDownloader.new + f = "#{tmpdir}/#{remote_pkg}" + tmpfile = File.new(f, 'w') + d.download!(url, tmpfile) + tmpfile.close + f end end class SRPM