From 4e81074270172718127ace2537d3e4a37411512a Mon Sep 17 00:00:00 2001 From: Michael Herstine Date: Mon, 24 Jul 2023 19:06:37 -0700 Subject: [PATCH] Fix issue #32 Parent dirs in elfeed-score-rule-stats-file are not Setting `elfeed-score-rule-stats-file` to a path with intermediate directories that don't exist will error-out. This fix will at least attempt to create them. Also, update the CI workflow & prep for the merge. --- .github/workflows/ci.yaml | 5 +++-- .github/workflows/melpazoid.yml | 2 +- .github/workflows/release.yml | 2 +- NEWS | 5 +++++ README.org | 16 ++++++++-------- configure.ac | 2 +- doc/version.texi | 4 ++-- elfeed-score-pkg.el | 2 +- elfeed-score-rule-stats.el | 15 ++++++++++----- elfeed-score.el | 4 ++-- test/test-stats.el | 28 ++++++++++++++++++++++++++++ 11 files changed, 62 insertions(+), 23 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index dfaf65f..6e21dae 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -51,5 +51,6 @@ jobs: ./bootstrap ./configure make - make check - make distcheck + make check || cat test/test-suite.log + pwd + make distcheck || cat elfeed-score-1.2.6/_build/sub/test/test-suite.log diff --git a/.github/workflows/melpazoid.yml b/.github/workflows/melpazoid.yml index 1dfda73..98d8c7a 100644 --- a/.github/workflows/melpazoid.yml +++ b/.github/workflows/melpazoid.yml @@ -1,5 +1,5 @@ # melpazoid build checks. -name: melpazoid +name: Run melpazoid on: workflow_dispatch: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3346528..d1a8a36 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,7 @@ # Setting up a release workflow for `elfeed-score'. Much thanks to # BurntShushi from whom I shamelessly copied a lot of this # -name: release +name: Cut a release on: # allow this workflow to be triggered manually, which is what this # event allegedly does diff --git a/NEWS b/NEWS index 03f94cf..899fe31 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,11 @@ elfeed-score News -- history of user-visible changes -*- outline -*- * elfeed-score 1.2 +** changes in elfeed-score 1.2.7 + +*** address issue #32 Parent dirs in elfeed-score-rule-stats-file are not created automatically + +If you set `elfeed-score-rule-stats-file` to a path in which some intermediate directories don't exist, elfeed-score will error on saving stats. ** changes in elfeed-score 1.2.6 *** make the depth at which the scoring function runs configurable in the new entry hook diff --git a/README.org b/README.org index 0d0bee6..e64338e 100644 --- a/README.org +++ b/README.org @@ -2,7 +2,7 @@ #+DESCRIPTION: Gnus-style scoring for Elfeed #+AUTHOR: Michael Herstine #+EMAIL: sp1ff@pobox.com -#+DATE: <2023-05-06 Sat 08:17> +#+DATE: <2023-07-26 Wed 07:28> #+AUTODATE: t #+OPTIONS: toc:nil org-md-headline-style:setext *:t ^:nil #+STARTUP: overview @@ -73,7 +73,7 @@ The easiest way to install elfeed-score is [[https://github.com/melpa/melpa][MEL If you would prefer to install the package manually, you can also download the Emacs package file on the GitHub releases [[https://github.com/sp1ff/elfeed-score/releases][page]] or from my personal [[https://www.unwoundstack/distros.html][page]]. Then say: #+BEGIN_SRC elisp -(package-install-file "elfeed-score-1.2.6.tar") +(package-install-file "elfeed-score-1.2.7.tar") #+END_SRC ** Autotools Source Distributions @@ -82,8 +82,8 @@ You can also download Autotools source tarballs (again available either on the G #+BEGIN_SRC bash cd /tmp -curl -L --output elfeed-score-1.2.6.tar.gz https://github.com/sp1ff/elfeed-score/releases/download/1.2.6/elfeed-score-1.2.6.tar.gz -tar xvf elfeed-score-1.2.6.tar.gz && cd elfeed-score-1.2.6 +curl -L --output elfeed-score-1.2.7.tar.gz https://github.com/sp1ff/elfeed-score/releases/download/1.2.7/elfeed-score-1.2.7.tar.gz +tar xvf elfeed-score-1.2.7.tar.gz && cd elfeed-score-1.2.7 export EMACSLOADPATH=$HOME/.emacs.d/elpa/elfeed-20200209.1942:$EMACSLOADPATH ./configure make @@ -98,16 +98,16 @@ The unit tests require some macros defined by the [[https://github.com/skeeto/el #+BEGIN_SRC bash cd /tmp git clone https://github.com/skeeto/elfeed.git -curl -L --output=elfeed-score-1.2.6.tar.gz https://github.com/sp1ff/elfeed-score/releases/download/1.2.6/elfeed-score-1.2.6.tar.gz -tar xvf elfeed-score-1.2.6.tar.gz && cd elfeed-score-1.2.6 -export EMACSLOADPATH=/tmp/elfeed-score-1.2.6:/tmp/elfeed:/tmp/elfeed/tests:$EMACSLOADPATH +curl -L --output=elfeed-score-1.2.7.tar.gz https://github.com/sp1ff/elfeed-score/releases/download/1.2.7/elfeed-score-1.2.7.tar.gz +tar xvf elfeed-score-1.2.7.tar.gz && cd elfeed-score-1.2.7 +export EMACSLOADPATH=/tmp/elfeed-score-1.2.7:/tmp/elfeed:/tmp/elfeed/tests:$EMACSLOADPATH ./configure make make check sudo make install #+END_SRC -Again, unless you already use =EMACSLOADPATH=, you'll need to set =EMACSLOADPATH= appropriately to your system, something like =EMACSLOADPATH=/tmp/elfeed-score-1.2.6:/tmp/elfeed:/tmp/elfeed/tests:/usr/share/emacs/25.2/lisp=. +Again, unless you already use =EMACSLOADPATH=, you'll need to set =EMACSLOADPATH= appropriately to your system, something like =EMACSLOADPATH=/tmp/elfeed-score-1.2.7:/tmp/elfeed:/tmp/elfeed/tests:/usr/share/emacs/25.2/lisp=. ** Building From Source Finally, you can of course just clone this repo & build there. I've started a [[https://github.com/sp1ff/elfeed-score/wiki][wiki]], whose intended audience are people looking to hack on elfeed-score, that includes build instructions. diff --git a/configure.ac b/configure.ac index 594133a..c77323a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ([2.69]) -AC_INIT([elfeed-score], [1.2.6], [sp1ff@pobox.com], [elfeed-score], [https://github.com/sp1ff/elfeed-score]) +AC_INIT([elfeed-score], [1.2.7], [sp1ff@pobox.com], [elfeed-score], [https://github.com/sp1ff/elfeed-score]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_SRCDIR([./elfeed-score.el]) AC_PROG_MAKE_SET diff --git a/doc/version.texi b/doc/version.texi index ccf7815..097ccb8 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -1,4 +1,4 @@ @set UPDATED 6 May 2023 @set UPDATED-MONTH May 2023 -@set EDITION 1.2.6 -@set VERSION 1.2.6 +@set EDITION 1.2.7 +@set VERSION 1.2.7 diff --git a/elfeed-score-pkg.el b/elfeed-score-pkg.el index 47aca3f..ec85779 100644 --- a/elfeed-score-pkg.el +++ b/elfeed-score-pkg.el @@ -1,5 +1,5 @@ (define-package "elfeed-score" - "1.2.6" + "1.2.7" "Gnus-style scoring for Elfeed" '((emacs "26.1") (elfeed "3.3.0"))) diff --git a/elfeed-score-rule-stats.el b/elfeed-score-rule-stats.el index bb4571b..ff78e28 100644 --- a/elfeed-score-rule-stats.el +++ b/elfeed-score-rule-stats.el @@ -124,9 +124,9 @@ This is a utility function for persisting LISP S-expressions to file. If possible, it will write SEXP to a temporary file in the same directory as FILE-NAME and then rename the temporary file to replace the original. Since the move operation is usually atomic -\(so long as both the source & the target are on the same volume) -any error leaves the original untouched, and there is never any -instant where the file is nonexistent. +\(so long as both the source & the target are on the same +filesystem) any error leaves the original untouched, and there is +never any instant where the file is nonexistent. This implementation will first check that the target file is writable and signal an error if it is not. Note that it will not @@ -145,7 +145,7 @@ heavily derivative of `basic-save-buffer-2'." (if (not (file-directory-p dir)) (if (file-exists-p dir) (error "%s is not a directory" dir) - (error "%s: no such directory" dir)) + (make-directory dir t)) (if (not (file-exists-p file-name)) (error "Directory %s write-protected" dir) (error "Attempt to save to a file that you aren't allowed to write"))))) @@ -181,7 +181,11 @@ heavily derivative of `basic-save-buffer-2'." "Current count of in-memory stats changes.") (defun elfeed-score-rule-stats-write (stats-file) - "Write the in-memory stats to STATS-FILE." + "Write the in-memory stats to STATS-FILE. + +If STATS-FILE doesn't exist, it will be created. If any parent +directories in its path don't exist, and the caller has +permission to create them, they will be created." (interactive (list (read-file-name "stats file: " nil elfeed-score-rule-stats-file t @@ -254,6 +258,7 @@ Returns a default-constructed stats object if RULE isn't in the table." ;; `elfeed-update-init-hooks' & restore it here, but I'm uncomfortable ;; with the risk that the update may be interrupted somehow, leaving ;; `elfeed-score-rule-stats-dirty-threshold' "stuck" from then on. + (defun elfeed-score-rule-stats-update-hook (_url) "Write stats when an elfeed update is complete." (when (and (eq (elfeed-queue-count-total) 0) diff --git a/elfeed-score.el b/elfeed-score.el index 9c570e2..bcc8dc7 100644 --- a/elfeed-score.el +++ b/elfeed-score.el @@ -3,7 +3,7 @@ ;; Copyright (C) 2019-2023 Michael Herstine ;; Author: Michael Herstine -;; Version: 1.2.6 +;; Version: 1.2.7 ;; Package-Requires: ((emacs "26.1") (elfeed "3.3.0")) ;; Keywords: news ;; URL: https://github.com/sp1ff/elfeed-score @@ -44,7 +44,7 @@ (require 'elfeed-score-scoring) (require 'elfeed-score-maint) -(defconst elfeed-score-version "1.2.6") +(defconst elfeed-score-version "1.2.7") (defgroup elfeed-score nil "Gnus-style scoring for Elfeed entries." diff --git a/test/test-stats.el b/test/test-stats.el index 8b4932d..fb89898 100644 --- a/test/test-stats.el +++ b/test/test-stats.el @@ -109,6 +109,34 @@ (delete-file "test-sexp") (delete-file "test-sexp-2")) +(ert-deftest test-issue-32 () + "Regression test against elfeed-score issue #32 +\"Parent dirs in elfeed-score-rule-stats-file are not created +automatically\" + +If `elfeed-score-rule-stats-write' is invoked with an argument +for which some parent directories don't exist, and the caller has +permissions, they should be created automatically." + + ;; Whip-up a few rules... + (let ((r1 (elfeed-score-title-rule--create + :text "Bar" :value 1 :type 's)) + (r2 (elfeed-score-feed-rule--create + :text "feed" :value 1 :type 's :attr 't))) + ;; & generate some stats for 'em. + (elfeed-score-rule-stats-on-match r1) + (elfeed-score-rule-stats-on-match r2) + (should (eq 2 (hash-table-count elfeed-score-rule-stats--table))) + ;; and send 'em to a target file whose parent directories don't exist (yet) + (let ((stats-file + (file-name-concat (make-temp-file "iss-32-" t) + "a" + "b" + "test-stats-file"))) + (elfeed-score-rule-stats-write stats-file) + (should (file-exists-p stats-file))) + (elfeed-score-serde-cleanup-stats))) + (provide 'test-stats) ;;; test-stats.el ends here.