From 59353d1c7b8900ff72a8489cd177e306abbf056a Mon Sep 17 00:00:00 2001 From: Velnbur Date: Sat, 28 Sep 2024 15:18:57 +0300 Subject: [PATCH] Implement semver comparison for deps Implement full comaparison for semver-like versions returned by pandoc and fd-find. --- rustic-doc.el | 61 +++++++++++++++++++++++++++++++++++++---- test/rustic-doc-test.el | 28 +++++++++++++++++++ 2 files changed, 84 insertions(+), 5 deletions(-) diff --git a/rustic-doc.el b/rustic-doc.el index 7a415c5..254d4e7 100644 --- a/rustic-doc.el +++ b/rustic-doc.el @@ -30,6 +30,45 @@ (require 'xdg) (fset 'rustic-doc--xdg-data-home 'xdg-data-home))) +(defun rustic-doc--make-semver (&rest version-kv) + "Return a new semver-like version from VERSION-KV. +VERSION-KV is a plist which must have :major key, and optionaly +:minor and :patch. Default values for :minor and :patch are 0. +Returned value is a list of the form (major minor patch)." + (let ((major (plist-get version-kv :major)) + (minor (or (plist-get version-kv :minor) 0)) + (patch (or (plist-get version-kv :patch) 0))) + (list major minor patch))) + +(defun rustic-doc--semver-from-string (version-str) + "Return a semver-like version from VERSION-STR." + (let* ((splitted-str (split-string version-str "\\.")) + (str-length (length splitted-str))) + (mapcar #'string-to-number + ;; take only first 3 elements or less + (seq-subseq splitted-str 0 (min 3 str-length))))) + +(defun rustic-doc--semver-greater (v1 v2) + "Return greater for two semver-like versions V1 and V2." + (defun -semver-major (v) (nth 0 v)) + (defun -semver-minor (v) (nth 1 v)) + (defun -semver-patch (v) (nth 2 v)) + + (cond + ((> (-semver-major v1) (-semver-major v2)) t) + ((< (-semver-major v1) (-semver-major v2)) nil) + ((> (-semver-minor v1) (-semver-minor v2)) t) + ((< (-semver-minor v1) (-semver-minor v2)) nil) + ((> (-semver-patch v1) (-semver-patch v2)) t) + ((< (-semver-patch v1) (-semver-patch v2)) nil) + (t nil))) + +(defconst rustic-doc-pandoc-min-version + (rustic-doc--make-semver :major 2 :minor 1)) + +(defconst rustic-doc-fd-find-min-version + (rustic-doc--make-semver :major 2)) + (defvar rustic-doc-lua-filter (concat (file-name-as-directory (getenv "HOME")) ".local/bin/rustic-doc-filter.lua") "Save location for the rustic-doc lua filter.") @@ -274,16 +313,28 @@ See buffer *cargo-makedocs* for more info") (rustic-doc--project-doc-dest))))) (message "Activate rustic-doc-mode to run `rustic-doc-convert-current-package"))) +(defun rustic-doc--extract-version (str) + "Extract semver-like version from `STR' and conver it to list. + +Both `fd-find' and `pandoc' output their versions in the form: +` \n', that's why this function parses the +version from first whitespace to the end of the line." + (let ((start (string-match-p " " str)) + (end (string-match-p "\n" str))) + (rustic-doc--semver-from-string (substring str start end)))) + (defun rustic-doc--confirm-dep-versions (missing-fd) "Verify that dependencies are not too old. -Do not check `fd' when MISSING-FD is non-nil." + Do not check `fd' when MISSING-FD is non-nil." (when (not missing-fd) - (when (> 8 (string-to-number - (substring (shell-command-to-string "fd --version") 3 4))) + (when (rustic-doc--semver-greater + rustic-doc-fd-find-min-version + (rustic-doc--extract-version (shell-command-to-string "fd --version"))) (message "Your version of fd is too old, please install a recent version, maybe through cargo."))) - (when (>= 11 (string-to-number - (substring (shell-command-to-string "pandoc --version") 9 11))) + (when (rustic-doc--semver-greater + rustic-doc-pandoc-min-version + (rustic-doc--extract-version (shell-command-to-string "pandoc --version"))) (message "Your version of pandoc is too old, please install a more recent version. See their github for more info."))) diff --git a/test/rustic-doc-test.el b/test/rustic-doc-test.el index cef86b0..c05ab77 100644 --- a/test/rustic-doc-test.el +++ b/test/rustic-doc-test.el @@ -11,4 +11,32 @@ (should (file-exists-p "~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/doc/rust/html/std/option")) (should (file-exists-p (f-join rustic-doc-save-loc "std" "option" "enum.Option.org")))) +(ert-deftest rustic-doc-semver-test () + (should (equal (rustic-doc--semver-from-string "1.0.0") '(1 0 0))) + (should (equal (rustic-doc--semver-from-string "1.0.0-alpha") '(1 0 0))) + (should (equal (rustic-doc--semver-from-string "1.0.0.1") '(1 0 0))) + + (setq cmp-test-vectors (list (list "1.0.0" "1.0.0.1" nil) + (list "1.0.0" "1.0.0-alpha" nil) + (list "2.0.1" "2.0.0" t) + (list "2.1.0" "2.0.0" t) + (list "2.1.1" "2.1.0" t))) + + (dolist (test cmp-test-vectors) + (let ((v1 (rustic-doc--semver-from-string (car test))) + (v2 (rustic-doc--semver-from-string (cadr test))) + (expected (caddr test))) + (should (equal (rustic-doc--semver-greater v1 v2) expected))))) + +(ert-deftest rustic-doc-verstion-extract-test () + (should (equal (rustic-doc--extract-version "fd 10.1.0 +") (list 10 1 0))) + (should (equal (rustic-doc--extract-version "pandoc 3.1.11.1 +Features: +server +lua +Scripting engine: Lua 5.4 +User data directory: /Users/user/.local/share/pandoc +Copyright (C) 2006-2023 John MacFarlane. Web: https://pandoc.org +This is free software; see the source for copying conditions. There is no +warranty, not even for merchantability or fitness for a particular purpose.") (list 3 1 11)))) + (provide 'rustic-doc-test)