lib/mixlib/install/backend/base.rb in mixlib-install-1.0.10 vs lib/mixlib/install/backend/base.rb in mixlib-install-1.0.11

- old
+ new

@@ -24,16 +24,89 @@ def initialize(options) @options = options end + # + # Returns the list of artifacts from the configured backend based on the + # configured product_name, product_version and channel. + # + # @abstract Subclasses should define this method. + # + # @return Array<ArtifactInfo> + # List of ArtifactInfo objects for the available artifacts. + def available_artifacts + raise "Must implement available_artifacts method that returns Array<ArtifactInfo>" + end + + # + # See #filter_artifacts def info - raise "Must implement info method that returns ArtifactInfo or Array<ArtifactInfo>" + filter_artifacts(available_artifacts) end - def endpoint - raise "Must implement endpoint method that returns endpoint String" + # + # Returns true if platform filters are available, false otherwise. + # + # Note that we assume #set_platform_info method is used on the Options + # class to set the platform options. + # + # @return TrueClass, FalseClass + def platform_filters_available? + !options.platform.nil? end + + # + # Filters and returns the available artifacts based on the configured + # platform filtering options. + # + # @return ArtifactInfo, Array<ArtifactInfo>, [] + # If the result is a single artifact, this returns ArtifactInfo. + # If the result is a list of artifacts, this returns Array<ArtifactInfo>. + # If no suitable artifact is found, this returns []. + def filter_artifacts(artifacts) + return artifacts unless platform_filters_available? + + # First filter the artifacts based on the platform and architecture + artifacts.select! do |a| + a.platform == options.platform && a.architecture == options.architecture + end + + # Now we are going to filter based on platform_version. + # We will return the artifact with an exact match if available. + # Otherwise we will search for a compatible artifact and return it + # if the compat options is set. + closest_compatible_artifact = nil + + artifacts.each do |a| + return a if a.platform_version == options.platform_version + + # We skip the artifacts produced for windows since their platform + # version is always set to 2008r2 which breaks our `to_f` comparison. + next if a.platform == "windows" + + # Calculate the closest compatible version. + # For an artifact to be compatible it needs to be smaller than the + # platform_version specified in options. + # To find the closest compatible one we keep a max of the compatible + # artifacts. + if closest_compatible_artifact.nil? || + (a.platform_version.to_f > closest_compatible_artifact.platform_version.to_f && + a.platform_version.to_f < options.platform_version.to_f ) + closest_compatible_artifact = a + end + end + + # If the compat flag is set and if we have found a compatible artifact + # we are going to use it. + if options.platform_version_compatibility_mode && closest_compatible_artifact + return closest_compatible_artifact + end + + # Otherwise, we return an empty array indicating we do not have any matching artifacts + return [] + end + end end end end