v0.0.37, add tree example, fix *command-line-args*

This commit is contained in:
Michiel Borkent 2019-11-27 18:08:03 +01:00
parent 4773457a68
commit 8afb87142e
4 changed files with 100 additions and 4 deletions

View file

@ -564,6 +564,25 @@ less
...
```
### Portable tree command
``` shellsession
$ clojure -Sdeps '{:deps {org.clojure/tools.cli {:mvn/version "0.4.2"}}}' examples/tree.clj src
src
└── babashka
├── impl
│ ├── tools
│ │ └── cli.clj
...
$ examples/tree.clj src
src
└── babashka
├── impl
│ ├── tools
│ │ └── cli.clj
```
## Thanks
- [adgoji](https://www.adgoji.com/) for financial support

77
examples/tree.clj Executable file
View file

@ -0,0 +1,77 @@
#!/usr/bin/env bb
;; to run with clojure: clojure -Sdeps '{:deps {org.clojure/tools.cli {:mvn/version "0.4.2"}}}' examples/tree.clj src
;; to run with babashka: examples/tree.clj src
(ns tree
"Tree command, inspired by https://github.com/lambdaisland/birch."
(:require [clojure.java.io :as io]
[clojure.tools.cli :refer [parse-opts]]))
(def I-branch "│ ")
(def T-branch "├── ")
(def L-branch "└── ")
(def SPACER " ")
(defn file-tree
[^java.io.File path]
(let [children (.listFiles path)
dir? (.isDirectory path)]
(cond->
{:name (.getName path)
:type (if dir? "directory" "file")}
dir? (assoc :contents
(map file-tree children)))))
(defn render-tree
[{:keys [:name :contents]}]
(cons name
(mapcat
(fn [child index]
(let [subtree (render-tree child)
last? (= index (dec (count contents)))
prefix-first (if last? L-branch T-branch)
prefix-rest (if last? SPACER I-branch)]
(cons (str prefix-first (first subtree))
(map #(str prefix-rest %) (next subtree)))))
contents
(range))))
(defn stats
[file-tree]
(apply merge-with +
{:total 1
:directories (case (:type file-tree)
"directory" 1
0)}
(map stats (:contents file-tree))))
(def cli-options [["-E" "--edn" "Output tree as EDN"]])
(defn -main [& args]
(let [{:keys [options arguments]}
(parse-opts args cli-options)
path (io/file
(or (first arguments)
"."))
tree (file-tree path)
{:keys [total directories]}
(stats tree)]
(if (:edn options)
(prn tree)
(do
(doseq [l (render-tree tree)]
(println l))
(println)
(println
(str directories " directories, " (- total directories) " files"))))))
(apply -main *command-line-args*)
;;;; Scratch
(comment
(-main "src" "-e" "-c"))

View file

@ -1 +1 @@
0.0.37-SNAPSHOT
0.0.37

View file

@ -195,7 +195,8 @@ Everything after that is bound to *command-line-args*."))
conch me.raynes.conch.low-level
async clojure.core.async
csv clojure.data.csv}
:namespaces {'clojure.core core-extras
:namespaces {'clojure.core (assoc core-extras
'*command-line-args* command-line-args)
'clojure.tools.cli tools-cli-namespace
'clojure.edn {'read-string edn/read-string}
'clojure.java.shell {'sh shell/sh}
@ -206,8 +207,7 @@ Everything after that is bound to *command-line-args*."))
'me.raynes.conch.low-level conch-namespace
'clojure.core.async async-namespace
'clojure.data.csv csv/csv-namespace}
:bindings {'*command-line-args* command-line-args
'java.lang.System/exit exit ;; override exit, so we have more control
:bindings {'java.lang.System/exit exit ;; override exit, so we have more control
'System/exit exit}
:env env
:features #{:bb}