I had a look and the problem with approach #2 is that the signature of
readLine expects 2 args: a format string and an array of objects to be used
in the prompt. And it returns an array of chars, so you need something like:
(let [console (System/console)
chars (.readPassword console "%s" (into-array [prompt]))]
(apply str chars))
I read in https://groups.google.com/forum/#!topic/clojure/ymDZj7T35x4 that
you can check also the contents of the *ns* var to determine if you are
running in a REPL or not.
I created a dummy Leiningen project with the following functions:
(defn read-password [prompt]
;; Based on https://groups.google.com/forum/#!topic/clojure/ymDZj7T35x4
(if (= "user" (str (.getName *ns*)))
(do
(print (format "%s [will be echoed to the screen]" prompt))
(flush)
(read-line))
(let [console (System/console)
chars (.readPassword console "%s" (into-array [prompt]))]
(apply str chars))))
(defn -main [& args]
(let [password (read-password "Enter your password:")]
(println (format "Your pasword is '%s'" password))))
When running with `lein run` it echoes to the screen as expected. When ran
as `java -jar target/uberjar/readpass-0.1.0-SNAPSHOT-standalone.jar` it
uses the version that doesn't echo.
-- Denis
El martes, 11 de abril de 2017, 15:10:08 (UTC-7), Guillermo Vayá Pérez
escribió:
>
> Hi,
> I'm currently trying to get a password from the user in case it wasn't
> supplied by other means, but it seems to be a bit more difficult than I
> expected. I've already searched both the web and this mail list finding
> only partial solutions to the problem. I must say I'm not completely fluent
> in Clojure, so I'm sure there is a lot of room for improvement both in my
> solution and also the way I write it. Help on both is appreciated.
>
> Up to now what I've got so far are a couple of solutions that I'm not
> happy with, I'll put some comments on each one to clarify any problems:
>
>
> (defn- get-passkey1
> []
> ;; - not a good method, it can be copied back selecting where
> ;; text appears to be (cursor moves although nothing is printed)
> ;; - code is ugly as hell
> ;; - ansi control codes are not portable
> (print (str "password: \033[8m"))
> (flush)
> (let [pass (read-line)]
> (print (str "\033[K\033[0m")) ;; k should kill the line, but since
> read-line expects a newline,
> ;; I don't get to really kill it, so the
> pass is exposed
> (flush)
> pass))
>
> (defn- get-passkey2
> []
> ;; - doesn't work as it initially fails due to a null pointer both with
> repl and lein run
> ;; - improves a little if run with lein trampoline run (not ideal), but
> ;; complains that there is no readPassword method that matches.
> (let [console (System/console)]
> (.readPassword console "Password: %s")))
>
> ;; this one needs (:import [jline.console ConsoleReader])
> (defn- get-passkey3
> []
> ;; - in a repl this freezes the interpreter
> ;; - seems to work fine with lein run, but getting the whole
> ;; library for two lines of code seems expensive to me.
> ;; - still I'd go this route if this was the way to go (no freezing at
> least)
> (print "Enter password")
> (flush)
> (let [cr (ConsoleReader.)]
> (.readLine cr "password?" \*)))
>
> The best solution I've worked up to now is a mix between 1 and 3,
> detecting if I'm in a repl (via another ugly hack to see if there are
> command line parameters) and choose between them to sort each one's
> shortcommings.
>
> I'm wondering if there is a better way (and hoping there is) or if I can
> fix the issues with any of the implementations so I don't have to apply
> patch of code over patch of code.
>
> Thanks for any help given,
>
> Guillermo Vayá
>
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.