1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
| | From fae622c8b77feebac66a538d76e4211de8bd8eb3 Mon Sep 17 00:00:00 2001
From: Philip McGrath <philip@philipmcgrath.com>
Date: Sun, 24 Jul 2022 21:50:44 -0400
Subject: [PATCH] fix saving `AnyStyle::Dictionary` after `populate!`
Some of these fixes are more generally applicable.
A more robust solution might find data files using
e.g. `Gem.find_files()`.
---
lib/anystyle/dictionary/gdbm.rb | 6 ++++++
lib/anystyle/dictionary/marshal.rb | 31 ++++++++++++++++++++++++------
2 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/lib/anystyle/dictionary/gdbm.rb b/lib/anystyle/dictionary/gdbm.rb
index 754903c..c814df2 100644
--- a/lib/anystyle/dictionary/gdbm.rb
+++ b/lib/anystyle/dictionary/gdbm.rb
@@ -1,5 +1,6 @@
module AnyStyle
require 'gdbm'
+ require 'fileutils'
class Dictionary
class GDBM < Dictionary
@@ -17,8 +18,13 @@ module AnyStyle
def open
close
+ FileUtils.mkdir_p(File.dirname(options[:path]))
@db = ::GDBM.new(*options.values_at(:path, :mode, :flags))
self
+ rescue Errno::EACCES
+ # GDBM.new tries this if :flags is nil, but not necessarily otherwise
+ @db = ::GDBM.new(options[:path],options[:mode],::GDBM::READER)
+ self
ensure
populate! if empty?
end
diff --git a/lib/anystyle/dictionary/marshal.rb b/lib/anystyle/dictionary/marshal.rb
index 761ca36..b9529d0 100644
--- a/lib/anystyle/dictionary/marshal.rb
+++ b/lib/anystyle/dictionary/marshal.rb
@@ -1,4 +1,6 @@
module AnyStyle
+ require 'fileutils'
+ require 'tempfile'
class Dictionary
class Marshal < Dictionary
@defaults = {
@@ -10,17 +12,34 @@ module AnyStyle
end
def open
- if File.exists?(options[:path])
- @db = ::Marshal.load(File.open(options[:path]))
- else
- @db = {}
+ File.open(options[:path]) do |file|
+ @db = ::Marshal.load(file)
end
self
+ rescue Errno::ENOENT
+ @db = {}
+ self
ensure
if empty?
populate!
- if File.writable?(options[:path])
- ::Marshal.dump(db, File.open(options[:path], 'wb'))
+ tmp = nil
+ begin
+ FileUtils.mkdir_p(File.dirname(options[:path]))
+ tmp = Tempfile.create(File.basename(options[:path]),
+ File.dirname(options[:path]),
+ mode: File::Constants::BINARY)
+ pth = tmp.path()
+ ::Marshal.dump(db, tmp)
+ tmp.close()
+ File.rename(tmp.path, options[:path]) # will overwrite if exists
+ tmp = nil
+ rescue SystemCallError => e
+ warn(e.message)
+ ensure
+ if tmp then
+ tmp.close()
+ tmp.unlink()
+ end
end
end
end
--
2.32.0
|