qdumpfs 0.6.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 606cd6d5f9de57b340a1ac41d5e621d2f947cff5e1fce3a9ec510be72e0f0d4d
4
- data.tar.gz: 073da696b6e73cd8059a246fbe18b51f09050f100bb9f7a454954921d4e5d228
3
+ metadata.gz: c7e95debed71b63b553da2ee5d9f4bb7828a855c1ed76a20188821fc507222f0
4
+ data.tar.gz: 31272461b61233cc082f9b44370eb3304415ac8025b67d8a13900795ead68570
5
5
  SHA512:
6
- metadata.gz: 34c7c309574b3cbd00175b0e327d1df5687fa2acb84fcb3d29ff5d77adeaacfddc5f91a28de702d0aaa06e0b694ea722d00d43ed50d7b7f74d80d2f754b1027c
7
- data.tar.gz: f5702a62c4b9ab44364df7c697c5d503ddccce6b946f2e7702de6783521aa05afa358df218686a90934a80af64906105068bb5cd0a77aa8fcacf597e56541436
6
+ metadata.gz: 7419e48fea0c72b06d7c810ae22cf6c12f78aa4e9bcce21ffeeba176eafd039836169b178c0a13f892ca3834f687ea0a271b811311e6bf4904917a15a315ebf9
7
+ data.tar.gz: 1e596cb96545f92477e8695fd77394aba619afc928176a2d0f505914c25d1215e1eeda648a7673d10794460ea4521cb93933fe1303313b08aa7660d25d8ccb2f
data/.gitignore CHANGED
@@ -12,4 +12,7 @@ log.txt
12
12
  *test.cmd
13
13
  test*.cmd
14
14
  *.log
15
+ /data/to
16
+ /data/to2
17
+
15
18
 
