Skip to content
This repository has been archived by the owner on Jun 23, 2020. It is now read-only.

Commit

Permalink
Split rpm spec class into submodules / mixins
Browse files Browse the repository at this point in the history
Specs still are functional though should be split along new
module lines
  • Loading branch information
movitto committed Jun 23, 2014
1 parent 3429644 commit 45bb1c3
Show file tree
Hide file tree
Showing 7 changed files with 620 additions and 513 deletions.
67 changes: 67 additions & 0 deletions lib/polisher/rpm/compares_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# RPM Spec Comparison Module
#
# Licensed under the MIT license
# Copyright (C) 2013-2014 Red Hat, Inc.

require 'polisher/gem'
require 'polisher/logger'

module Polisher
module RPM
module ComparesSpec
# Compare this spec to a sepecified upstream gem source
# and return result.
#
# upstream_source should be an instance of Polisher::Gem,
# Polisher::Gemfile, or other class defining a 'deps'
# accessor that returns an array of Gem::Requirement dependencies
#
# Result will be a hash containing the shared dependencies as
# well as those that differ and their respective differences
def compare(upstream_source)
same = {}
diff = {}
upstream_source.deps.each do |d|
spec_reqs = self.requirements_for_gem(d.name)
spec_reqs_specifier = spec_reqs.empty? ? nil :
spec_reqs.collect { |req| req.specifier }

if spec_reqs.nil?
diff[d.name] = {:spec => nil,
:upstream => d.requirement.to_s}

elsif !spec_reqs.any? { |req| req.matches?(d) } ||
!self.has_all_requirements_for?(d)
diff[d.name] = {:spec => spec_reqs_specifier,
:upstream => d.requirement.to_s}

elsif !diff.has_key?(d.name)
same[d.name] = {:spec => spec_reqs_specifier,
:upstream => d.requirement.to_s }
end
end

@metadata[:requires].each do |req|
next unless req.gem?

upstream_dep = upstream_source.deps.find { |d| d.name == req.gem_name }

if upstream_dep.nil?
diff[req.gem_name] = {:spec => req.specifier,
:upstream => nil}

elsif !req.matches?(upstream_dep)
diff[req.gem_name] = {:spec => req.specifier,
:upstream => upstream_dep.requirement.to_s }

elsif !diff.has_key?(req.gem_name)
same[req.gem_name] = {:spec => req.specifier,
:upstream => upstream_dep.requirement.to_s }
end
end unless @metadata[:requires].nil?

{:same => same, :diff => diff}
end
end # module ComparesSpec
end # module RPM
end # module Polisher
71 changes: 71 additions & 0 deletions lib/polisher/rpm/has_files.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# RPM Has Gem Module
#
# Licensed under the MIT license
# Copyright (C) 2013-2014 Red Hat, Inc.

require 'polisher/gem'
require 'polisher/logger'

module Polisher
module RPM
module HasFiles
# Return list of all files in the spec
def files
pkg_files.values.flatten
end

def self.included(base)
base.extend(ClassMethods)
end

