diff --git a/CHANGELOG.md b/CHANGELOG.md index 200f555..e38ed10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ See the [New Clojure project quickstart](https://blog.michielborkent.nl/new-clojure-project-quickstart.html) blog post for a gentle introduction into `neil`. +## Unreleased + +- [#245](https://github.com/babashka/neil/issues/245): neil.el - neil-executable-path now can be set to `clj -M:neil` + ## 0.3.68 - [#230](https://github.com/babashka/neil/issues/230): neil dep upgrade inserts git/url into upgraded dep ([@teodorlu](https://github.com/teodorlu)) diff --git a/README.md b/README.md index 4aa11e9..3054e53 100644 --- a/README.md +++ b/README.md @@ -257,9 +257,15 @@ Load it using your preferred Emacs package manager, e.g., for Doom Emacs: :config (setq neil-prompt-for-version-p nil neil-inject-dep-to-project-p t)) - + +;; by default it attempts to find "neil" somewhere in the $PATH, +;; but you can set the executable explicitly, e.g., +(setq neil-executable-path "neil-cmd") +;; or: +(setq neil-executable-path "clj -M:neil") ``` + ## Github's Rate Limit Github's API has a 60 hit/hour rate-limit. The workaround for this is creating a diff --git a/neil-tests.el b/neil-tests.el index a7c1c3c..b4b8634 100644 --- a/neil-tests.el +++ b/neil-tests.el @@ -20,10 +20,20 @@ (require 'buttercup) (require 'neil) -(describe "neil-find-clojure-package, no neil" +(describe "neil executable lookup" (it "throws error when neil cmd-line executable not found" (spy-on #'executable-find :and-return-value nil) - (expect (funcall #'neil-find-clojure-package "foo") :to-throw 'error))) + (expect (funcall #'neil--find-exe) :to-throw 'error)) + (it "Properly resolves to absolute exec path" + (let ((neil-executable-path "neil")) + (spy-on #'executable-find :and-return-value "/usr/bin/neil") + (expect (funcall #'neil--find-exe) :to-equal "/usr/bin/neil")) + (let ((neil-executable-path "clj -M:neil")) + (spy-on #'executable-find :and-return-value "/usr/bin/clj") + (expect (funcall #'neil--find-exe) :to-equal "/usr/bin/clj -M:neil")) + (let ((neil-executable-path "clojure -M:neil")) + (spy-on #'executable-find :and-return-value "/usr/bin/clojure") + (expect (funcall #'neil--find-exe) :to-equal "/usr/bin/clojure -M:neil")))) (describe "neil-find-clojure-package, happy path" :var (prompt-calls shell-cmd-calls) @@ -41,13 +51,13 @@ (setf shell-cmd-calls (1+ shell-cmd-calls)) (cond ((eq shell-cmd-calls 1) - (expect command :to-equal "/bin/neil dep search test-pkg") + (expect command :to-equal (concat (neil--find-exe) " dep search test-pkg")) (concat ":lib foo/test-pkg :version \"1.0.0\" :description \"good lib\"\n" ":lib bar/awesome-test-pkg :version \"2.1.0\" :description \"better lib\"\n")) ((eq shell-cmd-calls 2) - (expect command :to-equal "/bin/neil dep versions foo/test-pkg") + (expect command :to-equal (concat (neil--find-exe) " dep versions foo/test-pkg")) (concat ":lib foo/test-pkg :version \"1.0.0\"\n" ":lib bar/awesome-test-pkg :version \"2.1.0\"\n"))))) @@ -80,6 +90,11 @@ (it "shouldn't throw 'executable not found' error" (expect (neil-find-clojure-package "test-pkg") :not :to-throw)) + (it "should work for clj -M:neil" + (let* ((neil-executable-path "clj -M:neil")) + (expect (neil-find-clojure-package "test-pkg") :to-equal + "foo/test-pkg {:mvn/version \"1.0.0\"}"))) + (it "for clojure-cli, without version prompt" (spy-on #'neil--identify-project-build-tool :and-return-value '(clojure-cli)) (let ((neil-prompt-for-version-p nil)) diff --git a/neil.el b/neil.el index 5332787..42d0e1f 100644 --- a/neil.el +++ b/neil.el @@ -5,8 +5,8 @@ ;; Author: Ag Ibragimov ;; Maintainer: Ag Ibragimov ;; Created: April 20, 2022 -;; Modified: April 20, 2022 -;; Version: 0.0.1 +;; Modified: December 07, 2024 +;; Version: 0.3.68 ;; Keywords: convenience tools ;; Homepage: https://github.com/babashka/neil ;; Package-Requires: ((emacs "27.1")) @@ -62,6 +62,21 @@ Otherwise uses the given value." (let-alist (cdr (assoc s minibuffer-completion-table)) (concat " " .version " " .description))) +(defun neil--find-exe () + "Returns absolute path to neil executable." + (if-let* ((exe (cond + ;; it should work for `neil-executable-path' values like: + ;; "clj -M:neil" or "bb -Sdeps '...' -m babashka.neil" + ;; as well as simple: "neil" or "neil-cmd" likes. + ((and (stringp neil-executable-path) + (string-match "^\\([^ ]+\\)\\s-" neil-executable-path)) + (replace-regexp-in-string + "^\\([^ ]+\\)" + (executable-find (match-string 1 neil-executable-path)) + neil-executable-path)) + (t (executable-find (or neil-executable-path "neil")))))) + exe (user-error "Cannot find executable set in 'neil-executable-path'"))) + ;;;###autoload (defun neil-find-clojure-package (&optional term) "Find Clojure dependency by supplying TERM to neil cmd-line tool. @@ -74,7 +89,7 @@ the dependency to the project (deps.edn only)." "Search for Clojure libs: " (when (member (file-name-nondirectory (or (buffer-file-name) "")) '("deps.edn" "project.clj")) - (when-let ((sym (symbol-at-point))) + (when-let* ((sym (symbol-at-point))) (symbol-name sym)))))) (let* ((format-dep-str (lambda (lib-name version) @@ -113,8 +128,7 @@ the dependency to the project (deps.edn only)." (when desc `(description . ,desc))))))) res)))) - (exe (if-let ((exe (executable-find (or neil-executable-path "neil")))) - exe (user-error "Cannot find 'neil' cmd-line utility!"))) + (exe (neil--find-exe)) (res (funcall perform-action exe (concat "dep search " (shell-quote-argument term)))) (lib-name (let ((completion-extra-properties