data/Gemfile.lock CHANGED
@@ -1,13 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- qdumpfs (0.6.0)
4
+ qdumpfs (1.0.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- minitest (5.14.2)
10
- rake (13.0.1)
9
+ minitest (5.14.4)
10
+ rake (13.0.3)
11
11
 
12
12
  PLATFORMS
13
13
  ruby
data/README.md CHANGED
@@ -1,13 +1,14 @@
1
1
  # Qdumpfs
2
2
 
3
- qdumpfs is a modified version of pdumpfs.
3
+ pdumpfsの個人的改良版です。
4
4
 
5
- ## Installation
5
+ Gem化して最近のバージョンのバージョンのRubyに対応。コマンドの拡張などを行っています。
6
6
 
7
- gem install qdumpfs
7
+ ## インストール
8
8
 
9
- ## Usage
9
+ gem install qdumpfs
10
10
 
11
+ ## 使用方法
11
12
 
12
13
  ```
13
14
  Usage: qdumpfs [options] <source> <dest>
@@ -19,48 +20,53 @@ Options
19
20
  -e, --exclude=PATTERN exclude files/directories matching PATTERN
20
21
  -s, --exclude-by-size=SIZE exclude files larger than SIZE
21
22
  -w, --exclude-by-glob=GLOB exclude files matching GLOB
22
- -c, --command=COMMAND backup|sync|list|expire|verify|test
23
+ -c, --command=COMMAND backup|sync|list|expire|verify|delete
23
24
  -l, --limit=HOURS limit hours
24
25
  -k, --keep=KEEPARG ex: --keep 100Y12M12W30D (100years, 12months, 12weeks, 30days, default)
25
26
  ```
26
27
 
27
- ## Example
28
+ ## 実行例
29
+
30
+
31
+ バックアップを実行する場合。
28
32
 
29
- Backup your home directory, run the following command.
30
33
  ```
31
34
  qdumpfs /home/foo /backup
32
35
  ```
33
36
 
34
- You can specify command option(default is "backup").
37
+ "--command backup"オプションを明示することもできます。
38
+
35
39
  ```
36
40
  qdumpfs --command=backup /home/foo /backup
37
41
  ```
38
42
 
39
- Sync two backup directories.
43
+ "--command sync"でバックアップフォルダを同期できます。
40
44
  ```
41
45
  qdumpfs --command=sync /backup1 /backup2
42
46
  ```
43
47
 
44
- Sync two backup directories(limit 1 hours, keep 100Y12M12W30D).
48
+ バックアップフォルダの同期には膨大な時間が必要な場合があるため、実行時間を制限できます。以下は例えば1時間に制限する場合です。
45
49
  ```
46
50
  qdumpfs --command=sync --limit=1 /backup1 /backup2
47
51
  ```
48
52
 
49
- Sync two backup directories(limit 1 hours, keep specified backups only).
53
+ バックアップフォルダの同期で、1時間でかつ"100Y12M12W30D"を保存する場合のオプションです。
50
54
  ```
51
- qdumpfs --command=sync --limit=1 --keep=5Y6M7W10D --keep/backup1 /backup2
55
+ qdumpfs --command=sync --limit=1 --keep=5Y6M7W10D backup1 /backup2
52
56
  ```
53
57
 
54
- Expire backup directory.
58
+ "--command expire"で、"--keep="パターンに該当しないバックアップを削除できます。
55
59
  ```
56
- qdumpfs --command=expire --limit=1 --keep=5Y6M7W10D --keep/backup1 /backup2
60
+ qdumpfs --command=expire --limit=1 --keep=5Y6M7W10D backup1 /backup2
57
61
  ```
58
62
 
63
+ "--command delete"で、バックアップに存在する指定したパスを削除できます(間違えてバックアップした内容を削除したい場合などに使用)。
64
+ ```
65
+ qdumpfs --command=delete --delete-dir=backup1 --limit=1 r:/backup2
66
+ ```
59
67
 
60
68
  ## License
61
69
 
62
70
  qdumpfs is a free software with ABSOLUTELY NO WARRANTY under the terms of the GNU General Public License version 2.
63
71
 
64
72
 
65
-
66
-
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
@@ -38,15 +38,22 @@ module Qdumpfs
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
- opt.on('--logdir LOGDIR', 'logdir') {|v| opts[:logdir] = v}
42
- opt.on('--delete-from YYYYMMDD', 'delete backup from YYYY/MM/DD') {|v|
41
+ opt.on('--logdir=LOGDIR', 'logdir') {|v| opts[:logdir] = v}
42
+ opt.on('--delete-from=YYYYMMDD', 'delete backup from YYYY/MM/DD') {|v|
43
43
  opts[:delete_from] = Date.parse(v)
44
44
  }
45
- opt.on('--delete-to YYYYMMDD', 'delete backup to YYYY/MM/DD') {|v|
45
+ opt.on('--delete-to=YYYYMMDD', 'delete backup to YYYY/MM/DD') {|v|
46
46
  opts[:delete_to] = Date.parse(v)
47
- }
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
+ }
54
+ opt.on('-d', '--debug', 'debug mode') {|v| opts[:d] = v }
48
55
  opt.parse!(argv)
49
- option = Option.new(opts, ARGV)
56
+ option = Option.new(opts, argv)
50
57
  if opts[:v]
51
58
  puts "<<<<< qdumpfs options >>>>> "
52
59
  puts "logdir: #{option.logdir}"
@@ -58,8 +65,10 @@ module Qdumpfs
58
65
  command = Command.new(option)
59
66
  command.run
60
67
  rescue => e
61
- # p e.message
62
- # p e.backtrace
68
+ if option.debug
69
+ p e.message
70
+ p e.backtrace
71
+ end
63
72
  puts opt.help
64
73
  exit
65
74
  end
@@ -82,8 +91,6 @@ module Qdumpfs
82
91
  verify
83
92
  elsif @opt.cmd == 'delete'
84
93
  delete('delete')
85
- # elsif @opt.cmd == 'test'
86
- # test
87
94
  else
88
95
  raise RuntimeError, "unknown command: #{@opt.cmd}"
89
96
  end
@@ -130,11 +137,17 @@ module Qdumpfs
130
137
  end
131
138
 
132
139
  def filecount(dir)
133
- pscmd = 'Get-ChildItem -Recurse -File | Measure-Object | %{$_.Count}'
134
- cmd = "powershell -Command \"#{pscmd}\""
135
- result = nil
136
- Dir.chdir(dir) do
137
- result = `#{cmd}`
140
+ result = '0'
141
+ if windows?
142
+ pscmd = 'Get-ChildItem -Recurse -File | Measure-Object | %{$_.Count}'
143
+ cmd = "powershell -Command \"#{pscmd}\""
144
+ result = nil
145
+ Dir.chdir(dir) do
146
+ result = `#{cmd}`
147
+ result.chomp!
148
+ end
149
+ else
150
+ result = `find #{dir} | wc -l`
138
151
  result.chomp!
139
152
  end
140
153
  result.to_i
@@ -146,29 +159,6 @@ module Qdumpfs
146
159
  return src_count, dst_count
147
160
  end
148
161
 
149
- def get_snapshots(target_dir)
150
- # 指定したディレクトリに含まれるバックアップフォルダ(日付つき)を全て取得
151
- dd = "[0-9][0-9]"
152
- dddd = dd + dd
153
- # FIXME: Y10K problem.
154
- dirs = []
155
- glob_path = File.join(target_dir, dddd, dd, dd)
156
- Dir.glob(glob_path).sort.find {|dir|
157
- day, month, year = File.split_all(dir).reverse.map {|x| x.to_i }
158
- path = dir
159
- if File.directory?(path) and Date.valid_date?(year, month, day) and
160
- dirs << path
161
- end
162
- }
163
- dirs
164
- end
165
-
166
- def get_snapshot_date(snapshot)
167
- # バックアップディレクトリのパス(日付つき)から日付を取得して返す
168
- day, month, year = File.split_all(snapshot).reverse.map {|x| x.to_i }
169
- Time.new(year, month, day)
170
- end
171
-
172
162
  def update_snapshot(src, latest, today)
173
163
  # バックアップの差分コピーを実行
174
164
  # src: コピー元ディレクトリ ex) i:/from/home
@@ -189,8 +179,8 @@ module Qdumpfs
189
179
  # ファイルのアップデート
190
180
  update_file(s, l, t)
191
181
  dirs[t] = File.stat(s) if File.ftype(s) == "directory"
192
- rescue Errno::ENOENT, Errno::EACCES => e
193
- wprintf("%s: %s", src, e.message)
182
+ rescue => e
183
+ log("#{src}: #{e.message}")
194
184
  next
195
185
  end
196
186
  end
@@ -224,8 +214,8 @@ module Qdumpfs
224
214
  end
225
215
  chown_if_root(type, s, t)
226
216
  dirs[t] = File.stat(s) if File.ftype(s) == "directory"
227
- rescue Errno::ENOENT, Errno::EACCES => e
228
- wprintf("%s: %s", s, e.message)
217
+ rescue => e
218
+ log("#{src}: #{e.message}")
229
219
  next
230
220
  end
231
221
  end
@@ -237,7 +227,7 @@ module Qdumpfs
237
227
 
238
228
  #コピー元のスナップショット
239
229
  src_snapshots = BackupDir.scan_backup_dirs(src)
240
- @opt.detect_keep_dirs(src_snapshots)
230
+ @opt.detect_expire_dirs(src_snapshots)
241
231
 
242
232
  # コピー先の最新スナップショット
243
233
  dst_snapshots = BackupDir.scan_backup_dirs(dst)
@@ -306,6 +296,9 @@ module Qdumpfs
306
296
 
307
297
  @written_bytes = 0
308
298
  start_time = Time.now
299
+ if @opt.backup_at
300
+ start_time = to_time(@opt.backup_at)
301
+ end
309
302
  src = @opt.src
310
303
  dst = @opt.dst
311
304
 
@@ -451,11 +444,9 @@ module Qdumpfs
451
444
 
452
445
  def delete(cmd)
453
446
  @opt.validate_directories(1)
454
-
455
447
  start_time = Time.now
456
448
  limit_time = start_time + (@opt.limit_sec)
457
- log("##### #{cmd} start #{fmt(start_time)} => limit_time=#{fmt(limit_time)} #####")
458
-
449
+ log("##### #{cmd} delete-from=#{@opt.delete_from} delete-to=#{@opt.delete_to} start #{fmt(start_time)} => limit_time=#{fmt(limit_time)} #####")
459
450
  @opt.dirs.each do |target_dir|
460
451
 
461
452
  target_start = Time.now
@@ -476,6 +467,29 @@ module Qdumpfs
476
467
  log("##### #{cmd} end #####")
477
468
  end
478
469
 
470
+ def rm_dir(path)
471
+ can_delete = true
472
+ if @opt.dry_run
473
+ can_delete = false
474
+ elsif !FileTest.directory?(path)
475
+ can_delete = false
476
+ end
477
+ msg = can_delete ? "...ok..." : "...ng..."
478
+ print "Deleting #{path} #{msg}"
479
+
480
+ return unless can_delete
481
+
482
+ #それ以外は日付バックアップディレクトリ全体を削除
483
+ if windows?
484
+ # Windowsの場合
485
+ win_backup_path = to_win_path(path)
486
+ system("rmdir /S /Q #{win_backup_path}")
487
+ else
488
+ # Linux/macOSの場合
489
+ system("rm -rf #{path}")
490
+ end
491
+ end
492
+
479
493
  def delete_target_dir(cmd, target_dir)
480
494
  target_dir = to_unix_path(target_dir)
481
495
  puts "<<<<< Target dir: #{target_dir} >>>>>"
@@ -488,40 +502,20 @@ module Qdumpfs
488
502
  else
489
503
  raise RuntimeError, "unknown command: #{cmd}"
490
504
  end
491
-
492
- # p @opt.keep_year
493
- # p @opt.keep_month
494
- # p @opt.keep_day
495
-
505
+
496
506
  snapshots.each do |snapshot|
497
507
  next if snapshot.keep
498
508
  t_start = Time.now
499
- print "Deleting #{snapshot.path} ..."
500
-
501
- unless @opt.dry_run
502
- #http://superuser.com/questions/19762/mass-deleting-files-in-windows/289399#289399
503
- ##### here
504
- #bundle exec ruby exe/qdumpfs --dry-run --keep=100Y36M30W30D --command expire f:/pc1/pdumpfs/users f:/pc1/pdumpfs/opt f:/pc1/pdumpfs/d
505
-
506
- if windows?
507
- # Windowsの場合
508
- win_backup_path = to_win_path(snapshot.path)
509
-
510
- # byenow = "byenow"
511
- # if which(byenow)
512
- # print " bynow"
513
- # system("byenow -y --delete-ntapi --one-liner #{snapshot.path}")
514
- # else
515
- # print " pass1"
516
- # system("del /F /S /Q #{win_backup_path} > nul")
517
- # print " pass2"
518
- # system("rmdir /S /Q #{win_backup_path}")
519
- # end
520
- system("rmdir /S /Q #{win_backup_path}")
521
- else
522
- # Linux/macOSの場合
523
- system("rm -rf #{snapshot.path}")
509
+
510
+ if @opt.delete_dirs.size > 0
511
+ #削除するディレクトリが指定されている場合日付バックアップディレクトリの下そのディレクトリを削除
512
+ @opt.delete_dirs.each do |delete_dir|
513
+ delete_path = File.join(snapshot.path, delete_dir)
514
+ rm_dir(delete_path)
524
515
  end
516
+ else
517
+ #それ以外はバックアップディレクトリ全体が対象
518
+ rm_dir(snapshot.path)
525
519
  end
526
520
 
527
521
  t_end = Time.now
@@ -545,60 +539,6 @@ module Qdumpfs
545
539
  end
546
540
  end
547
541
 
548
- # def delete
549
- # @opt.validate_directories(1)
550
-
551
- # start_time = Time.now
552
- # limit_time = start_time + (@opt.limit_sec)
553
- # log("##### delete start #{fmt(start_time)} => limit_time=#{fmt(limit_time)} #####")
554
- # @opt.dirs.each do |target_dir|
555
- # target_start = Time.now
556
- # delete_target_dir(target_dir)
557
- # target_end = Time.now
558
-
559
- # # 次回expireにかかる時間を最終expire時間の半分と予想
560
- # next_expire = (target_end - target_start) / 2
561
-
562
- # cur_time = Time.now
563
- # in_imit = (cur_time + next_expire) < limit_time
564
-
565
- # log("## cur_time=#{fmt(cur_time)} + next_expire=#{next_expire} < limit_time=#{fmt(limit_time)} in_limit=#{in_limit} ## ")
566
- # unless in_limit
567
- # break
568
- # end
569
- # end
570
- # log("##### delete end #####")
571
- # end
572
-
573
- # def delete_target_dir(target_dir)
574
- # target_dir = to_unix_path(target_dir)
575
- # puts "<<<<< Target dir: #{target_dir} >>>>>"
576
-
577
- # snapshots = BackupDir.scan_backup_dirs(target_dir)
578
- # @opt.detect_delete_dirs(snapshots)
579
-
580
- # snapshots.each do |snapshot|
581
- # next if snapshot.keep
582
- # t_start = Time.now
583
- # print "Deleting #{snapshot.path} ..."
584
-
585
- # unless @opt.dry_run
586
- # if windows?
587
- # # Windowsの場合
588
- # win_backup_path = to_win_path(snapshot.path)
589
- # system("rmdir /S /Q #{win_backup_path}")
590
- # else
591
- # # Linux/macOSの場合
592
- # system("rm -rf #{snapshot.path}")
593
- # end
594
- # end
595
- # end
596
-
597
- # t_end = Time.now
598
- # diff = (t_end - t_start).to_i
599
- # diff_hours = diff / 3600
600
- # puts " done[#{diff} seconds = #{diff_hours} hours]."
601
- # end
602
542
 
603
543
  end
604
544
 
@@ -140,14 +140,18 @@ module Qdumpfs
140
140
  @keep_week = $1.to_i if keep =~ /(\d+)W/
141
141
  @keep_day = $1.to_i if keep =~ /(\d+)D/
142
142
  @delete_from = @opts[:delete_from]
143
- @delete_to = @opts[:delete_to]
143
+ @delete_to = @opts[:delete_to]
144
+ @delete_dirs = @opts[:delete_dirs] || []
145
+ @backup_at = @opts[:backup_at]
144
146
  @today = Date.today
147
+ @debug = @opts[:d]
145
148
  end
146
149
  attr_reader :dirs, :src, :dst, :cmd
147
150
  attr_reader :keep_year, :keep_month, :keep_week, :keep_day
148
151
  attr_reader :logdir, :logpath, :verifypath
149
152
  attr_reader :logger, :matcher, :reporter, :interval_proc
150
- attr_reader :delete_from, :delete_to
153
+ attr_reader :delete_from, :delete_to, :delete_dirs, :backup_at
154
+ attr_reader :debug
151
155
 
152
156
  def report(type, filename)
153
157
  if @opts[:v]
@@ -217,14 +221,21 @@ module Qdumpfs
217
221
  end
218
222
 
219
223
  def detect_delete_dirs(backup_dirs, delete_from, delete_to)
224
+
220
225
  backup_dirs.each do |backup_dir|
221
226
  backup_dir.keep = true
222
- if delete_from && backup_dir.date >= delete_from && delete_to && backup_dir.date <= delete_to
223
- backup_dir.keep = false
224
- elsif delete_from && backup_dir.date >= delete_from
225
- backup_dir.keep = false
226
- elsif delete_to && backup_dir.date <= delete_to
227
- backup_dir.keep = false
227
+ if delete_from && delete_to
228
+ if backup_dir.date >= delete_from && backup_dir.date <= delete_to
229
+ backup_dir.keep = false
230
+ end
231
+ elsif delete_from
232
+ if backup_dir.date >= delete_from
233
+ backup_dir.keep = false
234
+ end
235
+ elsif delete_to
236
+ if backup_dir.date <= delete_to
237
+ backup_dir.keep = false
238
+ end
228
239
  end
229
240
  end
230
241
  end
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
@@ -72,14 +73,14 @@ module QdumpfsFind
72
73
  yield file.dup.taint
73
74
  begin
74
75
  s = File.lstat(file)
75
- rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG => e
76
+ rescue => e
76
77
  logger.print("File.lstat path=#{file} error=#{e.message}")
77
78
  next
78
79
  end
79
80
  if s.directory? then
80
81
  begin
81
82
  fs = Dir.entries(file, :encoding=>'UTF-8')
82
- rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG => e
83
+ rescue => e
83
84
  logger.print("Dir.entries path=#{file} error=#{e.message}")
84
85
  next
85
86
  end
@@ -106,23 +107,22 @@ module QdumpfsUtils
106
107
 
107
108
  # We don't use File.copy for calling @interval_proc.
108
109
  def copy_file(src, dest)
109
- File.open(src, 'rb') {|r|
110
- File.open(dest, 'wb') {|w|
111
- block_size = (r.stat.blksize or 8192)
112
- begin
110
+ begin
111
+ File.open(src, 'rb') {|r|
112
+ File.open(dest, 'wb') {|w|
113
+ block_size = (r.stat.blksize or 8192)
113
114
  i = 0
114
115
  while true
115
116
  block = r.sysread(block_size)
116
117
  w.syswrite(block)
117
118
  i += 1
118
119
  @written_bytes += block.size
119
- # @interval_proc.call if i % 10 == 0
120
120
  end
121
- rescue EOFError => e
122
- # puts e.message, e.backtrace
123
- end
121
+ }
124
122
  }
125
- }
123
+ rescue EOFError => e
124
+ # puts e.message, e.backtrace
125
+ end
126
126
  unless FileTest.file?(dest)
127
127
  raise "copy_file fails #{dest}"
128
128
  end
@@ -278,6 +278,10 @@ module QdumpfsUtils
278
278
 
279
279
  def to_unix_path(path)
280
280
  path.gsub(/\\/, '/')
281
- end
281
+ end
282
+
283
+ def to_time(date)
284
+ Time.local(date.year, date.month, date.day)
285
+ end
282
286
  end
283
287
 
@@ -1,3 +1,4 @@
1
- module Qdumpfs
2
- VERSION = "0.6.0"
3
- end
1
+ module Qdumpfs
2
+ VERSION = "1.0.1"
3
+ end
4
+
data/run_list.sh ADDED
@@ -0,0 +1,5 @@
1
+ #!/bin/sh
2
+
3
+ curdir=$(dirname $0)
4
+ bundle exec ruby $curdir/exe/qdumpfs --command=list /Volumes/EXT/
5
+
data/run_qdumpfs.sh CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/bin/sh
2
2
 
3
3
  curdir=$(dirname $0)
4
- bundle exec ruby $curdir/exe/qdumpfs $*
4
+ bundle exec ruby $curdir/exe/qdumpfs "$@"
data/sample.sh ADDED
@@ -0,0 +1,5 @@
1
+ #!/bin/sh
2
+
3
+ curdir=$(dirname $0)
4
+ bundle exec ruby $curdir/exe/sample
5
+
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.6.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - src
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-18 00:00:00.000000000 Z
11
+ date: 2021-04-10 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
@@ -82,9 +86,11 @@ files:
82
86
  - qdumpfs.gemspec
83
87
  - run2_qdumpfs.cmd
84
88
  - run_list.cmd
89
+ - run_list.sh
85
90
  - run_qdumpfs.cmd
86
91
  - run_qdumpfs.sh
87
92
  - run_sync.cmd
93
+ - sample.sh
88
94
  - test_pdumpfs/data/bar
89
95
  - test_pdumpfs/data/baz/quux
90
96
  - test_pdumpfs/data/file