kostafey / ejc-sql

Emacs SQL client uses Clojure JDBC.
279 stars 29 forks source link

Doesn't work on nixos #136

Closed codygman closed 4 years ago

codygman commented 4 years ago

Specifically I get:

error in process sentinel: Could not start nREPL server: java.io.IOException: Permission denied. Please check your access rights for /nix/store/ay75a41p8z50654qq9afaakmbj9wwpxi-emacs-packages-deps/share/emacs/site-lisp/elpa/ejc-sql-20200607.2010

That's not suprising since the Nix store is readonly.

Full traceback ``` error in process sentinel: Could not start nREPL server: java.io.IOException: Permission denied. Please check your access rights for /nix/store/ay75a41p8z50654qq9afaakmbj9wwpxi-emacs-packages-deps/share/emacs/site-lisp/elpa/ejc-sql-20200607.2010/.nrepl-port at leiningen.repl$repl.invokeStatic (repl.clj:385) leiningen.repl$repl.doInvoke (repl.clj:316) clojure.lang.RestFn.applyTo (RestFn.java:142) clojure.lang.Var.applyTo (Var.java:705) clojure.core$apply.invokeStatic (core.clj:667) clojure.core$apply.invoke (core.clj:660) leiningen.core.main$partial_task$fn__6592.doInvoke (main.clj:284) clojure.lang.RestFn.applyTo (RestFn.java:139) clojure.lang.AFunction$1.doInvoke (AFunction.java:31) clojure.lang.RestFn.applyTo (RestFn.java:137) clojure.core$apply.invokeStatic (core.clj:667) clojure.core$apply.invoke (core.clj:660) leiningen.core.main$apply_task.invokeStatic (main.clj:334) leiningen.core.main$apply_task.invoke (main.clj:320) leiningen.core.main$resolve_and_apply.invokeStatic (main.clj:343) leiningen.core.main$resolve_and_apply.invoke (main.clj:336) leiningen.update_in$update_in.invokeStatic (update_in.clj:37) leiningen.update_in$update_in.doInvoke (update_in.clj:24) clojure.lang.RestFn.applyTo (RestFn.java:146) clojure.lang.Var.applyTo (Var.java:705) clojure.core$apply.invokeStatic (core.clj:667) clojure.core$apply.invoke (core.clj:660) leiningen.core.main$partial_task$fn__6592.doInvoke (main.clj:284) clojure.lang.RestFn.applyTo (RestFn.java:139) clojure.lang.AFunction$1.doInvoke (AFunction.java:31) clojure.lang.RestFn.applyTo (RestFn.java:137) clojure.core$apply.invokeStatic (core.clj:667) clojure.core$apply.invoke (core.clj:660) leiningen.core.main$apply_task.invokeStatic (main.clj:334) leiningen.core.main$apply_task.invoke (main.clj:320) leiningen.core.main$resolve_and_apply.invokeStatic (main.clj:343) leiningen.core.main$resolve_and_apply.invoke (main.clj:336) leiningen.update_in$update_in.invokeStatic (update_in.clj:37) leiningen.update_in$update_in.doInvoke (update_in.clj:24) clojure.lang.RestFn.applyTo (RestFn.java:146) clojure.lang.Var.applyTo (Var.java:705) clojure.core$apply.invokeStatic (core.clj:667) clojure.core$apply.invoke (core.clj:660) leiningen.core.main$partial_task$fn__6592.doInvoke (main.clj:284) clojure.lang.RestFn.applyTo (RestFn.java:139) clojure.lang.AFunction$1.doInvoke (AFunction.java:31) clojure.lang.RestFn.applyTo (RestFn.java:137) clojure.core$apply.invokeStatic (core.clj:667) clojure.core$apply.invoke (core.clj:660) leiningen.core.main$apply_task.invokeStatic (main.clj:334) leiningen.core.main$apply_task.invoke (main.clj:320) leiningen.core.main$resolve_and_apply.invokeStatic (main.clj:343) leiningen.core.main$resolve_and_apply.invoke (main.clj:336) leiningen.core.main$_main$fn__6681.invoke (main.clj:452) leiningen.core.main$_main.invokeStatic (main.clj:442) leiningen.core.main$_main.doInvoke (main.clj:439) clojure.lang.RestFn.applyTo (RestFn.java:137) clojure.lang.Var.applyTo (Var.java:705) clojure.core$apply.invokeStatic (core.clj:665) clojure.main$main_opt.invokeStatic (main.clj:491) clojure.main$main_opt.invoke (main.clj:487) clojure.main$main.invokeStatic (main.clj:598) clojure.main$main.doInvoke (main.clj:561) clojure.lang.RestFn.applyTo (RestFn.java:137) clojure.lang.Var.applyTo (Var.java:705) clojure.main.main (main.java:37) ```

I guess that means the official nixpkgs.emacsPackages.ejc-sql package should depend on leinigen with a preinstalled nrepl and all dependencies in advance, otherwise it won't work. Or maybe there's a setting to say "act normally and install to ~/.leiningen" or wherever that is.

The reason for this is in clomacs-launch-nrepl where the default directory seems to be where the library is.

For nix here that is the read only directory:

/nix/store/ay75a41p8z50654qq9afaakmbj9wwpxi-emacs-packages-deps/share/emacs/site-lisp/elpa/ejc-sql-20200607.2010/

I tried a naieve kind of change to just always set the directory to one place but that didn't seem to fix things:

(defun clomacs-launch-nrepl (lib-name
                             wrapped-eval
                             attributes
                             nrepl-ready-callback
                             backend)
  (let* ((starting-msg (format
                        "Starting nREPL server for %s..."
                        (propertize (or lib-name "current-buffer")
                                    'face 'font-lock-keyword-face)))
         (project-dir "/home/cody/nrepl-temp/") -- NOTE me trying to set the project-dir to a constant place I know I can write to on nixos
         (params (if project-dir (list :project-dir project-dir))))
    ;; simple run lein
    (pcase backend
      (:clj (clomacs-jack-in-clj params
                                 wrapped-eval
                                 attributes
                                 nrepl-ready-callback))
      (:cljs (clomacs-jack-in-cljs params
                                   wrapped-eval
                                   attributes
                                   nrepl-ready-callback))
      (_ (error "Unknown backend %s" backend)))
    (message starting-msg))
  nil)

Actually no, it did:

[nREPL] Starting server via /home/cody/.nix-profile/bin/lein update-in :dependencies conj \[nrepl\ \"0.8.0-alpha3\"\] -- update-in :plugins conj \[cider/cider-nrepl\ \"0.25.3-SNAPSHOT\"\] -- repl :headless :host localhost
Starting nREPL server for ejc-sql...
nil
[nREPL] server started on 37749
[nREPL] Establishing direct connection to localhost:37749 ...
[nREPL] Direct connection to localhost:37749 established

My test code was just wrong:

(clomacs-with-nrepl "ejc-sql" (message "hi"))

I did something wrong since ejc-connect-interactive now throws this error:

nrepl-send-sync-request: Wrong type argument: stringp, nil
kostafey commented 4 years ago

Hi, @codygman. At this moment, using the write-protected project directory is impossible. nREPL needs to create .nrepl-port file and it is not an option: https://github.com/nrepl/nrepl/blob/35e8eb5ba2c05c7063b8e794e6f2d62f587646cd/src/clojure/nrepl/cmdline.clj#L412

I guess that means the official nixpkgs.emacsPackages.ejc-sql package should depend on leinigen

I don't maintain nixpkg ejc-sql package. At this moment the only preferred way to install ejc-sql is by MEPLA: https://github.com/kostafey/ejc-sql#installation. And obviously, if you want, you can clone this repository to your preferred folder manually and configure Emacs to load the package from this directory.

I tried a naieve kind of change to just always set the directory to one place but that didn't seem to fix things:

As far as I know, it's rather useless, since project-dir should be configured properly to locate project.clj (build.boot) file.

(clomacs-with-nrepl "ejc-sql" (message "hi"))

Function is expected as clomacs-with-nrepl body:

(clomacs-with-nrepl "ejc-sql"
  (lambda ()
    (message "hi")))

So, the main idea of clomacs is not to create mixed Elisp-Clojure Emacs extensions only, but to create them totally introspective and interact with Clojure code as Emacs to its own Elisp. This is achieved by CIDER. I think it's possible to add embedded nREPL to ejc-sql than connect to it via CIDER as always: https://nrepl.org/nrepl/usage/server.html#_embedding_nrepl But anyway, I don't sure I'll implement it very soon. So, the best way to use ejc-sql at this monument is to install it as expected: via MELPA: https://github.com/kostafey/ejc-sql#installation.

codygman commented 4 years ago

Okay, I'll close this for now then.

Sadly though, for nix users installing via this repo or melpa will give the same error since both will want to write inside of /nix.

For any curious searchers who might want to use ejc-sql on nix I left off at setting project-dir to /tmp and got a new error that seems it could be elisp related. Here is the code, error is below.This was with commit

...
[nREPL] Direct connection to localhost:33047 established
nrepl-send-sync-request: Wrong type argument: stringp, nil
[nREPL] server started on 45381
[nREPL] Establishing direct connection to localhost:45381 ...
[nREPL] Direct connection to localhost:45381 established
nrepl-send-sync-request: Wrong type argument: stringp, nil
...
WeissP commented 11 months ago

I thought I could get rid of ejc-sql, but it turned out not to be possible :). So here is my workaround to (imperfectly) fix this issue:

Simply execute the following code before starting the REPL:

(setq ejc-sql-lib-path
      (clojure-project-dir
       (file-name-directory (find-library-name "ejc-sql"))))
(setq ejc-repl-dir "/tmp/ejc-sql")
(unless (file-directory-p ejc-repl-dir)
  (copy-directory ejc-sql-lib-path ejc-repl-dir nil t t)
  (set-file-modes ejc-repl-dir 493))
(defun find-library-name-overriding-ejc (lib-name)
  "Replace the library dir of ejc-sql"
  (when (string= lib-name "ejc-sql") (format "%s/ejc-sql.el" ejc-repl-dir)))
(advice-add 'find-library-name :before-until #'find-library-name-overriding-ejc)

The idea is simple: copy the source directory to /tmp and let find-library-name find ejc-sql in /tmp.