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