3
5
Fork 0
mirror of git://git.savannah.gnu.org/guix.git synced 2023-12-14 03:33:07 +01:00

gnu: ruby-anystyle: Initialize dictionary files.

For the GDBM and Marshal dictionary adapters to be useful with their
default settings, we must initialize their data files during the package
build: upstream would initialize them lazily, but that doesn't work with
an immutable installation directory (at least, not without more complex
patches). Otherwise, we would always end up rebuilding the dictionary at
startup, which is “slow” and “not recommended”.

* gnu/packages/patches/ruby-anystyle-fix-dictionary-populate.patch: New
patch.
* gnu/local.mk (dist_patch_DATA): Add it.
* gnu/packages/ruby.scm (ruby-anystyle)[patches]: Use it.
[arguments]<#:phases>: Add 'populate-dictionaries' phase.

Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
Philip McGrath 2022-07-25 08:16:33 -04:00 committed by Ludovic Courtès
parent bc2de56572
commit 14a50b62d4
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5
3 changed files with 125 additions and 1 deletions

View file

@ -1783,6 +1783,7 @@ dist_patch_DATA = \
%D%/packages/patches/rocm-opencl-runtime-4.3-noclinfo.patch \
%D%/packages/patches/rocm-opencl-runtime-4.3-noopencl.patch \
%D%/packages/patches/ruby-anystyle-data-immutable-install.patch \
%D%/packages/patches/ruby-anystyle-fix-dictionary-populate.patch \
%D%/packages/patches/ruby-latex-decode-fix-test.patch \
%D%/packages/patches/ruby-mustache-1.1.1-fix-race-condition-tests.patch \
%D%/packages/patches/ruby-sanitize-system-libxml.patch \

View file

@ -0,0 +1,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

View file

@ -13516,6 +13516,9 @@ the power of the built-in @code{OptionParser}.")
(substitute* "spec/anystyle/parser_spec.rb"
(("language: 'en'," orig)
(string-append "# " orig " # no lanugage_detector")))))
(patches
(search-patches
"ruby-anystyle-fix-dictionary-populate.patch"))
(file-name (git-file-name name version))))
(build-system ruby-build-system)
(propagated-inputs
@ -13545,7 +13548,33 @@ the power of the built-in @code{OptionParser}.")
(lambda args
(substitute* "anystyle.gemspec"
(("`git ls-files spec`")
"`find spec -type f | sort`")))))))
"`find spec -type f | sort`"))))
(add-after 'wrap 'populate-dictionaries
(lambda args
;; We must initiallize these files here, or they will never be
;; usable with the default settings. A more flexible approach
;; might use something like `Gem.find_files()` or
;; XDG_DATA_DIRS.
(with-output-to-file "initialize-dictionaries.rb"
(lambda ()
(display "
require 'anystyle/dictionary' # must come before 'anystyle/data'
require 'anystyle/data'
[:marshal, :gdbm].each do |adapter|
AnyStyle::Dictionary.create({adapter: adapter}).open().close()
end
")))
(let* ((old-gems (getenv "GEM_PATH"))
(new-gems (string-append #$output
"/lib/ruby/vendor_ruby:"
old-gems)))
(dynamic-wind
(lambda ()
(setenv "GEM_PATH" new-gems))
(lambda ()
(invoke "ruby" "initialize-dictionaries.rb"))
(lambda ()
(setenv "GEM_PATH" old-gems)))))))))
(home-page "https://anystyle.io")
(synopsis "Fast and smart citation reference parsing (Ruby library)")
(description