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