archive 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 03fd0b29dfe98ee0c8545cb831b85d56b62cf0f9
4
+ data.tar.gz: 7063adf82e2d6338c486670d91a87176d5b28d70
5
+ SHA512:
6
+ metadata.gz: 180d415f4639a31f50e2f90320e7c3af03bd3bad1495420a234d80064358e9f1f4176ebd76d8508c73b5dd1c4d19757570bd66e498628cd37e9b6699494d399f
7
+ data.tar.gz: 7d45612e9ee2e07b240a0c0b2008ff2ae7fd291fa7443c0f65a82fe2e716421ca366c4a5a367ca0b19b2fb188247277711460456a12500487dd93d82b68cacc4
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in archive.gemspec
4
+ gemspec
@@ -0,0 +1,10 @@
1
+ # vim: ft=ruby
2
+ guard 'minitest' do
3
+ # with Minitest::Unit
4
+ watch(%r!^test/(.*)\/?test_(.*)\.rb!)
5
+ watch(%r!^test/helper\.rb!) { "test" }
6
+ end
7
+
8
+ guard 'rake', :run_on_all => false, :task => 'rdoc_cov' do
9
+ watch(%r!^lib/(.*)([^/]+)\.rb!)
10
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Erik Hollensbe
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,88 @@
1
+ # Archive
2
+
3
+ Archive is a simple and effective way to utilize libarchive, the slicing,
4
+ dicing, all-in-one BSD archiving toolkit. It keeps it simple by only handling a
5
+ common subset of archive types:
6
+
7
+ * tar
8
+ * uncompressed
9
+ * gzipped
10
+ * bzip2'd
11
+ * zip (uncompressed, binary-only)
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ gem 'archive'
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install archive
26
+
27
+ You will also need a copy of 'libarchive'. This comes with some operating
28
+ systems (OS X, mingw builds on windows) and others you have to use your package
29
+ manager to install them. It is not required to install the gem, but to use it.
30
+
31
+ You will also need a compiler to install FFI.
32
+
33
+ ## Usage
34
+
35
+ ```ruby
36
+ # stuff the contents of $HOME in /tmp/tmp.tar.gz
37
+ Archive.compress("/tmp/tmp.tar.gz", ENV["HOME"])
38
+ # same thing, only a zip file
39
+ Archive.compress("/tmp/tmp.zip", ENV["HOME"], :type => :zip)
40
+ # now bzip2
41
+ Archive.compress("/tmp/tmp.tar.bz2", ENV["HOME"], :type => :tar, :compression => :bzip2)
42
+
43
+ # OOP interface:
44
+ ac = Archive::Compress.new("/tmp/my_files.tar.gz", :type => :tar, :compression => :gzip)
45
+ ac.compress(["some", "files"])
46
+
47
+ # let's extract those files
48
+ require 'fileutils'
49
+ FileUtils.mkdir_p("/tmp/woot")
50
+ # this works for any kind of archive we support -- no need to express which
51
+ # type
52
+ Archive.extract("/tmp/tmp.tar.gz", "/tmp/woot")
53
+
54
+ # OOP interface:
55
+ ae = Archive::Extract.new("/tmp/tmp.tar.gz", "/tmp/woot")
56
+ ae.extract
57
+ ```
58
+
59
+ ## Testing
60
+
61
+ Tests do not come with the gem because of file sizes of the archives and test
62
+ data in the repository.
63
+
64
+ Tests require bundler. Run `bundle exec rake test` to run the tests.
65
+
66
+ We have verified that archive works as intended on these platforms:
67
+
68
+ * Mac OS X 10.8
69
+ * Ubuntu Linux 12.04 LTS
70
+
71
+ And these Rubies:
72
+
73
+ * 1.9.3
74
+ * 2.0.0
75
+ * JRuby 1.7 with Java 7
76
+
77
+ Please let us know if your operating system isn't working! It'll likely
78
+ complain about a call called `stat` which varies wildly on different POSIX
79
+ systems. We just need to know what platform you're on and how we can install it
80
+ ourselves to move forward. Thanks!
81
+
82
+ ## Contributing
83
+
84
+ 1. Fork it
85
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
86
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
87
+ 4. Push to the branch (`git push origin my-new-feature`)
88
+ 5. Create new Pull Request
@@ -0,0 +1,32 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+ require 'rdoc/task'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << "test"
7
+ t.test_files = FileList["test/test_*.rb"]
8
+ t.verbose = true
9
+ end
10
+
11
+ RDoc::Task.new do |rdoc|
12
+ rdoc.title = "Simple library to manage tar and zip archives with libarchive and FFI"
13
+ rdoc.main = "README.md"
14
+ rdoc.rdoc_files.include("README.md", "lib/**/*.rb")
15
+ rdoc.rdoc_files -= ["lib/archive/version.rb"]
16
+ if ENV["RDOC_COVER"]
17
+ rdoc.options << "-C"
18
+ end
19
+ end
20
+
21
+ desc "run tests with coverage report"
22
+ task "test:coverage" do
23
+ ENV["COVERAGE"] = "1"
24
+ Rake::Task["test"].invoke
25
+ end
26
+
27
+ desc "run rdoc with coverage report"
28
+ task :rdoc_cov do
29
+ # ugh
30
+ ENV["RDOC_COVER"] = "1"
31
+ ruby "-S rake rerdoc"
32
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'archive/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "archive"
8
+ spec.version = Archive::VERSION
9
+ spec.authors = ["Erik Hollensbe"]
10
+ spec.email = ["erik+github@hollensbe.org"]
11
+ spec.description = %q{Simple library to manage tar and zip archives with libarchive and FFI}
12
+ spec.summary = %q{Simple library to manage tar and zip archives with libarchive and FFI}
13
+ spec.homepage = "https://github.com/erikh/archive"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/).reject { |f| File.dirname(f) =~ /^test/ }
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = []
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'ffi', '~> 1.8.1'
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency 'minitest'
26
+ spec.add_development_dependency 'guard-minitest'
27
+ spec.add_development_dependency 'guard-rake', '~> 0.0.8'
28
+ spec.add_development_dependency 'rdoc', '~> 4.0'
29
+ spec.add_development_dependency 'rb-fsevent'
30
+ spec.add_development_dependency 'simplecov'
31
+ end
@@ -0,0 +1,79 @@
1
+ require 'archive/version'
2
+ require 'archive/libarchive'
3
+ require 'archive/extract'
4
+ require 'archive/compress'
5
+
6
+ #
7
+ # Archive is a small library to leverage the FreeBSD project's libarchive to
8
+ # unpack tarballs and zip files.
9
+ #
10
+ # See the helper methods in this module, or Archive::Extract and
11
+ # Archive::Compress if you want an OOP interface.
12
+ #
13
+ module Archive
14
+
15
+ #
16
+ # Extract a file into a directory. The default directory is the current
17
+ # directory.
18
+ #
19
+ # Format and compression will be auto-detected.
20
+ #
21
+ # See Archive::Extract for more information.
22
+ #
23
+ def self.extract(filename, dir=Dir.pwd)
24
+ Archive::Extract.new(filename, dir).extract
25
+ end
26
+
27
+ #
28
+ # Just like ::extract, but prints the filenames extracted to stdout.
29
+ #
30
+ def self.extract_and_print(filename, dir=Dir.pwd)
31
+ Archive::Extract.new(filename, dir).extract(true)
32
+ end
33
+
34
+ #
35
+ # Compress a directory's files into the filename provided. The default
36
+ # directory is the current directory.
37
+ #
38
+ # args is a hash that contains two values, :type and :compression.
39
+ #
40
+ # * :type may be :tar or :zip
41
+ # * :compression may be :gzip, :bzip2, or nil (no compression)
42
+ #
43
+ # If the type :zip is selected, no compression will be used. Additionally,
44
+ # files in the .zip will all be stored as binary files.
45
+ #
46
+ # No files in your directory that are not *real files* will be added to the
47
+ # archive.
48
+ #
49
+ # See Archive::Compress for more information, and a way to compress just the
50
+ # files you want.
51
+ #
52
+ def self.compress(filename, dir=Dir.pwd, args={ :type => :tar, :compression => :gzip })
53
+ Archive::Compress.new(filename, args).compress(get_files(dir))
54
+ end
55
+
56
+ #
57
+ # Similar to ::compress, but outputs the files it's compressing.
58
+ #
59
+ def self.compress_and_print(filename, dir=Dir.pwd, args={ :type => :tar, :compression => :gzip })
60
+ Archive::Compress.new(filename, args).compress(get_files(dir), true)
61
+ end
62
+
63
+ protected
64
+
65
+ #
66
+ # Finds the files for the dir passed to ::compress.
67
+ #
68
+ def self.get_files(dir)
69
+ require 'find'
70
+
71
+ files = []
72
+
73
+ Find.find(dir) do |path|
74
+ files.push(path) if File.file?(path)
75
+ end
76
+
77
+ return files
78
+ end
79
+ end
@@ -0,0 +1,126 @@
1
+ require 'pathname'
2
+
3
+ module Archive # :nodoc:
4
+ #
5
+ # Compression OOP interface for Archive. See ::new and #compress for more information.
6
+ #
7
+ class Compress
8
+ # the filename of the compressed archive
9
+ attr_reader :filename
10
+ # the type of the archive. See ::new.
11
+ attr_reader :type
12
+ # the compression type of the archive. See ::new.
13
+ attr_reader :compression
14
+
15
+ # The buffer size for reading content.
16
+ BUFSIZE = 32767
17
+
18
+ #
19
+ # Create a new Compress object. Takes a filename as string, and args as
20
+ # hash.
21
+ #
22
+ # args is a hash that contains two values, :type and :compression.
23
+ #
24
+ # * :type may be :tar or :zip
25
+ # * :compression may be :gzip, :bzip2, or nil (no compression)
26
+ #
27
+ # If the type :zip is selected, no compression will be used. Additionally,
28
+ # files in the .zip will all be stored as binary files.
29
+ #
30
+ # The default set of arguments is
31
+ #
32
+ # { :type => :tar, :compression => :gzip }
33
+ #
34
+ def initialize(filename, args={ :type => :tar, :compression => :gzip })
35
+ @filename = filename
36
+ @type = args[:type] || :tar
37
+ @compression = args[:compression]
38
+
39
+ if type == :zip
40
+ @compression = nil
41
+ end
42
+ end
43
+
44
+ #
45
+ # Run the compression. Files are an array of filenames. Optional flag for
46
+ # verbosity; if true, will print each file it adds to the archive to
47
+ # stdout.
48
+ #
49
+ # Files must be real files. No symlinks, directories, unix sockets,
50
+ # character devices, etc. This method will raise ArgumentError if you
51
+ # provide any.
52
+ #
53
+ def compress(files, verbose=false)
54
+ if files.any? { |f| !File.file?(f) }
55
+ raise ArgumentError, "Files supplied must all be real, actual files -- not directories or symlinks."
56
+ end
57
+
58
+ configure_archive
59
+ compress_files(files, verbose)
60
+ free_archive
61
+ end
62
+
63
+ protected
64
+
65
+ def configure_archive # :nodoc:
66
+ @archive = LibArchive.archive_write_new
67
+ LibArchive.enable_output_compression(@archive, @compression)
68
+ LibArchive.enable_output_archive(@archive, @type)
69
+
70
+ result = LibArchive.archive_write_open_filename(@archive, @filename)
71
+ if result != LibArchive::ARCHIVE_OK
72
+ raise LibArchive.archive_error_string(@archive)
73
+ end
74
+
75
+ @disk = LibArchive.archive_read_disk_new
76
+ LibArchive.archive_read_disk_set_standard_lookup(@disk)
77
+ end
78
+
79
+ def compress_files(files, verbose) # :nodoc:
80
+ buff = FFI::Buffer.new BUFSIZE
81
+
82
+ # truncate our archive, this solves a few issues.
83
+ File.open(filename, 'w').close
84
+
85
+ files.reject { |f| Pathname.new(f).realpath == Pathname.new(filename).realpath }.each do |file|
86
+ # TODO return value maybe?
87
+ puts file if verbose
88
+
89
+ stat = FFI::MemoryPointer.new Stat, 1, true
90
+ entry = LibArchive.archive_entry_new
91
+
92
+ LibArchive.archive_entry_set_pathname(entry, file)
93
+ result = LibArchive.stat(File.join(Dir.pwd, file), stat)
94
+
95
+ if result != 0
96
+ raise "Error while calling stat(): #{LibArchive.strerror(FFI.errno)}"
97
+ end
98
+
99
+ LibArchive.archive_read_disk_entry_from_file(@disk, entry, -1, stat)
100
+
101
+ result = LibArchive.archive_write_header(@archive, entry)
102
+
103
+ if result != LibArchive::ARCHIVE_OK
104
+ raise "archive error: #{LibArchive.archive_error_string(@archive)}"
105
+ end
106
+
107
+ File.open(file, 'r') do |f|
108
+ loop do
109
+ len = FFI::IO.native_read(f, buff, BUFSIZE)
110
+ LibArchive.archive_write_data(@archive, buff, len)
111
+ break if f.eof?
112
+ end
113
+ end
114
+
115
+ LibArchive.archive_entry_free(entry)
116
+ end
117
+ end
118
+
119
+ def free_archive # :nodoc:
120
+ LibArchive.archive_read_close(@disk)
121
+ LibArchive.archive_read_free(@disk)
122
+ LibArchive.archive_write_close(@archive)
123
+ LibArchive.archive_write_free(@archive)
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,125 @@
1
+ module Archive # :nodoc:
2
+ #
3
+ # Extraction OOP interface for Archive. See ::new and #extract for more information.
4
+ #
5
+ class Extract
6
+
7
+ # The filename of the compressed archive. See ::new.
8
+ attr_reader :filename
9
+ # The extraction directory target. See ::new.
10
+ attr_reader :dir
11
+
12
+ #
13
+ # Create a new Extract object. Takes a filename as string containing the
14
+ # archive name, and a directory name as string containing the target path
15
+ # to extract to. The default target is the current directory.
16
+ #
17
+ # If either the filename or directory name do not already exist,
18
+ # ArgumentError will be raised.
19
+ #
20
+ # Extraction tries to preserve timestamps and permissions, but not uid/gid.
21
+ # Note that this is format-dependent -- e.g., .zip files will always be
22
+ # extracted as mode 0777.
23
+ #
24
+ def initialize(filename, dir=Dir.pwd)
25
+ unless File.exist?(filename)
26
+ raise ArgumentError, "File '#{filename}' does not exist!"
27
+ end
28
+
29
+ unless File.directory?(dir)
30
+ raise ArgumentError, "Directory '#{dir}' does not exist!"
31
+ end
32
+
33
+ @filename = filename
34
+ @dir = dir
35
+
36
+ @extract_flags =
37
+ LibArchive::ARCHIVE_EXTRACT_PERM |
38
+ LibArchive::ARCHIVE_EXTRACT_TIME
39
+ end
40
+
41
+ #
42
+ # Perform the extraction. Takes an optional value that when true prints
43
+ # each filename extracted to stdout.
44
+ #
45
+ def extract(verbose=false)
46
+ create_io_objects
47
+ open_file
48
+
49
+ header_loop(verbose)
50
+
51
+ close
52
+ end
53
+
54
+ protected
55
+
56
+ def create_io_objects # :nodoc:
57
+ @in = LibArchive.archive_read_new
58
+ @out = LibArchive.archive_write_disk_new
59
+ LibArchive.archive_write_disk_set_options(@out, @extract_flags)
60
+ @entry = FFI::MemoryPointer.new :pointer
61
+ LibArchive.enable_input_formats(@in)
62
+ end
63
+
64
+ def open_file # :nodoc:
65
+ LibArchive.archive_read_open_filename(@in, @filename, 10240)
66
+ end
67
+
68
+ def header_loop(verbose) # :nodoc:
69
+ while ((result = LibArchive.archive_read_next_header(@in, @entry)) != LibArchive::ARCHIVE_EOF)
70
+
71
+ if result != LibArchive::ARCHIVE_OK
72
+ raise LibArchive.archive_error_string(@in)
73
+ end
74
+
75
+ entry_pointer = @entry.get_pointer(0)
76
+
77
+ full_path = File.join(@dir, LibArchive.archive_entry_pathname(entry_pointer))
78
+ LibArchive.archive_entry_set_pathname(entry_pointer, full_path)
79
+
80
+ # TODO return value maybe?
81
+ puts LibArchive.archive_entry_pathname(entry_pointer) if verbose
82
+
83
+ if ((result = LibArchive.archive_write_header(@out, entry_pointer)) != LibArchive::ARCHIVE_OK)
84
+ raise LibArchive.archive_error_string(@out)
85
+ end
86
+
87
+ unpack_loop
88
+
89
+ LibArchive.archive_write_finish_entry(@out)
90
+ end
91
+ end
92
+
93
+ def unpack_loop # :nodoc:
94
+ loop do
95
+ buffer = FFI::MemoryPointer.new :pointer, 1
96
+ size = FFI::MemoryPointer.new :size_t
97
+ offset = FFI::MemoryPointer.new :long_long
98
+
99
+ result = LibArchive.archive_read_data_block(@in, buffer, size, offset)
100
+
101
+ break if result == LibArchive::ARCHIVE_EOF
102
+
103
+ unless result == LibArchive::ARCHIVE_OK
104
+ raise LibArchive.archive_error_string(@in)
105
+ end
106
+
107
+ result = LibArchive.archive_write_data_block(@out, buffer.get_pointer(0), size.read_ulong_long, offset.read_long_long);
108
+
109
+ if result != LibArchive::ARCHIVE_OK
110
+ raise LibArchive.archive_error_string(@out)
111
+ end
112
+ end
113
+ end
114
+
115
+ def close # :nodoc:
116
+ LibArchive.archive_read_close(@in)
117
+ LibArchive.archive_read_free(@in)
118
+ LibArchive.archive_write_close(@out)
119
+ LibArchive.archive_write_free(@out)
120
+ @in = nil
121
+ @out = nil
122
+ @entry = nil
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,202 @@
1
+ require 'ffi'
2
+
3
+ module Archive # :nodoc:
4
+ class Stat < ::FFI::Struct # :nodoc:
5
+ #--
6
+ # this is necessary to pass rdoc's coverage tests
7
+ #++
8
+ module FFI # :nodoc:
9
+ end
10
+ class Timespec < ::FFI::Struct
11
+ layout :tv_sec, :long,
12
+ :tv_nsec, :long
13
+ end
14
+
15
+ if ::FFI::Platform.mac?
16
+ layout(
17
+ :st_dev, :dev_t,
18
+ :st_mode, :mode_t,
19
+ :st_nlink, :nlink_t,
20
+ :st_ino, :ino_t,
21
+ :st_uid, :uid_t,
22
+ :st_gid, :gid_t,
23
+ :st_rdev, :dev_t,
24
+ :st_atimespec, Timespec,
25
+ :st_mtimespec, Timespec,
26
+ :st_ctimespec, Timespec,
27
+ :st_birthtimespec, Timespec,
28
+ :st_size, :off_t,
29
+ :st_blocks, :quad_t,
30
+ :st_blksize, :ulong,
31
+ :st_flags, :ulong,
32
+ :st_gen, :ulong,
33
+ :st_lspare, :long,
34
+ :st_qspare, :long_long
35
+ )
36
+ else
37
+ layout(
38
+ :st_dev, :dev_t,
39
+ :st_ino, :ino_t,
40
+ :st_mode, :mode_t,
41
+ :st_nlink, :nlink_t,
42
+ :st_uid, :uid_t,
43
+ :st_gid, :gid_t,
44
+ :st_rdev, :dev_t,
45
+ :st_atimespec, Timespec,
46
+ :st_mtimespec, Timespec,
47
+ :st_ctimespec, Timespec,
48
+ :st_size, :off_t,
49
+ :st_blocks, :quad_t,
50
+ :st_blksize, :ulong,
51
+ :st_flags, :ulong,
52
+ :st_gen, :ulong
53
+ )
54
+ end
55
+ end
56
+ module LibArchive # :nodoc:
57
+ #--
58
+ # this is necessary to pass rdoc's coverage tests
59
+ #++
60
+ module FFI # :nodoc:
61
+ module Library # :nodoc:
62
+ end
63
+ end
64
+
65
+ extend ::FFI::Library # :nodoc:
66
+
67
+ #
68
+ # needed by archiving entry functions
69
+ #
70
+ ffi_lib ::FFI::Library::LIBC
71
+
72
+ attach_function :strerror, [:int], :string
73
+
74
+ if ::FFI::Platform.mac?
75
+ attach_function :stat64, [:string, :pointer], :int
76
+ def self.stat(*args) # :nodoc:
77
+ stat64(*args)
78
+ end
79
+ elsif RbConfig::CONFIG['host_os'] =~ /linux/
80
+ attach_function :__xstat, [:int, :string, :pointer], :int
81
+ def self.stat(*args) # :nodoc:
82
+ __xstat(0, *args)
83
+ end
84
+ else
85
+ attach_function :stat, [:string, :pointer], :int
86
+ end
87
+
88
+ ffi_lib 'archive'
89
+
90
+ ARCHIVE_OK = 0 # :nodoc:
91
+ ARCHIVE_EOF = 1 # :nodoc:
92
+ ARCHIVE_RETRY = -10 # :nodoc:
93
+ ARCHIVE_WARN = -20 # :nodoc:
94
+ ARCHIVE_FAILED = -25 # :nodoc:
95
+ ARCHIVE_FATAL = -30 # :nodoc:
96
+
97
+ ARCHIVE_EXTRACT_OWNER = 0x0001 # :nodoc:
98
+ ARCHIVE_EXTRACT_PERM = 0x0002 # :nodoc:
99
+ ARCHIVE_EXTRACT_TIME = 0x0004 # :nodoc:
100
+
101
+ attach_function :archive_read_new, [], :pointer
102
+ attach_function :archive_read_disk_new, [], :pointer
103
+ attach_function :archive_read_disk_set_standard_lookup, [:pointer], :void
104
+ attach_function :archive_write_new, [], :pointer
105
+ attach_function :archive_write_disk_new, [], :pointer
106
+ attach_function :archive_write_disk_set_options, [:pointer, :int], :void
107
+ attach_function :archive_read_support_format_tar, [:pointer], :void
108
+ attach_function :archive_read_support_format_gnutar, [:pointer], :void
109
+ attach_function :archive_read_support_format_zip, [:pointer], :void
110
+
111
+ def self.enable_input_formats(arg) # :nodoc:
112
+ archive_read_support_format_gnutar(arg)
113
+ archive_read_support_format_zip(arg)
114
+ archive_read_support_format_zip(arg)
115
+ enable_input_compression(arg)
116
+ end
117
+
118
+ attach_function :archive_write_set_format_ustar, [:pointer], :void
119
+ attach_function :archive_write_set_format_zip, [:pointer], :void
120
+
121
+ def self.enable_output_archive(arg, type=:tar)
122
+ case type
123
+ when :tar
124
+ archive_write_set_format_ustar(arg)
125
+ when :zip
126
+ archive_write_set_format_zip(arg)
127
+ end
128
+ end
129
+
130
+ begin
131
+ attach_function :archive_read_support_filter_all, [:pointer], :void
132
+ def self.enable_input_compression(arg) # :nodoc:
133
+ archive_read_support_filter_all(arg)
134
+ end
135
+ rescue ::FFI::NotFoundError
136
+ attach_function :archive_read_support_compression_all, [:pointer], :void
137
+ def self.enable_input_compression(arg) # :nodoc:
138
+ archive_read_support_compression_all(arg)
139
+ end
140
+ end
141
+
142
+ begin
143
+ attach_function :archive_write_add_filter_gzip, [:pointer], :void
144
+ attach_function :archive_write_add_filter_bzip2, [:pointer], :void
145
+ def self.enable_output_compression(arg, type=:gzip) # :nodoc:
146
+ case type
147
+ when :gzip
148
+ archive_write_add_filter_gzip(arg)
149
+ when :bzip2
150
+ archive_write_add_filter_bzip2(arg)
151
+ end
152
+ end
153
+ rescue ::FFI::NotFoundError
154
+ attach_function :archive_write_set_compression_gzip, [:pointer], :void
155
+ attach_function :archive_write_set_compression_bzip2, [:pointer], :void
156
+ def self.enable_output_compression(arg, type=:gzip) # :nodoc:
157
+ case type
158
+ when :gzip
159
+ archive_write_set_compression_gzip(arg)
160
+ when :bzip2
161
+ archive_write_set_compression_bzip2(arg)
162
+ end
163
+ end
164
+ end
165
+
166
+ attach_function :archive_read_open_filename, [:pointer, :string, :size_t], :int
167
+ attach_function :archive_write_open_filename, [:pointer, :string], :int
168
+
169
+ attach_function :archive_entry_new, [], :pointer
170
+ attach_function :archive_entry_free, [:pointer], :void
171
+ attach_function :archive_read_disk_entry_from_file, [:pointer, :pointer, :int, :pointer], :int
172
+
173
+ attach_function :archive_error_string, [:pointer], :string
174
+ attach_function :archive_read_next_header, [:pointer, :pointer], :int
175
+ attach_function :archive_write_header, [:pointer, :pointer], :int
176
+ attach_function :archive_write_finish_entry, [:pointer], :int
177
+ attach_function :archive_read_close, [:pointer], :void
178
+ attach_function :archive_write_close, [:pointer], :void
179
+
180
+ begin
181
+ attach_function :archive_read_free, [:pointer], :void
182
+ attach_function :archive_write_free, [:pointer], :void
183
+ rescue ::FFI::NotFoundError
184
+ attach_function :archive_read_finish, [:pointer], :void
185
+ def self.archive_read_free(arg) # :nodoc:
186
+ archive_read_finish(arg)
187
+ end
188
+
189
+ attach_function :archive_write_finish, [:pointer], :void
190
+ def self.archive_write_free(arg) # :nodoc:
191
+ archive_write_finish(arg)
192
+ end
193
+ end
194
+
195
+ attach_function :archive_read_data_block, [:pointer, :pointer, :pointer, :pointer], :int
196
+ attach_function :archive_write_data_block, [:pointer, :pointer, :size_t, :long_long], :int
197
+ attach_function :archive_write_data, [:pointer, :pointer, :size_t], :void
198
+
199
+ attach_function :archive_entry_pathname, [:pointer], :string
200
+ attach_function :archive_entry_set_pathname, [:pointer, :string], :void
201
+ end
202
+ end
@@ -0,0 +1,3 @@
1
+ module Archive
2
+ VERSION = "0.0.1"
3
+ end
data/test.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'archive'
2
+
3
+ Dir.chdir("test/data")
4
+ Archive.compress_and_print("test.tar.gz", "libarchive")
metadata ADDED
@@ -0,0 +1,183 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: archive
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Erik Hollensbe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-04-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 1.8.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 1.8.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: guard-rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 0.0.8
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: 0.0.8
97
+ - !ruby/object:Gem::Dependency
98
+ name: rdoc
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '4.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '4.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rb-fsevent
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: simplecov
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: Simple library to manage tar and zip archives with libarchive and FFI
140
+ email:
141
+ - erik+github@hollensbe.org
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - .gitignore
147
+ - Gemfile
148
+ - Guardfile
149
+ - LICENSE.txt
150
+ - README.md
151
+ - Rakefile
152
+ - archive.gemspec
153
+ - lib/archive.rb
154
+ - lib/archive/compress.rb
155
+ - lib/archive/extract.rb
156
+ - lib/archive/libarchive.rb
157
+ - lib/archive/version.rb
158
+ - test.rb
159
+ homepage: https://github.com/erikh/archive
160
+ licenses:
161
+ - MIT
162
+ metadata: {}
163
+ post_install_message:
164
+ rdoc_options: []
165
+ require_paths:
166
+ - lib
167
+ required_ruby_version: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - '>='
170
+ - !ruby/object:Gem::Version
171
+ version: '0'
172
+ required_rubygems_version: !ruby/object:Gem::Requirement
173
+ requirements:
174
+ - - '>='
175
+ - !ruby/object:Gem::Version
176
+ version: '0'
177
+ requirements: []
178
+ rubyforge_project:
179
+ rubygems_version: 2.0.3
180
+ signing_key:
181
+ specification_version: 4
182
+ summary: Simple library to manage tar and zip archives with libarchive and FFI
183
+ test_files: []