qdumpfs 0.5.1 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a5a18d42979f9ddc74bca2e274dc76b38ab50377398497b244399e9997a693da
4
- data.tar.gz: 017acf5a04a798a3eefab1626b2262a8a8fcfe5a10350b4dd8b2ac7003810c03
3
+ metadata.gz: d4f23500798845b355c0218ddb9fe5245d18bc0fb206a948d272f379adba6f3e
4
+ data.tar.gz: 1acc58713bd896da322648ac909bbbbd8359831c530e5f160d022d8091fa4adc
5
5
  SHA512:
6
- metadata.gz: 1dc38b92a65d33b0ebcf52e9db1ba9a6c0940ac7dc1e2270e86ee8f329fbceb466a490dad1f763f0caeaa72e97bfc3156873e6fd5402606e9eb5a2858c82c29f
7
- data.tar.gz: 948fd22961accdd955cdb6c66b73c11548be2e6a8bc99fc41fbec23b8ba3cd82ae70df1c21d4653e4ee9cc28b5ec34b53a50b1caf227bd2240d0bef2176edab7
6
+ metadata.gz: 4e1d6c3155d669e9a17a199b8ea70749615fe116c496c166bc477036c66715814337d1cbb8db562236d5bed755ba3f21bc45600f5d5e2f070f5eb847f9275057
7
+ data.tar.gz: 2a4deb71d95507c1ddba720899528874df09f0245b9a668a90aca5fd2d4d06472632ee2b5b1b7c78c1a6d5e894c4c77f21ffa09b1734350f2aff697568aede4c
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.5.1)
4
+ qdumpfs (1.0.0)
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
@@ -34,13 +34,26 @@ 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
- opt.on('--logdir LOGDIR', 'logdir') {|v| opts[:logdir] = 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
+ 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
+ }
54
+ opt.on('-d', '--debug', 'debug mode') {|v| opts[:d] = v }
42
55
  opt.parse!(argv)
43
- option = Option.new(opts, ARGV)
56
+ option = Option.new(opts, argv)
44
57
  if opts[:v]
45
58
  puts "<<<<< qdumpfs options >>>>> "
46
59
  puts "logdir: #{option.logdir}"
@@ -52,6 +65,10 @@ module Qdumpfs
52
65
  command = Command.new(option)
53
66
  command.run
54
67
  rescue => e
68
+ if option.debug
69
+ p e.message
70
+ p e.backtrace
71
+ end
55
72
  puts opt.help
56
73
  exit
57
74
  end
@@ -69,13 +86,13 @@ module Qdumpfs
69
86
  elsif @opt.cmd == 'list'
70
87
  list
71
88
  elsif @opt.cmd == 'expire'
72
- expire
89
+ delete('expire')
73
90
  elsif @opt.cmd == 'verify'
74
91
  verify
75
- # elsif @opt.cmd == 'test'
76
- # test
77
- # else
78
- raise RuntimeError, "unknown command: #{cmd}"
92
+ elsif @opt.cmd == 'delete'
93
+ delete('delete')
94
+ else
95
+ raise RuntimeError, "unknown command: #{@opt.cmd}"
79
96
  end
80
97
  end
81
98
 
@@ -120,11 +137,17 @@ module Qdumpfs
120
137
  end
121
138
 
122
139
  def filecount(dir)
