Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix up creating archives #18

Merged
merged 1 commit into from
Apr 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/mixlib/archive.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
require "mixlib/archive/tar"
require "mixlib/archive/version"
require "mixlib/log"
require "find"

module Mixlib
class Archive
attr_reader :archiver
alias_method :extractor, :archiver

def self.archive_directory(path, archive, gzip: false, format: :tar, compression: :none)
targets = Find.find(path).collect { |fn| fn }
new(archive).create(targets, gzip: gzip)
end

def initialize(archive, empty: false)
@empty = empty

Expand Down
28 changes: 25 additions & 3 deletions lib/mixlib/archive/lib_archive.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def initialize(archive, options = {})
def extract(destination, perms: true, ignore: [])
ignore_re = Regexp.union(ignore)
flags = perms ? ::Archive::EXTRACT_PERM : nil
FileUtils.mkdir_p(destination)
Dir.chdir(destination) do
reader = ::Archive::Reader.open_filename(@archive)

Expand Down Expand Up @@ -47,17 +48,38 @@ def create(files, gzip: false)
::Archive.write_open_filename(archive, compression, format) do |tar|
files.each do |fn|
tar.new_entry do |entry|
content = nil
entry.pathname = fn
entry.copy_stat(fn)
tar.write_header(entry)
stat = File.lstat(fn)
if File.file?(fn)
content = File.read(fn)
tar.write_data(content)
entry.size = content.size
end
entry.mode = stat.mode
entry.filetype = resolve_type(stat.ftype)
entry.atime = stat.atime
entry.mtime = stat.mtime
entry.symlink = File.readlink(fn) if File.symlink?(fn)
tar.write_header(entry)

tar.write_data(content) unless content.nil?
end
end
end
end

def resolve_type(type)
case type
when "characterSpecial"
::Archive::Entry::CHARACTER_SPECIAL
when "blockSpecial"
::Archive::Entry::BLOCK_SPECIAL
when "link"
::Archive::Entry::SYMBOLIC_LINK
else
::Archive::Entry.const_get(type.upcase)
end
end
end
end
end
9 changes: 7 additions & 2 deletions lib/mixlib/archive/tar.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require "rubygems/package"
require "tempfile"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't see a Tempfile or tmpdir?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line 74

require "zlib"

module Mixlib
Expand Down Expand Up @@ -85,10 +86,14 @@ def create(files, gzip: false)

target.close
if gzip
Zlib::GzipWriter.open(archive) do |gz|
Zlib::GzipWriter.open(archive, Zlib::BEST_COMPRESSION) do |gz|
gz.mtime = File.mtime(target.path)
gz.orig_name = File.basename(archive)
gz.write IO.binread(target.path)
File.open(target.path) do |file|
while (chunk = file.read(16 * 1024))
gz.write(chunk)
end
end
end
else
FileUtils.mv(target.path, archive)
Expand Down
1 change: 1 addition & 0 deletions spec/fixtures/fixture_a
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fixture_a
1 change: 1 addition & 0 deletions spec/fixtures/fixture_b
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fixture_b
1 change: 1 addition & 0 deletions spec/fixtures/fixture_c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fixture_c
57 changes: 57 additions & 0 deletions spec/mixlib/lib_archive_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
require "spec_helper"

describe Mixlib::Archive::LibArchive do
let(:tar_archive) { "#{fixtures_path}/test.tar" }
let(:tgz_archive) { "#{fixtures_path}/test.tgz" }
let(:tar_gz_archive) { "#{fixtures_path}/test.tar.gz" }

let(:extraction) { lambda { |f| } }

let(:destination) { Dir.mktmpdir }

let(:gzip_header) { [0x1F, 0x8B].pack("C*") }

before do
allow(IO).to receive(:binread).and_return(nil)
end

after do
FileUtils.remove_entry destination
end

describe "#reader"

describe "#create" do
let(:test_root) { Dir.mktmpdir(nil) }
let(:archive_path) { File.join(test_root, "test.tar.gz") }
let(:file_paths) { %w{ . .. fixture_a fixture_b fixture_c } }

context "using the correct options" do
it "requests the correct tar format" do
expect(::Archive).to receive(:write_open_filename).with(archive_path, 0, ::Archive::FORMAT_TAR_PAX_RESTRICTED)
Mixlib::Archive::LibArchive.new(archive_path).create([])
end

it "requests gzip compression" do
expect(::Archive).to receive(:write_open_filename).with(archive_path, ::Archive::COMPRESSION_GZIP, ::Archive::FORMAT_TAR_PAX_RESTRICTED)
Mixlib::Archive::LibArchive.new(archive_path).create([], gzip: true)
end

it "requests no compression" do
expect(::Archive).to receive(:write_open_filename).with(archive_path, ::Archive::COMPRESSION_NONE, ::Archive::FORMAT_TAR_PAX_RESTRICTED)
Mixlib::Archive::LibArchive.new(archive_path).create([], gzip: false)
end
end

it "creates a tarball" do
Dir.chdir(fixtures_path) do
Mixlib::Archive::LibArchive.new(archive_path).create(file_paths, gzip: true)
end
expect(File.file?(archive_path)).to be true
target = File.join(test_root, "target")
Mixlib::Archive::LibArchive.new(archive_path).extract(target)
expect(Dir.entries(target)).to match_array file_paths
end

end
end
17 changes: 17 additions & 0 deletions spec/mixlib/tar_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,21 @@
end

end

describe "#create" do
let(:test_root) { Dir.mktmpdir(nil) }
let(:archive_path) { File.join(test_root, "test.tar.gz") }
let(:file_paths) { %w{ . .. fixture_a fixture_b fixture_c } }

it "creates a tarball" do
Dir.chdir(fixtures_path) do
Mixlib::Archive::Tar.new(archive_path).create(file_paths, gzip: true)
end
expect(File.file?(archive_path)).to be true
target = File.join(test_root, "target")
Mixlib::Archive::LibArchive.new(archive_path).extract(target, ignore: %w{ . .. })
expect(Dir.entries(target)).to match_array file_paths
end

end
end
15 changes: 15 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,18 @@
require "mixlib/archive"
require "mixlib/archive/tar"
require "mixlib/archive/lib_archive"

module Fixtures
def fixtures_path
spec_root.join("fixtures")
end

def spec_root
Pathname.new(File.expand_path(File.dirname(__FILE__)))
end
end

RSpec.configure do |config|
config.raise_errors_for_deprecations!
config.include Fixtures
end