qdumpfs 1.2.1 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.vscode/settings.json +3 -0
- data/Gemfile.lock +5 -4
- data/build.cmd +1 -1
- data/lib/qdumpfs/option.rb +19 -8
- data/lib/qdumpfs/util.rb +2 -1
- data/lib/qdumpfs/version.rb +1 -1
- data/lib/qdumpfs/win32.rb +0 -140
- data/lib/qdumpfs.rb +4 -4
- data/run_sync.cmd +2 -2
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b25a6c117f23df1dee400451de5cc4a74b1f701d3b1b8f10c3e7dbf2b9b1bc45
|
4
|
+
data.tar.gz: 82d1049e0c68f14ac62fb758f4924867cb04a0ca1c80a260e2d397fa5f45ebcf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff36ff467335da6da4dff83413cd3756e50cde6b83cccbc438b04bd44f41ccf59b3f3daf90335bdfe9f7ccf62bcd473de72e643f7f05229844bf4e2e238888ec
|
7
|
+
data.tar.gz: ef34f14cbfd8f16cc5f7172b590714bfb3b996e198dac6e12af8b34a94bb290776e8a84ec337ca7493712c6ae8d78dbb9bfa3e2780dc89b221ae48d020639a2e
|
data/Gemfile.lock
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
qdumpfs (1.
|
4
|
+
qdumpfs (1.5.1)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
-
minitest (5.
|
9
|
+
minitest (5.19.0)
|
10
10
|
rake (13.0.6)
|
11
11
|
|
12
12
|
PLATFORMS
|
13
|
-
|
13
|
+
x64-mingw32
|
14
|
+
x86_64-darwin-22
|
14
15
|
|
15
16
|
DEPENDENCIES
|
16
17
|
bundler (~> 2.0)
|
@@ -19,4 +20,4 @@ DEPENDENCIES
|
|
19
20
|
rake (>= 12.3.3)
|
20
21
|
|
21
22
|
BUNDLED WITH
|
22
|
-
2.
|
23
|
+
2.2.33
|
data/build.cmd
CHANGED
data/lib/qdumpfs/option.rb
CHANGED
@@ -13,17 +13,28 @@ module Qdumpfs
|
|
13
13
|
backup_dirs << backup_dir
|
14
14
|
end
|
15
15
|
end
|
16
|
+
backup_dirs.sort_by!{|backup_dir| backup_dir.date}
|
16
17
|
backup_dirs
|
17
18
|
end
|
18
19
|
|
19
20
|
def self.find(backup_dirs, from_date, to_date)
|
20
21
|
backup_dirs.select{|backup_dir| backup_dir.date >= from_date && backup_dir.date <= to_date}
|
21
22
|
end
|
23
|
+
|
24
|
+
def self.dump(dirs)
|
25
|
+
dirs.each do |dir|
|
26
|
+
puts dir
|
27
|
+
end
|
28
|
+
end
|
22
29
|
|
23
30
|
def initialize
|
24
31
|
@keep = false
|
25
32
|
end
|
26
33
|
attr_accessor :path, :date, :keep
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
"path=#{@path} date=#{@date} keep=#{@keep}"
|
37
|
+
end
|
27
38
|
end
|
28
39
|
|
29
40
|
|
@@ -214,13 +225,13 @@ module Qdumpfs
|
|
214
225
|
@dirs.each do |dir|
|
215
226
|
validate_directory(dir)
|
216
227
|
end
|
217
|
-
if @dirs.size == 2 && windows?
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
end
|
228
|
+
# if @dirs.size == 2 && windows?
|
229
|
+
# # ディレクトリが2つだけ指定されている場合、コピー先はntfsである必要がある
|
230
|
+
# unless ntfs?(dst)
|
231
|
+
# fstype = get_filesystem_type(dst)
|
232
|
+
# raise sprintf("only NTFS is supported but %s is %s.", dst, fstype)
|
233
|
+
# end
|
234
|
+
# end
|
224
235
|
if @dirs.size < min_count
|
225
236
|
raise "#{min_count} directories required."
|
226
237
|
end
|
@@ -298,7 +309,7 @@ module Qdumpfs
|
|
298
309
|
end
|
299
310
|
|
300
311
|
def keep_dirs(backup_dirs, num)
|
301
|
-
num.downto(0) do |i|
|
312
|
+
(num - 1).downto(0) do |i|
|
302
313
|
from_date, to_date = yield(i)
|
303
314
|
dirs = BackupDir.find(backup_dirs, from_date, to_date)
|
304
315
|
dirs[0].keep = true if dirs.size > 0
|
data/lib/qdumpfs/util.rb
CHANGED
@@ -171,7 +171,7 @@ module QdumpfsUtils
|
|
171
171
|
case File.ftype(src)
|
172
172
|
when "file"
|
173
173
|
same_file = same_file?(src, latest)
|
174
|
-
|
174
|
+
# puts "same_file? #{src} #{latest} result=#{same_file}"
|
175
175
|
if same_file
|
176
176
|
type = "unchanged"
|
177
177
|
else
|
@@ -183,6 +183,7 @@ module QdumpfsUtils
|
|
183
183
|
type = "symlink"
|
184
184
|
end
|
185
185
|
else
|
186
|
+
# puts "latest=#{latest}"
|
186
187
|
case File.ftype(src)
|
187
188
|
when "file"
|
188
189
|
type = "new_file"
|
data/lib/qdumpfs/version.rb
CHANGED
data/lib/qdumpfs/win32.rb
CHANGED
@@ -4,143 +4,3 @@ def windows?
|
|
4
4
|
/mswin32|cygwin|mingw|bccwin/.match(RUBY_PLATFORM)
|
5
5
|
end
|
6
6
|
|
7
|
-
if windows?
|
8
|
-
# http://www.virtuouscode.com/2011/08/25/temporarily-disabling-warnings-in-ruby/
|
9
|
-
|
10
|
-
# https://stackoverflow.com/questions/39051793/can-i-hide-the-warning-message-dl-is-deprecated-please-use-fiddle-in-ruby
|
11
|
-
original_verbose = $VERBOSE
|
12
|
-
$VERBOSE = nil
|
13
|
-
|
14
|
-
require 'Win32API'
|
15
|
-
require "win32ole"
|
16
|
-
|
17
|
-
$VERBOSE = original_verbose
|
18
|
-
|
19
|
-
if RUBY_VERSION < "1.8.0"
|
20
|
-
CreateHardLinkA = Win32API.new("kernel32", "CreateHardLinkA", "ppl", 'i')
|
21
|
-
def File.link(l, t)
|
22
|
-
result = CreateHardLinkA.call(t, l, 0)
|
23
|
-
|
24
|
-
raise Errno::EACCES if result == 0
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def expand_special_folders(dir)
|
29
|
-
specials = %w[(?:AllUsers)?(?:Desktop|Programs|Start(?:Menu|up)) Favorites
|
30
|
-
Fonts MyDocuments NetHood PrintHood Recent SendTo Templates]
|
31
|
-
|
32
|
-
pattern = Regexp.compile(sprintf('^@(%s)', specials.join('|')))
|
33
|
-
|
34
|
-
dir.sub(pattern) do |match|
|
35
|
-
WIN32OLE.new("WScript.Shell").SpecialFolders(match)
|
36
|
-
end.tr('\\', File::SEPARATOR)
|
37
|
-
end
|
38
|
-
|
39
|
-
GetVolumeInformation = Win32API.new("kernel32", "GetVolumeInformation", "PPLPPPPL", "I")
|
40
|
-
def get_filesystem_type(path)
|
41
|
-
return nil unless(FileTest.exist?(path))
|
42
|
-
|
43
|
-
drive = File.expand_path(path)[0..2]
|
44
|
-
buff = "\0" * 1024
|
45
|
-
GetVolumeInformation.call(drive, nil, 0, nil, nil, nil, buff, 1024)
|
46
|
-
|
47
|
-
buff.sub(/\000+/, '')
|
48
|
-
end
|
49
|
-
|
50
|
-
def ntfs?(dir)
|
51
|
-
get_filesystem_type(dir) == "NTFS"
|
52
|
-
end
|
53
|
-
|
54
|
-
GetLocaltime = Win32API.new("kernel32", "GetLocalTime", "P", 'V')
|
55
|
-
SystemTimeToFileTime = Win32API.new("kernel32", "SystemTimeToFileTime", "PP", 'I')
|
56
|
-
def get_file_time(time)
|
57
|
-
pSYSTEMTIME = ' ' * 2 * 8 # 2byte x 8
|
58
|
-
pFILETIME = ' ' * 2 * 8 # 2byte x 8
|
59
|
-
|
60
|
-
GetLocaltime.call(pSYSTEMTIME)
|
61
|
-
t1 = pSYSTEMTIME.unpack("S8")
|
62
|
-
t1[0..1] = time.year, time.month
|
63
|
-
t1[3..6] = time.day, time.hour, time.min, time.sec
|
64
|
-
|
65
|
-
SystemTimeToFileTime.call(t1.pack("S8"), pFILETIME)
|
66
|
-
|
67
|
-
pFILETIME
|
68
|
-
end
|
69
|
-
|
70
|
-
GENERIC_WRITE = 0x40000000
|
71
|
-
OPEN_EXISTING = 3
|
72
|
-
FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
|
73
|
-
|
74
|
-
class << File
|
75
|
-
alias_method(:utime_orig, :utime)
|
76
|
-
end
|
77
|
-
|
78
|
-
CreateFile = Win32API.new("kernel32", "CreateFileA","PLLLLLL", "L")
|
79
|
-
SetFileTime = Win32API.new("kernel32", "SetFileTime", "LPPP", "I")
|
80
|
-
CloseHandle = Win32API.new("kernel32", "CloseHandle", "L", "I")
|
81
|
-
|
82
|
-
def File.utime(a, m, dir)
|
83
|
-
File.utime_orig(a, m, dir) unless(File.directory?(dir))
|
84
|
-
|
85
|
-
atime = get_file_time(a.dup.utc)
|
86
|
-
mtime = get_file_time(m.dup.utc)
|
87
|
-
|
88
|
-
hDir = CreateFile.Call(dir.dup, GENERIC_WRITE, 0, 0, OPEN_EXISTING,
|
89
|
-
FILE_FLAG_BACKUP_SEMANTICS, 0)
|
90
|
-
SetFileTime.call(hDir, 0, atime, mtime)
|
91
|
-
CloseHandle.Call(hDir)
|
92
|
-
|
93
|
-
return 0
|
94
|
-
end
|
95
|
-
|
96
|
-
LOCALE_USER_DEFAULT = 0x400
|
97
|
-
LOCALE_SABBREVLANGNAME = 3
|
98
|
-
LOCALE_USE_CP_ACP = 0x40000000
|
99
|
-
GetLocaleInfo = Win32API.new("kernel32", "GetLocaleInfo", "IIPI", "I")
|
100
|
-
|
101
|
-
def get_locale_name
|
102
|
-
locale_name = " " * 32
|
103
|
-
status = GetLocaleInfo.call(LOCALE_USER_DEFAULT,
|
104
|
-
LOCALE_SABBREVLANGNAME | LOCALE_USE_CP_ACP,
|
105
|
-
locale_name, 32)
|
106
|
-
if status == 0
|
107
|
-
return nil
|
108
|
-
else
|
109
|
-
return locale_name.split("\x00").first
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
SW_HIDE = 0
|
114
|
-
SW_SHOWNORMAL = 1
|
115
|
-
|
116
|
-
ShellExecute = Win32API.new("shell32", "ShellExecute", "LPPPPL", 'L')
|
117
|
-
LoadIcon = Win32API.new("user32", "LoadIcon", "II", "I")
|
118
|
-
GetModuleFileName = Win32API.new("kernel32", "GetModuleFileName","IPI","I")
|
119
|
-
|
120
|
-
def get_exe_file_name
|
121
|
-
path = "\0" * 1024
|
122
|
-
length = GetModuleFileName.call(0 ,path, path.length)
|
123
|
-
return path[0, length].tr('\\', File::SEPARATOR)
|
124
|
-
end
|
125
|
-
|
126
|
-
def get_program_file_name
|
127
|
-
exe_file_name = get_exe_file_name
|
128
|
-
if File.basename(exe_file_name) == "ruby.exe"
|
129
|
-
return File.expand_path($0).gsub('\\', File::SEPARATOR)
|
130
|
-
else
|
131
|
-
return exe_file_name
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
def get_program_directory
|
136
|
-
program_file_name = get_program_file_name
|
137
|
-
return File.dirname(program_file_name)
|
138
|
-
end
|
139
|
-
|
140
|
-
def init
|
141
|
-
locale_name = get_locale_name
|
142
|
-
# $KCODE = "SJIS" if locale_name == "JPN"
|
143
|
-
end
|
144
|
-
|
145
|
-
init
|
146
|
-
end
|
data/lib/qdumpfs.rb
CHANGED
@@ -241,15 +241,15 @@ module Qdumpfs
|
|
241
241
|
|
242
242
|
def sync_latest(src, dst, base = nil)
|
243
243
|
# pdumpfsのバックアップフォルダを同期する
|
244
|
-
|
244
|
+
|
245
245
|
#コピー元のスナップショット
|
246
246
|
src_snapshots = BackupDir.scan_backup_dirs(src)
|
247
247
|
@opt.detect_expire_dirs(src_snapshots)
|
248
|
-
|
248
|
+
|
249
249
|
# コピー先の最新スナップショット
|
250
250
|
dst_snapshots = BackupDir.scan_backup_dirs(dst)
|
251
251
|
dst_snapshot = dst_snapshots[-1]
|
252
|
-
|
252
|
+
|
253
253
|
# コピー元フォルダの決定
|
254
254
|
src_snapshot = nil
|
255
255
|
src_snapshots.each do |snapshot|
|
@@ -259,7 +259,7 @@ module Qdumpfs
|
|
259
259
|
break
|
260
260
|
end
|
261
261
|
end
|
262
|
-
|
262
|
+
|
263
263
|
if src_snapshot.nil?
|
264
264
|
return false, nil, nil
|
265
265
|
end
|
data/run_sync.cmd
CHANGED
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: 1.
|
4
|
+
version: 1.5.1
|
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: 2023-08-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -63,6 +63,7 @@ extra_rdoc_files: []
|
|
63
63
|
files:
|
64
64
|
- ".gitignore"
|
65
65
|
- ".travis.yml"
|
66
|
+
- ".vscode/settings.json"
|
66
67
|
- CODE_OF_CONDUCT.md
|
67
68
|
- Gemfile
|
68
69
|
- Gemfile.lock
|
@@ -120,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
121
|
- !ruby/object:Gem::Version
|
121
122
|
version: '0'
|
122
123
|
requirements: []
|
123
|
-
rubygems_version: 3.2.
|
124
|
+
rubygems_version: 3.2.33
|
124
125
|
signing_key:
|
125
126
|
specification_version: 4
|
126
127
|
summary: qdumpfs
|