mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
Refactor unpack strategies into separate files.
This commit is contained in:
parent
2c9dc62d35
commit
b6e54a06e0
@ -329,7 +329,7 @@ end
|
|||||||
# Useful for installing jars.
|
# Useful for installing jars.
|
||||||
class NoUnzipCurlDownloadStrategy < CurlDownloadStrategy
|
class NoUnzipCurlDownloadStrategy < CurlDownloadStrategy
|
||||||
def stage
|
def stage
|
||||||
UncompressedUnpackStrategy.new(cached_location)
|
UnpackStrategy::Uncompressed.new(cached_location)
|
||||||
.extract(basename: basename_without_params)
|
.extract(basename: basename_without_params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
14
Library/Homebrew/test/unpack_strategy/bazaar_spec.rb
Normal file
14
Library/Homebrew/test/unpack_strategy/bazaar_spec.rb
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::Bazaar do
|
||||||
|
let(:repo) {
|
||||||
|
mktmpdir.tap do |repo|
|
||||||
|
FileUtils.touch repo/"test"
|
||||||
|
(repo/".bzr").mkpath
|
||||||
|
end
|
||||||
|
}
|
||||||
|
let(:path) { repo }
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
include_examples "#extract", children: ["test"]
|
||||||
|
end
|
8
Library/Homebrew/test/unpack_strategy/bzip2_spec.rb
Normal file
8
Library/Homebrew/test/unpack_strategy/bzip2_spec.rb
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::Bzip2 do
|
||||||
|
let(:path) { TEST_FIXTURE_DIR/"cask/container.bz2" }
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
include_examples "#extract", children: ["container"]
|
||||||
|
end
|
14
Library/Homebrew/test/unpack_strategy/cvs_spec.rb
Normal file
14
Library/Homebrew/test/unpack_strategy/cvs_spec.rb
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::Cvs do
|
||||||
|
let(:repo) {
|
||||||
|
mktmpdir.tap do |repo|
|
||||||
|
FileUtils.touch repo/"test"
|
||||||
|
(repo/"CVS").mkpath
|
||||||
|
end
|
||||||
|
}
|
||||||
|
let(:path) { repo }
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
include_examples "#extract", children: ["CVS", "test"]
|
||||||
|
end
|
32
Library/Homebrew/test/unpack_strategy/directory_spec.rb
Normal file
32
Library/Homebrew/test/unpack_strategy/directory_spec.rb
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::Directory do
|
||||||
|
let(:path) {
|
||||||
|
mktmpdir.tap do |path|
|
||||||
|
FileUtils.touch path/"file"
|
||||||
|
FileUtils.ln_s "file", path/"symlink"
|
||||||
|
end
|
||||||
|
}
|
||||||
|
subject(:strategy) { described_class.new(path) }
|
||||||
|
let(:unpack_dir) { mktmpdir }
|
||||||
|
|
||||||
|
it "does not follow symlinks" do
|
||||||
|
strategy.extract(to: unpack_dir)
|
||||||
|
expect(unpack_dir/"symlink").to be_a_symlink
|
||||||
|
end
|
||||||
|
|
||||||
|
it "preserves permissions of contained files" do
|
||||||
|
FileUtils.chmod 0644, path/"file"
|
||||||
|
|
||||||
|
strategy.extract(to: unpack_dir)
|
||||||
|
expect((unpack_dir/"file").stat.mode & 0777).to eq 0644
|
||||||
|
end
|
||||||
|
|
||||||
|
it "preserves the permissions of the destination directory" do
|
||||||
|
FileUtils.chmod 0700, path
|
||||||
|
FileUtils.chmod 0755, unpack_dir
|
||||||
|
|
||||||
|
strategy.extract(to: unpack_dir)
|
||||||
|
expect(unpack_dir.stat.mode & 0777).to eq 0755
|
||||||
|
end
|
||||||
|
end
|
17
Library/Homebrew/test/unpack_strategy/git_spec.rb
Normal file
17
Library/Homebrew/test/unpack_strategy/git_spec.rb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::Git do
|
||||||
|
let(:repo) {
|
||||||
|
mktmpdir.tap do |repo|
|
||||||
|
system "git", "-C", repo, "init"
|
||||||
|
|
||||||
|
FileUtils.touch repo/"test"
|
||||||
|
system "git", "-C", repo, "add", "test"
|
||||||
|
system "git", "-C", repo, "commit", "-m", "Add `test` file."
|
||||||
|
end
|
||||||
|
}
|
||||||
|
let(:path) { repo }
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
include_examples "#extract", children: [".git", "test"]
|
||||||
|
end
|
8
Library/Homebrew/test/unpack_strategy/gzip_spec.rb
Normal file
8
Library/Homebrew/test/unpack_strategy/gzip_spec.rb
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::Gzip do
|
||||||
|
let(:path) { TEST_FIXTURE_DIR/"cask/container.gz" }
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
include_examples "#extract", children: ["container"]
|
||||||
|
end
|
8
Library/Homebrew/test/unpack_strategy/jar_spec.rb
Normal file
8
Library/Homebrew/test/unpack_strategy/jar_spec.rb
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::Jar do
|
||||||
|
let(:path) { TEST_FIXTURE_DIR/"test.jar" }
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
include_examples "#extract", children: ["test.jar"]
|
||||||
|
end
|
7
Library/Homebrew/test/unpack_strategy/lha_spec.rb
Normal file
7
Library/Homebrew/test/unpack_strategy/lha_spec.rb
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::Lha do
|
||||||
|
let(:path) { TEST_FIXTURE_DIR/"test.lha" }
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
end
|
7
Library/Homebrew/test/unpack_strategy/lzip_spec.rb
Normal file
7
Library/Homebrew/test/unpack_strategy/lzip_spec.rb
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::Lzip do
|
||||||
|
let(:path) { TEST_FIXTURE_DIR/"test.lz" }
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
end
|
12
Library/Homebrew/test/unpack_strategy/mercurial_spec.rb
Normal file
12
Library/Homebrew/test/unpack_strategy/mercurial_spec.rb
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::Mercurial do
|
||||||
|
let(:repo) {
|
||||||
|
mktmpdir.tap do |repo|
|
||||||
|
(repo/".hg").mkpath
|
||||||
|
end
|
||||||
|
}
|
||||||
|
let(:path) { repo }
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
end
|
7
Library/Homebrew/test/unpack_strategy/p7zip_spec.rb
Normal file
7
Library/Homebrew/test/unpack_strategy/p7zip_spec.rb
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::P7Zip do
|
||||||
|
let(:path) { TEST_FIXTURE_DIR/"cask/container.7z" }
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
end
|
7
Library/Homebrew/test/unpack_strategy/rar_spec.rb
Normal file
7
Library/Homebrew/test/unpack_strategy/rar_spec.rb
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::Rar do
|
||||||
|
let(:path) { TEST_FIXTURE_DIR/"cask/container.rar" }
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
end
|
16
Library/Homebrew/test/unpack_strategy/shared_examples.rb
Normal file
16
Library/Homebrew/test/unpack_strategy/shared_examples.rb
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
require "unpack_strategy"
|
||||||
|
|
||||||
|
shared_examples "UnpackStrategy::detect" do
|
||||||
|
it "is correctly detected" do
|
||||||
|
expect(UnpackStrategy.detect(path)).to be_a described_class
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_examples "#extract" do |children: []|
|
||||||
|
specify "#extract" do
|
||||||
|
mktmpdir do |unpack_dir|
|
||||||
|
described_class.new(path).extract(to: unpack_dir)
|
||||||
|
expect(unpack_dir.children(false).map(&:to_s)).to match_array children
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
22
Library/Homebrew/test/unpack_strategy/subversion_spec.rb
Normal file
22
Library/Homebrew/test/unpack_strategy/subversion_spec.rb
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::Subversion do
|
||||||
|
let(:repo) {
|
||||||
|
mktmpdir.tap do |repo|
|
||||||
|
system "svnadmin", "create", repo
|
||||||
|
end
|
||||||
|
}
|
||||||
|
let(:working_copy) {
|
||||||
|
mktmpdir.tap do |working_copy|
|
||||||
|
system "svn", "checkout", "file://#{repo}", working_copy
|
||||||
|
|
||||||
|
FileUtils.touch working_copy/"test"
|
||||||
|
system "svn", "add", working_copy/"test"
|
||||||
|
system "svn", "commit", working_copy, "-m", "Add `test` file."
|
||||||
|
end
|
||||||
|
}
|
||||||
|
let(:path) { working_copy }
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
include_examples "#extract", children: ["test"]
|
||||||
|
end
|
18
Library/Homebrew/test/unpack_strategy/tar_spec.rb
Normal file
18
Library/Homebrew/test/unpack_strategy/tar_spec.rb
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::Tar do
|
||||||
|
let(:path) { TEST_FIXTURE_DIR/"cask/container.tar.gz" }
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
include_examples "#extract", children: ["container"]
|
||||||
|
|
||||||
|
context "when TAR archive is corrupted" do
|
||||||
|
let(:path) {
|
||||||
|
(mktmpdir/"test.tar").tap do |path|
|
||||||
|
FileUtils.touch path
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
end
|
||||||
|
end
|
11
Library/Homebrew/test/unpack_strategy/uncompressed_spec.rb
Normal file
11
Library/Homebrew/test/unpack_strategy/uncompressed_spec.rb
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::Uncompressed do
|
||||||
|
let(:path) {
|
||||||
|
(mktmpdir/"test").tap do |path|
|
||||||
|
FileUtils.touch path
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
end
|
8
Library/Homebrew/test/unpack_strategy/xar_spec.rb
Normal file
8
Library/Homebrew/test/unpack_strategy/xar_spec.rb
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::Xar, :needs_macos do
|
||||||
|
let(:path) { TEST_FIXTURE_DIR/"cask/container.xar" }
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
include_examples "#extract", children: ["container"]
|
||||||
|
end
|
7
Library/Homebrew/test/unpack_strategy/xz_spec.rb
Normal file
7
Library/Homebrew/test/unpack_strategy/xz_spec.rb
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::Xz do
|
||||||
|
let(:path) { TEST_FIXTURE_DIR/"cask/container.xz" }
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
end
|
18
Library/Homebrew/test/unpack_strategy/zip_spec.rb
Normal file
18
Library/Homebrew/test/unpack_strategy/zip_spec.rb
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
require_relative "shared_examples"
|
||||||
|
|
||||||
|
describe UnpackStrategy::Zip do
|
||||||
|
let(:path) { TEST_FIXTURE_DIR/"cask/MyFancyApp.zip" }
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
include_examples "#extract", children: ["MyFancyApp"]
|
||||||
|
|
||||||
|
context "when ZIP archive is corrupted" do
|
||||||
|
let(:path) {
|
||||||
|
(mktmpdir/"test.zip").tap do |path|
|
||||||
|
FileUtils.touch path
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
include_examples "UnpackStrategy::detect"
|
||||||
|
end
|
||||||
|
end
|
@ -1,20 +1,3 @@
|
|||||||
require "unpack_strategy"
|
|
||||||
|
|
||||||
RSpec.shared_examples "UnpackStrategy::detect" do
|
|
||||||
it "is correctly detected" do
|
|
||||||
expect(UnpackStrategy.detect(path)).to be_a described_class
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
RSpec.shared_examples "#extract" do |children: []|
|
|
||||||
specify "#extract" do
|
|
||||||
mktmpdir do |unpack_dir|
|
|
||||||
described_class.new(path).extract(to: unpack_dir)
|
|
||||||
expect(unpack_dir.children(false).map(&:to_s)).to match_array children
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe UnpackStrategy do
|
describe UnpackStrategy do
|
||||||
describe "#extract_nestedly" do
|
describe "#extract_nestedly" do
|
||||||
subject(:strategy) { described_class.detect(path) }
|
subject(:strategy) { described_class.detect(path) }
|
||||||
@ -75,210 +58,3 @@ describe UnpackStrategy do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe DirectoryUnpackStrategy do
|
|
||||||
let(:path) {
|
|
||||||
mktmpdir.tap do |path|
|
|
||||||
FileUtils.touch path/"file"
|
|
||||||
FileUtils.ln_s "file", path/"symlink"
|
|
||||||
end
|
|
||||||
}
|
|
||||||
subject(:strategy) { described_class.new(path) }
|
|
||||||
let(:unpack_dir) { mktmpdir }
|
|
||||||
|
|
||||||
it "does not follow symlinks" do
|
|
||||||
strategy.extract(to: unpack_dir)
|
|
||||||
expect(unpack_dir/"symlink").to be_a_symlink
|
|
||||||
end
|
|
||||||
|
|
||||||
it "preserves permissions of contained files" do
|
|
||||||
FileUtils.chmod 0644, path/"file"
|
|
||||||
|
|
||||||
strategy.extract(to: unpack_dir)
|
|
||||||
expect((unpack_dir/"file").stat.mode & 0777).to eq 0644
|
|
||||||
end
|
|
||||||
|
|
||||||
it "preserves the permissions of the destination directory" do
|
|
||||||
FileUtils.chmod 0700, path
|
|
||||||
FileUtils.chmod 0755, unpack_dir
|
|
||||||
|
|
||||||
strategy.extract(to: unpack_dir)
|
|
||||||
expect(unpack_dir.stat.mode & 0777).to eq 0755
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe UncompressedUnpackStrategy do
|
|
||||||
let(:path) {
|
|
||||||
(mktmpdir/"test").tap do |path|
|
|
||||||
FileUtils.touch path
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
end
|
|
||||||
|
|
||||||
describe P7ZipUnpackStrategy do
|
|
||||||
let(:path) { TEST_FIXTURE_DIR/"cask/container.7z" }
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
end
|
|
||||||
|
|
||||||
describe XarUnpackStrategy, :needs_macos do
|
|
||||||
let(:path) { TEST_FIXTURE_DIR/"cask/container.xar" }
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
include_examples "#extract", children: ["container"]
|
|
||||||
end
|
|
||||||
|
|
||||||
describe XzUnpackStrategy do
|
|
||||||
let(:path) { TEST_FIXTURE_DIR/"cask/container.xz" }
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
end
|
|
||||||
|
|
||||||
describe RarUnpackStrategy do
|
|
||||||
let(:path) { TEST_FIXTURE_DIR/"cask/container.rar" }
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
end
|
|
||||||
|
|
||||||
describe LzipUnpackStrategy do
|
|
||||||
let(:path) { TEST_FIXTURE_DIR/"test.lz" }
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
end
|
|
||||||
|
|
||||||
describe LhaUnpackStrategy do
|
|
||||||
let(:path) { TEST_FIXTURE_DIR/"test.lha" }
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
end
|
|
||||||
|
|
||||||
describe JarUnpackStrategy do
|
|
||||||
let(:path) { TEST_FIXTURE_DIR/"test.jar" }
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
include_examples "#extract", children: ["test.jar"]
|
|
||||||
end
|
|
||||||
|
|
||||||
describe ZipUnpackStrategy do
|
|
||||||
let(:path) { TEST_FIXTURE_DIR/"cask/MyFancyApp.zip" }
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
include_examples "#extract", children: ["MyFancyApp"]
|
|
||||||
|
|
||||||
context "when ZIP archive is corrupted" do
|
|
||||||
let(:path) {
|
|
||||||
(mktmpdir/"test.zip").tap do |path|
|
|
||||||
FileUtils.touch path
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe GzipUnpackStrategy do
|
|
||||||
let(:path) { TEST_FIXTURE_DIR/"cask/container.gz" }
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
include_examples "#extract", children: ["container"]
|
|
||||||
end
|
|
||||||
|
|
||||||
describe Bzip2UnpackStrategy do
|
|
||||||
let(:path) { TEST_FIXTURE_DIR/"cask/container.bz2" }
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
include_examples "#extract", children: ["container"]
|
|
||||||
end
|
|
||||||
|
|
||||||
describe TarUnpackStrategy do
|
|
||||||
let(:path) { TEST_FIXTURE_DIR/"cask/container.tar.gz" }
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
include_examples "#extract", children: ["container"]
|
|
||||||
|
|
||||||
context "when TAR archive is corrupted" do
|
|
||||||
let(:path) {
|
|
||||||
(mktmpdir/"test.tar").tap do |path|
|
|
||||||
FileUtils.touch path
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe GitUnpackStrategy do
|
|
||||||
let(:repo) {
|
|
||||||
mktmpdir.tap do |repo|
|
|
||||||
system "git", "-C", repo, "init"
|
|
||||||
|
|
||||||
FileUtils.touch repo/"test"
|
|
||||||
system "git", "-C", repo, "add", "test"
|
|
||||||
system "git", "-C", repo, "commit", "-m", "Add `test` file."
|
|
||||||
end
|
|
||||||
}
|
|
||||||
let(:path) { repo }
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
include_examples "#extract", children: [".git", "test"]
|
|
||||||
end
|
|
||||||
|
|
||||||
describe SubversionUnpackStrategy do
|
|
||||||
let(:repo) {
|
|
||||||
mktmpdir.tap do |repo|
|
|
||||||
system "svnadmin", "create", repo
|
|
||||||
end
|
|
||||||
}
|
|
||||||
let(:working_copy) {
|
|
||||||
mktmpdir.tap do |working_copy|
|
|
||||||
system "svn", "checkout", "file://#{repo}", working_copy
|
|
||||||
|
|
||||||
FileUtils.touch working_copy/"test"
|
|
||||||
system "svn", "add", working_copy/"test"
|
|
||||||
system "svn", "commit", working_copy, "-m", "Add `test` file."
|
|
||||||
end
|
|
||||||
}
|
|
||||||
let(:path) { working_copy }
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
include_examples "#extract", children: ["test"]
|
|
||||||
end
|
|
||||||
|
|
||||||
describe CvsUnpackStrategy do
|
|
||||||
let(:repo) {
|
|
||||||
mktmpdir.tap do |repo|
|
|
||||||
FileUtils.touch repo/"test"
|
|
||||||
(repo/"CVS").mkpath
|
|
||||||
end
|
|
||||||
}
|
|
||||||
let(:path) { repo }
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
include_examples "#extract", children: ["CVS", "test"]
|
|
||||||
end
|
|
||||||
|
|
||||||
describe BazaarUnpackStrategy do
|
|
||||||
let(:repo) {
|
|
||||||
mktmpdir.tap do |repo|
|
|
||||||
FileUtils.touch repo/"test"
|
|
||||||
(repo/".bzr").mkpath
|
|
||||||
end
|
|
||||||
}
|
|
||||||
let(:path) { repo }
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
include_examples "#extract", children: ["test"]
|
|
||||||
end
|
|
||||||
|
|
||||||
describe MercurialUnpackStrategy do
|
|
||||||
let(:repo) {
|
|
||||||
mktmpdir.tap do |repo|
|
|
||||||
(repo/".hg").mkpath
|
|
||||||
end
|
|
||||||
}
|
|
||||||
let(:path) { repo }
|
|
||||||
|
|
||||||
include_examples "UnpackStrategy::detect"
|
|
||||||
end
|
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
class UnpackStrategy
|
module UnpackStrategy
|
||||||
# length of the longest regex (currently TarUnpackStrategy)
|
# length of the longest regex (currently Tar)
|
||||||
MAX_MAGIC_NUMBER_LENGTH = 262
|
MAX_MAGIC_NUMBER_LENGTH = 262
|
||||||
private_constant :MAX_MAGIC_NUMBER_LENGTH
|
private_constant :MAX_MAGIC_NUMBER_LENGTH
|
||||||
|
|
||||||
def self.strategies
|
def self.strategies
|
||||||
@strategies ||= [
|
@strategies ||= [
|
||||||
JarUnpackStrategy,
|
Jar,
|
||||||
LuaRockUnpackStrategy,
|
LuaRock,
|
||||||
MicrosoftOfficeXmlUnpackStrategy,
|
MicrosoftOfficeXml,
|
||||||
ZipUnpackStrategy,
|
Zip,
|
||||||
XarUnpackStrategy,
|
Xar,
|
||||||
CompressUnpackStrategy,
|
Compress,
|
||||||
TarUnpackStrategy,
|
Tar,
|
||||||
GzipUnpackStrategy,
|
Gzip,
|
||||||
Bzip2UnpackStrategy,
|
Bzip2,
|
||||||
XzUnpackStrategy,
|
Xz,
|
||||||
LzipUnpackStrategy,
|
Lzip,
|
||||||
GitUnpackStrategy,
|
Git,
|
||||||
MercurialUnpackStrategy,
|
Mercurial,
|
||||||
SubversionUnpackStrategy,
|
Subversion,
|
||||||
CvsUnpackStrategy,
|
Cvs,
|
||||||
FossilUnpackStrategy,
|
Fossil,
|
||||||
BazaarUnpackStrategy,
|
Bazaar,
|
||||||
P7ZipUnpackStrategy,
|
P7Zip,
|
||||||
RarUnpackStrategy,
|
Rar,
|
||||||
LhaUnpackStrategy,
|
Lha,
|
||||||
].freeze
|
].freeze
|
||||||
end
|
end
|
||||||
private_class_method :strategies
|
private_class_method :strategies
|
||||||
@ -43,11 +43,11 @@ class UnpackStrategy
|
|||||||
# This is so that bad files produce good error messages.
|
# This is so that bad files produce good error messages.
|
||||||
strategy ||= case path.extname
|
strategy ||= case path.extname
|
||||||
when ".tar", ".tar.gz", ".tgz", ".tar.bz2", ".tbz", ".tar.xz", ".txz"
|
when ".tar", ".tar.gz", ".tgz", ".tar.bz2", ".tbz", ".tar.xz", ".txz"
|
||||||
TarUnpackStrategy
|
Tar
|
||||||
when ".zip"
|
when ".zip"
|
||||||
ZipUnpackStrategy
|
Zip
|
||||||
else
|
else
|
||||||
UncompressedUnpackStrategy
|
Uncompressed
|
||||||
end
|
end
|
||||||
|
|
||||||
strategy.new(path, ref_type: ref_type, ref: ref)
|
strategy.new(path, ref_type: ref_type, ref: ref)
|
||||||
@ -77,301 +77,36 @@ class UnpackStrategy
|
|||||||
children = tmp_unpack_dir.children
|
children = tmp_unpack_dir.children
|
||||||
|
|
||||||
if children.count == 1 && !children.first.directory?
|
if children.count == 1 && !children.first.directory?
|
||||||
s = self.class.detect(children.first)
|
s = UnpackStrategy.detect(children.first)
|
||||||
|
|
||||||
s.extract_nestedly(to: to, verbose: verbose)
|
s.extract_nestedly(to: to, verbose: verbose)
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
DirectoryUnpackStrategy.new(tmp_unpack_dir).extract(to: to, verbose: verbose)
|
Directory.new(tmp_unpack_dir).extract(to: to, verbose: verbose)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class DirectoryUnpackStrategy < UnpackStrategy
|
require "unpack_strategy/bazaar"
|
||||||
def self.can_extract?(path:, magic_number:)
|
require "unpack_strategy/bzip2"
|
||||||
path.directory?
|
require "unpack_strategy/compress"
|
||||||
end
|
require "unpack_strategy/cvs"
|
||||||
|
require "unpack_strategy/directory"
|
||||||
private
|
require "unpack_strategy/fossil"
|
||||||
|
require "unpack_strategy/git"
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
require "unpack_strategy/gzip"
|
||||||
path.children.each do |child|
|
require "unpack_strategy/jar"
|
||||||
FileUtils.copy_entry child, unpack_dir/child.basename, true, false
|
require "unpack_strategy/lha"
|
||||||
end
|
require "unpack_strategy/lua_rock"
|
||||||
end
|
require "unpack_strategy/lzip"
|
||||||
end
|
require "unpack_strategy/mercurial"
|
||||||
|
require "unpack_strategy/microsoft_office_xml"
|
||||||
class UncompressedUnpackStrategy < UnpackStrategy
|
require "unpack_strategy/p7zip"
|
||||||
alias extract_nestedly extract
|
require "unpack_strategy/rar"
|
||||||
|
require "unpack_strategy/subversion"
|
||||||
private
|
require "unpack_strategy/tar"
|
||||||
|
require "unpack_strategy/uncompressed"
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
require "unpack_strategy/xar"
|
||||||
FileUtils.cp path, unpack_dir/basename, preserve: true, verbose: verbose
|
require "unpack_strategy/xz"
|
||||||
end
|
require "unpack_strategy/zip"
|
||||||
end
|
|
||||||
|
|
||||||
class MicrosoftOfficeXmlUnpackStrategy < UncompressedUnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
return false unless ZipUnpackStrategy.can_extract?(path: path, magic_number: magic_number)
|
|
||||||
|
|
||||||
# Check further if the ZIP is a Microsoft Office XML document.
|
|
||||||
magic_number.match?(/\APK\003\004/n) &&
|
|
||||||
magic_number.match?(%r{\A.{30}(\[Content_Types\]\.xml|_rels/\.rels)}n)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class LuaRockUnpackStrategy < UncompressedUnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
return false unless ZipUnpackStrategy.can_extract?(path: path, magic_number: magic_number)
|
|
||||||
|
|
||||||
# Check further if the ZIP is a LuaRocks package.
|
|
||||||
out, = Open3.capture3("zipinfo", "-1", path)
|
|
||||||
out.encode(Encoding::UTF_8, invalid: :replace)
|
|
||||||
.split("\n")
|
|
||||||
.any? { |line| line.match?(%r{\A[^/]+.rockspec\Z}) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class JarUnpackStrategy < UncompressedUnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
return false unless ZipUnpackStrategy.can_extract?(path: path, magic_number: magic_number)
|
|
||||||
|
|
||||||
# Check further if the ZIP is a JAR/WAR.
|
|
||||||
out, = Open3.capture3("zipinfo", "-1", path)
|
|
||||||
out.encode(Encoding::UTF_8, invalid: :replace)
|
|
||||||
.split("\n")
|
|
||||||
.include?("META-INF/MANIFEST.MF")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class P7ZipUnpackStrategy < UnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
magic_number.match?(/\A7z\xBC\xAF\x27\x1C/n)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
|
||||||
safe_system "7zr", "x", "-y", "-bd", "-bso0", path, "-o#{unpack_dir}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class ZipUnpackStrategy < UnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
magic_number.match?(/\APK(\003\004|\005\006)/n)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
|
||||||
quiet_flags = verbose ? [] : ["-qq"]
|
|
||||||
safe_system "unzip", *quiet_flags, path, "-d", unpack_dir
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class TarUnpackStrategy < UnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
return true if magic_number.match?(/\A.{257}ustar/n)
|
|
||||||
|
|
||||||
# Check if `tar` can list the contents, then it can also extract it.
|
|
||||||
IO.popen(["tar", "tf", path], err: File::NULL) do |stdout|
|
|
||||||
!stdout.read(1).nil?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
|
||||||
safe_system "tar", "xf", path, "-C", unpack_dir
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class CompressUnpackStrategy < TarUnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
magic_number.match?(/\A\037\235/n)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class XzUnpackStrategy < UnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
magic_number.match?(/\A\xFD7zXZ\x00/n)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
|
||||||
FileUtils.cp path, unpack_dir/basename, preserve: true
|
|
||||||
quiet_flags = verbose ? [] : ["-q"]
|
|
||||||
safe_system Formula["xz"].opt_bin/"unxz", *quiet_flags, "-T0", unpack_dir/basename
|
|
||||||
extract_nested_tar(unpack_dir)
|
|
||||||
end
|
|
||||||
|
|
||||||
def extract_nested_tar(unpack_dir)
|
|
||||||
return unless DependencyCollector.tar_needs_xz_dependency?
|
|
||||||
return if (children = unpack_dir.children).count != 1
|
|
||||||
return if (tar = children.first).extname != ".tar"
|
|
||||||
|
|
||||||
Dir.mktmpdir do |tmpdir|
|
|
||||||
tmpdir = Pathname(tmpdir)
|
|
||||||
FileUtils.mv tar, tmpdir/tar.basename
|
|
||||||
TarUnpackStrategy.new(tmpdir/tar.basename).extract(to: unpack_dir)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Bzip2UnpackStrategy < UnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
magic_number.match?(/\ABZh/n)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
|
||||||
FileUtils.cp path, unpack_dir/basename, preserve: true
|
|
||||||
quiet_flags = verbose ? [] : ["-q"]
|
|
||||||
safe_system "bunzip2", *quiet_flags, unpack_dir/basename
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class GzipUnpackStrategy < UnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
magic_number.match?(/\A\037\213/n)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
|
||||||
FileUtils.cp path, unpack_dir/basename, preserve: true
|
|
||||||
quiet_flags = verbose ? [] : ["-q"]
|
|
||||||
safe_system "gunzip", *quiet_flags, "-N", unpack_dir/basename
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class LzipUnpackStrategy < UnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
magic_number.match?(/\ALZIP/n)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
|
||||||
FileUtils.cp path, unpack_dir/basename, preserve: true
|
|
||||||
quiet_flags = verbose ? [] : ["-q"]
|
|
||||||
safe_system Formula["lzip"].opt_bin/"lzip", "-d", *quiet_flags, unpack_dir/basename
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class XarUnpackStrategy < UnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
magic_number.match?(/\Axar!/n)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
|
||||||
safe_system "xar", "-x", "-f", path, "-C", unpack_dir
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class RarUnpackStrategy < UnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
magic_number.match?(/\ARar!/n)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
|
||||||
safe_system Formula["unrar"].opt_bin/"unrar", "x", "-inul", path, unpack_dir
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class LhaUnpackStrategy < UnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
magic_number.match?(/\A..-(lh0|lh1|lz4|lz5|lzs|lh\\40|lhd|lh2|lh3|lh4|lh5)-/n)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
|
||||||
safe_system Formula["lha"].opt_bin/"lha", "xq2w=#{unpack_dir}", path
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class GitUnpackStrategy < DirectoryUnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
super && (path/".git").directory?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class SubversionUnpackStrategy < DirectoryUnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
super && (path/".svn").directory?
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
|
||||||
safe_system "svn", "export", "--force", path, unpack_dir
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class CvsUnpackStrategy < DirectoryUnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
super && (path/"CVS").directory?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class MercurialUnpackStrategy < DirectoryUnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
super && (path/".hg").directory?
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
|
||||||
with_env "PATH" => PATH.new(Formula["mercurial"].opt_bin, ENV["PATH"]) do
|
|
||||||
safe_system "hg", "--cwd", path, "archive", "--subrepos", "-y", "-t", "files", unpack_dir
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class FossilUnpackStrategy < UnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
return false unless magic_number.match?(/\ASQLite format 3\000/n)
|
|
||||||
|
|
||||||
# Fossil database is made up of artifacts, so the `artifact` table must exist.
|
|
||||||
query = "select count(*) from sqlite_master where type = 'view' and name = 'artifact'"
|
|
||||||
Utils.popen_read("sqlite3", path, query).to_i == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
|
||||||
args = if @ref_type && @ref
|
|
||||||
[@ref]
|
|
||||||
else
|
|
||||||
[]
|
|
||||||
end
|
|
||||||
|
|
||||||
with_env "PATH" => PATH.new(Formula["fossil"].opt_bin, ENV["PATH"]) do
|
|
||||||
safe_system "fossil", "open", path, *args, chdir: unpack_dir
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class BazaarUnpackStrategy < DirectoryUnpackStrategy
|
|
||||||
def self.can_extract?(path:, magic_number:)
|
|
||||||
super && (path/".bzr").directory?
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
|
||||||
super
|
|
||||||
|
|
||||||
# The export command doesn't work on checkouts (see https://bugs.launchpad.net/bzr/+bug/897511).
|
|
||||||
FileUtils.rm_r unpack_dir/".bzr"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
18
Library/Homebrew/unpack_strategy/bazaar.rb
Normal file
18
Library/Homebrew/unpack_strategy/bazaar.rb
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
require_relative "directory"
|
||||||
|
|
||||||
|
module UnpackStrategy
|
||||||
|
class Bazaar < Directory
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
super && (path/".bzr").directory?
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
|
super
|
||||||
|
|
||||||
|
# The export command doesn't work on checkouts (see https://bugs.launchpad.net/bzr/+bug/897511).
|
||||||
|
FileUtils.rm_r unpack_dir/".bzr"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
17
Library/Homebrew/unpack_strategy/bzip2.rb
Normal file
17
Library/Homebrew/unpack_strategy/bzip2.rb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
module UnpackStrategy
|
||||||
|
class Bzip2
|
||||||
|
include UnpackStrategy
|
||||||
|
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
magic_number.match?(/\ABZh/n)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
|
FileUtils.cp path, unpack_dir/basename, preserve: true
|
||||||
|
quiet_flags = verbose ? [] : ["-q"]
|
||||||
|
safe_system "bunzip2", *quiet_flags, unpack_dir/basename
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
9
Library/Homebrew/unpack_strategy/compress.rb
Normal file
9
Library/Homebrew/unpack_strategy/compress.rb
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
require_relative "tar"
|
||||||
|
|
||||||
|
module UnpackStrategy
|
||||||
|
class Compress < Tar
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
magic_number.match?(/\A\037\235/n)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
9
Library/Homebrew/unpack_strategy/cvs.rb
Normal file
9
Library/Homebrew/unpack_strategy/cvs.rb
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
require_relative "directory"
|
||||||
|
|
||||||
|
module UnpackStrategy
|
||||||
|
class Cvs < Directory
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
super && (path/"CVS").directory?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
17
Library/Homebrew/unpack_strategy/directory.rb
Normal file
17
Library/Homebrew/unpack_strategy/directory.rb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
module UnpackStrategy
|
||||||
|
class Directory
|
||||||
|
include UnpackStrategy
|
||||||
|
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
path.directory?
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
|
path.children.each do |child|
|
||||||
|
FileUtils.copy_entry child, unpack_dir/child.basename, true, false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
27
Library/Homebrew/unpack_strategy/fossil.rb
Normal file
27
Library/Homebrew/unpack_strategy/fossil.rb
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
module UnpackStrategy
|
||||||
|
class Fossil
|
||||||
|
include UnpackStrategy
|
||||||
|
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
return false unless magic_number.match?(/\ASQLite format 3\000/n)
|
||||||
|
|
||||||
|
# Fossil database is made up of artifacts, so the `artifact` table must exist.
|
||||||
|
query = "select count(*) from sqlite_master where type = 'view' and name = 'artifact'"
|
||||||
|
Utils.popen_read("sqlite3", path, query).to_i == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
|
args = if @ref_type && @ref
|
||||||
|
[@ref]
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
|
with_env "PATH" => PATH.new(Formula["fossil"].opt_bin, ENV["PATH"]) do
|
||||||
|
safe_system "fossil", "open", path, *args, chdir: unpack_dir
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
9
Library/Homebrew/unpack_strategy/git.rb
Normal file
9
Library/Homebrew/unpack_strategy/git.rb
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
require_relative "directory"
|
||||||
|
|
||||||
|
module UnpackStrategy
|
||||||
|
class Git < Directory
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
super && (path/".git").directory?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
17
Library/Homebrew/unpack_strategy/gzip.rb
Normal file
17
Library/Homebrew/unpack_strategy/gzip.rb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
module UnpackStrategy
|
||||||
|
class Gzip
|
||||||
|
include UnpackStrategy
|
||||||
|
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
magic_number.match?(/\A\037\213/n)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
|
FileUtils.cp path, unpack_dir/basename, preserve: true
|
||||||
|
quiet_flags = verbose ? [] : ["-q"]
|
||||||
|
safe_system "gunzip", *quiet_flags, "-N", unpack_dir/basename
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
15
Library/Homebrew/unpack_strategy/jar.rb
Normal file
15
Library/Homebrew/unpack_strategy/jar.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
require_relative "uncompressed"
|
||||||
|
|
||||||
|
module UnpackStrategy
|
||||||
|
class Jar < Uncompressed
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
return false unless Zip.can_extract?(path: path, magic_number: magic_number)
|
||||||
|
|
||||||
|
# Check further if the ZIP is a JAR/WAR.
|
||||||
|
out, = Open3.capture3("zipinfo", "-1", path)
|
||||||
|
out.encode(Encoding::UTF_8, invalid: :replace)
|
||||||
|
.split("\n")
|
||||||
|
.include?("META-INF/MANIFEST.MF")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
19
Library/Homebrew/unpack_strategy/lha.rb
Normal file
19
Library/Homebrew/unpack_strategy/lha.rb
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
module UnpackStrategy
|
||||||
|
class Lha
|
||||||
|
include UnpackStrategy
|
||||||
|
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
magic_number.match?(/\A..-(lh0|lh1|lz4|lz5|lzs|lh\\40|lhd|lh2|lh3|lh4|lh5)-/n)
|
||||||
|
end
|
||||||
|
|
||||||
|
def dependencies
|
||||||
|
@dependencies ||= [Formula["lha"]]
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
|
safe_system Formula["lha"].opt_bin/"lha", "xq2w=#{unpack_dir}", path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
15
Library/Homebrew/unpack_strategy/lua_rock.rb
Normal file
15
Library/Homebrew/unpack_strategy/lua_rock.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
require_relative "uncompressed"
|
||||||
|
|
||||||
|
module UnpackStrategy
|
||||||
|
class LuaRock < Uncompressed
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
return false unless Zip.can_extract?(path: path, magic_number: magic_number)
|
||||||
|
|
||||||
|
# Check further if the ZIP is a LuaRocks package.
|
||||||
|
out, = Open3.capture3("zipinfo", "-1", path)
|
||||||
|
out.encode(Encoding::UTF_8, invalid: :replace)
|
||||||
|
.split("\n")
|
||||||
|
.any? { |line| line.match?(%r{\A[^/]+.rockspec\Z}) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
21
Library/Homebrew/unpack_strategy/lzip.rb
Normal file
21
Library/Homebrew/unpack_strategy/lzip.rb
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
module UnpackStrategy
|
||||||
|
class Lzip
|
||||||
|
include UnpackStrategy
|
||||||
|
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
magic_number.match?(/\ALZIP/n)
|
||||||
|
end
|
||||||
|
|
||||||
|
def dependencies
|
||||||
|
@dependencies ||= [Formula["lzip"]]
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
|
FileUtils.cp path, unpack_dir/basename, preserve: true
|
||||||
|
quiet_flags = verbose ? [] : ["-q"]
|
||||||
|
safe_system Formula["lzip"].opt_bin/"lzip", "-d", *quiet_flags, unpack_dir/basename
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
17
Library/Homebrew/unpack_strategy/mercurial.rb
Normal file
17
Library/Homebrew/unpack_strategy/mercurial.rb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
require_relative "directory"
|
||||||
|
|
||||||
|
module UnpackStrategy
|
||||||
|
class Mercurial < Directory
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
super && (path/".hg").directory?
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
|
with_env "PATH" => PATH.new(Formula["mercurial"].opt_bin, ENV["PATH"]) do
|
||||||
|
safe_system "hg", "--cwd", path, "archive", "--subrepos", "-y", "-t", "files", unpack_dir
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
13
Library/Homebrew/unpack_strategy/microsoft_office_xml.rb
Normal file
13
Library/Homebrew/unpack_strategy/microsoft_office_xml.rb
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
require_relative "uncompressed"
|
||||||
|
|
||||||
|
module UnpackStrategy
|
||||||
|
class MicrosoftOfficeXml < Uncompressed
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
return false unless Zip.can_extract?(path: path, magic_number: magic_number)
|
||||||
|
|
||||||
|
# Check further if the ZIP is a Microsoft Office XML document.
|
||||||
|
magic_number.match?(/\APK\003\004/n) &&
|
||||||
|
magic_number.match?(%r{\A.{30}(\[Content_Types\]\.xml|_rels/\.rels)}n)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
19
Library/Homebrew/unpack_strategy/p7zip.rb
Normal file
19
Library/Homebrew/unpack_strategy/p7zip.rb
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
module UnpackStrategy
|
||||||
|
class P7Zip
|
||||||
|
include UnpackStrategy
|
||||||
|
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
magic_number.match?(/\A7z\xBC\xAF\x27\x1C/n)
|
||||||
|
end
|
||||||
|
|
||||||
|
def dependencies
|
||||||
|
@dependencies ||= [Formula["p7zip"]]
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
|
safe_system "7zr", "x", "-y", "-bd", "-bso0", path, "-o#{unpack_dir}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
19
Library/Homebrew/unpack_strategy/rar.rb
Normal file
19
Library/Homebrew/unpack_strategy/rar.rb
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
module UnpackStrategy
|
||||||
|
class Rar
|
||||||
|
include UnpackStrategy
|
||||||
|
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
magic_number.match?(/\ARar!/n)
|
||||||
|
end
|
||||||
|
|
||||||
|
def dependencies
|
||||||
|
@dependencies ||= [Formula["unrar"]]
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
|
safe_system Formula["unrar"].opt_bin/"unrar", "x", "-inul", path, unpack_dir
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
15
Library/Homebrew/unpack_strategy/subversion.rb
Normal file
15
Library/Homebrew/unpack_strategy/subversion.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
require_relative "directory"
|
||||||
|
|
||||||
|
module UnpackStrategy
|
||||||
|
class Subversion < Directory
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
super && (path/".svn").directory?
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
|
safe_system "svn", "export", "--force", path, unpack_dir
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
20
Library/Homebrew/unpack_strategy/tar.rb
Normal file
20
Library/Homebrew/unpack_strategy/tar.rb
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
module UnpackStrategy
|
||||||
|
class Tar
|
||||||
|
include UnpackStrategy
|
||||||
|
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
return true if magic_number.match?(/\A.{257}ustar/n)
|
||||||
|
|
||||||
|
# Check if `tar` can list the contents, then it can also extract it.
|
||||||
|
IO.popen(["tar", "tf", path], err: File::NULL) do |stdout|
|
||||||
|
!stdout.read(1).nil?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
|
safe_system "tar", "xf", path, "-C", unpack_dir
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
13
Library/Homebrew/unpack_strategy/uncompressed.rb
Normal file
13
Library/Homebrew/unpack_strategy/uncompressed.rb
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
module UnpackStrategy
|
||||||
|
class Uncompressed
|
||||||
|
include UnpackStrategy
|
||||||
|
|
||||||
|
alias extract_nestedly extract
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
|
FileUtils.cp path, unpack_dir/basename, preserve: true, verbose: verbose
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
15
Library/Homebrew/unpack_strategy/xar.rb
Normal file
15
Library/Homebrew/unpack_strategy/xar.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
module UnpackStrategy
|
||||||
|
class Xar
|
||||||
|
include UnpackStrategy
|
||||||
|
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
magic_number.match?(/\Axar!/n)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
|
safe_system "xar", "-x", "-f", path, "-C", unpack_dir
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
34
Library/Homebrew/unpack_strategy/xz.rb
Normal file
34
Library/Homebrew/unpack_strategy/xz.rb
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
module UnpackStrategy
|
||||||
|
class Xz
|
||||||
|
include UnpackStrategy
|
||||||
|
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
magic_number.match?(/\A\xFD7zXZ\x00/n)
|
||||||
|
end
|
||||||
|
|
||||||
|
def dependencies
|
||||||
|
@dependencies ||= [Formula["xz"]]
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
|
FileUtils.cp path, unpack_dir/basename, preserve: true
|
||||||
|
quiet_flags = verbose ? [] : ["-q"]
|
||||||
|
safe_system Formula["xz"].opt_bin/"unxz", *quiet_flags, "-T0", unpack_dir/basename
|
||||||
|
extract_nested_tar(unpack_dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
def extract_nested_tar(unpack_dir)
|
||||||
|
return unless DependencyCollector.tar_needs_xz_dependency?
|
||||||
|
return if (children = unpack_dir.children).count != 1
|
||||||
|
return if (tar = children.first).extname != ".tar"
|
||||||
|
|
||||||
|
Dir.mktmpdir do |tmpdir|
|
||||||
|
tmpdir = Pathname(tmpdir)
|
||||||
|
FileUtils.mv tar, tmpdir/tar.basename
|
||||||
|
Tar.new(tmpdir/tar.basename).extract(to: unpack_dir)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
16
Library/Homebrew/unpack_strategy/zip.rb
Normal file
16
Library/Homebrew/unpack_strategy/zip.rb
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
module UnpackStrategy
|
||||||
|
class Zip
|
||||||
|
include UnpackStrategy
|
||||||
|
|
||||||
|
def self.can_extract?(path:, magic_number:)
|
||||||
|
magic_number.match?(/\APK(\003\004|\005\006)/n)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
|
quiet_flags = verbose ? [] : ["-qq"]
|
||||||
|
safe_system "unzip", *quiet_flags, path, "-d", unpack_dir
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user