ruzip 0.1.0 → 0.2.0
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.gitlab-ci.yml +1 -2
- data/.rdoc_options +9 -0
- data/CHANGELOG.md +6 -0
- data/README.md +21 -15
- data/Rakefile +4 -5
- data/ext/Cargo.lock +102 -220
- data/ext/Cargo.toml +4 -3
- data/ext/src/lib.rs +114 -100
- data/ruzip.gemspec +8 -5
- data/sig/ruzip.rbs +24 -2
- data/test/fixtures/.gitkeep +0 -0
- data/test/test_file.rb +8 -0
- data/test/test_package.rb +33 -0
- data/test/test_writer.rb +44 -0
- metadata +56 -20
- data/CODE_OF_CONDUCT.md +0 -84
- data/test/test_ruzip.rb +0 -7
data/ext/src/lib.rs
CHANGED
|
@@ -1,56 +1,22 @@
|
|
|
1
|
-
use magnus::{
|
|
2
|
-
|
|
3
|
-
};
|
|
1
|
+
use magnus::{Error, Integer, RString, Ruby, Value, class, function, method, prelude::*};
|
|
2
|
+
use std::cell::RefCell;
|
|
4
3
|
use std::fs;
|
|
5
|
-
use std::io::{
|
|
4
|
+
use std::io::{Read, Write};
|
|
6
5
|
use std::os::fd::FromRawFd;
|
|
7
6
|
use std::sync::{Arc, Mutex};
|
|
8
|
-
use zip::ZipArchive;
|
|
7
|
+
use zip::{ZipArchive, ZipWriter};
|
|
9
8
|
|
|
10
9
|
type Result<T> = std::result::Result<T, Error>;
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
struct IO(Value);
|
|
16
|
-
|
|
17
|
-
impl io::Read for IO {
|
|
18
|
-
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
|
19
|
-
let buf_len = buf.len();
|
|
20
|
-
let r_string: Value = self.0.funcall_public("read", (buf_len,)).unwrap(); // FIXME: unwrap(). Should use second arg?
|
|
21
|
-
if r_string.is_nil() {
|
|
22
|
-
Ok(0)
|
|
23
|
-
} else {
|
|
24
|
-
let data = r_string.to_string();
|
|
25
|
-
let len = data.len();
|
|
26
|
-
buf.clone_from_slice(data.as_bytes()); // FIXME: clone_from_slice panics when sizes of buf and data are not the same
|
|
27
|
-
Ok(len)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
11
|
+
fn map_err(err: impl std::error::Error, ruby: &Ruby) -> Error {
|
|
12
|
+
Error::new(ruby.exception_runtime_error(), format!("{}", err))
|
|
30
13
|
}
|
|
31
14
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
use io::SeekFrom::*;
|
|
35
|
-
let value = self.0;
|
|
36
|
-
|
|
37
|
-
match pos {
|
|
38
|
-
Start(i) => value
|
|
39
|
-
.funcall_public::<&str, (u64, Symbol), u64>("seek", (i, Symbol::new("SET")))
|
|
40
|
-
.unwrap(), // FIXME: unwrap()
|
|
41
|
-
End(i) => value
|
|
42
|
-
.funcall_public("seek", (i, Symbol::new("END")))
|
|
43
|
-
.unwrap(),
|
|
44
|
-
Current(i) => value
|
|
45
|
-
.funcall_public("seek", (i, Symbol::new("CUR")))
|
|
46
|
-
.unwrap(),
|
|
47
|
-
};
|
|
48
|
-
Ok(value.funcall_public("pos", ()).unwrap())
|
|
49
|
-
}
|
|
50
|
-
}
|
|
15
|
+
#[magnus::wrap(class = "RuZip::Archive", free_immediately, size)]
|
|
16
|
+
struct Archive(Arc<Mutex<ZipArchive<fs::File>>>);
|
|
51
17
|
|
|
52
18
|
impl Archive {
|
|
53
|
-
fn new(r_io: Value) -> Result<Self> {
|
|
19
|
+
fn new(ruby: &Ruby, r_io: Value) -> Result<Self> {
|
|
54
20
|
let io = if r_io.is_kind_of(class::io()) {
|
|
55
21
|
let fileno: Integer = r_io.funcall_public("fileno", ())?;
|
|
56
22
|
let raw_fd = fileno.to_i32()?;
|
|
@@ -60,58 +26,46 @@ impl Archive {
|
|
|
60
26
|
r_io.funcall_public::<&str, (), RString>("to_path", ())?
|
|
61
27
|
.to_string()?,
|
|
62
28
|
)
|
|
63
|
-
.
|
|
29
|
+
.map_err(|e| map_err(e, ruby))?
|
|
64
30
|
} else if r_io.respond_to("read", false)? {
|
|
65
31
|
// IO(r_io);
|
|
66
32
|
todo!("#read");
|
|
67
33
|
} else if r_io.is_kind_of(class::string()) {
|
|
68
|
-
fs::File::open(r_io.to_r_string()?.to_string()?).
|
|
34
|
+
fs::File::open(r_io.to_r_string()?.to_string()?).map_err(|e| map_err(e, ruby))?
|
|
69
35
|
} else {
|
|
70
36
|
return Err(Error::new(
|
|
71
|
-
|
|
37
|
+
ruby.exception_type_error(),
|
|
72
38
|
format!("Unsupported argument type: {}", r_io.inspect()),
|
|
73
39
|
));
|
|
74
40
|
};
|
|
75
|
-
let zip: ZipArchive<fs::File> = ZipArchive::new(io)
|
|
76
|
-
.map_err(|e| Error::new(exception::runtime_error(), format!("{}", e)))?;
|
|
41
|
+
let zip: ZipArchive<fs::File> = ZipArchive::new(io).map_err(|e| map_err(e, ruby))?;
|
|
77
42
|
Ok(Self(Arc::new(Mutex::new(zip))))
|
|
78
43
|
}
|
|
79
44
|
|
|
80
|
-
fn len(&
|
|
81
|
-
Ok(
|
|
82
|
-
.0
|
|
83
|
-
.lock()
|
|
84
|
-
.map_err(|e| Error::new(exception::runtime_error(), format!("{}", e)))?
|
|
85
|
-
.len())
|
|
45
|
+
fn len(ruby: &Ruby, rb_self: &Self) -> Result<usize> {
|
|
46
|
+
Ok(rb_self.0.lock().map_err(|e| map_err(e, ruby))?.len())
|
|
86
47
|
}
|
|
87
48
|
|
|
88
|
-
fn by_index(&
|
|
89
|
-
match
|
|
49
|
+
fn by_index(ruby: &Ruby, rb_self: &Self, index: usize) -> Result<File> {
|
|
50
|
+
match rb_self
|
|
90
51
|
.0
|
|
91
52
|
.lock()
|
|
92
|
-
.map_err(|e|
|
|
53
|
+
.map_err(|e| map_err(e, ruby))?
|
|
93
54
|
.by_index(index)
|
|
94
55
|
{
|
|
95
|
-
Ok(_) => Ok(File(
|
|
96
|
-
Err(e) => Err(
|
|
56
|
+
Ok(_) => Ok(File(rb_self.0.clone(), index)),
|
|
57
|
+
Err(e) => Err(map_err(e, ruby)),
|
|
97
58
|
}
|
|
98
59
|
}
|
|
99
60
|
|
|
100
|
-
fn by_name(&
|
|
101
|
-
let
|
|
102
|
-
|
|
103
|
-
.map_err(|e| Error::new(exception::runtime_error(), format!("{}", e)))?;
|
|
104
|
-
let mut archive = self
|
|
105
|
-
.0
|
|
106
|
-
.lock()
|
|
107
|
-
.map_err(|e| Error::new(exception::runtime_error(), format!("{}", e)))?;
|
|
61
|
+
fn by_name(ruby: &Ruby, rb_self: &Self, name: String) -> Result<Option<File>> {
|
|
62
|
+
let name_bytes = name.as_bytes();
|
|
63
|
+
let mut archive = rb_self.0.lock().map_err(|e| map_err(e, ruby))?;
|
|
108
64
|
// TODO: Cache entries
|
|
109
65
|
for i in 0..archive.len() {
|
|
110
|
-
let file = archive
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if file.name_raw() == name_string.clone().into_bytes() {
|
|
114
|
-
return Ok(Some(File(self.0.clone(), i)));
|
|
66
|
+
let file = archive.by_index(i).map_err(|e| map_err(e, ruby))?;
|
|
67
|
+
if file.name_raw() == name_bytes {
|
|
68
|
+
return Ok(Some(File(rb_self.0.clone(), i)));
|
|
115
69
|
}
|
|
116
70
|
}
|
|
117
71
|
Ok(None)
|
|
@@ -122,42 +76,42 @@ impl Archive {
|
|
|
122
76
|
struct File(Arc<Mutex<ZipArchive<fs::File>>>, usize);
|
|
123
77
|
|
|
124
78
|
impl File {
|
|
125
|
-
|
|
126
|
-
fn name(&self) -> Result<String> {
|
|
79
|
+
fn name(ruby: &Ruby, rb_self: &Self) -> Result<String> {
|
|
127
80
|
String::from_utf8(
|
|
128
|
-
|
|
81
|
+
rb_self
|
|
82
|
+
.0
|
|
129
83
|
.lock()
|
|
130
|
-
.map_err(|e|
|
|
131
|
-
.by_index(
|
|
132
|
-
.map_err(|e|
|
|
84
|
+
.map_err(|e| map_err(e, ruby))?
|
|
85
|
+
.by_index(rb_self.1)
|
|
86
|
+
.map_err(|e| map_err(e, ruby))?
|
|
133
87
|
.name_raw()
|
|
134
88
|
.into(),
|
|
135
89
|
)
|
|
136
|
-
.map_err(|e|
|
|
90
|
+
.map_err(|e| map_err(e, ruby))
|
|
137
91
|
}
|
|
138
92
|
|
|
139
|
-
fn size(&
|
|
140
|
-
let size =
|
|
93
|
+
fn size(ruby: &Ruby, rb_self: &Self) -> Result<u64> {
|
|
94
|
+
let size = rb_self
|
|
141
95
|
.0
|
|
142
96
|
.lock()
|
|
143
|
-
.map_err(|e|
|
|
144
|
-
.by_index(
|
|
145
|
-
.map_err(|e|
|
|
97
|
+
.map_err(|e| map_err(e, ruby))?
|
|
98
|
+
.by_index(rb_self.1)
|
|
99
|
+
.map_err(|e| map_err(e, ruby))?
|
|
146
100
|
.size();
|
|
147
101
|
Ok(size)
|
|
148
102
|
}
|
|
149
103
|
|
|
150
104
|
// TODO: Use ExtendedTimestamp if available
|
|
151
|
-
fn last_modified(&
|
|
152
|
-
let last_modified =
|
|
105
|
+
fn last_modified(ruby: &Ruby, rb_self: &Self) -> Result<Option<Value>> {
|
|
106
|
+
let last_modified = rb_self
|
|
153
107
|
.0
|
|
154
108
|
.lock()
|
|
155
|
-
.map_err(|e|
|
|
156
|
-
.by_index(
|
|
157
|
-
.map_err(|e|
|
|
109
|
+
.map_err(|e| map_err(e, ruby))?
|
|
110
|
+
.by_index(rb_self.1)
|
|
111
|
+
.map_err(|e| map_err(e, ruby))?
|
|
158
112
|
.last_modified();
|
|
159
113
|
match last_modified {
|
|
160
|
-
Some(mtime) => Ok(Some(
|
|
114
|
+
Some(mtime) => Ok(Some(ruby.class_time().new_instance((
|
|
161
115
|
mtime.year(),
|
|
162
116
|
mtime.month(),
|
|
163
117
|
mtime.day(),
|
|
@@ -169,16 +123,70 @@ impl File {
|
|
|
169
123
|
}
|
|
170
124
|
}
|
|
171
125
|
|
|
172
|
-
fn read(&
|
|
173
|
-
let mut
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
126
|
+
fn read(ruby: &Ruby, rb_self: &Self) -> Result<RString> {
|
|
127
|
+
let mut archive = rb_self.0.lock().map_err(|e| map_err(e, ruby))?;
|
|
128
|
+
let mut file = archive.by_index(rb_self.1).map_err(|e| map_err(e, ruby))?;
|
|
129
|
+
let mut buf = Vec::with_capacity(file.size() as usize);
|
|
130
|
+
file.read_to_end(&mut buf).map_err(|e| map_err(e, ruby))?;
|
|
131
|
+
Ok(RString::from_slice(&buf))
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
#[magnus::wrap(class = "RuZip::Writer", free_immediately, size)]
|
|
136
|
+
struct Writer(RefCell<Option<ZipWriter<fs::File>>>);
|
|
137
|
+
|
|
138
|
+
impl Writer {
|
|
139
|
+
fn new(ruby: &Ruby, path: String) -> Result<Self> {
|
|
140
|
+
let file = fs::File::create(path).map_err(|e| map_err(e, ruby))?;
|
|
141
|
+
let writer = ZipWriter::new(file);
|
|
142
|
+
Ok(Self(RefCell::new(Some(writer))))
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
fn finish(ruby: &Ruby, rb_self: &Self) -> Result<Archive> {
|
|
146
|
+
match rb_self.0.take() {
|
|
147
|
+
Some(writer) => {
|
|
148
|
+
let archive = writer
|
|
149
|
+
.finish_into_readable()
|
|
150
|
+
.map_err(|e| map_err(e, ruby))?;
|
|
151
|
+
Ok(Archive(Arc::new(Mutex::new(archive))))
|
|
152
|
+
}
|
|
153
|
+
None => Err(Error::new(
|
|
154
|
+
ruby.exception_runtime_error(),
|
|
155
|
+
"Already finished",
|
|
156
|
+
)),
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
fn start_file(ruby: &Ruby, rb_self: &Self, name: String) -> Result<()> {
|
|
161
|
+
match rb_self.0.take() {
|
|
162
|
+
Some(mut writer) => {
|
|
163
|
+
writer
|
|
164
|
+
.start_file(name, zip::write::SimpleFileOptions::default())
|
|
165
|
+
.map_err(|e| map_err(e, ruby))?;
|
|
166
|
+
rb_self.0.replace(Some(writer));
|
|
167
|
+
Ok(())
|
|
168
|
+
}
|
|
169
|
+
None => Err(Error::new(
|
|
170
|
+
ruby.exception_runtime_error(),
|
|
171
|
+
"Already finished",
|
|
172
|
+
)),
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
fn write(ruby: &Ruby, rb_self: &Self, buf: String) -> Result<()> {
|
|
177
|
+
match rb_self.0.take() {
|
|
178
|
+
Some(mut writer) => {
|
|
179
|
+
writer
|
|
180
|
+
.write_all(buf.as_bytes())
|
|
181
|
+
.map_err(|e| map_err(e, ruby))?;
|
|
182
|
+
rb_self.0.replace(Some(writer));
|
|
183
|
+
Ok(())
|
|
184
|
+
}
|
|
185
|
+
None => Err(Error::new(
|
|
186
|
+
ruby.exception_runtime_error(),
|
|
187
|
+
"Already finished",
|
|
188
|
+
)),
|
|
189
|
+
}
|
|
182
190
|
}
|
|
183
191
|
}
|
|
184
192
|
|
|
@@ -198,5 +206,11 @@ fn init(ruby: &Ruby) -> Result<()> {
|
|
|
198
206
|
file_class.define_method("last_modified", method!(File::last_modified, 0))?;
|
|
199
207
|
file_class.define_method("read", method!(File::read, 0))?;
|
|
200
208
|
|
|
209
|
+
let writer_class = module.define_class("Writer", ruby.class_object())?;
|
|
210
|
+
writer_class.define_singleton_method("new", function!(Writer::new, 1))?;
|
|
211
|
+
writer_class.define_method("finish", method!(Writer::finish, 0))?;
|
|
212
|
+
writer_class.define_method("start_file", method!(Writer::start_file, 1))?;
|
|
213
|
+
writer_class.define_method("write", method!(Writer::write, 1))?;
|
|
214
|
+
|
|
201
215
|
Ok(())
|
|
202
216
|
}
|
data/ruzip.gemspec
CHANGED
|
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
|
12
12
|
spec.description = "Library to support the reading and writing of zip files. A wrapper of Rust's zip crate."
|
|
13
13
|
spec.homepage = "https://gitlab.com/KitaitiMakoto/ruzip"
|
|
14
14
|
spec.license = "MIT"
|
|
15
|
-
spec.required_ruby_version = ">=
|
|
15
|
+
spec.required_ruby_version = ">= 3.1.0"
|
|
16
16
|
spec.required_rubygems_version = ">= 3.3.11"
|
|
17
17
|
|
|
18
18
|
spec.metadata["homepage_uri"] = spec.homepage
|
|
@@ -24,16 +24,19 @@ Gem::Specification.new do |spec|
|
|
|
24
24
|
spec.files = Dir.chdir(__dir__) do
|
|
25
25
|
`git ls-files -z`.split("\x0")
|
|
26
26
|
end
|
|
27
|
+
spec.test_files = spec.files.select {|file| file.start_with?("test/")}
|
|
27
28
|
spec.require_paths = ["lib"]
|
|
28
29
|
spec.extensions = ["ext/Cargo.toml"]
|
|
29
30
|
|
|
30
|
-
spec.add_development_dependency "rake"
|
|
31
|
-
spec.add_development_dependency "
|
|
32
|
-
spec.add_development_dependency "test-unit", "~> 3.0"
|
|
31
|
+
spec.add_development_dependency "rake"
|
|
32
|
+
spec.add_development_dependency "test-unit"
|
|
33
33
|
spec.add_development_dependency "test-unit-notify"
|
|
34
|
-
spec.add_development_dependency "terminal-notifier"
|
|
34
|
+
spec.add_development_dependency "terminal-notifier" if RUBY_PLATFORM.match?(/darwin/)
|
|
35
35
|
spec.add_development_dependency "rubygems-tasks"
|
|
36
36
|
spec.add_development_dependency "kar"
|
|
37
|
+
spec.add_development_dependency "rdoc"
|
|
38
|
+
spec.add_development_dependency "rbs"
|
|
39
|
+
spec.add_development_dependency "archive-zip"
|
|
37
40
|
|
|
38
41
|
# For more information and examples about making a new gem, check out our
|
|
39
42
|
# guide at: https://bundler.io/guides/creating_gem.html
|
data/sig/ruzip.rbs
CHANGED
|
@@ -1,4 +1,26 @@
|
|
|
1
1
|
module RuZip
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
class Archive
|
|
3
|
+
def self.new: (IO | path) -> instance
|
|
4
|
+
def len: -> Integer
|
|
5
|
+
def by_index: (Integer) -> File
|
|
6
|
+
def by_name: (String) -> File
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class File
|
|
10
|
+
def name: -> String
|
|
11
|
+
|
|
12
|
+
# The size of decompressed file
|
|
13
|
+
def size: -> Integer
|
|
14
|
+
def last_modified: -> (Time | nil)
|
|
15
|
+
|
|
16
|
+
# Reads contents and returns it as BINARY string
|
|
17
|
+
def read: -> String
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class Writer
|
|
21
|
+
def self.new: (String) -> instance
|
|
22
|
+
def finish: -> Archive
|
|
23
|
+
def start_file: (String) -> void
|
|
24
|
+
def write: (String) -> void
|
|
25
|
+
end
|
|
4
26
|
end
|
|
File without changes
|
data/test/test_file.rb
CHANGED
|
@@ -8,6 +8,14 @@ class TestFile < Test::Unit::TestCase
|
|
|
8
8
|
test "retrieve" do
|
|
9
9
|
file = @archive.by_name("META-INF/container.xml")
|
|
10
10
|
assert_instance_of RuZip::File, file
|
|
11
|
+
assert_equal <<XML.gsub(/\r\n/, "\n"), file.read.force_encoding('UTF-8').gsub(/\r\n/, "\n")
|
|
12
|
+
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
|
13
|
+
<container xmlns="urn:oasis:names:tc:opendocument:xmlns:container" version="1.0">
|
|
14
|
+
<rootfiles>
|
|
15
|
+
<rootfile full-path="EPUB/package.opf" media-type="application/oebps-package+xml"/>
|
|
16
|
+
</rootfiles>
|
|
17
|
+
</container>
|
|
18
|
+
XML
|
|
11
19
|
end
|
|
12
20
|
|
|
13
21
|
test "retrieve non-existent" do
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require "test/unit"
|
|
2
|
+
require "test/unit/notify"
|
|
3
|
+
require 'tempfile'
|
|
4
|
+
require 'tmpdir'
|
|
5
|
+
require 'shellwords'
|
|
6
|
+
|
|
7
|
+
class TestPackage < Test::Unit::TestCase
|
|
8
|
+
def test_build
|
|
9
|
+
Tempfile.create do |file|
|
|
10
|
+
assert system("gem", "build", "ruzip.gemspec", "--output", file.to_path, exception: true)
|
|
11
|
+
assert file.size > 0
|
|
12
|
+
assert_path_exist file.to_path
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def test_install
|
|
17
|
+
gemspec = Gem::Specification.load("ruzip.gemspec")
|
|
18
|
+
Dir.mktmpdir do |dir|
|
|
19
|
+
dir = File.realpath(dir)
|
|
20
|
+
gemfile = File.join(dir, gemspec.file_name)
|
|
21
|
+
system "gem", "build", "ruzip.gemspec", "--output", gemfile, exception: true
|
|
22
|
+
install_dir = File.join(dir, "install")
|
|
23
|
+
FileUtils.mkdir install_dir
|
|
24
|
+
|
|
25
|
+
env = {
|
|
26
|
+
"BUNDLE_GEMFILE" => nil,
|
|
27
|
+
"RUBYOPT" => nil
|
|
28
|
+
}
|
|
29
|
+
system env, "gem", "install", "--install-dir", install_dir, "--no-document", gemfile, exception: true
|
|
30
|
+
assert_path_exist File.join(install_dir, "gems", gemspec.full_name, "lib", "ruzip.#{RbConfig::CONFIG["DLEXT"]}")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
data/test/test_writer.rb
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require_relative "helper"
|
|
2
|
+
require "tmpdir"
|
|
3
|
+
require "archive/zip"
|
|
4
|
+
|
|
5
|
+
class TestWriter < Test::Unit::TestCase
|
|
6
|
+
test "new with path" do
|
|
7
|
+
Dir.mktmpdir do |dir|
|
|
8
|
+
path = File.join(dir, "output.zip")
|
|
9
|
+
writer = RuZip::Writer.new(path)
|
|
10
|
+
assert_kind_of RuZip::Writer, writer
|
|
11
|
+
assert_path_exist path
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
test "finish" do
|
|
16
|
+
Dir.mktmpdir do |dir|
|
|
17
|
+
path = File.join(dir, "output.zip")
|
|
18
|
+
writer = RuZip::Writer.new(path)
|
|
19
|
+
archive = writer.finish
|
|
20
|
+
assert_instance_of RuZip::Archive, archive
|
|
21
|
+
assert_raise do
|
|
22
|
+
writer.finish
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
test "add file" do
|
|
28
|
+
Dir.mktmpdir do |dir|
|
|
29
|
+
path = File.join(dir, "output.zip")
|
|
30
|
+
writer = RuZip::Writer.new(path)
|
|
31
|
+
inner_path = "hello.txt"
|
|
32
|
+
writer.start_file(inner_path)
|
|
33
|
+
content = "Hello, World!"
|
|
34
|
+
writer.write content
|
|
35
|
+
writer.finish
|
|
36
|
+
|
|
37
|
+
Archive::Zip.open path do |archive|
|
|
38
|
+
file = archive.each.first
|
|
39
|
+
assert_equal inner_path, file.zip_path
|
|
40
|
+
assert_equal content, file.file_data.read(content.length)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruzip
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kitaiti Makoto
|
|
@@ -13,18 +13,18 @@ dependencies:
|
|
|
13
13
|
name: rake
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
|
-
- - "
|
|
16
|
+
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '
|
|
18
|
+
version: '0'
|
|
19
19
|
type: :development
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
|
-
- - "
|
|
23
|
+
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: '
|
|
25
|
+
version: '0'
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
|
-
name:
|
|
27
|
+
name: test-unit
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
30
|
- - ">="
|
|
@@ -38,21 +38,21 @@ dependencies:
|
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
39
|
version: '0'
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
|
-
name: test-unit
|
|
41
|
+
name: test-unit-notify
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
43
43
|
requirements:
|
|
44
|
-
- - "
|
|
44
|
+
- - ">="
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: '
|
|
46
|
+
version: '0'
|
|
47
47
|
type: :development
|
|
48
48
|
prerelease: false
|
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
|
-
- - "
|
|
51
|
+
- - ">="
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: '
|
|
53
|
+
version: '0'
|
|
54
54
|
- !ruby/object:Gem::Dependency
|
|
55
|
-
name:
|
|
55
|
+
name: terminal-notifier
|
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
|
57
57
|
requirements:
|
|
58
58
|
- - ">="
|
|
@@ -66,7 +66,7 @@ dependencies:
|
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
67
|
version: '0'
|
|
68
68
|
- !ruby/object:Gem::Dependency
|
|
69
|
-
name:
|
|
69
|
+
name: rubygems-tasks
|
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
|
71
71
|
requirements:
|
|
72
72
|
- - ">="
|
|
@@ -80,7 +80,7 @@ dependencies:
|
|
|
80
80
|
- !ruby/object:Gem::Version
|
|
81
81
|
version: '0'
|
|
82
82
|
- !ruby/object:Gem::Dependency
|
|
83
|
-
name:
|
|
83
|
+
name: kar
|
|
84
84
|
requirement: !ruby/object:Gem::Requirement
|
|
85
85
|
requirements:
|
|
86
86
|
- - ">="
|
|
@@ -94,7 +94,35 @@ dependencies:
|
|
|
94
94
|
- !ruby/object:Gem::Version
|
|
95
95
|
version: '0'
|
|
96
96
|
- !ruby/object:Gem::Dependency
|
|
97
|
-
name:
|
|
97
|
+
name: rdoc
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - ">="
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: rbs
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - ">="
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '0'
|
|
117
|
+
type: :development
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - ">="
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '0'
|
|
124
|
+
- !ruby/object:Gem::Dependency
|
|
125
|
+
name: archive-zip
|
|
98
126
|
requirement: !ruby/object:Gem::Requirement
|
|
99
127
|
requirements:
|
|
100
128
|
- - ">="
|
|
@@ -118,8 +146,8 @@ extra_rdoc_files: []
|
|
|
118
146
|
files:
|
|
119
147
|
- ".gitignore"
|
|
120
148
|
- ".gitlab-ci.yml"
|
|
149
|
+
- ".rdoc_options"
|
|
121
150
|
- CHANGELOG.md
|
|
122
|
-
- CODE_OF_CONDUCT.md
|
|
123
151
|
- Gemfile
|
|
124
152
|
- MIT-LICENSE
|
|
125
153
|
- README.md
|
|
@@ -129,10 +157,12 @@ files:
|
|
|
129
157
|
- ext/src/lib.rs
|
|
130
158
|
- ruzip.gemspec
|
|
131
159
|
- sig/ruzip.rbs
|
|
160
|
+
- test/fixtures/.gitkeep
|
|
132
161
|
- test/helper.rb
|
|
133
162
|
- test/test_archive.rb
|
|
134
163
|
- test/test_file.rb
|
|
135
|
-
- test/
|
|
164
|
+
- test/test_package.rb
|
|
165
|
+
- test/test_writer.rb
|
|
136
166
|
homepage: https://gitlab.com/KitaitiMakoto/ruzip
|
|
137
167
|
licenses:
|
|
138
168
|
- MIT
|
|
@@ -147,14 +177,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
147
177
|
requirements:
|
|
148
178
|
- - ">="
|
|
149
179
|
- !ruby/object:Gem::Version
|
|
150
|
-
version:
|
|
180
|
+
version: 3.1.0
|
|
151
181
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
152
182
|
requirements:
|
|
153
183
|
- - ">="
|
|
154
184
|
- !ruby/object:Gem::Version
|
|
155
185
|
version: 3.3.11
|
|
156
186
|
requirements: []
|
|
157
|
-
rubygems_version:
|
|
187
|
+
rubygems_version: 4.0.3
|
|
158
188
|
specification_version: 4
|
|
159
189
|
summary: Library to support the reading and writing of zip files.
|
|
160
|
-
test_files:
|
|
190
|
+
test_files:
|
|
191
|
+
- test/fixtures/.gitkeep
|
|
192
|
+
- test/helper.rb
|
|
193
|
+
- test/test_archive.rb
|
|
194
|
+
- test/test_file.rb
|
|
195
|
+
- test/test_package.rb
|
|
196
|
+
- test/test_writer.rb
|