lib/omnibus/fetcher.rb in omnibus-3.2.2 vs lib/omnibus/fetcher.rb in omnibus-4.0.0.beta.1
- old
+ new
@@ -12,176 +12,135 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
-require 'pp'
-
module Omnibus
- # Base class for classes that fetch project sources from the internet.
- #
- # @abstract Subclass and override the {#clean}, {#description},
- # {#fetch}, {#fetch_required?}, and {#version_guid} methods
- #
- # @todo Is this class supposed to be abstract or not? Pretty sure
- # it's supposed to be abstract
class Fetcher
- # Given an error and a fetcher that generated the error, print a
- # formatted report of the error and stacktrace, along with fetcher
- # details to stderr.
+ include Digestable
+ include Logging
+ include Util
+
#
- # @note Does not rethrow the error; that must currently be done manually.
+ # The software for this fetcher.
#
- # @todo Since this is always called from within a fetcher, and
- # since the fetcher always passes itself in in the {#initialize}
- # method, this really ought to be encapsulated in a method call on
- # {Omnibus::Fetcher}.
- # @todo Also, since we always 'raise' after calling {#explain}, we
- # should just go ahead and exit from here. No need to raise,
- # since we're already outputting the real error and stacktrace
- # here.
- class ErrorReporter
- def initialize(error, fetcher)
- @error, @fetcher = error, fetcher
- end
-
- # @todo Why not just make an attribute for error?
- #
- # @todo And for that matter, why not make an attribute for the
- # fetcher as well? Or why not just use `@error` like we use
- # `@fetcher`?
- def e
- @error
- end
-
- # @todo If {Omnibus::Fetcher#description} is meant to show
- # parameters (presumably the kind of fetcher and the software it
- # is fetching?),
- # @todo make this use the logger
- def explain(why)
- $stderr.puts '* ' * 40
- $stderr.puts why
- $stderr.puts 'Fetcher params:'
- $stderr.puts indent(@fetcher.description, 2)
- $stderr.puts 'Exception:'
- $stderr.puts indent("#{e.class}: #{e.message.strip}", 2)
- Array(e.backtrace).each { |l| $stderr.puts indent(l, 4) }
- $stderr.puts '* ' * 40
- end
-
- private
-
- # Indent each line of a string with `n` spaces.
- #
- # Splits the string at `\n` characters and then pads the left
- # side with `n` spaces. Rejoins them all again with `\n`.
- #
- # @param string [String] the string to indent
- # @param n [Fixnum] the number of " " characters to indent each line.
- # @return [String]
- def indent(string, n)
- string.split("\n").map { |l| ' '.rjust(n) << l }.join("\n")
- end
- end
-
- class UnsupportedSourceLocation < ArgumentError
- end
-
- NULL_ARG = Object.new
-
- # Returns an implementation of {Fetcher} that can retrieve the
- # given software.
+ # @return [Software]
#
- # @param software [Omnibus::Software] the software the Fetcher should fetch
- # @return [Omnibus::Fetcher]
- def self.for(software)
- if software.source
- if software.source[:url] && Config.use_s3_caching
- S3CacheFetcher.new(software)
- else
- without_caching_for(software)
- end
- else
- Fetcher.new(software)
- end
- end
+ attr_reader :software
- # @param software [Omnibus::Software] the software to fetch
- # @raise [UnsupportedSourceLocation] if the software's source is not
- # one of `:url`, `:git`, or `:path`
- # @see Omnibus::Software#source
- # @todo Define an enumeration of the acceptable software types
- # @todo This probably ought to be folded into {#for} method above.
- # It looks like this is called explicitly in
- # {Omnibus::S3Cache#fetch}, but that could be handled by having a
- # second optional parameter that always disables caching.
- # @todo Since the software determines what fetcher must be used to
- # fetch it, perhaps this should be a method on {Omnibus::Software}
- # instead.
- def self.without_caching_for(software)
- if software.source[:url]
- NetFetcher.new(software)
- elsif software.source[:git]
- GitFetcher.new(software)
- elsif software.source[:path]
- PathFetcher.new(software)
- else
- raise UnsupportedSourceLocation, "Don't know how to fetch software project #{software}"
- end
- end
-
- include Logging
- include Util
-
- attr_reader :name
-
- # @todo What is this? It doesn't appear to be used anywhere
- attr_reader :source_timefile
-
+ #
+ # Create a new Fetcher object from the given software.
+ #
+ # @param [Software] software
+ # the software to create this fetcher
+ #
def initialize(software)
@software = software
end
- # @!group Methods for Subclasses to Implement
+ #
+ # @!group Abstract methods
+ #
+ # The following methods are all abstract and should be overriden in child
+ # classes.
+ # --------------------------------------------------
- # @todo All extenders of this class override this method. Since
- # this class appears to be intended as an abstract one, this
- # should raise a NotImplementedError
- def description
- # Not as pretty as we'd like, but it's a sane default:
- inspect
- end
-
- # @todo All extenders of this class override this method. Since
- # this class appears to be intended as an abstract one, this
- # should raise a NotImplementedError
+ #
+ # @abstract
+ #
def fetch_required?
- false
+ raise NotImplementedError
end
- # @todo Empty method is very suspicious; raise NotImplementedError instead.
+ #
+ # @abstract
+ #
def clean
+ raise NotImplementedError
end
- # @todo Empty method is very suspicious; raise NotImplementedError instead.
+ #
+ # @abstract
+ #
def fetch
+ raise NotImplementedError
end
- # @todo Empty method is very suspicious; raise NotImplementedError instead.
+ #
+ # @abstract
+ #
def version_guid
+ raise NotImplementedError
end
- # Returns the version to be used during build caching.
- # By default fetchers don't override the versions.
+ #
+ # @abstract
+ #
def version_for_cache
- nil
+ raise NotImplementedError
end
+ #
+ # @!endgroup
+ # --------------------------------------------------
+
private
+ #
+ # The "source" for this software, with applied overrides.
+ #
+ # @return [Hash]
+ #
+ def source
+ software.source
+ end
+
+ #
+ # The path where extracted software should live.
+ #
+ # @see Software#project_dir
+ #
+ # @return [String]
+ #
+ def project_dir
+ software.project_dir
+ end
+
+ #
+ # The version for this sfotware, with applied overrides.
+ #
+ # @return [String]
+ #
+ def version
+ software.version
+ end
+
+ #
+ # Override the +log_key+ for this fetcher to include the name of the
+ # software during the fetch.
+ #
+ # @return [String]
+ #
def log_key
- @log_key ||= "#{super}: #{@software.name}"
+ @log_key ||= "#{super}: #{software.name}"
end
- # !@endgroup
+
+ #
+ # Idempotently create the required directories for building/downloading.
+ # Fetchers should call this method before performing any operations that
+ # manipulate the filesystem.
+ #
+ # @return [void]
+ #
+ def create_required_directories
+ [
+ Config.cache_dir,
+ Config.source_dir,
+ software.build_dir,
+ software.project_dir,
+ ].each do |directory|
+ FileUtils.mkdir_p(directory) unless File.directory?(directory)
+ end
+ end
end
end