123
- pscmd = 'Get-ChildItem -Recurse -File | Measure-Object | %{$_.Count}'
124
- cmd = "powershell -Command \"#{pscmd}\""
125
- result = nil
126
- Dir.chdir(dir) do
127
- 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`
128
151
  result.chomp!
129
152
  end
130
153
  result.to_i
@@ -136,29 +159,6 @@ module Qdumpfs
136
159
  return src_count, dst_count
137
160
  end
138
161
 
139
- def get_snapshots(target_dir)
140
- # 指定したディレクトリに含まれるバックアップフォルダ(日付つき)を全て取得
141
- dd = "[0-9][0-9]"
142
- dddd = dd + dd
143
- # FIXME: Y10K problem.
144
- dirs = []
145
- glob_path = File.join(target_dir, dddd, dd, dd)
146
- Dir.glob(glob_path).sort.find {|dir|
147
- day, month, year = File.split_all(dir).reverse.map {|x| x.to_i }
148
- path = dir
149
- if File.directory?(path) and Date.valid_date?(year, month, day) and
150
- dirs << path
151
- end
152
- }
153
- dirs
154
- end
155
-
156
- def get_snapshot_date(snapshot)
157
- # バックアップディレクトリのパス(日付つき)から日付を取得して返す
158
- day, month, year = File.split_all(snapshot).reverse.map {|x| x.to_i }
159
- Time.new(year, month, day)
160
- end
161
-
162
162
  def update_snapshot(src, latest, today)
163
163
  # バックアップの差分コピーを実行
164
164
  # src: コピー元ディレクトリ ex) i:/from/home
@@ -179,7 +179,7 @@ module Qdumpfs
179
179
  # ファイルのアップデート
180
180
  update_file(s, l, t)
181
181
  dirs[t] = File.stat(s) if File.ftype(s) == "directory"
182
- rescue Errno::ENOENT, Errno::EACCES => e
182
+ rescue => e
183
183
  wprintf("%s: %s", src, e.message)
184
184
  next
185
185
  end
@@ -214,7 +214,7 @@ module Qdumpfs
214
214
  end
215
215
  chown_if_root(type, s, t)
216
216
  dirs[t] = File.stat(s) if File.ftype(s) == "directory"
217
- rescue Errno::ENOENT, Errno::EACCES => e
217
+ rescue => e
218
218
  wprintf("%s: %s", s, e.message)
219
219
  next
220
220
  end
@@ -227,7 +227,7 @@ module Qdumpfs
227
227
 
228
228
  #コピー元のスナップショット
229
229
  src_snapshots = BackupDir.scan_backup_dirs(src)
230
- @opt.detect_keep_dirs(src_snapshots)
230
+ @opt.detect_expire_dirs(src_snapshots)
231
231
 
232
232
  # コピー先の最新スナップショット
233
233
  dst_snapshots = BackupDir.scan_backup_dirs(dst)
@@ -296,6 +296,9 @@ module Qdumpfs
296
296
 
297
297
  @written_bytes = 0
298
298
  start_time = Time.now
299
+ if @opt.backup_at
300
+ start_time = to_time(@opt.backup_at)
301
+ end
299
302
  src = @opt.src
300
303
  dst = @opt.dst
301
304
 
@@ -439,74 +442,80 @@ module Qdumpfs
439
442
  file.close
440
443
  end
441
444
 
442
- def expire
445
+ def delete(cmd)
443
446
  @opt.validate_directories(1)
444
-
445
447
  start_time = Time.now
446
448
  limit_time = start_time + (@opt.limit_sec)
447
- log("##### expire start #{fmt(start_time)} => limit_time=#{fmt(limit_time)} #####")
448
-
449
+ log("##### #{cmd} delete-from=#{@opt.delete_from} delete-to=#{@opt.delete_to} start #{fmt(start_time)} => limit_time=#{fmt(limit_time)} #####")
449
450
  @opt.dirs.each do |target_dir|
450
451
 
451
452
  target_start = Time.now
452
- expire_target_dir(target_dir)
453
+ delete_target_dir(cmd, target_dir)
453
454
  target_end = Time.now
454
455
 
455
456
  # 次回expireにかかる時間を最終expire時間の半分と予想
456
457
  next_expire = (target_end - target_start) / 2
457
458
 
458
459
  cur_time = Time.now
459
- in_imit = (cur_time + next_expire) < limit_time
460
+ in_limit = (cur_time + next_expire) < limit_time
460
461
 
461
462
  log("## cur_time=#{fmt(cur_time)} + next_expire=#{next_expire} < limit_time=#{fmt(limit_time)} in_limit=#{in_limit} ## ")
462
463
  unless in_limit
463
464
  break
464
465
  end
465
466
  end
466
-
467
- log("##### expire end #####")
467
+ log("##### #{cmd} end #####")
468
468
  end
469
-
470
- def expire_target_dir(target_dir)
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
+
493
+ def delete_target_dir(cmd, target_dir)
471
494
  target_dir = to_unix_path(target_dir)
472
495
  puts "<<<<< Target dir: #{target_dir} >>>>>"
473
496
 
474
497
  snapshots = BackupDir.scan_backup_dirs(target_dir)
475
- @opt.detect_keep_dirs(snapshots)
476
-
477
- # p @opt.keep_year
478
- # p @opt.keep_month
479
- # p @opt.keep_day
480
-
498
+ if cmd == 'expire'
499
+ @opt.detect_expire_dirs(snapshots)
500
+ elsif cmd == 'delete'
501
+ @opt.detect_delete_dirs(snapshots, @opt.delete_from, @opt.delete_to)
502
+ else
503
+ raise RuntimeError, "unknown command: #{cmd}"
504
+ end
505
+
481
506
  snapshots.each do |snapshot|
482
507
  next if snapshot.keep
483
508
  t_start = Time.now
484
- print "Deleting #{snapshot.path} ..."
485
-
486
- unless @opt.dry_run
487
- #http://superuser.com/questions/19762/mass-deleting-files-in-windows/289399#289399
488
- ##### here
489
- #bundle exec ruby exe/qdumpfs --dry-run --keep=100Y36M30W30D --command expire f:/pc1/pdumpfs/users f:/pc1/pdumpfs/opt f:/pc1/pdumpfs/d
490
-
491
- if windows?
492
- # Windowsの場合
493
- win_backup_path = to_win_path(snapshot.path)
494
-
495
- # byenow = "byenow"
496
- # if which(byenow)
497
- # print " bynow"
498
- # system("byenow -y --delete-ntapi --one-liner #{snapshot.path}")
499
- # else
500
- # print " pass1"
501
- # system("del /F /S /Q #{win_backup_path} > nul")
502
- # print " pass2"
503
- # system("rmdir /S /Q #{win_backup_path}")
504
- # end
505
- system("rmdir /S /Q #{win_backup_path}")
506
- else
507
- # Linux/macOSの場合
508
- 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)
509
515
  end
516
+ else
517
+ #それ以外はバックアップディレクトリ全体が対象
518
+ rm_dir(snapshot.path)
510
519
  end
511
520
 
512
521
  t_end = Time.now
@@ -527,8 +536,10 @@ module Qdumpfs
527
536
  puts "Keep dirs:"
528
537
  snapshots.each do |snapshot|
529
538
  puts snapshot.path if snapshot.keep
530
- end
531
-
539
+ end
532
540
  end
541
+
542
+
533
543
  end
544
+
534
545
  end
@@ -139,12 +139,19 @@ 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
147
+ @debug = @opts[:d]
143
148
  end
144
149
  attr_reader :dirs, :src, :dst, :cmd
145
150
  attr_reader :keep_year, :keep_month, :keep_week, :keep_day
146
151
  attr_reader :logdir, :logpath, :verifypath
147
152
  attr_reader :logger, :matcher, :reporter, :interval_proc
153
+ attr_reader :delete_from, :delete_to, :delete_dirs, :backup_at
154
+ attr_reader :debug
148
155
 
149
156
  def report(type, filename)
150
157
  if @opts[:v]
@@ -206,12 +213,32 @@ module Qdumpfs
206
213
  end
207
214
  end
208
215
 
209
- def detect_keep_dirs(backup_dirs)
216
+ def detect_expire_dirs(backup_dirs)
210
217
  detect_year_keep_dirs(backup_dirs)
211
218
  detect_month_keep_dirs(backup_dirs)
212
219
  detect_week_keep_dirs(backup_dirs)
213
220
  detect_day_keep_dirs(backup_dirs)
214
221
  end
222
+
223
+ def detect_delete_dirs(backup_dirs, delete_from, delete_to)
224
+
225
+ backup_dirs.each do |backup_dir|
226
+ backup_dir.keep = true
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
239
+ end
240
+ end
241
+ end
215
242
 
216
243
  def open_verifyfile
217
244
  if FileTest.file?(@verifypath)
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.5.1"
3
- end
1
+ module Qdumpfs
2
+ VERSION = "1.0.0"
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.5.1
4
+ version: 1.0.0
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-17 00:00:00.000000000 Z
11
+ date: 2021-04-07 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