Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement semver comparison for rust-doc dependencies #570

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 56 additions & 5 deletions rustic-doc.el
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
(require 'xdg)
(fset 'rustic-doc--xdg-data-home 'xdg-data-home)))

(defconst rustic-doc-pandoc-min-version
(rustic-mode--make-semver :major 2 :minor 1))

(defconst rustic-doc-fd-find-min-version
(rustic-mode--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.")
Expand Down Expand Up @@ -72,6 +78,39 @@ Needs to be a function because of its reliance on
(defvar helm-ag-success-exit-status)
(declare-function helm-ag "ext:helm-ag")

(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
(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)))

(defun rustic-doc-default-search-function (search-dir search-term)
"Default search functionality.
Uses helm-ag and ripgrep if possible, grep otherwise.
Expand Down Expand Up @@ -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:
`<program> <semver>\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.")))


Expand Down
27 changes: 27 additions & 0 deletions test/rustic-doc-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,30 @@
(sleep-for 1))
(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))))