Skip to content
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
22 changes: 12 additions & 10 deletions lib/morph-cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require 'tempfile'
require 'fileutils'
require 'filesize'
require 'zlib'
require 'faraday'
require 'faraday/multipart'
require 'minitar'
Expand Down Expand Up @@ -42,7 +43,7 @@ def self.execute(directory, _development, env_config)
connection.post("/run") do |req|
req.body = {
api_key: env_config[:api_key],
code: Faraday::Multipart::FilePart.new(file, "application/octet-stream")
code: Faraday::Multipart::FilePart.new(file, "application/gzip")
}
req.options.timeout = timeout
req.options.on_data = proc do |chunk, _overall_received_bytes, env|
Expand Down Expand Up @@ -106,21 +107,22 @@ def self.in_directory(directory)
FileUtils.cd(cwd)
end

# Packs the given paths (relative to directory) into a tar file and returns
# an open, rewound file handle ready for upload.
# Packs the given paths (relative to directory) into a gzip-compressed tar
# file and returns an open, rewound file handle ready for upload.
def self.create_tar(directory, paths)
tempfile = Tempfile.new(["morph", ".tar"])
tempfile = Tempfile.new(["morph", ".tar.gz"])
tempfile.binmode

in_directory(directory) do
output = Minitar::Output.new(tempfile)
paths.each do |entry|
Minitar.pack_file(entry, output)
end
gzip = Zlib::GzipWriter.new(tempfile)
output = Minitar::Output.new(gzip)
paths.each { |entry| Minitar.pack_file(entry, output) }
ensure
# Writes the tar trailer and flushes without closing the underlying
# tempfile, so the returned handle stays open for reading.
# Closing the tar writer writes the tar trailer; finishing (not
# closing) the gzip stream writes the gzip trailer, leaving the
# underlying tempfile handle open for reading.
output&.tar&.close
gzip&.finish
end

tempfile.flush
Expand Down
24 changes: 18 additions & 6 deletions spec/morph_cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def with_scraper_directory
end
end

it "posts the API key and the code as multipart form data" do
it "posts the API key and the gzipped code as multipart form data" do
stub_request(:post, "https://morph.io/run").to_return(status: 200, body: "")

with_scraper_directory do |dir|
Expand All @@ -41,7 +41,7 @@ def with_scraper_directory
expect(WebMock).to(have_requested(:post, "https://morph.io/run").with do |req|
req.headers["Content-Type"].start_with?("multipart/form-data") &&
req.body.include?("secret-key") &&
req.body.include?("scraper.rb")
req.body.b.include?("\x1f\x8b".b) # gzip magic bytes
end)
end

Expand Down Expand Up @@ -122,7 +122,7 @@ def with_scraper_directory
end

describe ".create_tar" do
it "packs the given paths into a readable tar" do
it "packs the given paths into a readable gzip-compressed tar" do
Dir.mktmpdir do |dir|
File.write(File.join(dir, "scraper.rb"), "puts 'hi'\n")
FileUtils.mkdir_p(File.join(dir, "lib"))
Expand All @@ -132,13 +132,25 @@ def with_scraper_directory
tar = described_class.create_tar(dir, paths)

names = []
Minitar::Input.open(tar.path) do |input|
input.each { |entry| names << entry.full_name }
Zlib::GzipReader.open(tar.path) do |gzip|
Minitar::Input.open(gzip) do |input|
input.each { |entry| names << entry.full_name }
end
end
expect(names).to contain_exactly("scraper.rb", "lib/helper.rb")
end
end

it "compresses the tar" do
Dir.mktmpdir do |dir|
File.write(File.join(dir, "scraper.rb"), "a" * 100_000)

tar = described_class.create_tar(dir, described_class.all_paths(dir))

expect(File.size(tar.path)).to be < 100_000
end
end

it "returns an open file handle ready for reading" do
Dir.mktmpdir do |dir|
File.write(File.join(dir, "scraper.rb"), "puts 'hi'\n")
Expand All @@ -147,7 +159,7 @@ def with_scraper_directory

expect(tar).not_to be_closed
expect(tar.pos).to eq(0)
expect(tar.read).to include("scraper.rb")
expect(tar.read(2)).to eq("\x1f\x8b".b) # gzip magic bytes
end
end
end
Expand Down