excavate 0.2.4 → 0.3.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.
- checksums.yaml +4 -4
- data/.github/workflows/metanorma.yml +76 -0
- data/.github/workflows/test-and-release.yml +69 -0
- data/Gemfile +1 -1
- data/README.adoc +27 -0
- data/excavate.gemspec +1 -2
- data/lib/excavate/archive.rb +139 -10
- data/lib/excavate/cli.rb +38 -9
- data/lib/excavate/extractors/ole_extractor.rb +2 -0
- data/lib/excavate/version.rb +1 -1
- data/lib/excavate.rb +6 -1
- metadata +8 -8
- data/.github/workflows/release.yml +0 -36
- data/.github/workflows/rspec.yml +0 -47
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b66a3e8ff5083bd78711cff8289e18f958578d84fea44be53dcd4f5349508755
|
|
4
|
+
data.tar.gz: 1c65ff305ed20893b27470063280f60698d9920db597d42af8e75127c947784a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: feac4007753c19cb52d9f32432f96ab2a2cf6553556cb950ad15f210a0e8f3d0209622b81702e17d4a9fef3e975b42f7f97178d7d55dfc914731245093a159f0
|
|
7
|
+
data.tar.gz: 93bed15a89d5f620e45232f9de42afde7efaabc7e79734617c8443f2324858a6a97e6b9e40995ee18ad5bce4d36ea1ac584b238d257accf567e88472ea0fd991
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
name: metanorma
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: '${{ github.workflow }}-${{ github.job }}-${{ github.head_ref || github.ref_name }}'
|
|
10
|
+
cancel-in-progress: true
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
prepare:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
outputs:
|
|
16
|
+
head_tag: ${{ steps.check.outputs.head_tag }}
|
|
17
|
+
foreign_pr: ${{ steps.check.outputs.foreign_pr }}
|
|
18
|
+
steps:
|
|
19
|
+
- name: Checkout
|
|
20
|
+
uses: actions/checkout@v2.3.4
|
|
21
|
+
|
|
22
|
+
- name: Retrieve tags
|
|
23
|
+
run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* || true
|
|
24
|
+
- name: Set output variables
|
|
25
|
+
id: check
|
|
26
|
+
run: |
|
|
27
|
+
fpr="no"
|
|
28
|
+
tag=""
|
|
29
|
+
if [[ "${{ github.ref }}" == refs/heads/* ]]; then
|
|
30
|
+
tag="$(git tag --points-at HEAD)"
|
|
31
|
+
elif [[ "${{ github.ref }}" == refs/pull/* ]] && [ "${{ github.event.pull_request.head.repo.full_name }}" != "${{ github.event.pull_request.base.repo.full_name }}" ]; then
|
|
32
|
+
fpr="yes"
|
|
33
|
+
fi
|
|
34
|
+
echo "::set-output name=foreign_pr::${fpr}"
|
|
35
|
+
echo "::set-output name=head_tag::${tag}"
|
|
36
|
+
|
|
37
|
+
test:
|
|
38
|
+
name: Test with Metanorma on Ruby ${{ matrix.ruby }} ${{ matrix.os }}
|
|
39
|
+
needs: prepare
|
|
40
|
+
runs-on: ${{ matrix.os }}
|
|
41
|
+
continue-on-error: false
|
|
42
|
+
strategy:
|
|
43
|
+
fail-fast: false
|
|
44
|
+
matrix:
|
|
45
|
+
ruby: [ '2.7', '3.0', '3.1' ]
|
|
46
|
+
os: [ ubuntu-latest, windows-latest, macos-latest ]
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/checkout@v3
|
|
49
|
+
with:
|
|
50
|
+
repository: metanorma/metanorma
|
|
51
|
+
|
|
52
|
+
- uses: metanorma/metanorma-build-scripts/inkscape-setup-action@main
|
|
53
|
+
|
|
54
|
+
- uses: actions/checkout@v3
|
|
55
|
+
with:
|
|
56
|
+
path: "excavate"
|
|
57
|
+
|
|
58
|
+
- run: 'echo ''gem "excavate", path: "./excavate"'' > Gemfile.devel'
|
|
59
|
+
|
|
60
|
+
- if: matrix.ruby == '3.0'
|
|
61
|
+
uses: ruby/setup-ruby@v1
|
|
62
|
+
with:
|
|
63
|
+
ruby-version: ${{ matrix.ruby }}
|
|
64
|
+
bundler-cache: false
|
|
65
|
+
rubygems: latest
|
|
66
|
+
|
|
67
|
+
- if: matrix.ruby == '3.0'
|
|
68
|
+
run: bundle
|
|
69
|
+
|
|
70
|
+
- if: matrix.ruby != '3.0'
|
|
71
|
+
uses: ruby/setup-ruby@v1
|
|
72
|
+
with:
|
|
73
|
+
ruby-version: ${{ matrix.ruby }}
|
|
74
|
+
bundler-cache: true
|
|
75
|
+
|
|
76
|
+
- run: bundle exec rake
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
name: test-and-release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
tags: [ 'v*' ]
|
|
7
|
+
pull_request:
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: '${{ github.workflow }}-${{ github.job }}-${{ github.head_ref || github.ref_name }}'
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
prepare:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
outputs:
|
|
17
|
+
head_tag: ${{ steps.check.outputs.head_tag }}
|
|
18
|
+
foreign_pr: ${{ steps.check.outputs.foreign_pr }}
|
|
19
|
+
steps:
|
|
20
|
+
- name: Checkout
|
|
21
|
+
uses: actions/checkout@v2.3.4
|
|
22
|
+
|
|
23
|
+
- name: Retrieve tags
|
|
24
|
+
run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* || true
|
|
25
|
+
- name: Set output variables
|
|
26
|
+
id: check
|
|
27
|
+
run: |
|
|
28
|
+
fpr="no"
|
|
29
|
+
tag=""
|
|
30
|
+
if [[ "${{ github.ref }}" == refs/heads/* ]]; then
|
|
31
|
+
tag="$(git tag --points-at HEAD)"
|
|
32
|
+
elif [[ "${{ github.ref }}" == refs/pull/* ]] && [ "${{ github.event.pull_request.head.repo.full_name }}" != "${{ github.event.pull_request.base.repo.full_name }}" ]; then
|
|
33
|
+
fpr="yes"
|
|
34
|
+
fi
|
|
35
|
+
echo "::set-output name=foreign_pr::${fpr}"
|
|
36
|
+
echo "::set-output name=head_tag::${tag}"
|
|
37
|
+
|
|
38
|
+
test:
|
|
39
|
+
name: Test on Ruby ${{ matrix.ruby }} ${{ matrix.os }}
|
|
40
|
+
needs: prepare
|
|
41
|
+
runs-on: ${{ matrix.os }}
|
|
42
|
+
continue-on-error: false
|
|
43
|
+
strategy:
|
|
44
|
+
fail-fast: false
|
|
45
|
+
matrix:
|
|
46
|
+
ruby: [ '2.6', '2.7', '3.0', '3.1' ]
|
|
47
|
+
os: [ ubuntu-latest, windows-latest, macos-latest ]
|
|
48
|
+
|
|
49
|
+
steps:
|
|
50
|
+
- uses: actions/checkout@v3
|
|
51
|
+
|
|
52
|
+
- uses: ruby/setup-ruby@v1
|
|
53
|
+
with:
|
|
54
|
+
ruby-version: ${{ matrix.ruby }}
|
|
55
|
+
bundler-cache: true
|
|
56
|
+
|
|
57
|
+
- run: bundle exec rspec
|
|
58
|
+
|
|
59
|
+
release:
|
|
60
|
+
name: Release gem
|
|
61
|
+
needs: test
|
|
62
|
+
runs-on: ubuntu-latest
|
|
63
|
+
if: contains(github.ref, 'refs/tags/v')
|
|
64
|
+
steps:
|
|
65
|
+
- uses: actions/checkout@v3
|
|
66
|
+
|
|
67
|
+
- uses: cadwallion/publish-rubygems-action@master
|
|
68
|
+
env:
|
|
69
|
+
RUBYGEMS_API_KEY: ${{secrets.FONTIST_CI_RUBYGEMS_API_KEY}}
|
data/Gemfile
CHANGED
data/README.adoc
CHANGED
|
@@ -61,6 +61,13 @@ end
|
|
|
61
61
|
$ excavate --recursive path/to/archive.cab
|
|
62
62
|
----
|
|
63
63
|
|
|
64
|
+
It supports recursive extraction of a directory containing archives:
|
|
65
|
+
|
|
66
|
+
[source,sh]
|
|
67
|
+
----
|
|
68
|
+
$ excavate --recursive path/to/dir_with_archives
|
|
69
|
+
----
|
|
70
|
+
|
|
64
71
|
If you'd like to skip extraction of nested archives, just use:
|
|
65
72
|
|
|
66
73
|
[source,sh]
|
|
@@ -68,6 +75,26 @@ If you'd like to skip extraction of nested archives, just use:
|
|
|
68
75
|
$ excavate path/to/archive.cab
|
|
69
76
|
----
|
|
70
77
|
|
|
78
|
+
To extract a particular file or files specify them as last arguments:
|
|
79
|
+
|
|
80
|
+
[source,sh]
|
|
81
|
+
----
|
|
82
|
+
$ excavate --recursive archive.cab file1 dir/file2
|
|
83
|
+
----
|
|
84
|
+
|
|
85
|
+
Also `excavate` supports extraction from nested archives:
|
|
86
|
+
|
|
87
|
+
[source,sh]
|
|
88
|
+
----
|
|
89
|
+
$ excavate --recursive archive.cab dir/nested.zip/file
|
|
90
|
+
----
|
|
91
|
+
|
|
92
|
+
And filtering:
|
|
93
|
+
|
|
94
|
+
[source,sh]
|
|
95
|
+
----
|
|
96
|
+
$ excavate archive.cab --filter "**/specialfile*.txt"
|
|
97
|
+
----
|
|
71
98
|
|
|
72
99
|
== Dependencies
|
|
73
100
|
|
data/excavate.gemspec
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
|
|
3
2
|
require_relative "lib/excavate/version"
|
|
4
3
|
|
|
5
4
|
Gem::Specification.new do |spec|
|
|
@@ -31,6 +30,6 @@ Gem::Specification.new do |spec|
|
|
|
31
30
|
spec.add_runtime_dependency "libmspack", "~> 0.1"
|
|
32
31
|
spec.add_runtime_dependency "ruby-ole", "~> 1.0"
|
|
33
32
|
spec.add_runtime_dependency "rubyzip", "~> 2.3"
|
|
34
|
-
spec.add_runtime_dependency "
|
|
33
|
+
spec.add_runtime_dependency "seven-zip", "~> 1.4"
|
|
35
34
|
spec.add_runtime_dependency "thor", "~> 1.0"
|
|
36
35
|
end
|
data/lib/excavate/archive.rb
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
module Excavate
|
|
2
2
|
class Archive
|
|
3
|
+
INVALID_MEMORY_MESSAGE =
|
|
4
|
+
"invalid memory read at address=0x0000000000000000".freeze
|
|
5
|
+
|
|
3
6
|
TYPES = { "cab" => Extractors::CabExtractor,
|
|
4
7
|
"cpio" => Extractors::CpioExtractor,
|
|
5
8
|
"exe" => Extractors::SevenZipExtractor,
|
|
@@ -14,9 +17,10 @@ module Excavate
|
|
|
14
17
|
@archive = archive
|
|
15
18
|
end
|
|
16
19
|
|
|
17
|
-
def files(recursive_packages: false)
|
|
20
|
+
def files(recursive_packages: false, files: [], filter: nil)
|
|
18
21
|
target = Dir.mktmpdir
|
|
19
|
-
extract(target, recursive_packages: recursive_packages
|
|
22
|
+
extract(target, recursive_packages: recursive_packages,
|
|
23
|
+
files: files, filter: filter)
|
|
20
24
|
|
|
21
25
|
all_files_in(target).map do |file|
|
|
22
26
|
yield file
|
|
@@ -25,10 +29,105 @@ module Excavate
|
|
|
25
29
|
FileUtils.rm_rf(target)
|
|
26
30
|
end
|
|
27
31
|
|
|
28
|
-
def extract(target = nil,
|
|
32
|
+
def extract(target = nil,
|
|
33
|
+
recursive_packages: false,
|
|
34
|
+
files: [],
|
|
35
|
+
filter: nil)
|
|
36
|
+
if files.size.positive?
|
|
37
|
+
extract_particular_files(target, files,
|
|
38
|
+
recursive_packages: recursive_packages)
|
|
39
|
+
elsif filter
|
|
40
|
+
extract_by_filter(target, filter,
|
|
41
|
+
recursive_packages: recursive_packages)
|
|
42
|
+
else
|
|
43
|
+
extract_all(target, recursive_packages: recursive_packages)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def extract_particular_files(target, files, recursive_packages: false)
|
|
50
|
+
tmp = Dir.mktmpdir
|
|
51
|
+
extract_all(tmp, recursive_packages: recursive_packages)
|
|
52
|
+
found_files = find_files(tmp, files)
|
|
53
|
+
copy_files(found_files, target || Dir.pwd)
|
|
54
|
+
ensure
|
|
55
|
+
FileUtils.rm_rf(tmp)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def copy_files(files, target)
|
|
59
|
+
files.map do |file|
|
|
60
|
+
FileUtils.mkdir_p(target)
|
|
61
|
+
target_path = File.join(target, File.basename(file))
|
|
62
|
+
ensure_not_exist(target_path)
|
|
63
|
+
|
|
64
|
+
FileUtils.cp(file, target_path)
|
|
65
|
+
|
|
66
|
+
target_path
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def ensure_not_exist(path)
|
|
71
|
+
if File.exist?(path)
|
|
72
|
+
type = File.directory?(path) ? "directory" : "file"
|
|
73
|
+
raise(TargetExistsError,
|
|
74
|
+
"Target #{type} `#{File.basename(path)}` already exists.")
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def find_files(source, files)
|
|
79
|
+
all_files = all_files_in(source)
|
|
80
|
+
|
|
81
|
+
files.map do |target_file|
|
|
82
|
+
found_file = all_files.find do |source_file|
|
|
83
|
+
file_matches?(source_file, target_file, source)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
unless found_file
|
|
87
|
+
raise(TargetNotFoundError, "File `#{target_file}` not found.")
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
found_file
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def file_matches?(source_file, target_file, source_dir)
|
|
95
|
+
base_path(source_file, source_dir) == target_file
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def base_path(path, prefix)
|
|
99
|
+
path.sub(prefix, "").sub(/^\//, "").sub(/^\\/, "")
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def extract_by_filter(target, filter, recursive_packages: false)
|
|
103
|
+
tmp = Dir.mktmpdir
|
|
104
|
+
extract_all(tmp, recursive_packages: recursive_packages)
|
|
105
|
+
found_files = find_by_filter(tmp, filter)
|
|
106
|
+
copy_files(found_files, target || Dir.pwd)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def find_by_filter(source, filter)
|
|
110
|
+
all_files = all_files_in(source)
|
|
111
|
+
|
|
112
|
+
found_files = all_files.select do |source_file|
|
|
113
|
+
file_matches_filter?(source_file, filter, source)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
if found_files.empty?
|
|
117
|
+
raise(TargetNotFoundError, "Filter `#{filter}` matched no file.")
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
found_files
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def file_matches_filter?(source_file, filter, source_dir)
|
|
124
|
+
File.fnmatch?(filter, base_path(source_file, source_dir))
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def extract_all(target, recursive_packages: false)
|
|
29
128
|
source = File.expand_path(@archive)
|
|
30
129
|
target ||= default_target(source)
|
|
31
|
-
|
|
130
|
+
ensure_empty(target)
|
|
32
131
|
|
|
33
132
|
if recursive_packages
|
|
34
133
|
extract_recursively(source, target)
|
|
@@ -39,11 +138,16 @@ module Excavate
|
|
|
39
138
|
target
|
|
40
139
|
end
|
|
41
140
|
|
|
42
|
-
|
|
141
|
+
def ensure_empty(path)
|
|
142
|
+
unless Dir.empty?(path)
|
|
143
|
+
raise(TargetNotEmptyError,
|
|
144
|
+
"Target directory `#{File.basename(path)}` is not empty.")
|
|
145
|
+
end
|
|
146
|
+
end
|
|
43
147
|
|
|
44
148
|
def default_target(source)
|
|
45
149
|
target = File.expand_path(File.basename(source, ".*"))
|
|
46
|
-
|
|
150
|
+
ensure_not_exist(target)
|
|
47
151
|
|
|
48
152
|
FileUtils.mkdir(target)
|
|
49
153
|
|
|
@@ -51,7 +155,7 @@ module Excavate
|
|
|
51
155
|
end
|
|
52
156
|
|
|
53
157
|
def extract_recursively(archive, target)
|
|
54
|
-
|
|
158
|
+
extract_to_directory(archive, target)
|
|
55
159
|
|
|
56
160
|
all_files_in(target).each do |file|
|
|
57
161
|
next unless archive?(file)
|
|
@@ -60,14 +164,39 @@ module Excavate
|
|
|
60
164
|
end
|
|
61
165
|
end
|
|
62
166
|
|
|
167
|
+
def extract_to_directory(archive, target)
|
|
168
|
+
if File.directory?(archive)
|
|
169
|
+
duplicate_dir(archive, target)
|
|
170
|
+
elsif !archive?(archive)
|
|
171
|
+
copy_file(archive, target)
|
|
172
|
+
else
|
|
173
|
+
extract_once(archive, target)
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def duplicate_dir(source, target)
|
|
178
|
+
Dir.chdir(source) do
|
|
179
|
+
(Dir.entries(".") - [".", ".."]).each do |entry|
|
|
180
|
+
FileUtils.cp_r(entry, target)
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def copy_file(archive, target)
|
|
186
|
+
FileUtils.cp(archive, target)
|
|
187
|
+
end
|
|
188
|
+
|
|
63
189
|
def extract_once(archive, target)
|
|
64
190
|
extension = normalized_extension(archive)
|
|
65
191
|
extractor_class = TYPES[extension]
|
|
66
|
-
|
|
192
|
+
unless extractor_class
|
|
193
|
+
raise(UnknownArchiveError, "Could not unarchive `#{archive}`.")
|
|
194
|
+
end
|
|
67
195
|
|
|
68
196
|
extractor_class.new(archive).extract(target)
|
|
69
197
|
rescue StandardError => e
|
|
70
|
-
raise unless extension == "exe" &&
|
|
198
|
+
raise unless extension == "exe" &&
|
|
199
|
+
e.message.start_with?("Invalid file format")
|
|
71
200
|
|
|
72
201
|
Extractors::CabExtractor.new(archive).extract(target)
|
|
73
202
|
end
|
|
@@ -81,7 +210,7 @@ module Excavate
|
|
|
81
210
|
rescue FFI::NullPointerError => e
|
|
82
211
|
FileUtils.rmdir(target)
|
|
83
212
|
raise unless normalized_extension(archive) == "exe" &&
|
|
84
|
-
e.message.start_with?(
|
|
213
|
+
e.message.start_with?(INVALID_MEMORY_MESSAGE)
|
|
85
214
|
end
|
|
86
215
|
|
|
87
216
|
def normalized_extension(file)
|
data/lib/excavate/cli.rb
CHANGED
|
@@ -8,6 +8,13 @@ module Excavate
|
|
|
8
8
|
STATUS_UNKNOWN_ERROR = 1
|
|
9
9
|
STATUS_TARGET_EXISTS = 2
|
|
10
10
|
STATUS_TARGET_NOT_EMPTY = 3
|
|
11
|
+
STATUS_TARGET_NOT_FOUND = 4
|
|
12
|
+
|
|
13
|
+
ERROR_TO_STATUS = {
|
|
14
|
+
TargetExistsError => STATUS_TARGET_EXISTS,
|
|
15
|
+
TargetNotEmptyError => STATUS_TARGET_NOT_EMPTY,
|
|
16
|
+
TargetNotFoundError => STATUS_TARGET_NOT_FOUND,
|
|
17
|
+
}.freeze
|
|
11
18
|
|
|
12
19
|
def self.exit_on_failure?
|
|
13
20
|
false
|
|
@@ -23,15 +30,22 @@ module Excavate
|
|
|
23
30
|
super(args, config)
|
|
24
31
|
end
|
|
25
32
|
|
|
26
|
-
desc "extract ARCHIVE",
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
desc "extract ARCHIVE [FILE...]",
|
|
34
|
+
"Extract FILE or all files from ARCHIVE to a new directory"
|
|
35
|
+
option :recursive, aliases: :r, type: :boolean, default: false,
|
|
36
|
+
desc: "Also extract all nested archives."
|
|
37
|
+
option :filter, type: :string,
|
|
38
|
+
desc: "Filter by pattern (supports **, *, ?, etc)"
|
|
39
|
+
def extract(archive, *files)
|
|
40
|
+
target = Excavate::Archive.new(archive).extract(
|
|
41
|
+
recursive_packages: options[:recursive],
|
|
42
|
+
files: files,
|
|
43
|
+
filter: options[:filter],
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
success("Successfully extracted to #{format_paths(target)}")
|
|
47
|
+
rescue Error => e
|
|
48
|
+
handle_error(e)
|
|
35
49
|
end
|
|
36
50
|
default_task :extract
|
|
37
51
|
|
|
@@ -42,9 +56,24 @@ module Excavate
|
|
|
42
56
|
STATUS_SUCCESS
|
|
43
57
|
end
|
|
44
58
|
|
|
59
|
+
def handle_error(exception)
|
|
60
|
+
status = ERROR_TO_STATUS[exception.class]
|
|
61
|
+
raise exception unless status
|
|
62
|
+
|
|
63
|
+
error(exception.message, status)
|
|
64
|
+
end
|
|
65
|
+
|
|
45
66
|
def error(message, status)
|
|
46
67
|
say(message, :red)
|
|
47
68
|
status
|
|
48
69
|
end
|
|
70
|
+
|
|
71
|
+
def format_paths(path_or_paths)
|
|
72
|
+
paths = Array(path_or_paths).map do |x|
|
|
73
|
+
File.directory?(x) ? "#{File.basename(x)}/" : File.basename(x)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
paths.join(", ")
|
|
77
|
+
end
|
|
49
78
|
end
|
|
50
79
|
end
|
data/lib/excavate/version.rb
CHANGED
data/lib/excavate.rb
CHANGED
|
@@ -8,7 +8,12 @@ require_relative "excavate/utils"
|
|
|
8
8
|
|
|
9
9
|
module Excavate
|
|
10
10
|
class Error < StandardError; end
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
class TargetExistsError < Error; end
|
|
13
|
+
|
|
13
14
|
class TargetNotEmptyError < Error; end
|
|
15
|
+
|
|
16
|
+
class TargetNotFoundError < Error; end
|
|
17
|
+
|
|
18
|
+
class UnknownArchiveError < Error; end
|
|
14
19
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: excavate
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-08-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: arr-pm
|
|
@@ -81,19 +81,19 @@ dependencies:
|
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '2.3'
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
84
|
+
name: seven-zip
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
87
|
- - "~>"
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '1.
|
|
89
|
+
version: '1.4'
|
|
90
90
|
type: :runtime
|
|
91
91
|
prerelease: false
|
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
94
|
- - "~>"
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '1.
|
|
96
|
+
version: '1.4'
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
98
|
name: thor
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -116,8 +116,8 @@ executables:
|
|
|
116
116
|
extensions: []
|
|
117
117
|
extra_rdoc_files: []
|
|
118
118
|
files:
|
|
119
|
-
- ".github/workflows/
|
|
120
|
-
- ".github/workflows/
|
|
119
|
+
- ".github/workflows/metanorma.yml"
|
|
120
|
+
- ".github/workflows/test-and-release.yml"
|
|
121
121
|
- ".gitignore"
|
|
122
122
|
- ".rspec"
|
|
123
123
|
- ".rubocop.yml"
|
|
@@ -168,7 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
168
168
|
- !ruby/object:Gem::Version
|
|
169
169
|
version: '0'
|
|
170
170
|
requirements: []
|
|
171
|
-
rubygems_version: 3.
|
|
171
|
+
rubygems_version: 3.3.7
|
|
172
172
|
signing_key:
|
|
173
173
|
specification_version: 4
|
|
174
174
|
summary: Extract nested archives with a single command.
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
name: release
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- 'v*'
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
release:
|
|
10
|
-
runs-on: ubuntu-18.04
|
|
11
|
-
steps:
|
|
12
|
-
- uses: actions/checkout@v1
|
|
13
|
-
|
|
14
|
-
- uses: ruby/setup-ruby@v1
|
|
15
|
-
with:
|
|
16
|
-
ruby-version: '2.6'
|
|
17
|
-
|
|
18
|
-
- run: bundle config set path 'vendor/bundle'
|
|
19
|
-
|
|
20
|
-
- run: bundle install --jobs 4 --retry 3
|
|
21
|
-
|
|
22
|
-
- run: bundle exec rspec
|
|
23
|
-
|
|
24
|
-
- name: Publish to rubygems.org
|
|
25
|
-
env:
|
|
26
|
-
RUBYGEMS_API_KEY: ${{secrets.FONTIST_CI_RUBYGEMS_API_KEY}}
|
|
27
|
-
run: |
|
|
28
|
-
gem install gem-release
|
|
29
|
-
touch ~/.gem/credentials
|
|
30
|
-
cat > ~/.gem/credentials << EOF
|
|
31
|
-
---
|
|
32
|
-
:rubygems_api_key: ${RUBYGEMS_API_KEY}
|
|
33
|
-
EOF
|
|
34
|
-
chmod 0600 ~/.gem/credentials
|
|
35
|
-
git status
|
|
36
|
-
gem release
|
data/.github/workflows/rspec.yml
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
name: rspec
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [ master, main ]
|
|
6
|
-
pull_request:
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
build:
|
|
10
|
-
name: Test on Ruby ${{ matrix.ruby }} ${{ matrix.os }}
|
|
11
|
-
runs-on: ${{ matrix.os }}
|
|
12
|
-
continue-on-error: ${{ matrix.experimental }}
|
|
13
|
-
strategy:
|
|
14
|
-
fail-fast: false
|
|
15
|
-
matrix:
|
|
16
|
-
ruby: [ '2.4', '2.5', '2.6', '2.7' ]
|
|
17
|
-
os: [ ubuntu-latest, windows-latest, macos-latest ]
|
|
18
|
-
experimental: [ false ]
|
|
19
|
-
include:
|
|
20
|
-
- ruby: '3.0'
|
|
21
|
-
os: 'ubuntu-latest'
|
|
22
|
-
experimental: true
|
|
23
|
-
- ruby: '3.0'
|
|
24
|
-
os: 'windows-latest'
|
|
25
|
-
experimental: true
|
|
26
|
-
- ruby: '3.0'
|
|
27
|
-
os: 'macos-latest'
|
|
28
|
-
experimental: true
|
|
29
|
-
|
|
30
|
-
steps:
|
|
31
|
-
- uses: actions/checkout@master
|
|
32
|
-
|
|
33
|
-
- uses: ruby/setup-ruby@v1
|
|
34
|
-
with:
|
|
35
|
-
ruby-version: ${{ matrix.ruby }}
|
|
36
|
-
|
|
37
|
-
- uses: actions/cache@v1
|
|
38
|
-
with:
|
|
39
|
-
path: vendor/bundle
|
|
40
|
-
key: bundle-${{ matrix.os }}-${{ matrix.ruby }}-${{ hashFiles('**/*.gemspec') }}
|
|
41
|
-
restore-keys: bundle-${{ matrix.os }}-${{ matrix.ruby }}
|
|
42
|
-
|
|
43
|
-
- run: bundle config set path 'vendor/bundle'
|
|
44
|
-
|
|
45
|
-
- run: bundle install --jobs 4 --retry 3
|
|
46
|
-
|
|
47
|
-
- run: bundle exec rspec
|