module ClassMethods
# Helper to return bool indicating if specified gem file is satisfied
# by specified spec file.
#
# Spec file satisfies gem file if they are the same or the spec file
# corresponds to the the directory in which the gem file resides.
def file_satisfies?(spec_file, gem_file)
# If spec file for which gemfile.gsub(/^specfile/)
# is different than the gemfile the spec contains the gemfile
#
# TODO: need to incorporate regex matching into this
gem_file.gsub(/^#{spec_file.unrpmize}/, '') != gem_file
end
end # module ClassMethods

# Return bool indicating if spec is missing specified gemfile.
def missing_gem_file?(gem_file)
files.none? { |spec_file| self.class.file_satisfies?(spec_file, gem_file) }
end

# Return list of gem files for which we have no corresponding spec files
def missing_files_for(gem)
# we check for files in the gem for which there are no spec files
# corresponding to gem file or directory which it resides in
gem.file_paths.select { |gem_file| missing_gem_file?(gem_file) }
end

# Return list of files in upstream gem which have not been included
def excluded_files
# TODO: also append files marked as %{exclude} (or handle elsewhere?)
missing_files_for(upstream_gem)
end

# Return boolean indicating if the specified file is on excluded list
def excludes_file?(file)
excluded_files.include?(file)
end

# Return extra package file _not_ in the specified gem
def extra_gem_files(gem = nil)
gem ||= upstream_gem
pkg_extra = {}
pkg_files.each do |pkg, files|
extra = files.select { |spec_file| !gem.has_file_satisfied_by?(spec_file) }
pkg_extra[pkg] = extra unless extra.empty?
end
pkg_extra
end
end # module HasFiles
end # module RPM
end # module Polisher
58 changes: 58 additions & 0 deletions lib/polisher/rpm/has_gem.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# RPM Has Gem Module
#
# Licensed under the MIT license
# Copyright (C) 2013-2014 Red Hat, Inc.

require 'polisher/gem'
require 'polisher/logger'

module Polisher
module RPM
module HasGem
# Return gem corresponding to spec name/version
def upstream_gem
@gem, @update_gem = nil, false if @update_gem
@gem ||= Polisher::Gem.from_rubygems gem_name, version
end

# Return list of gem dependencies for which we have no
# corresponding requirements
def missing_deps_for(gem)
# Comparison by name here assuming if it is in existing spec,
# spec author will have ensured versions are correct for their purposes
gem.deps.select { |dep| requirements_for_gem(dep.name).empty? }
end

# Return list of gem dev dependencies for which we have
# no corresponding requirements
def missing_dev_deps_for(gem)
# Same note as in #missing_deps_for above
gem.dev_deps.select { |dep| build_requirements_for_gem(dep.name).empty? }
end

# Return list of dependencies of upstream gem which
# have not been included
def excluded_deps
missing_deps_for(upstream_gem)
end

# Return boolean indicating if the specified gem is on excluded list
def excludes_dep?(gem_name)
excluded_deps.any? { |d| d.name == gem_name }
end

# Return list of dev dependencies of upstream gem which
# have not been included
def excluded_dev_deps
missing_dev_deps_for(upstream_gem)
end

# Return boolean indicating if the specified gem is on
# excluded dev dep list
def excludes_dev_dep?(gem_name)
excluded_dev_deps.any? { |d| d.name == gem_name }
end

end # module HasGem
end # module RPM
end # module Polisher
87 changes: 87 additions & 0 deletions lib/polisher/rpm/has_requirements.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# RPM Has Requirements Module
#
# Licensed under the MIT license
# Copyright (C) 2013-2014 Red Hat, Inc.

require 'polisher/gem'
require 'polisher/logger'

module Polisher
module RPM
module HasRequirements
# Return all the Requires for the specified gem
def requirements_for_gem(gem_name)
@metadata[:requires].nil? ? [] :
@metadata[:requires].select { |r| r.gem_name == gem_name }
end

# Return all the BuildRequires for the specified gem
def build_requirements_for_gem(gem_name)
@metadata[:build_requires].nil? ? [] :
@metadata[:build_requires].select { |r| r.gem_name == gem_name }
end

# Return bool indicating if this spec specifies all the
# requirements in the specified gem dependency
#
# @param [Gem::Dependency] gem_dep dependency which to retreive / compare
# requirements
def has_all_requirements_for?(gem_dep)
reqs = self.requirements_for_gem gem_dep.name
# create a spec requirement dependency for each expanded subrequirement,
# verify we can find a match for that
gem_dep.requirement.to_s.split(',').all? { |greq|
Gem2Rpm::Helpers.expand_requirement([greq.split]).all? { |ereq|
tereq = Requirement.new :name => "#{requirement_prefix}(#{gem_dep.name})",
:condition => ereq.first,
:version => ereq.last.to_s
reqs.any? { |req| req.matches?(tereq)}
}
}
end

# Return all gem Requires
def gem_requirements
@metadata[:requires].nil? ? [] :
@metadata[:requires].select { |r| r.gem? }
end

# Return all gem BuildRequires
def gem_build_requirements
@metadata[:build_requires].nil? ? [] :
@metadata[:build_requires].select { |r| r.gem? }
end

# Return all non gem Requires
def non_gem_requirements
@metadata[:requires].nil? ? [] :
@metadata[:requires].select { |r| !r.gem? }
end

# Return all non gem BuildRequires
def non_gem_build_requirements
@metadata[:build_requires].nil? ? [] :
@metadata[:build_requires].select { |r| !r.gem? }
end

def self.included(base)
base.extend(ClassMethods)
end

module ClassMethods
# RPM Spec Requirement Prefix
def requirement_prefix
Requirement.prefix
end

def package_prefix
requirement_prefix
end
end # module ClassMethods

def requirement_prefix
self.class.requirement_prefix
end
end # module HasRequirements
end # module RPM
end # module Polisher
106 changes: 106 additions & 0 deletions lib/polisher/rpm/parses_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# RPM Parses Spec Module
#
# Licensed under the MIT license
# Copyright (C) 2013-2014 Red Hat, Inc.

require 'polisher/gem'
require 'polisher/logger'

module Polisher
module RPM
module ParsesSpec
def self.included(base)
base.extend(ClassMethods)
end

module ClassMethods
# Parse the specified rpm spec and return new RPM::Spec instance from metadata
#
# @param [String] string contents of spec to parse
# @return [Polisher::RPM::Spec] spec instantiated from rpmspec metadata
def parse(spec)
in_subpackage = false
in_changelog = false
in_files = false
subpkg_name = nil
meta = {:contents => spec}
spec.each_line { |l|
if l =~ RPM::Spec::COMMENT_MATCHER
;

# TODO support optional gem prefix
elsif l =~ RPM::Spec::GEM_NAME_MATCHER
meta[:gem_name] = $1.strip
meta[:gem_name] = $1.strip

elsif l =~ RPM::Spec::SPEC_NAME_MATCHER &&
$1.strip != "%{gem_name}"
meta[:gem_name] = $1.strip

elsif l =~ RPM::Spec::SPEC_VERSION_MATCHER
meta[:version] = $1.strip

elsif l =~ RPM::Spec::SPEC_RELEASE_MATCHER
meta[:release] = $1.strip

elsif l =~ RPM::Spec::SPEC_SUBPACKAGE_MATCHER
subpkg_name = $1.strip
in_subpackage = true

elsif l =~ RPM::Spec::SPEC_REQUIRES_MATCHER &&
!in_subpackage
meta[:requires] ||= []
meta[:requires] << RPM::Requirement.parse($1.strip)

elsif l =~ RPM::Spec::SPEC_BUILD_REQUIRES_MATCHER &&
!in_subpackage
meta[:build_requires] ||= []
meta[:build_requires] << RPM::Requirement.parse($1.strip)

elsif l =~ RPM::Spec::SPEC_CHANGELOG_MATCHER
in_changelog = true

elsif l =~ RPM::Spec::SPEC_FILES_MATCHER
subpkg_name = nil
in_files = true

elsif l =~ RPM::Spec::SPEC_SUBPKG_FILES_MATCHER
subpkg_name = $1.strip
in_files = true

elsif l =~ RPM::Spec::SPEC_CHECK_MATCHER
meta[:has_check] = true

elsif in_changelog
meta[:changelog] ||= ""
meta[:changelog] << l

elsif in_files
tgt = subpkg_name.nil? ? meta[:gem_name] : subpkg_name

if l =~ RPM::Spec::SPEC_EXCLUDED_FILE_MATCHER
sl = Regexp.last_match(1)
meta[:pkg_excludes] ||= {}
meta[:pkg_excludes][tgt] ||= []
meta[:pkg_excludes][tgt] << sl unless sl.blank?

else
sl = l.strip
meta[:pkg_files] ||= {}
meta[:pkg_files][tgt] ||= []
meta[:pkg_files][tgt] << sl unless sl.blank?
end
end
}

meta[:changelog_entries] = meta[:changelog] ?
meta[:changelog].split("\n\n") : []
meta[:changelog_entries].collect! { |c| c.strip }.compact!

self.new meta
end

end # module ClassMethods
end # module ParsesSpec
end # module RPM
end # module Polisher

0 comments on commit 45bb1c3

Please sign in to comment.