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

feat: pretty printing without color #16

Merged
merged 1 commit into from
Oct 12, 2022
Merged
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
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ Options:
-i, --in FORMAT yaml Input format: csv, edn, json, lines, msgpack, text, transit, yaml
-o, --out FORMAT edn Output format: csv, edn, json, lines, msgpack, text, transit, yaml
-p, --[no-]pretty Pretty print output - default is true
--color COLOR auto When pretty printing, whether to use colors: auto, off, on - default is auto
-c Same as --color=on
-C Same as --color=off
-k, --key-fn FN keyword Function used to transform keys - currently only supported for JSON and CSV
--yaml-unsafe Enables unsafe mode in clj-yaml / SnakeYAML
--[no-]yaml-keywords Turn map keys into keywords in clj-yaml - default is true
Expand Down
6 changes: 4 additions & 2 deletions src/cq/formats.clj
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@
(edn/read (PushbackReader. (io/reader in)))))

(defn ->edn-writer
[{:keys [pretty]}]
[{:keys [pretty color]}]
(if pretty
(fn [x out]
(binding [*out* (io/writer out)]
(puget/cprint x)))
(if color
(puget/cprint x)
(puget/pprint x))))
(fn [x out]
(binding [*out* (io/writer out)]
(pr x)
Expand Down
23 changes: 22 additions & 1 deletion src/cq/main.clj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

(require 'cq.readers)

(def colors #{:auto :on :off})

(def colors-str (str/join ", " (sort (map name colors))))

(def formats (set (keys fmt/formats)))

(def formats-str (str/join ", " (sort formats)))
Expand All @@ -24,6 +28,16 @@
:validate [formats]]
["-p" "--[no-]pretty" "Pretty print output - default is true"
:default true]
[nil "--color COLOR" (str "When pretty printing, whether to use colors: " colors-str " - default is auto")
:default "auto"
:parse-fn keyword
:validate [colors]]
["-c" nil "Same as --color=on"
:id :color
:assoc-fn (fn [m _ _] (assoc m :color :on))]
["-C" nil "Same as --color=off"
:id :color
:assoc-fn (fn [m _ _] (assoc m :color :off))]
["-k" "--key-fn FN" "Function used to transform keys - currently only supported for JSON and CSV"
:default "keyword"]
[nil "--yaml-unsafe" "Enables unsafe mode in clj-yaml / SnakeYAML"]
Expand Down Expand Up @@ -96,11 +110,18 @@
(def ^:dynamic *stdin* System/in)
(def ^:dynamic *stdout* System/out)

(defn- handle-auto-options [opts]
(update opts :color #(case %
:auto true ; would be nice to detect
:on true
false)))

(defn main
[args]
(let [{:keys [arguments exit-message ok?]
{:keys [in out] :as opts} :options}
(validate-args args)]
(validate-args args)
opts (handle-auto-options opts)]
(if exit-message
(exit (if ok? 0 1) exit-message)
(let [expressions (args->exprs arguments)
Expand Down
20 changes: 19 additions & 1 deletion test/cq/formats_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,25 @@
(is (= {:a {:b [1 2 3]}} (test-reader-str sut/->edn-reader nil "{:a {:b [1 2 3]}}"))))

(testing "writer"
(is (= "{:a {:b [1 2 3]}}\n" (test-writer-str sut/->edn-writer nil {:a {:b [1 2 3]}})))))
(is (= "{:a {:b [1 2 3]}}\n" (test-writer-str sut/->edn-writer nil {:a {:b [1 2 3]}})))

(testing "pretty"
(is (= "{:a {:b [1 2 3],\n :c [2 3 {:something :long}],\n :d [1 2 {:something :even/longer}]}}\n"
(test-writer-str sut/->edn-writer {:pretty true :color false} {:a {:b [1 2 3] :c [2 3 {:something :long}] :d [1 2 {:something :even/longer}]}})))

(testing "color"
(is (= "\u001B[1;31m{\u001B[0m\u001B[1;33m:a\u001B[0m \u001B[1;31m{\u001B[0m\u001B[1;33m:b\u001B[0m \u001B[1;31m[\u001B[0m\u001B[36m1\u001B[0m \u001B[36m2\u001B[0m \u001B[36m3\u001B[0m\u001B[1;31m]\u001B[0m,\n \u001B[1;33m:c\u001B[0m \u001B[1;31m[\u001B[0m\u001B[36m2\u001B[0m \u001B[36m3\u001B[0m \u001B[1;31m{\u001B[0m\u001B[1;33m:something\u001B[0m \u001B[1;33m:long\u001B[0m\u001B[1;31m}\u001B[0m\u001B[1;31m]\u001B[0m,\n \u001B[1;33m:d\u001B[0m \u001B[1;31m[\u001B[0m\u001B[36m1\u001B[0m \u001B[36m2\u001B[0m \u001B[1;31m{\u001B[0m\u001B[1;33m:something\u001B[0m \u001B[1;33m:even/longer\u001B[0m\u001B[1;31m}\u001B[0m\u001B[1;31m]\u001B[0m\u001B[1;31m}\u001B[0m\u001B[1;31m}\u001B[0m\n"
(test-writer-str sut/->edn-writer {:pretty true :color true} {:a {:b [1 2 3] :c [2 3 {:something :long}] :d [1 2 {:something :even/longer}]}})))))))

(comment
;; simple utility for printing an ANSI escaped sequence for a test constant
;; ANSI uses the ESC character for escape codes and it is lost in printing
(let [x {:a {:b [1 2 3] :c [2 3 {:something :long}] :d [1 2 {:something :even/longer}]}}
s (test-writer-str sut/->edn-writer {:pretty true :color true} x)]
(str/join (for [c s]
(if (= 27 (int c))
"ESC" ; replace with \u001B and you get a test constant
c)))))

(defn resource->bytes [file]
(with-open [xin (io/input-stream (io/resource file))
Expand Down