qdumpfs 0.4.0 → 0.8.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 +4 -0
- data/Gemfile.lock +2 -2
- data/README.md +53 -12
- data/data/from/0.txt +1 -0
- data/data/from/a/1.txt +1 -0
- data/exe/sample +40 -0
- data/lib/qdumpfs.rb +87 -91
- data/lib/qdumpfs/option.rb +34 -7
- data/lib/qdumpfs/util.rb +6 -1
- data/lib/qdumpfs/version.rb +4 -3
- data/run_qdumpfs.sh +0 -0
- data/sample.sh +5 -0
- data/test_pdumpfs/pdumpfs-test +0 -0
- data/test_qdumpfs.sh +6 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc8d8dec60fe04598e9dd5bea8528f5299a7cbb7ee0f0432c3b6d46488917edf
|
4
|
+
data.tar.gz: '029dffccca2865524f208d28f2ebe2f63b2de465e0a5f08de93c597156fd48a9'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c393b76dddd9978adf5dfc77cfb25f3c14bfb9b1aca0767228b8b4c70fdf11206f4a35c9e0f5098b1c7ba1e3b113dc8f51de3ad14b48d39fe1dff8dd21309f1
|
7
|
+
data.tar.gz: 054605d2b4f91e2c0fdbd0518614b81a9f04f0ba378f0d92c5aba28c59456ae88c40dfb156579295c10130c248fc314197bd03398f18435cd1e0596696f444f2
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,31 +1,72 @@
|
|
1
1
|
# Qdumpfs
|
2
2
|
|
3
|
-
|
3
|
+
pdumpfsの個人的改良版です。
|
4
4
|
|
5
|
-
|
5
|
+
Gem化して最近のバージョンのバージョンのRubyに対応。コマンドの拡張などを行っています。
|
6
|
+
|
7
|
+
## インストール
|
6
8
|
|
7
9
|
gem install qdumpfs
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
+
## 使用方法
|
12
|
+
|
13
|
+
```
|
14
|
+
Usage: qdumpfs [options] <source> <dest>
|
15
|
+
-h, --help show this message
|
16
|
+
Options
|
17
|
+
-v, --verbose verbose message
|
18
|
+
-r, --report report message
|
19
|
+
-n, --dry-run don't actually run any commands
|
20
|
+
-e, --exclude=PATTERN exclude files/directories matching PATTERN
|
21
|
+
-s, --exclude-by-size=SIZE exclude files larger than SIZE
|
22
|
+
-w, --exclude-by-glob=GLOB exclude files matching GLOB
|
23
|
+
-c, --command=COMMAND backup|sync|list|expire|verify|delete
|
24
|
+
-l, --limit=HOURS limit hours
|
25
|
+
-k, --keep=KEEPARG ex: --keep 100Y12M12W30D (100years, 12months, 12weeks, 30days, default)
|
11
26
|
```
|
12
27
|
|
13
|
-
|
28
|
+
## 実行例
|
14
29
|
|
15
|
-
$ bundle
|
16
30
|
|
17
|
-
|
31
|
+
バックアップを実行する場合。
|
18
32
|
|
19
|
-
|
33
|
+
```
|
34
|
+
qdumpfs /home/foo /backup
|
35
|
+
```
|
20
36
|
|
21
|
-
|
37
|
+
"--command backup"オプションを明示することもできます。
|
22
38
|
|
23
|
-
|
39
|
+
```
|
40
|
+
qdumpfs --command=backup /home/foo /backup
|
41
|
+
```
|
24
42
|
|
25
|
-
|
43
|
+
"--command sync"でバックアップフォルダを同期できます。
|
44
|
+
```
|
45
|
+
qdumpfs --command=sync /backup1 /backup2
|
46
|
+
```
|
26
47
|
|
27
|
-
|
48
|
+
バックアップフォルダの同期には膨大な時間が必要な場合があるため、実行時間を制限できます。以下は例えば1時間に制限する場合です。
|
49
|
+
```
|
50
|
+
qdumpfs --command=sync --limit=1 /backup1 /backup2
|
51
|
+
```
|
52
|
+
|
53
|
+
バックアップフォルダの同期で、1時間でかつ"100Y12M12W30D"を保存する場合のオプションです。
|
54
|
+
```
|
55
|
+
qdumpfs --command=sync --limit=1 --keep=5Y6M7W10D backup1 /backup2
|
56
|
+
```
|
57
|
+
|
58
|
+
"--command expire"で、"--keep="パターンに該当しないバックアップを削除できます。
|
59
|
+
```
|
60
|
+
qdumpfs --command=expire --limit=1 --keep=5Y6M7W10D backup1 /backup2
|
61
|
+
```
|
62
|
+
|
63
|
+
"--command delete"で、バックアップに存在する指定したパスを削除できます(間違えてバックアップした内容を削除したい場合などに使用)。
|
64
|
+
```
|
65
|
+
qdumpfs --command=delete --delete-dir=backup1 --limit=1 r:/backup2
|
66
|
+
```
|
28
67
|
|
68
|
+
## License
|
29
69
|
|
70
|
+
qdumpfs is a free software with ABSOLUTELY NO WARRANTY under the terms of the GNU General Public License version 2.
|
30
71
|
|
31
72
|
|
data/data/from/0.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0
|
data/data/from/a/1.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1
|
data/exe/sample
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require "qdumpfs"
|
5
|
+
|
6
|
+
from = "./data/from"
|
7
|
+
to = "./data/to"
|
8
|
+
to2 = "./data/to2"
|
9
|
+
|
10
|
+
def create_dir(dir)
|
11
|
+
if FileTest.directory?(dir)
|
12
|
+
FileUtils.rm_rf(dir)
|
13
|
+
end
|
14
|
+
FileUtils.mkpath(dir)
|
15
|
+
end
|
16
|
+
|
17
|
+
create_dir(to)
|
18
|
+
create_dir(to2)
|
19
|
+
|
20
|
+
|
21
|
+
arg = ["--backup-at=20210119", from, to]
|
22
|
+
Qdumpfs::Command.run(arg)
|
23
|
+
arg = ["--backup-at=20210121", from, to]
|
24
|
+
Qdumpfs::Command.run(arg)
|
25
|
+
arg = ["--backup-at=20210122", from, to]
|
26
|
+
Qdumpfs::Command.run(arg)
|
27
|
+
arg = ["--backup-at=20210123", from, to]
|
28
|
+
Qdumpfs::Command.run(arg)
|
29
|
+
arg = ["--backup-at=20210124", from, to]
|
30
|
+
Qdumpfs::Command.run(arg)
|
31
|
+
|
32
|
+
|
33
|
+
arg = ["--backup-at=20210122", from, to2]
|
34
|
+
Qdumpfs::Command.run(arg)
|
35
|
+
arg = ["--backup-at=20210123", from, to2]
|
36
|
+
|
37
|
+
arg = ["--command=delete", "--delete-from=20210122", "--delete-to=20210123", "--limit=1", to, to2]
|
38
|
+
Qdumpfs::Command.run(arg)
|
39
|
+
|
40
|
+
|
data/lib/qdumpfs.rb
CHANGED
@@ -19,8 +19,8 @@ module Qdumpfs
|
|
19
19
|
opts = {}
|
20
20
|
opt = OptionParser.new(argv)
|
21
21
|
opt.version = VERSION
|
22
|
-
opt.banner = "Usage: #{opt.program_name} [
|
23
|
-
opt.separator('')
|
22
|
+
opt.banner = "Usage: #{opt.program_name} [options] <source> <dest>"
|
23
|
+
opt.separator('Options')
|
24
24
|
opt.on_head('-h', '--help', 'show this message') do |v|
|
25
25
|
puts opt.help
|
26
26
|
exit
|
@@ -34,24 +34,40 @@ module Qdumpfs
|
|
34
34
|
}
|
35
35
|
opt.on('-s SIZE', '--exclude-by-size=SIZE', 'exclude files larger than SIZE') {|v| opts[:es] = v }
|
36
36
|
opt.on('-w GLOB', '--exclude-by-glob=GLOB', 'exclude files matching GLOB') {|v| opts[:ep] = v }
|
37
|
-
commands = ['backup', 'sync', 'list', 'expire', 'verify', '
|
37
|
+
commands = ['backup', 'sync', 'list', 'expire', 'verify', 'delete']
|
38
38
|
opt.on('-c COMMAND', '--command=COMMAND', commands, commands.join('|')) {|v| opts[:c] = v}
|
39
39
|
opt.on('-l HOURS', '--limit=HOURS', 'limit hours') {|v| opts[:limit] = v}
|
40
40
|
opt.on('-k KEEPARG', '--keep=KEEPARG', 'ex: --keep 100Y12M12W30D (100years, 12months, 12weeks, 30days, default)') {|v| opts[:keep] = v}
|
41
|
-
|
42
|
-
|
41
|
+
opt.on('--logdir=LOGDIR', 'logdir') {|v| opts[:logdir] = v}
|
42
|
+
opt.on('--delete-from=YYYYMMDD', 'delete backup from YYYY/MM/DD') {|v|
|
43
|
+
opts[:delete_from] = Date.parse(v)
|
44
|
+
}
|
45
|
+
opt.on('--delete-to=YYYYMMDD', 'delete backup to YYYY/MM/DD') {|v|
|
46
|
+
opts[:delete_to] = Date.parse(v)
|
47
|
+
}
|
48
|
+
opt.on('--delete-dir=DIRS', 'relative path from the snapshot root of the backup. ex: --delete-dir=foo,home/bar') {|v|
|
49
|
+
opts[:delete_dirs] = v.split(/,/)
|
50
|
+
}
|
51
|
+
opt.on('--backup-at=YYYYMMDD', 'backup at YYYY/MM/DD') {|v|
|
52
|
+
opts[:backup_at] = Date.parse(v)
|
53
|
+
}
|
43
54
|
opt.parse!(argv)
|
44
|
-
option = Option.new(opts,
|
45
|
-
|
55
|
+
option = Option.new(opts, argv)
|
56
|
+
if opts[:v]
|
57
|
+
puts "<<<<< qdumpfs options >>>>> "
|
58
|
+
puts "logdir: #{option.logdir}"
|
59
|
+
puts "logpath: #{option.logpath}"
|
60
|
+
puts "verifypath: #{option.verifypath}"
|
61
|
+
puts
|
62
|
+
end
|
46
63
|
begin
|
47
64
|
command = Command.new(option)
|
48
65
|
command.run
|
49
|
-
rescue ArgumentError => e
|
50
|
-
puts e.message, e.backtrace
|
51
|
-
puts opt.help
|
52
|
-
exit
|
53
66
|
rescue => e
|
54
|
-
|
67
|
+
# p e.message
|
68
|
+
# p e.backtrace
|
69
|
+
puts opt.help
|
70
|
+
exit
|
55
71
|
end
|
56
72
|
end
|
57
73
|
|
@@ -67,13 +83,13 @@ module Qdumpfs
|
|
67
83
|
elsif @opt.cmd == 'list'
|
68
84
|
list
|
69
85
|
elsif @opt.cmd == 'expire'
|
70
|
-
expire
|
86
|
+
delete('expire')
|
71
87
|
elsif @opt.cmd == 'verify'
|
72
88
|
verify
|
73
|
-
elsif @opt.cmd == '
|
74
|
-
|
89
|
+
elsif @opt.cmd == 'delete'
|
90
|
+
delete('delete')
|
75
91
|
else
|
76
|
-
raise RuntimeError, "unknown command: #{cmd}"
|
92
|
+
raise RuntimeError, "unknown command: #{@opt.cmd}"
|
77
93
|
end
|
78
94
|
end
|
79
95
|
|
@@ -134,29 +150,6 @@ module Qdumpfs
|
|
134
150
|
return src_count, dst_count
|
135
151
|
end
|
136
152
|
|
137
|
-
def get_snapshots(target_dir)
|
138
|
-
# 指定したディレクトリに含まれるバックアップフォルダ(日付つき)を全て取得
|
139
|
-
dd = "[0-9][0-9]"
|
140
|
-
dddd = dd + dd
|
141
|
-
# FIXME: Y10K problem.
|
142
|
-
dirs = []
|
143
|
-
glob_path = File.join(target_dir, dddd, dd, dd)
|
144
|
-
Dir.glob(glob_path).sort.find {|dir|
|
145
|
-
day, month, year = File.split_all(dir).reverse.map {|x| x.to_i }
|
146
|
-
path = dir
|
147
|
-
if File.directory?(path) and Date.valid_date?(year, month, day) and
|
148
|
-
dirs << path
|
149
|
-
end
|
150
|
-
}
|
151
|
-
dirs
|
152
|
-
end
|
153
|
-
|
154
|
-
def get_snapshot_date(snapshot)
|
155
|
-
# バックアップディレクトリのパス(日付つき)から日付を取得して返す
|
156
|
-
day, month, year = File.split_all(snapshot).reverse.map {|x| x.to_i }
|
157
|
-
Time.new(year, month, day)
|
158
|
-
end
|
159
|
-
|
160
153
|
def update_snapshot(src, latest, today)
|
161
154
|
# バックアップの差分コピーを実行
|
162
155
|
# src: コピー元ディレクトリ ex) i:/from/home
|
@@ -294,6 +287,9 @@ module Qdumpfs
|
|
294
287
|
|
295
288
|
@written_bytes = 0
|
296
289
|
start_time = Time.now
|
290
|
+
if @opt.backup_at
|
291
|
+
start_time = to_time(@opt.backup_at)
|
292
|
+
end
|
297
293
|
src = @opt.src
|
298
294
|
dst = @opt.dst
|
299
295
|
|
@@ -394,15 +390,7 @@ module Qdumpfs
|
|
394
390
|
diff = time_diff(start_time, end_time)
|
395
391
|
log("##### sync end #{fmt(end_time)} diff=#{diff} last_sync_complete=#{last_sync_complete} #####")
|
396
392
|
end
|
397
|
-
|
398
|
-
def open_verify_file
|
399
|
-
filename = File.join(@log_dir, 'verify.txt')
|
400
|
-
if FileTest.file?(filename)
|
401
|
-
File.unlink(filename)
|
402
|
-
end
|
403
|
-
File.open(filename, 'a')
|
404
|
-
end
|
405
|
-
|
393
|
+
|
406
394
|
def verify
|
407
395
|
file = @opt.open_verifyfile
|
408
396
|
|
@@ -445,74 +433,80 @@ module Qdumpfs
|
|
445
433
|
file.close
|
446
434
|
end
|
447
435
|
|
448
|
-
def
|
436
|
+
def delete(cmd)
|
449
437
|
@opt.validate_directories(1)
|
450
|
-
|
451
438
|
start_time = Time.now
|
452
439
|
limit_time = start_time + (@opt.limit_sec)
|
453
|
-
log("#####
|
454
|
-
|
440
|
+
log("##### #{cmd} delete-from=#{@opt.delete_from} delete-to=#{@opt.delete_to} start #{fmt(start_time)} => limit_time=#{fmt(limit_time)} #####")
|
455
441
|
@opt.dirs.each do |target_dir|
|
456
442
|
|
457
443
|
target_start = Time.now
|
458
|
-
|
444
|
+
delete_target_dir(cmd, target_dir)
|
459
445
|
target_end = Time.now
|
460
446
|
|
461
447
|
# 次回expireにかかる時間を最終expire時間の半分と予想
|
462
448
|
next_expire = (target_end - target_start) / 2
|
463
449
|
|
464
450
|
cur_time = Time.now
|
465
|
-
|
451
|
+
in_limit = (cur_time + next_expire) < limit_time
|
466
452
|
|
467
453
|
log("## cur_time=#{fmt(cur_time)} + next_expire=#{next_expire} < limit_time=#{fmt(limit_time)} in_limit=#{in_limit} ## ")
|
468
454
|
unless in_limit
|
469
455
|
break
|
470
456
|
end
|
471
457
|
end
|
472
|
-
|
473
|
-
log("##### expire end #####")
|
458
|
+
log("##### #{cmd} end #####")
|
474
459
|
end
|
475
|
-
|
476
|
-
def
|
460
|
+
|
461
|
+
def rm_dir(path)
|
462
|
+
can_delete = true
|
463
|
+
if @opt.dry_run
|
464
|
+
can_delete = false
|
465
|
+
elsif !FileTest.directory?(path)
|
466
|
+
can_delete = false
|
467
|
+
end
|
468
|
+
msg = can_delete ? "...ok..." : "...ng..."
|
469
|
+
print "Deleting #{path} #{msg}"
|
470
|
+
|
471
|
+
return unless can_delete
|
472
|
+
|
473
|
+
#それ以外は日付バックアップディレクトリ全体を削除
|
474
|
+
if windows?
|
475
|
+
# Windowsの場合
|
476
|
+
win_backup_path = to_win_path(path)
|
477
|
+
system("rmdir /S /Q #{win_backup_path}")
|
478
|
+
else
|
479
|
+
# Linux/macOSの場合
|
480
|
+
system("rm -rf #{path}")
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
def delete_target_dir(cmd, target_dir)
|
477
485
|
target_dir = to_unix_path(target_dir)
|
478
486
|
puts "<<<<< Target dir: #{target_dir} >>>>>"
|
479
487
|
|
480
488
|
snapshots = BackupDir.scan_backup_dirs(target_dir)
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
489
|
+
if cmd == 'expire'
|
490
|
+
@opt.detect_expire_dirs(snapshots)
|
491
|
+
elsif cmd == 'delete'
|
492
|
+
@opt.detect_delete_dirs(snapshots, @opt.delete_from, @opt.delete_to)
|
493
|
+
else
|
494
|
+
raise RuntimeError, "unknown command: #{cmd}"
|
495
|
+
end
|
496
|
+
|
487
497
|
snapshots.each do |snapshot|
|
488
498
|
next if snapshot.keep
|
489
499
|
t_start = Time.now
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
if windows?
|
498
|
-
# Windowsの場合
|
499
|
-
win_backup_path = to_win_path(snapshot.path)
|
500
|
-
|
501
|
-
# byenow = "byenow"
|
502
|
-
# if which(byenow)
|
503
|
-
# print " bynow"
|
504
|
-
# system("byenow -y --delete-ntapi --one-liner #{snapshot.path}")
|
505
|
-
# else
|
506
|
-
# print " pass1"
|
507
|
-
# system("del /F /S /Q #{win_backup_path} > nul")
|
508
|
-
# print " pass2"
|
509
|
-
# system("rmdir /S /Q #{win_backup_path}")
|
510
|
-
# end
|
511
|
-
system("rmdir /S /Q #{win_backup_path}")
|
512
|
-
else
|
513
|
-
# Linux/macOSの場合
|
514
|
-
system("rm -rf #{snapshot.path}")
|
500
|
+
|
501
|
+
if @opt.delete_dirs.size > 0
|
502
|
+
#削除するディレクトリが指定されている場合日付バックアップディレクトリの下そのディレクトリを削除
|
503
|
+
@opt.delete_dirs.each do |delete_dir|
|
504
|
+
delete_path = File.join(snapshot.path, delete_dir)
|
505
|
+
rm_dir(delete_path)
|
515
506
|
end
|
507
|
+
else
|
508
|
+
#それ以外はバックアップディレクトリ全体が対象
|
509
|
+
rm_dir(snapshot.path)
|
516
510
|
end
|
517
511
|
|
518
512
|
t_end = Time.now
|
@@ -533,8 +527,10 @@ module Qdumpfs
|
|
533
527
|
puts "Keep dirs:"
|
534
528
|
snapshots.each do |snapshot|
|
535
529
|
puts snapshot.path if snapshot.keep
|
536
|
-
end
|
537
|
-
|
530
|
+
end
|
538
531
|
end
|
532
|
+
|
533
|
+
|
539
534
|
end
|
535
|
+
|
540
536
|
end
|
data/lib/qdumpfs/option.rb
CHANGED
@@ -109,9 +109,9 @@ module Qdumpfs
|
|
109
109
|
@cmd = @opts[:c] || 'backup'
|
110
110
|
|
111
111
|
# @logger = NullLogger.new
|
112
|
-
logfile =
|
112
|
+
logfile = 'qdumpfs.log'
|
113
113
|
#ログディレクトリの作成
|
114
|
-
@logdir =
|
114
|
+
@logdir = @opts[:logdir] || Dir.pwd
|
115
115
|
Dir.mkdir(@logdir) unless FileTest.directory?(@logdir)
|
116
116
|
@logpath = File.join(@logdir, logfile)
|
117
117
|
@logger = SimpleLogger.new(@logpath)
|
@@ -139,12 +139,17 @@ module Qdumpfs
|
|
139
139
|
@keep_month = $1.to_i if keep =~ /(\d+)M/
|
140
140
|
@keep_week = $1.to_i if keep =~ /(\d+)W/
|
141
141
|
@keep_day = $1.to_i if keep =~ /(\d+)D/
|
142
|
+
@delete_from = @opts[:delete_from]
|
143
|
+
@delete_to = @opts[:delete_to]
|
144
|
+
@delete_dirs = @opts[:delete_dirs]
|
145
|
+
@backup_at = @opts[:backup_at]
|
142
146
|
@today = Date.today
|
143
147
|
end
|
144
148
|
attr_reader :dirs, :src, :dst, :cmd
|
145
149
|
attr_reader :keep_year, :keep_month, :keep_week, :keep_day
|
146
|
-
attr_reader :logdir, :
|
150
|
+
attr_reader :logdir, :logpath, :verifypath
|
147
151
|
attr_reader :logger, :matcher, :reporter, :interval_proc
|
152
|
+
attr_reader :delete_from, :delete_to, :delete_dirs, :backup_at
|
148
153
|
|
149
154
|
def report(type, filename)
|
150
155
|
if @opts[:v]
|
@@ -162,7 +167,9 @@ module Qdumpfs
|
|
162
167
|
else
|
163
168
|
# 何も指定されていない場合
|
164
169
|
if type == 'new_file'
|
165
|
-
|
170
|
+
stat = File.stat(filename)
|
171
|
+
size = stat.size
|
172
|
+
msg = format_report(type, filename, size)
|
166
173
|
end
|
167
174
|
end
|
168
175
|
log(msg)
|
@@ -204,12 +211,32 @@ module Qdumpfs
|
|
204
211
|
end
|
205
212
|
end
|
206
213
|
|
207
|
-
def
|
214
|
+
def detect_expire_dirs(backup_dirs)
|
208
215
|
detect_year_keep_dirs(backup_dirs)
|
209
216
|
detect_month_keep_dirs(backup_dirs)
|
210
217
|
detect_week_keep_dirs(backup_dirs)
|
211
218
|
detect_day_keep_dirs(backup_dirs)
|
212
219
|
end
|
220
|
+
|
221
|
+
def detect_delete_dirs(backup_dirs, delete_from, delete_to)
|
222
|
+
|
223
|
+
backup_dirs.each do |backup_dir|
|
224
|
+
backup_dir.keep = true
|
225
|
+
if delete_from && delete_to
|
226
|
+
if backup_dir.date >= delete_from && backup_dir.date <= delete_to
|
227
|
+
backup_dir.keep = false
|
228
|
+
end
|
229
|
+
elsif delete_from
|
230
|
+
if backup_dir.date >= delete_from
|
231
|
+
backup_dir.keep = false
|
232
|
+
end
|
233
|
+
elsif delete_to
|
234
|
+
if backup_dir.date <= delete_to
|
235
|
+
backup_dir.keep = false
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
213
240
|
|
214
241
|
def open_verifyfile
|
215
242
|
if FileTest.file?(@verifypath)
|
@@ -227,8 +254,8 @@ module Qdumpfs
|
|
227
254
|
end
|
228
255
|
|
229
256
|
private
|
230
|
-
def format_report(type, filename)
|
231
|
-
sprintf("
|
257
|
+
def format_report(type, filename, size)
|
258
|
+
sprintf("%s\t%s\t%d\n", type, filename, size)
|
232
259
|
end
|
233
260
|
|
234
261
|
def format_report_with_size(type, filename, size, format_size)
|
data/lib/qdumpfs/util.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# coding: utf-8
|
1
2
|
def wprintf(format, *args)
|
2
3
|
STDERR.printf("pdumpfs: " + format + "\n", *args)
|
3
4
|
end
|
@@ -278,6 +279,10 @@ module QdumpfsUtils
|
|
278
279
|
|
279
280
|
def to_unix_path(path)
|
280
281
|
path.gsub(/\\/, '/')
|
281
|
-
end
|
282
|
+
end
|
283
|
+
|
284
|
+
def to_time(date)
|
285
|
+
Time.local(date.year, date.month, date.day)
|
286
|
+
end
|
282
287
|
end
|
283
288
|
|
data/lib/qdumpfs/version.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
-
module Qdumpfs
|
2
|
-
VERSION = "0.
|
3
|
-
end
|
1
|
+
module Qdumpfs
|
2
|
+
VERSION = "0.8.0"
|
3
|
+
end
|
4
|
+
|
data/run_qdumpfs.sh
CHANGED
File without changes
|
data/sample.sh
ADDED
data/test_pdumpfs/pdumpfs-test
CHANGED
File without changes
|
data/test_qdumpfs.sh
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qdumpfs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- src
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -57,6 +57,7 @@ email:
|
|
57
57
|
- src@srcw.net
|
58
58
|
executables:
|
59
59
|
- qdumpfs
|
60
|
+
- sample
|
60
61
|
extensions: []
|
61
62
|
extra_rdoc_files: []
|
62
63
|
files:
|
@@ -73,7 +74,10 @@ files:
|
|
73
74
|
- bin/setup
|
74
75
|
- build.cmd
|
75
76
|
- build.sh
|
77
|
+
- data/from/0.txt
|
78
|
+
- data/from/a/1.txt
|
76
79
|
- exe/qdumpfs
|
80
|
+
- exe/sample
|
77
81
|
- lib/qdumpfs.rb
|
78
82
|
- lib/qdumpfs/option.rb
|
79
83
|
- lib/qdumpfs/util.rb
|
@@ -85,12 +89,14 @@ files:
|
|
85
89
|
- run_qdumpfs.cmd
|
86
90
|
- run_qdumpfs.sh
|
87
91
|
- run_sync.cmd
|
92
|
+
- sample.sh
|
88
93
|
- test_pdumpfs/data/bar
|
89
94
|
- test_pdumpfs/data/baz/quux
|
90
95
|
- test_pdumpfs/data/file
|
91
96
|
- test_pdumpfs/data/foo
|
92
97
|
- test_pdumpfs/data/secret/secret
|
93
98
|
- test_pdumpfs/pdumpfs-test
|
99
|
+
- test_qdumpfs.sh
|
94
100
|
homepage: https://github.com/src256/qdumpfs
|
95
101
|
licenses:
|
96
102
|
- MIT
|