extracter 1.2.21
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of extracter might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/README.md +207 -0
- data/bin/extract +7 -0
- data/bin/extract_it +13 -0
- data/doc/README.gen +165 -0
- data/extracter.gemspec +106 -0
- data/lib/extracter/base/base.rb +140 -0
- data/lib/extracter/class/extract_this_archive.rb +277 -0
- data/lib/extracter/class/extracter.rb +1057 -0
- data/lib/extracter/constants/constants.rb +157 -0
- data/lib/extracter/extract_it/extract_it.rb +240 -0
- data/lib/extracter/requires/require_the_extracter_project.rb +8 -0
- data/lib/extracter/toplevel_methods/is_this_a_valid_archive.rb +41 -0
- data/lib/extracter/toplevel_methods/misc.rb +34 -0
- data/lib/extracter/version/version.rb +21 -0
- data/lib/extracter.rb +5 -0
- data/test/testing_class_extracter.rb +25 -0
- data/test/testing_class_method_extract_what_to.rb +9 -0
- metadata +106 -0
@@ -0,0 +1,1057 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# Encoding: UTF-8
|
3
|
+
# frozen_string_literal: true
|
4
|
+
# =========================================================================== #
|
5
|
+
# === Extracter::Extracter
|
6
|
+
#
|
7
|
+
# The primary purpose of this class is to abstract extracting source files
|
8
|
+
# to a target location. You just pass the argument of the file that has
|
9
|
+
# to be extracted to this class, and it should handle the rest.
|
10
|
+
#
|
11
|
+
# The class can be used to "extract" audio files as well, by calling the
|
12
|
+
# module ExtractAudio, which is part of MultimediaParadise. You can try
|
13
|
+
# this - just pass a .mp4 file as first argument to this class. Make sure
|
14
|
+
# to have installed that gem before, via: gem install multimedia_paradise
|
15
|
+
#
|
16
|
+
# Usage examples:
|
17
|
+
#
|
18
|
+
# Extracter::Extracter.new(ARGV)
|
19
|
+
# Extracter.new('foo.mp3')
|
20
|
+
# Extracter.new('xyz-1.0.tar.gz')
|
21
|
+
#
|
22
|
+
# =========================================================================== #
|
23
|
+
# require 'extracter/class/extracter.rb'
|
24
|
+
# =========================================================================== #
|
25
|
+
require 'extracter/base/base.rb'
|
26
|
+
|
27
|
+
module Extracter
|
28
|
+
|
29
|
+
class Extracter < ::Extracter::Base # === Extracter::Extracter
|
30
|
+
|
31
|
+
require 'fileutils'
|
32
|
+
require 'extracter/toplevel_methods/is_this_a_valid_archive.rb'
|
33
|
+
require 'extracter/toplevel_methods/misc.rb'
|
34
|
+
require 'extracter/version/version.rb'
|
35
|
+
require 'extracter/class/extract_this_archive.rb'
|
36
|
+
|
37
|
+
begin
|
38
|
+
require 'opn'
|
39
|
+
rescue LoadError; end
|
40
|
+
|
41
|
+
# ========================================================================= #
|
42
|
+
# === NAMESPACE
|
43
|
+
# ========================================================================= #
|
44
|
+
NAMESPACE = inspect
|
45
|
+
|
46
|
+
# ========================================================================= #
|
47
|
+
# === SHOW_ONLY_THE_SHORT_NAME_OF_THE_ARCHIVE
|
48
|
+
#
|
49
|
+
# If this constant is set to true then we will only show the shortened
|
50
|
+
# name of the archive in question by default.
|
51
|
+
# ========================================================================= #
|
52
|
+
SHOW_ONLY_THE_SHORT_NAME_OF_THE_ARCHIVE = true
|
53
|
+
|
54
|
+
# ========================================================================= #
|
55
|
+
# === initialize
|
56
|
+
#
|
57
|
+
# The first argument to this method should be the archive that the user
|
58
|
+
# wants to extract. This must be a (locally) existing archive, such as
|
59
|
+
# foobar.tar.xz or something similar.
|
60
|
+
#
|
61
|
+
# The second argument to this method, called `extract_to`, specifies the
|
62
|
+
# target location, where this class will extract the archive into, if
|
63
|
+
# available. Some keywords and shortcuts exist for this option - for
|
64
|
+
# instance, TEMP means $MY_TEMP, which can be set by the user.
|
65
|
+
#
|
66
|
+
# Specific usage example in pure Ruby:
|
67
|
+
#
|
68
|
+
# x = Extracter.what_to('pry-0.9.9.4.gem', '/home/Temp')
|
69
|
+
#
|
70
|
+
# ========================================================================= #
|
71
|
+
def initialize(
|
72
|
+
commandline_arguments = ARGV,
|
73
|
+
extract_to = nil,
|
74
|
+
run_already = true,
|
75
|
+
&block
|
76
|
+
)
|
77
|
+
register_sigint
|
78
|
+
reset
|
79
|
+
@internal_hash[:run_already] = run_already
|
80
|
+
set_commandline_arguments(
|
81
|
+
commandline_arguments
|
82
|
+
)
|
83
|
+
if debug? # Some debug-information in this case.
|
84
|
+
e "The first argument what is: `#{commandline_arguments}`"
|
85
|
+
e "The second argument where_to is: `#{extract_to}`"
|
86
|
+
end
|
87
|
+
case run_already
|
88
|
+
# ======================================================================= #
|
89
|
+
# === :dont_run_yet
|
90
|
+
# ======================================================================= #
|
91
|
+
when :dont_run_yet,
|
92
|
+
:do_not_run_yet,
|
93
|
+
:default
|
94
|
+
@internal_hash[:run_already] = false
|
95
|
+
end
|
96
|
+
set_extract_to(extract_to) if extract_to
|
97
|
+
# ======================================================================= #
|
98
|
+
# === Handle blocks next
|
99
|
+
# ======================================================================= #
|
100
|
+
if block_given?
|
101
|
+
yielded = yield
|
102
|
+
case yielded
|
103
|
+
# ===================================================================== #
|
104
|
+
# === :dont_run_yet
|
105
|
+
# ===================================================================== #
|
106
|
+
when :dont_run_yet,
|
107
|
+
:do_not_run_yet,
|
108
|
+
:default
|
109
|
+
@internal_hash[:run_already] = false
|
110
|
+
# ===================================================================== #
|
111
|
+
# === :show_the_full_name_of_the_archive
|
112
|
+
# ===================================================================== #
|
113
|
+
when :show_the_full_name_of_the_archive
|
114
|
+
do_show_the_full_name_of_the_archive
|
115
|
+
end
|
116
|
+
end
|
117
|
+
run if run_already?
|
118
|
+
end
|
119
|
+
|
120
|
+
# ========================================================================= #
|
121
|
+
# === reset (reset tag)
|
122
|
+
# ========================================================================= #
|
123
|
+
def reset
|
124
|
+
super()
|
125
|
+
# ======================================================================= #
|
126
|
+
# === :try_to_use_colours
|
127
|
+
# ======================================================================= #
|
128
|
+
@internal_hash[:try_to_use_colours] = true
|
129
|
+
# ======================================================================= #
|
130
|
+
# === :colour_to_use_for_directories
|
131
|
+
# ======================================================================= #
|
132
|
+
@internal_hash[:colour_to_use_for_directories] = 'cyan'
|
133
|
+
# ======================================================================= #
|
134
|
+
# === :use_opn
|
135
|
+
# ======================================================================= #
|
136
|
+
@internal_hash[:use_opn] = true # ← Whether to use make use of Opn by default or not.
|
137
|
+
# ======================================================================= #
|
138
|
+
# === :show_the_full_name_of_the_archive
|
139
|
+
# ======================================================================= #
|
140
|
+
@internal_hash[:show_the_full_name_of_the_archive] = false
|
141
|
+
# ======================================================================= #
|
142
|
+
# === :debug
|
143
|
+
# ======================================================================= #
|
144
|
+
@internal_hash[:debug] = false
|
145
|
+
# ======================================================================= #
|
146
|
+
# === :append_this_to_the_commandline
|
147
|
+
#
|
148
|
+
# This variable can always be used to append onto the commandline.
|
149
|
+
# That way we can pass additional options to "tar", for instance.
|
150
|
+
# ======================================================================= #
|
151
|
+
@internal_hash[:append_this_to_the_commandline] = ''.dup
|
152
|
+
# ======================================================================= #
|
153
|
+
# === :namespace
|
154
|
+
#
|
155
|
+
# Specify the main namespace to be used. This setting can be modified
|
156
|
+
# at "runtime".
|
157
|
+
# ======================================================================= #
|
158
|
+
@internal_hash[:namespace] = NAMESPACE
|
159
|
+
# ======================================================================= #
|
160
|
+
# === :be_verbose
|
161
|
+
# ======================================================================= #
|
162
|
+
@internal_hash[:be_verbose] = true
|
163
|
+
# ======================================================================= #
|
164
|
+
# === :show_the_name
|
165
|
+
#
|
166
|
+
# If this variable is true then the name of the class will be shown
|
167
|
+
# on the commandline, via opn().
|
168
|
+
# ======================================================================= #
|
169
|
+
@internal_hash[:show_the_name] = false
|
170
|
+
# ======================================================================= #
|
171
|
+
# === :show_only_the_short_name_of_the_archive
|
172
|
+
# ======================================================================= #
|
173
|
+
@internal_hash[:show_only_the_short_name_of_the_archive] =
|
174
|
+
SHOW_ONLY_THE_SHORT_NAME_OF_THE_ARCHIVE
|
175
|
+
# ======================================================================= #
|
176
|
+
# === :run_simulation
|
177
|
+
# ======================================================================= #
|
178
|
+
@internal_hash[:run_simulation] = false # ← Whether to run in simulation, or for "real".
|
179
|
+
# ======================================================================= #
|
180
|
+
# === :extract_to
|
181
|
+
# ======================================================================= #
|
182
|
+
@internal_hash[:extract_to] = return_pwd
|
183
|
+
do_show_name # We will show the name usually.
|
184
|
+
prepare_the_hash_for_opn
|
185
|
+
# ======================================================================= #
|
186
|
+
# === :use_colours
|
187
|
+
# ======================================================================= #
|
188
|
+
enable_colours
|
189
|
+
end
|
190
|
+
|
191
|
+
# ========================================================================= #
|
192
|
+
# === do_not_show_name
|
193
|
+
#
|
194
|
+
# Tells us whether to use opn() or not.
|
195
|
+
# ========================================================================= #
|
196
|
+
def do_not_show_name
|
197
|
+
@internal_hash[:show_the_name] = false
|
198
|
+
end
|
199
|
+
|
200
|
+
# ========================================================================= #
|
201
|
+
# === show_the_name?
|
202
|
+
# ========================================================================= #
|
203
|
+
def show_the_name?
|
204
|
+
@internal_hash[:show_the_name]
|
205
|
+
end
|
206
|
+
|
207
|
+
# ========================================================================= #
|
208
|
+
# === check_whether_rar_is_available
|
209
|
+
#
|
210
|
+
# We try to find out whether unrar is available.
|
211
|
+
# ========================================================================= #
|
212
|
+
def check_whether_rar_is_available
|
213
|
+
is_available = false
|
214
|
+
ENV['PATH'].split(':').each {|entry|
|
215
|
+
is_available = true if File.exist? "#{entry}/unrar"
|
216
|
+
}
|
217
|
+
unless is_available
|
218
|
+
copn; e 'Sorry, unrar is not available. Please install it first.'
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
# ========================================================================= #
|
223
|
+
# === debug?
|
224
|
+
# ========================================================================= #
|
225
|
+
def debug?
|
226
|
+
@internal_hash[:debug]
|
227
|
+
end
|
228
|
+
|
229
|
+
# ========================================================================= #
|
230
|
+
# === run_already?
|
231
|
+
# ========================================================================= #
|
232
|
+
def run_already?
|
233
|
+
@internal_hash[:run_already]
|
234
|
+
end
|
235
|
+
|
236
|
+
# ========================================================================= #
|
237
|
+
# === enable_debug
|
238
|
+
# ========================================================================= #
|
239
|
+
def enable_debug
|
240
|
+
@internal_hash[:debug] = true
|
241
|
+
end
|
242
|
+
|
243
|
+
# ========================================================================= #
|
244
|
+
# === return_pwd
|
245
|
+
# ========================================================================= #
|
246
|
+
def return_pwd
|
247
|
+
"#{Dir.pwd}/".squeeze('/')
|
248
|
+
end
|
249
|
+
|
250
|
+
# ========================================================================= #
|
251
|
+
# === set_use_opn
|
252
|
+
# ========================================================================= #
|
253
|
+
def set_use_opn(i = true)
|
254
|
+
@internal_hash[:use_opn] = i
|
255
|
+
end
|
256
|
+
|
257
|
+
# ========================================================================= #
|
258
|
+
# === use_opn?
|
259
|
+
# ========================================================================= #
|
260
|
+
def use_opn?
|
261
|
+
@internal_hash[:use_opn]
|
262
|
+
end
|
263
|
+
|
264
|
+
# ========================================================================= #
|
265
|
+
# === set_commandline_arguments
|
266
|
+
# ========================================================================= #
|
267
|
+
def set_commandline_arguments(i = '')
|
268
|
+
i = [i].flatten.compact
|
269
|
+
@commandline_arguments = i
|
270
|
+
end
|
271
|
+
|
272
|
+
# ========================================================================= #
|
273
|
+
# === commandline_arguments?
|
274
|
+
# ========================================================================= #
|
275
|
+
def commandline_arguments?
|
276
|
+
@commandline_arguments
|
277
|
+
end
|
278
|
+
|
279
|
+
# ========================================================================= #
|
280
|
+
# === first_argument?
|
281
|
+
# ========================================================================= #
|
282
|
+
def first_argument?
|
283
|
+
@commandline_arguments.first
|
284
|
+
end; alias first? first_argument? # === first?
|
285
|
+
|
286
|
+
# ========================================================================= #
|
287
|
+
# === padded_extract_to?
|
288
|
+
# ========================================================================= #
|
289
|
+
def padded_extract_to?
|
290
|
+
" -C #{extract_to?} "
|
291
|
+
end
|
292
|
+
|
293
|
+
# ========================================================================= #
|
294
|
+
# === set_colour_for_directories
|
295
|
+
#
|
296
|
+
# Set the colour for directories to use.
|
297
|
+
# ========================================================================= #
|
298
|
+
def set_colour_for_directories(i)
|
299
|
+
@internal_hash[:colour_to_use_for_directories] = ::Colours.beautify(i)
|
300
|
+
end
|
301
|
+
|
302
|
+
# ========================================================================= #
|
303
|
+
# === extract_to?
|
304
|
+
#
|
305
|
+
# Note that this method is guaranteed to return a String.
|
306
|
+
# ========================================================================= #
|
307
|
+
def extract_to?
|
308
|
+
@internal_hash[:extract_to].to_s
|
309
|
+
end; alias source_package_location extract_to? # === source_package
|
310
|
+
alias extract_to_this_location? extract_to? # === extract_to_this_location?
|
311
|
+
alias extracted_to? extract_to? # === extracted_to?
|
312
|
+
alias extracted_path? extract_to? # === extracted_path?
|
313
|
+
|
314
|
+
# ========================================================================= #
|
315
|
+
# === opnn
|
316
|
+
#
|
317
|
+
# This variant will also check whether we should show the name or not.
|
318
|
+
# ========================================================================= #
|
319
|
+
def opnn(
|
320
|
+
use_this_hash = use_this_opn_hash?
|
321
|
+
)
|
322
|
+
if use_opn? and Object.const_defined?(:Opn) and show_the_name?
|
323
|
+
Opn.opn(use_this_hash)
|
324
|
+
end
|
325
|
+
end; alias opn opnn # === opn
|
326
|
+
alias copn opnn # === copn
|
327
|
+
|
328
|
+
# ========================================================================= #
|
329
|
+
# === use_this_opn_hash?
|
330
|
+
# ========================================================================= #
|
331
|
+
def use_this_opn_hash?
|
332
|
+
@internal_hash[:use_this_opn_hash]
|
333
|
+
end; alias main_hash? use_this_opn_hash? # === main_hash?
|
334
|
+
|
335
|
+
# ========================================================================= #
|
336
|
+
# === show_help (help tag)
|
337
|
+
#
|
338
|
+
# This method will show the available - and documented - help options
|
339
|
+
# for class Extracter.
|
340
|
+
#
|
341
|
+
# To call this method via the commandline try:
|
342
|
+
#
|
343
|
+
# extract --help
|
344
|
+
#
|
345
|
+
# ========================================================================= #
|
346
|
+
def show_help
|
347
|
+
e
|
348
|
+
opnn; e 'How to extract archives, without helper scripts?'
|
349
|
+
e
|
350
|
+
e ' tar -zxvf foobar.tar.gz # for .tar.gz'
|
351
|
+
e ' tar xvzf foobar.tgz # for .tgz'
|
352
|
+
e ' tar xvfJ foobar.tar.xz # for .tar.xz'
|
353
|
+
e ' tar jxf foobar.tar.bz2 # for .tar.bz2'
|
354
|
+
e ' tar -xf foobar.tar.bz2 # for .tbz'
|
355
|
+
e ' tar --lzip -xvf zutils-1.5.tar.lz # for .tar.lz'
|
356
|
+
e ' unsquashfs foobar-1.2.3.sxz # for .sxz'
|
357
|
+
e ' 7z x -so C:\home\x\src\htop\htop-3.0.5.tar.xz | 6z x -si -ttar # on windows'
|
358
|
+
e
|
359
|
+
opnn; e 'Furthermore, there are some commandline options '\
|
360
|
+
'that can'
|
361
|
+
opnn; e 'be used for this class (class Extracter).'
|
362
|
+
e
|
363
|
+
e ' --to=/home/Temp # extract into the '\
|
364
|
+
'directory /home/Temp/'
|
365
|
+
e
|
366
|
+
end
|
367
|
+
|
368
|
+
# ========================================================================= #
|
369
|
+
# === pad (pad tag)
|
370
|
+
#
|
371
|
+
# This method must be able to deal with ' ' as well as with '()'.
|
372
|
+
#
|
373
|
+
# The second character is the character that will be used for the
|
374
|
+
# padding.
|
375
|
+
# ========================================================================= #
|
376
|
+
def pad(
|
377
|
+
i, with_this_character = "'"
|
378
|
+
)
|
379
|
+
if i.include?('(') or i.include?(')')
|
380
|
+
i.tr!('(','\(')
|
381
|
+
i.tr!(')','\)') if i.include? ')'
|
382
|
+
i = pad(i, '"')
|
383
|
+
else
|
384
|
+
return with_this_character+
|
385
|
+
i+
|
386
|
+
with_this_character
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
# ========================================================================= #
|
391
|
+
# === namespace?
|
392
|
+
# ========================================================================= #
|
393
|
+
def namespace?
|
394
|
+
@internal_hash[:namespace]
|
395
|
+
end
|
396
|
+
|
397
|
+
# ========================================================================= #
|
398
|
+
# === be_verbose
|
399
|
+
# ========================================================================= #
|
400
|
+
def be_verbose
|
401
|
+
set_be_verbose(true)
|
402
|
+
end
|
403
|
+
|
404
|
+
# ========================================================================= #
|
405
|
+
# === be_silent
|
406
|
+
# ========================================================================= #
|
407
|
+
def be_silent
|
408
|
+
set_be_verbose(false)
|
409
|
+
end; alias be_quiet be_silent # === be_quiet
|
410
|
+
|
411
|
+
# ========================================================================= #
|
412
|
+
# === set_be_verbose
|
413
|
+
#
|
414
|
+
# This sets the verbosity level of the class. Use only this method
|
415
|
+
# when you wish to modify the @be_verbose instance variable.
|
416
|
+
# ========================================================================= #
|
417
|
+
def set_be_verbose(i = false)
|
418
|
+
@internal_hash[:be_verbose] = i
|
419
|
+
end; alias set_verbosity set_be_verbose # === set_verbosity
|
420
|
+
|
421
|
+
# ========================================================================= #
|
422
|
+
# === be_verbose?
|
423
|
+
#
|
424
|
+
# Getter method for whether we will be verbose or not.
|
425
|
+
# ========================================================================= #
|
426
|
+
def be_verbose?
|
427
|
+
@internal_hash[:be_verbose]
|
428
|
+
end
|
429
|
+
|
430
|
+
# ========================================================================= #
|
431
|
+
# === register_sigint
|
432
|
+
# ========================================================================= #
|
433
|
+
def register_sigint
|
434
|
+
Signal.trap('SIGINT') {
|
435
|
+
e sfancy('Requesting a graceful exit from ')+
|
436
|
+
colour_to_use_for_directories?+
|
437
|
+
'class Extracter'+
|
438
|
+
sfancy('. Exiting now.')
|
439
|
+
exit
|
440
|
+
}
|
441
|
+
end
|
442
|
+
|
443
|
+
# ========================================================================= #
|
444
|
+
# === colour_to_use_for_directories?
|
445
|
+
# ========================================================================= #
|
446
|
+
def colour_to_use_for_directories?
|
447
|
+
if use_colours?
|
448
|
+
return @internal_hash[:colour_to_use_for_directories]
|
449
|
+
else
|
450
|
+
return ''
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
# ========================================================================= #
|
455
|
+
# === do_show_the_full_name_of_the_archive
|
456
|
+
# ========================================================================= #
|
457
|
+
def do_show_the_full_name_of_the_archive
|
458
|
+
@internal_hash[:show_the_full_name_of_the_archive] = true
|
459
|
+
end
|
460
|
+
|
461
|
+
# ========================================================================= #
|
462
|
+
# === prefix_namespace_with
|
463
|
+
# ========================================================================= #
|
464
|
+
def prefix_namespace_with(i)
|
465
|
+
@internal_hash[:namespace] = "#{i}#{@internal_hash[:namespace].dup}"
|
466
|
+
update_the_main_hash # Also update the opn-hash here.
|
467
|
+
end
|
468
|
+
|
469
|
+
# ========================================================================= #
|
470
|
+
# === pad_opn_with_n_tokens
|
471
|
+
# ========================================================================= #
|
472
|
+
def pad_opn_with_n_tokens(n_tokens = nil)
|
473
|
+
if n_tokens
|
474
|
+
determine_default_opn_hash # Update this, just in case.
|
475
|
+
main_hash?.update(padding: n_tokens)
|
476
|
+
end
|
477
|
+
end; alias set_pad_opn_with_n_tokens pad_opn_with_n_tokens # === set_pad_opn_with_n_tokens
|
478
|
+
|
479
|
+
# ========================================================================= #
|
480
|
+
# === prepare_the_hash_for_opn
|
481
|
+
# ========================================================================= #
|
482
|
+
def prepare_the_hash_for_opn(
|
483
|
+
use_this_hash = {
|
484
|
+
namespace: namespace?,
|
485
|
+
use_colours: use_colours?
|
486
|
+
}
|
487
|
+
)
|
488
|
+
# ======================================================================= #
|
489
|
+
# === :use_this_opn_hash
|
490
|
+
# ======================================================================= #
|
491
|
+
@internal_hash[:use_this_opn_hash] = use_this_hash
|
492
|
+
return @internal_hash[:use_this_opn_hash]
|
493
|
+
end; alias update_the_opn_hash prepare_the_hash_for_opn # === update_the_opn_hash
|
494
|
+
alias determine_default_opn_hash prepare_the_hash_for_opn # === determine_default_opn_hash
|
495
|
+
alias determine_the_default_opn_hash prepare_the_hash_for_opn # === determine_the_default_opn_hash
|
496
|
+
alias update_the_main_hash prepare_the_hash_for_opn # === update_the_main_hash
|
497
|
+
|
498
|
+
# ========================================================================= #
|
499
|
+
# === show_only_the_short_name_of_the_archive?
|
500
|
+
# ========================================================================= #
|
501
|
+
def show_only_the_short_name_of_the_archive?
|
502
|
+
@internal_hash[:show_only_the_short_name_of_the_archive]
|
503
|
+
end
|
504
|
+
|
505
|
+
# ========================================================================= #
|
506
|
+
# === set_run_simulation
|
507
|
+
# ========================================================================= #
|
508
|
+
def set_run_simulation(i = false) # false is the default here.
|
509
|
+
@internal_hash[:run_simulation] = i
|
510
|
+
end
|
511
|
+
|
512
|
+
# ========================================================================= #
|
513
|
+
# === run_simulation=
|
514
|
+
# ========================================================================= #
|
515
|
+
def run_simulation=(i)
|
516
|
+
@internal_hash[:run_simulation] = i
|
517
|
+
end
|
518
|
+
|
519
|
+
# ========================================================================= #
|
520
|
+
# === run_simulation?
|
521
|
+
# ========================================================================= #
|
522
|
+
def run_simulation?
|
523
|
+
@internal_hash[:run_simulation]
|
524
|
+
end
|
525
|
+
|
526
|
+
# ========================================================================= #
|
527
|
+
# === strip_components
|
528
|
+
#
|
529
|
+
# The first argument to this method will determine how far "down" tar
|
530
|
+
# will strip the components.
|
531
|
+
# ========================================================================= #
|
532
|
+
def strip_components(
|
533
|
+
by_n = 1
|
534
|
+
)
|
535
|
+
@internal_hash[:append_this_to_the_commandline] <<
|
536
|
+
" --strip-components=#{by_n}"
|
537
|
+
end
|
538
|
+
|
539
|
+
# ========================================================================= #
|
540
|
+
# === do_show_name
|
541
|
+
#
|
542
|
+
# If this method is called then the class here will show the name of
|
543
|
+
# the file on the commandline, via opn().
|
544
|
+
# ========================================================================= #
|
545
|
+
def do_show_name
|
546
|
+
@internal_hash[:show_the_name] = true
|
547
|
+
end
|
548
|
+
|
549
|
+
# ========================================================================= #
|
550
|
+
# === enable_colours
|
551
|
+
# ========================================================================= #
|
552
|
+
def enable_colours
|
553
|
+
set_use_colours(true)
|
554
|
+
@internal_hash[:colour_to_use_for_directories] = cyan?
|
555
|
+
end
|
556
|
+
|
557
|
+
# ========================================================================= #
|
558
|
+
# === report_to_the_user
|
559
|
+
#
|
560
|
+
# This method reports to the user. Usually this is done only via this
|
561
|
+
# file here though.
|
562
|
+
# ========================================================================= #
|
563
|
+
def report_to_the_user(
|
564
|
+
i, extract_to = extract_to?
|
565
|
+
)
|
566
|
+
if be_verbose?
|
567
|
+
opnn; e 'Finished extracting to `'+sdir(
|
568
|
+
extract_to+
|
569
|
+
remove_file_extension(
|
570
|
+
File.basename(i)
|
571
|
+
)+ # This is an Array.
|
572
|
+
'/'
|
573
|
+
)+'`.'
|
574
|
+
end
|
575
|
+
end
|
576
|
+
|
577
|
+
# ========================================================================= #
|
578
|
+
# === disable_colours
|
579
|
+
#
|
580
|
+
# Use this method if you want to disable colour-support of this class.
|
581
|
+
# ========================================================================= #
|
582
|
+
def disable_colours
|
583
|
+
set_use_colours(false)
|
584
|
+
@internal_hash[:colour_to_use_for_directories] = ''.dup
|
585
|
+
end
|
586
|
+
|
587
|
+
# ========================================================================= #
|
588
|
+
# === set_use_colours
|
589
|
+
# ========================================================================= #
|
590
|
+
def set_use_colours(i)
|
591
|
+
# ======================================================================= #
|
592
|
+
# We must also sync this towards our main Hash, for opn(). The next
|
593
|
+
# line of code achieves precisely that.
|
594
|
+
# ======================================================================= #
|
595
|
+
main_hash?.update(use_colours: i)
|
596
|
+
@internal_hash[:try_to_use_colours] = i
|
597
|
+
end
|
598
|
+
|
599
|
+
# ========================================================================= #
|
600
|
+
# === try_to_use_colours?
|
601
|
+
# ========================================================================= #
|
602
|
+
def try_to_use_colours?
|
603
|
+
@internal_hash[:try_to_use_colours]
|
604
|
+
end
|
605
|
+
|
606
|
+
# ========================================================================= #
|
607
|
+
# === remove_file_extension
|
608
|
+
# ========================================================================= #
|
609
|
+
def remove_file_extension(i)
|
610
|
+
_ = File.basename(i)
|
611
|
+
return ::Extracter.remove_archive_type(_)
|
612
|
+
end; alias remove_extension remove_file_extension # === remove_extensions
|
613
|
+
alias remove_ext remove_file_extension # === remove_ext
|
614
|
+
|
615
|
+
# ========================================================================= #
|
616
|
+
# === rds
|
617
|
+
# ========================================================================= #
|
618
|
+
def rds(i)
|
619
|
+
return i.squeeze('/') if i.respond_to? :squeeze
|
620
|
+
return i
|
621
|
+
end
|
622
|
+
|
623
|
+
# ========================================================================= #
|
624
|
+
# === set_extract_to
|
625
|
+
#
|
626
|
+
# This is the method that should be used to determine into which
|
627
|
+
# directory this class will extract archives into.
|
628
|
+
#
|
629
|
+
# Note that this target can be modified from the commandline, if
|
630
|
+
# the user wants to do so.
|
631
|
+
# ========================================================================= #
|
632
|
+
def set_extract_to(
|
633
|
+
i = :temp_dir
|
634
|
+
)
|
635
|
+
if i.is_a?(Hash) and i.empty?
|
636
|
+
i = :temp_dir
|
637
|
+
end
|
638
|
+
if i.is_a? Hash
|
639
|
+
# ===================================================================== #
|
640
|
+
# === :run_already
|
641
|
+
# ===================================================================== #
|
642
|
+
if i.has_key? :run_already
|
643
|
+
@internal_hash[:run_already] = i.delete(:run_already)
|
644
|
+
end
|
645
|
+
# ===================================================================== #
|
646
|
+
# === :prepend_this_namespace
|
647
|
+
# ===================================================================== #
|
648
|
+
if i.has_key? :prepend_this_namespace
|
649
|
+
prefix_with_this = i.delete(:prepend_this_namespace) # Get rid of it from the Hash as well.
|
650
|
+
prefix_namespace_with(prefix_with_this)
|
651
|
+
end
|
652
|
+
# ===================================================================== #
|
653
|
+
# === :use_colours
|
654
|
+
# ===================================================================== #
|
655
|
+
if i.has_key? :use_colours
|
656
|
+
set_use_colours(i.delete(:use_colours))
|
657
|
+
end
|
658
|
+
# ===================================================================== #
|
659
|
+
# === :verbosity
|
660
|
+
#
|
661
|
+
# Handle how verbose the class shall be.
|
662
|
+
# ===================================================================== #
|
663
|
+
if i.has_key? :verbosity
|
664
|
+
set_be_verbose(i.delete(:verbosity))
|
665
|
+
# ===================================================================== #
|
666
|
+
# === :be_verbose
|
667
|
+
# ===================================================================== #
|
668
|
+
elsif i.has_key? :be_verbose
|
669
|
+
set_be_verbose(i.delete(:be_verbose))
|
670
|
+
end
|
671
|
+
# ===================================================================== #
|
672
|
+
# === :append_this_to_the_commandline
|
673
|
+
# ===================================================================== #
|
674
|
+
if i.has_key? :append_this_to_the_commandline
|
675
|
+
@internal_hash[:append_this_to_the_commandline] =
|
676
|
+
i.delete(:append_this_to_the_commandline)
|
677
|
+
end
|
678
|
+
# ===================================================================== #
|
679
|
+
# === :use_opn
|
680
|
+
# ===================================================================== #
|
681
|
+
if i.has_key? :use_opn
|
682
|
+
set_use_opn(i.delete(:use_opn))
|
683
|
+
end
|
684
|
+
# ===================================================================== #
|
685
|
+
# === :pad_opn_with_n_tokens
|
686
|
+
# ===================================================================== #
|
687
|
+
if i.has_key? :pad_opn_with_n_tokens
|
688
|
+
set_pad_opn_with_n_tokens(i.delete(:pad_opn_with_n_tokens))
|
689
|
+
end
|
690
|
+
# ===================================================================== #
|
691
|
+
# === :run_simulation
|
692
|
+
# ===================================================================== #
|
693
|
+
if i.has_key? :run_simulation
|
694
|
+
set_run_simulation(i.delete(:run_simulation))
|
695
|
+
end
|
696
|
+
# ===================================================================== #
|
697
|
+
# === :use_colours
|
698
|
+
# ===================================================================== #
|
699
|
+
if i.has_key? :use_colours
|
700
|
+
set_use_colours(i.delete(use_colours))
|
701
|
+
end
|
702
|
+
# ===================================================================== #
|
703
|
+
# === :extract_to
|
704
|
+
#
|
705
|
+
# This entry point allows the user to specify another extract-to
|
706
|
+
# directory. Note that :to is treated the same way as :extract_to.
|
707
|
+
#
|
708
|
+
# This entry point must come last. The idea is that it will then
|
709
|
+
# become the new value for i.
|
710
|
+
# ===================================================================== #
|
711
|
+
if i.has_key? :extract_to
|
712
|
+
i = i.delete(:extract_to)
|
713
|
+
# ===================================================================== #
|
714
|
+
# === :to
|
715
|
+
# ===================================================================== #
|
716
|
+
elsif i.has_key? :to
|
717
|
+
i = i.delete(:to)
|
718
|
+
end
|
719
|
+
end
|
720
|
+
case i # case tag
|
721
|
+
# ======================================================================= #
|
722
|
+
# === :default
|
723
|
+
# ======================================================================= #
|
724
|
+
when :default
|
725
|
+
i = return_pwd
|
726
|
+
# ======================================================================= #
|
727
|
+
# === TEMP
|
728
|
+
# ======================================================================= #
|
729
|
+
when 'TEMP',
|
730
|
+
'MY_TEMP',
|
731
|
+
'MYTEMP',
|
732
|
+
:temp_dir,
|
733
|
+
nil
|
734
|
+
i = TEMP_DIR
|
735
|
+
end
|
736
|
+
i = rds(i)
|
737
|
+
i.gsub!(/--to=/,'') if i.include? '--to='
|
738
|
+
i = i.to_s.dup # We expect a String most definitely.
|
739
|
+
@internal_hash[:extract_to] = i
|
740
|
+
end; alias set_extract_to_this_location set_extract_to # === set_extract_to_this_location
|
741
|
+
alias extract_to= set_extract_to # === extract_to=
|
742
|
+
alias extract_to set_extract_to # === extract_to
|
743
|
+
|
744
|
+
# ========================================================================= #
|
745
|
+
# === try_to_extract_this_iso_file
|
746
|
+
# ========================================================================= #
|
747
|
+
def try_to_extract_this_iso_file(i)
|
748
|
+
opnn; e 'Extracting an .iso file is a bit more complicated '\
|
749
|
+
'than extracting a .tar.gz tarball'
|
750
|
+
opnn; e 'archive. This class will first create a helper '\
|
751
|
+
'directory; then mount the .iso there,'
|
752
|
+
opnn; e 'then copy the content to the main directory.'
|
753
|
+
helper_directory = File.dirname(i)+
|
754
|
+
'/READ_ONLY_DIRECTORY_'+
|
755
|
+
File.basename(
|
756
|
+
i.delete_suffix(File.extname(i))
|
757
|
+
)+
|
758
|
+
'/'
|
759
|
+
mkdir(helper_directory) unless File.directory? helper_directory
|
760
|
+
esystem 'mount -o loop '+i+' '+helper_directory
|
761
|
+
e 'The helper directory in use is '\
|
762
|
+
'`'+sdir(File.absolute_path(helper_directory))+'`.'
|
763
|
+
main_directory = File.dirname(i)+
|
764
|
+
'/'+
|
765
|
+
File.basename(
|
766
|
+
i.delete_suffix(File.extname(i))
|
767
|
+
)+
|
768
|
+
'/'
|
769
|
+
e 'Next creating the main directory at `'+sdir(main_directory)+'`.'
|
770
|
+
mkdir(main_directory) unless File.directory? main_directory
|
771
|
+
e 'Next copying the content of the helper directory recursively '
|
772
|
+
e 'from `'+sdir(helper_directory)+'`'
|
773
|
+
e 'onto `'+sdir(
|
774
|
+
main_directory+File.basename(helper_directory)+'/'
|
775
|
+
)+'`.'
|
776
|
+
cpr(
|
777
|
+
helper_directory,
|
778
|
+
main_directory+File.basename(helper_directory)+'/'
|
779
|
+
)
|
780
|
+
a = main_directory+File.basename(helper_directory)+'/'
|
781
|
+
e 'Relocating the files next from:'
|
782
|
+
e
|
783
|
+
e " #{sdir(a)}"
|
784
|
+
e
|
785
|
+
Dir[a+'*'].each {|entry|
|
786
|
+
mv(
|
787
|
+
entry,
|
788
|
+
main_directory
|
789
|
+
)
|
790
|
+
}
|
791
|
+
# ======================================================================= #
|
792
|
+
# And remove the directory:
|
793
|
+
# ======================================================================= #
|
794
|
+
remove_this_directory(a)
|
795
|
+
e 'The content of the extracted (or rather, mounted) archive is:'
|
796
|
+
e
|
797
|
+
pp Dir["#{main_directory}*"]
|
798
|
+
e
|
799
|
+
end
|
800
|
+
|
801
|
+
# ========================================================================= #
|
802
|
+
# === work_on_the_given_input
|
803
|
+
# ========================================================================= #
|
804
|
+
def work_on_the_given_input(
|
805
|
+
array = commandline_arguments?,
|
806
|
+
extract_to = extract_to?
|
807
|
+
)
|
808
|
+
# ======================================================================= #
|
809
|
+
# If the user supplied a directory then a random entry will be grabbed
|
810
|
+
# from said directory.
|
811
|
+
# ======================================================================= #
|
812
|
+
if array.is_a?(String) and File.directory?(array)
|
813
|
+
array = Dir[rds("#{array}/")+'*'].sample
|
814
|
+
end
|
815
|
+
case extract_to
|
816
|
+
when nil
|
817
|
+
extract_to = extract_to?
|
818
|
+
end
|
819
|
+
if array.empty?
|
820
|
+
opnn; e 'No archive (input) was provided. Please provide the file'
|
821
|
+
opnn; e 'that is to be extracted.'
|
822
|
+
else
|
823
|
+
array.each {|this_file|
|
824
|
+
# =================================================================== #
|
825
|
+
# Create the directory if it does not yet exist.
|
826
|
+
# =================================================================== #
|
827
|
+
create_directory(extract_to) unless File.directory?(extract_to)
|
828
|
+
# =================================================================== #
|
829
|
+
# Handle the case when the user did input a number.
|
830
|
+
# =================================================================== #
|
831
|
+
begin
|
832
|
+
if this_file =~ /^\d$/
|
833
|
+
this_file = Dir['*'][( this_file.to_i - 1 )] unless File.exist?(this_file)
|
834
|
+
end
|
835
|
+
rescue ArgumentError => error
|
836
|
+
e 'Error for '+sfancy(this_file)+':'
|
837
|
+
pp error
|
838
|
+
end
|
839
|
+
# =================================================================== #
|
840
|
+
# If the user supplied a directory then a random entry will be
|
841
|
+
# grabbed from said directory.
|
842
|
+
#
|
843
|
+
# Usage example:
|
844
|
+
#
|
845
|
+
# rubyextracter /home/x/src/htop/
|
846
|
+
#
|
847
|
+
# =================================================================== #
|
848
|
+
if File.directory? this_file
|
849
|
+
this_file = Dir[rds("#{this_file}/")+'*'].sample
|
850
|
+
end
|
851
|
+
extract_this_archive(this_file, extract_to)
|
852
|
+
report_to_the_user(this_file, extract_to)
|
853
|
+
}
|
854
|
+
end
|
855
|
+
end
|
856
|
+
|
857
|
+
# ========================================================================= #
|
858
|
+
# === create_directory (mkdir tag)
|
859
|
+
#
|
860
|
+
# Use this to create directories.
|
861
|
+
# ========================================================================= #
|
862
|
+
def create_directory(i)
|
863
|
+
FileUtils.mkdir_p(i) unless File.directory?(i)
|
864
|
+
end; alias mkdir create_directory # === mkdir
|
865
|
+
|
866
|
+
# ========================================================================= #
|
867
|
+
# === notify_the_user_that_this_extension_has_not_been_registered_yet
|
868
|
+
# ========================================================================= #
|
869
|
+
def notify_the_user_that_this_extension_has_not_been_registered_yet(i)
|
870
|
+
opnn; e "The archive at `#{i}` is #{tomato('not')}"
|
871
|
+
opnn; e "registered as a permissive extension."
|
872
|
+
fail_message_not_registered(i)
|
873
|
+
end
|
874
|
+
|
875
|
+
# ========================================================================= #
|
876
|
+
# === fail_message_not_registered
|
877
|
+
#
|
878
|
+
# Output a fail message when the archive format is not registered.
|
879
|
+
# ========================================================================= #
|
880
|
+
def fail_message_not_registered(i)
|
881
|
+
copn; e "Can not extract `#{sfancy(i)}` - it is not registered."
|
882
|
+
end
|
883
|
+
|
884
|
+
# ========================================================================= #
|
885
|
+
# === try_to_extract_this_img_file
|
886
|
+
# ========================================================================= #
|
887
|
+
def try_to_extract_this_img_file(i)
|
888
|
+
opnn; e 'Handling a squashfs .img file format next:'
|
889
|
+
name_without_extension = i.delete_suffix(File.extname(i))
|
890
|
+
mkdir(name_without_extension) unless File.directory? name_without_extension
|
891
|
+
esystem "mount -o loop -t squashfs #{i} #{name_without_extension}"
|
892
|
+
e 'The content of the extracted (or rather, mounted) archive is:'
|
893
|
+
pp Dir["#{name_without_extension}*"]
|
894
|
+
end
|
895
|
+
|
896
|
+
# ========================================================================= #
|
897
|
+
# === menu (menu tag)
|
898
|
+
# ========================================================================= #
|
899
|
+
def menu(
|
900
|
+
i = commandline_arguments?
|
901
|
+
)
|
902
|
+
if i.is_a? Array
|
903
|
+
i.each {|entry| menu(entry) }
|
904
|
+
else
|
905
|
+
case i
|
906
|
+
# ===================================================================== #
|
907
|
+
# === --help
|
908
|
+
# ===================================================================== #
|
909
|
+
when /^-?-?help$/i
|
910
|
+
show_help
|
911
|
+
exit
|
912
|
+
end
|
913
|
+
end
|
914
|
+
end
|
915
|
+
|
916
|
+
# ========================================================================= #
|
917
|
+
# === esystem (system tag, esystem tag)
|
918
|
+
# ========================================================================= #
|
919
|
+
def esystem(
|
920
|
+
i, try_to_use_colours = try_to_use_colours?
|
921
|
+
)
|
922
|
+
i = i.dup if i.frozen?
|
923
|
+
# ======================================================================= #
|
924
|
+
# Next, consider appending something onto the commandline.
|
925
|
+
# ======================================================================= #
|
926
|
+
_ = @internal_hash[:append_this_to_the_commandline]
|
927
|
+
unless _.empty?
|
928
|
+
if i.include? ' '
|
929
|
+
splitted = i.split(' ')
|
930
|
+
splitted[0] << " #{_}"
|
931
|
+
i = splitted.join(' ')
|
932
|
+
else
|
933
|
+
i << " #{_}"
|
934
|
+
end
|
935
|
+
end
|
936
|
+
if run_simulation?
|
937
|
+
copn; e 'As we are running in simulation mode, the following command '
|
938
|
+
copn; e 'is the one that we would have been used if we were to not run '
|
939
|
+
copn; e 'in simulation mode:'
|
940
|
+
if be_verbose?
|
941
|
+
if try_to_use_colours
|
942
|
+
e ::Colours.steelblue(i)
|
943
|
+
else
|
944
|
+
e i
|
945
|
+
end
|
946
|
+
end
|
947
|
+
else
|
948
|
+
if be_verbose?
|
949
|
+
if try_to_use_colours
|
950
|
+
e ::Colours.steelblue(i)
|
951
|
+
else
|
952
|
+
e i
|
953
|
+
end
|
954
|
+
end
|
955
|
+
# ===================================================================== #
|
956
|
+
# Next, run the sys-command.
|
957
|
+
# ===================================================================== #
|
958
|
+
begin
|
959
|
+
system i
|
960
|
+
# =================================================================== #
|
961
|
+
# We have to rescue here because unrar might not be available and
|
962
|
+
# so on.
|
963
|
+
# =================================================================== #
|
964
|
+
rescue Exception => error
|
965
|
+
e 'An error has happened upon attempting to run this system command:'
|
966
|
+
e
|
967
|
+
e " #{i}"
|
968
|
+
e
|
969
|
+
pp error; e '-----------'; pp error.class; e '-----------'
|
970
|
+
end
|
971
|
+
end
|
972
|
+
end; alias run_this_system_command esystem # === run_this_system_command
|
973
|
+
|
974
|
+
# ========================================================================= #
|
975
|
+
# === run (run tag, def tag)
|
976
|
+
# ========================================================================= #
|
977
|
+
def run
|
978
|
+
menu
|
979
|
+
work_on_the_given_input
|
980
|
+
end
|
981
|
+
|
982
|
+
# ========================================================================= #
|
983
|
+
# === Extracter::Extracter.extract_this
|
984
|
+
#
|
985
|
+
# This method provides a convenient API to extract something to a
|
986
|
+
# specified directory, as a class method. It defaults to the
|
987
|
+
# current working directory, as that is by far the most convenient
|
988
|
+
# way to extract a source tarball/archive.
|
989
|
+
#
|
990
|
+
# ========================================================================= #
|
991
|
+
def self.extract_this(
|
992
|
+
i = ARGV,
|
993
|
+
to = {}, # This may also be a String rather than a Hash.
|
994
|
+
&block
|
995
|
+
)
|
996
|
+
::Extracter::Extracter.new(ARGV, to, &block)
|
997
|
+
end; self.instance_eval { alias what_to extract_this } # === Extracter::Extracter.what_to
|
998
|
+
self.instance_eval { alias extract extract_this } # === Extracter::Extracter.extract
|
999
|
+
self.instance_eval { alias extract_what_to extract_this } # === Extracter::Extracter.extract_what_to
|
1000
|
+
|
1001
|
+
# ========================================================================= #
|
1002
|
+
# === Extracter::Extracter[]
|
1003
|
+
# ========================================================================= #
|
1004
|
+
def self.[](i = ARGV, extract_where_to = Dir.pwd)
|
1005
|
+
new(i, extract_where_to)
|
1006
|
+
end
|
1007
|
+
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
# ========================================================================= #
|
1011
|
+
# === Extracter.extract_what_to
|
1012
|
+
#
|
1013
|
+
# Useage example goes like this:
|
1014
|
+
#
|
1015
|
+
# Extracter.extract_what_to('foo-1.0.tar.xz', '/tmp')
|
1016
|
+
# Extracter.extract_what_to('/Depot/jjjj/tesseract-5.1.0.tar.xz', Dir.pwd+'/')
|
1017
|
+
#
|
1018
|
+
# ========================================================================= #
|
1019
|
+
def self.extract_what_to(
|
1020
|
+
what = ARGV,
|
1021
|
+
extract_to = :default, # ← This can also be a Hash. It denotes where we want to extract to.
|
1022
|
+
run_already = true, # :do_not_run_yet,
|
1023
|
+
&block
|
1024
|
+
)
|
1025
|
+
_ = ::Extracter::Extracter.new(
|
1026
|
+
what,
|
1027
|
+
extract_to,
|
1028
|
+
run_already,
|
1029
|
+
&block
|
1030
|
+
)
|
1031
|
+
return _ # We must return the class, as other projects may depend on this.
|
1032
|
+
end; self.instance_eval { alias extract_this extract_what_to } # === Extracter.extract_this
|
1033
|
+
self.instance_eval { alias extract extract_what_to } # === Extracter.extract
|
1034
|
+
self.instance_eval { alias what_to extract_what_to } # === Extracter.what_to
|
1035
|
+
self.instance_eval { alias new extract_what_to } # === Extracter.new
|
1036
|
+
self.instance_eval { alias [] extract_what_to } # === Extracter[]
|
1037
|
+
|
1038
|
+
end
|
1039
|
+
|
1040
|
+
if __FILE__ == $PROGRAM_NAME
|
1041
|
+
_ = Extracter::Extracter.new(ARGV) { :do_not_run_yet }
|
1042
|
+
if ARGV.size > 2
|
1043
|
+
_ = Extracter::Extracter.new(ARGV, :default) { :do_not_run_yet }
|
1044
|
+
else
|
1045
|
+
_ = Extracter::Extracter.new(ARGV[0], ARGV[1]) { :do_not_run_yet }
|
1046
|
+
end
|
1047
|
+
# _.enable_debug
|
1048
|
+
_.be_verbose
|
1049
|
+
# _.strip_components # This would be equivalent to: --strip-components=1
|
1050
|
+
_.run
|
1051
|
+
end # rubyextracter
|
1052
|
+
# extracter
|
1053
|
+
# extracter htop-1.0.2.tar.xz
|
1054
|
+
# extracter xfig-3.2.5.tar.bz2
|
1055
|
+
# extract htop* /Depot/
|
1056
|
+
# extract recode-3.7.tar.xz /Depot/
|
1057
|
+
# extract qt-4.8.6.tar.xz --to=/home/Temp
|