From d155619fda2ee300e6da2fb362d389a021d11dbd Mon Sep 17 00:00:00 2001 From: hag Date: Wed, 21 Sep 2016 13:41:49 +0200 Subject: [PATCH] renamed Source::Package to Source::Archive --- CHANGELOG.md | 1 + lib/fpm/fry/recipe.rb | 2 +- lib/fpm/fry/recipe/builder.rb | 2 +- lib/fpm/fry/source.rb | 5 +- lib/fpm/fry/source/{package.rb => archive.rb} | 74 ++++++++++++++++--- lib/fpm/fry/source/git.rb | 2 +- spec/recipe_spec.rb | 2 +- .../{package_spec.rb => archive_spec.rb} | 51 ++++++++----- 8 files changed, 101 insertions(+), 38 deletions(-) rename lib/fpm/fry/source/{package.rb => archive.rb} (67%) rename spec/source/{package_spec.rb => archive_spec.rb} (82%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d2c577..3d64cf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * [ENHANCEMENT] tests can now run against a real docker host, improving test depth * [ENHANCEMENT] removed OsDb. This file contained some hardcoded Os versions which was not future proof. It was a workaround to get started more quickly. * [FIX] patched sources now fail when the underlying patch fails +* [CHANGE] Renamed "Source::Package" to "Source::Archive" which is more striking. The term "package" is also used for build results. # 0.2.2 / 2016.09.05 diff --git a/lib/fpm/fry/recipe.rb b/lib/fpm/fry/recipe.rb index 3cd5d74..6950372 100644 --- a/lib/fpm/fry/recipe.rb +++ b/lib/fpm/fry/recipe.rb @@ -1,5 +1,5 @@ require 'fpm/fry/source' -require 'fpm/fry/source/package' +require 'fpm/fry/source/archive' require 'fpm/fry/source/dir' require 'fpm/fry/source/patched' require 'fpm/fry/source/git' diff --git a/lib/fpm/fry/recipe/builder.rb b/lib/fpm/fry/recipe/builder.rb index 57f5697..9a25ed2 100644 --- a/lib/fpm/fry/recipe/builder.rb +++ b/lib/fpm/fry/recipe/builder.rb @@ -282,7 +282,7 @@ def register_source_type( klass ) def register_default_source_types! register_source_type Source::Git - register_source_type Source::Package + register_source_type Source::Archive register_source_type Source::Dir end diff --git a/lib/fpm/fry/source.rb b/lib/fpm/fry/source.rb index 6a7307b..e5137c4 100644 --- a/lib/fpm/fry/source.rb +++ b/lib/fpm/fry/source.rb @@ -1,8 +1,5 @@ require 'fpm/fry/with_data' -module FPM; module Fry ; - - # h2. Interface - module Source +module FPM; module Fry ; module Source # Raised when building a cache failed. class CacheFailed < StandardError diff --git a/lib/fpm/fry/source/package.rb b/lib/fpm/fry/source/archive.rb similarity index 67% rename from lib/fpm/fry/source/package.rb rename to lib/fpm/fry/source/archive.rb index 0d81ed3..72f9836 100644 --- a/lib/fpm/fry/source/package.rb +++ b/lib/fpm/fry/source/archive.rb @@ -7,30 +7,62 @@ require 'fpm/fry/exec' require 'cabin' module FPM; module Fry ; module Source - class Package + # Used to build from an archive. + # + # @example in a recipe + # source 'http://curl.haxx.se/download/curl-7.36.0.tar.gz', + # checksum: '33015795d5650a2bfdd9a4a28ce4317cef944722a5cfca0d1563db8479840e90' + # + # It is highly advised to supply a checksum ( althought it's not mandatory ). + # This checksum will be used to test for cache validity and data integrity. The + # checksum algorithm is automatically guessed based on the length of the checksum. + # + # - 40 characters = sha1 + # - 64 characters = sha256 + # + # Let's be honest: all other checksum algorithms aren't or shouldn't be in use anyway. + class Archive REGEX = %r!\Ahttps?:! + # @return [:archive] def self.name :package end def self.aliases - [:http] + [:package,:http] end + # Guesses if the given url is an archive. + # + # @example not an archive + # FPM::Fry::Source::Archive.guess("bzr://something") # => nil + # + # @example an archive + # FPM::Fry::Source::Archive.guess("https://some/thing.tar.gz") #=> 6 + # + # @return [nil] when it's not an archive + # @return [Numeric] number of characters used def self.guess( url ) Source::guess_regex(REGEX, url) end + # Raised when too many redirects happened. class RedirectError < CacheFailed end + # Raised when the archive type is not known. + class UnknownArchiveType < StandardError + include WithData + end + class Cache < Struct.new(:package,:tempdir) extend Forwardable - def_delegators :package, :url, :checksum, :checksum_algorithm, :agent, :logger, :file_map + def_delegators :package, :url, :checksum, :checksum_algorithm, :logger, :file_map + # @return [String] cachekey which is equal to the checksum def cachekey @observed_checksum || checksum end @@ -93,7 +125,7 @@ def fetch_url( url, redirs = 3, &block) case(resp) when Net::HTTPRedirection if redirs == 0 - raise RedirectError, "Too many redirects" + raise RedirectError.new("Too many redirects", url: url.to_s, location: resp['location']) end logger.debug("Following redirect", url: url.to_s , location: resp['location']) return fetch_url( resp['location'], redirs - 1, &block) @@ -167,7 +199,7 @@ def copy_to(dst) update! Exec['unzip', tempfile, '-d', dst ] end - + private def unpacked_tmpdir File.join(tempdir, cachekey) end @@ -198,26 +230,44 @@ def copy_to(dst) '.bundle' => PlainCache } - attr :file_map, :data, :url, :extension, :checksum, :checksum_algorithm, :agent, :logger + attr :file_map, :data, :url, :checksum, :checksum_algorithm, :logger + # @param [URI] url + # @param [Hash] options + # @option options [Cabin::Channel] :logger (default cabin channel) + # @option options [String] :checksum a checksum of the archive + # @raise [UnknownArchiveType] when the archive type is unknown def initialize( url, options = {} ) @url = URI(url) - @extension = options.fetch(:extension){ - CACHE_CLASSES.keys.find{|ext| - @url.path.end_with?(ext) - } - } + @cache_class = guess_cache_class(@url) @logger = options.fetch(:logger){ Cabin::Channel.get } @checksum = options[:checksum] @checksum_algorithm = guess_checksum_algorithm(options[:checksum]) @file_map = options.fetch(:file_map){ {'' => ''} } end + # Creates a cache. + # + # @param [String] tempdir + # @return [TarCache] for plain .tar files + # @return [TarGzCache] for .tar.gz files + # @return [TarBz2Cache] for .tar.bz2 files + # @return [ZipCache] for .zip files + # @return [PlainCache] for .bin files def build_cache(tempdir) - CACHE_CLASSES.fetch(extension).new(self, tempdir) + @cache_class.new(self, tempdir) end private + def guess_cache_class( url ) + CACHE_CLASSES.each do |ext,klass| + if url.path.end_with?(ext) + return klass + end + end + raise UnknownArchiveType.new("Unknown archive type", url: url.to_s, known_extensions: CACHE_CLASSES.keys) + end + def guess_checksum_algorithm( checksum ) case(checksum) when nil diff --git a/lib/fpm/fry/source/git.rb b/lib/fpm/fry/source/git.rb index e0bc52c..c3e499c 100644 --- a/lib/fpm/fry/source/git.rb +++ b/lib/fpm/fry/source/git.rb @@ -20,7 +20,7 @@ class Git REGEX = %r!\A(?:git:|\S+@\S+:\S+\.git\z|https?:(?://git\.|.*\.git\z)|ssh:.*\.git\z|git\+[a-z0-9]+:)! - # @return :git + # @return [:git] def self.name :git end diff --git a/spec/recipe_spec.rb b/spec/recipe_spec.rb index 6136bb5..8c63491 100644 --- a/spec/recipe_spec.rb +++ b/spec/recipe_spec.rb @@ -242,7 +242,7 @@ def build(vars ={}, str) subject{ FPM::Fry::Recipe::Builder.new({}) } { - 'http://foo.bar/baz.tar.gz' => FPM::Fry::Source::Package, + 'http://foo.bar/baz.tar.gz' => FPM::Fry::Source::Archive, 'http://foo.bar/baz.git' => FPM::Fry::Source::Git, 'git@foo.bar:baz/baz.git' => FPM::Fry::Source::Git, 'git+ssh://foo.bar/baz' => FPM::Fry::Source::Git, diff --git a/spec/source/package_spec.rb b/spec/source/archive_spec.rb similarity index 82% rename from spec/source/package_spec.rb rename to spec/source/archive_spec.rb index 3aaef0f..1126c39 100644 --- a/spec/source/package_spec.rb +++ b/spec/source/archive_spec.rb @@ -1,9 +1,9 @@ -require 'fpm/fry/source/package' +require 'fpm/fry/source/archive' require 'tempfile' require 'fileutils' require 'webmock/rspec' require 'rubygems/package' -describe FPM::Fry::Source::Package do +describe FPM::Fry::Source::Archive do let(:tmpdir){ Dir.mktmpdir("fpm-fry") @@ -26,7 +26,7 @@ it "fetches a file" do stub_request(:get,'http://example/file.tar').to_return(body: "doesn't matter", status: 200) - src = FPM::Fry::Source::Package.new("http://example/file.tar") + src = FPM::Fry::Source::Archive.new("http://example/file.tar") src.build_cache(tmpdir) expect( File.read(File.join(tmpdir, 'file.tar')) ).to eq("doesn't matter") end @@ -34,7 +34,7 @@ it "follows redirects" do stub_request(:get,'http://example/fileA.tar').to_return(status: 302, headers: {'Location' => 'http://example/fileB.tar'} ) stub_request(:get,'http://example/fileB.tar').to_return(body: "doesn't matter", status: 200) - src = FPM::Fry::Source::Package.new("http://example/fileA.tar") + src = FPM::Fry::Source::Archive.new("http://example/fileA.tar") src.build_cache(tmpdir) expect( File.read(File.join(tmpdir, 'fileA.tar')) ).to eq("doesn't matter") end @@ -42,7 +42,7 @@ it "doesn't follow too many redirects" do stub_request(:get,'http://example/fileA.tar').to_return(status: 302, headers: {'Location' => 'http://example/fileB.tar'} ) stub_request(:get,'http://example/fileB.tar').to_return(status: 302, headers: {'Location' => 'http://example/fileA.tar'} ) - src = FPM::Fry::Source::Package.new("http://example/fileA.tar") + src = FPM::Fry::Source::Archive.new("http://example/fileA.tar") expect{ src.build_cache(tmpdir) }.to raise_error( FPM::Fry::Source::CacheFailed, "Too many redirects") @@ -50,7 +50,7 @@ it "reports missing files" do stub_request(:get,'http://example/file.tar').to_return(status: 404) - src = FPM::Fry::Source::Package.new("http://example/file.tar") + src = FPM::Fry::Source::Archive.new("http://example/file.tar") expect{ src.build_cache(tmpdir) }.to raise_error(FPM::Fry::Source::CacheFailed, "Unable to fetch file"){|e| @@ -64,7 +64,7 @@ it "reports wrong checksums" do stub_request(:get,'http://example/file.tar').to_return(body: "doesn't matter", status: 200) - src = FPM::Fry::Source::Package.new("http://example/file.tar", checksum: Digest::SHA256.hexdigest("something else")) + src = FPM::Fry::Source::Archive.new("http://example/file.tar", checksum: Digest::SHA256.hexdigest("something else")) expect{ src.build_cache(tmpdir).tar_io }.to raise_error(FPM::Fry::Source::CacheFailed, "Checksum failed"){|e| @@ -77,14 +77,14 @@ end it "returns checksum as cachekey if present" do - src = FPM::Fry::Source::Package.new("http://example/file.tar", checksum: "477c34d98f9e090a4441cf82d2f1f03e64c8eb730e8c1ef39a8595e685d4df65") + src = FPM::Fry::Source::Archive.new("http://example/file.tar", checksum: "477c34d98f9e090a4441cf82d2f1f03e64c8eb730e8c1ef39a8595e685d4df65") cache = src.build_cache(tmpdir) expect( cache.cachekey ).to eq("477c34d98f9e090a4441cf82d2f1f03e64c8eb730e8c1ef39a8595e685d4df65") end it "fetches file for cachekey if no checksum present" do stub_request(:get,'http://example/file.tar').to_return(body: "doesn't matter", status: 200) - src = FPM::Fry::Source::Package.new("http://example/file.tar") + src = FPM::Fry::Source::Archive.new("http://example/file.tar") cache = src.build_cache(tmpdir) expect( cache.cachekey ).to eq("477c34d98f9e090a4441cf82d2f1f03e64c8eb730e8c1ef39a8595e685d4df65") end @@ -103,7 +103,7 @@ it "untars a file" do stub_request(:get,'http://example/file.tar').to_return(body: body, status: 200) - src = FPM::Fry::Source::Package.new("http://example/file.tar") + src = FPM::Fry::Source::Archive.new("http://example/file.tar") cache = src.build_cache(tmpdir) cache.copy_to(destdir) expect( Dir.new(destdir).each.to_a ).to contain_exactly('.','..','foo') @@ -114,7 +114,7 @@ context '#tar_io' do it "untars a file" do stub_request(:get,'http://example/file.tar').to_return(body: body, status: 200) - src = FPM::Fry::Source::Package.new("http://example/file.tar") + src = FPM::Fry::Source::Archive.new("http://example/file.tar") cache = src.build_cache(tmpdir) expect( cache.tar_io.read ).to eq body end @@ -125,7 +125,7 @@ gz.write(body) gz.close stub_request(:get,'http://example/file.tar.gz').to_return(body: gzbody.string, status: 200) - src = FPM::Fry::Source::Package.new("http://example/file.tar.gz") + src = FPM::Fry::Source::Archive.new("http://example/file.tar.gz") cache = src.build_cache(tmpdir) expect( cache.tar_io.read ).to eq body end @@ -146,7 +146,7 @@ context '#tar_io' do it "unzips a zip file" do stub_request(:get,'http://example/file.zip').to_return(body: zipfile, status: 200) - src = FPM::Fry::Source::Package.new("http://example/file.zip") + src = FPM::Fry::Source::Archive.new("http://example/file.zip") cache = src.build_cache(tmpdir) io = cache.tar_io begin @@ -161,11 +161,11 @@ it "doesn't unzip twice" do stub_request(:get,'http://example/file.zip').to_return(body: zipfile, status: 200) - src = FPM::Fry::Source::Package.new("http://example/file.zip") + src = FPM::Fry::Source::Archive.new("http://example/file.zip") cache = src.build_cache(tmpdir) cache.tar_io.close - src = FPM::Fry::Source::Package.new("http://example/file.zip") + src = FPM::Fry::Source::Archive.new("http://example/file.zip") cache = src.build_cache(tmpdir) expect(cache).not_to receive(:copy_to) cache.tar_io.close @@ -178,7 +178,7 @@ context '#tar_io' do it "tars the file" do stub_request(:get,'http://example/dir/plainfile.bin').to_return(body: "bar", status: 200) - src = FPM::Fry::Source::Package.new('http://example/dir/plainfile.bin') + src = FPM::Fry::Source::Archive.new('http://example/dir/plainfile.bin') cache = src.build_cache(tmpdir) io = cache.tar_io begin @@ -203,7 +203,7 @@ it "copies a file" do stub_request(:get,'http://example/dir/plainfile.bin').to_return(body: "bar", status: 200) - src = FPM::Fry::Source::Package.new('http://example/dir/plainfile.bin') + src = FPM::Fry::Source::Archive.new('http://example/dir/plainfile.bin') cache = src.build_cache(tmpdir) cache.copy_to(destdir) expect( Dir.new(destdir).each.to_a ).to contain_exactly '.','..','plainfile.bin' @@ -226,7 +226,7 @@ context '#tar_io' do it "untars a tar file" do stub_request(:get,'http://example/file.tar.bz2').to_return(body: tarfile, status: 200) - src = FPM::Fry::Source::Package.new("http://example/file.tar.bz2") + src = FPM::Fry::Source::Archive.new("http://example/file.tar.bz2") cache = src.build_cache(tmpdir) io = cache.tar_io begin @@ -240,4 +240,19 @@ end end + + context 'with an unknown extension' do + + it 'raises an error' do + expect{ + FPM::Fry::Source::Archive.new("http://example/file.unknown") + }.to raise_error(FPM::Fry::Source::Archive::UnknownArchiveType,"Unknown archive type"){|e| + expect(e.data).to include( + url: "http://example/file.unknown", + known_extensions: include(".tar",".tar.gz") + ) + } + end + + end end