v0.0.37, add tree example, fix *command-line-args*
This commit is contained in:
parent
4773457a68
commit
8afb87142e
4 changed files with 100 additions and 4 deletions
19
README.md
19
README.md
|
|
@ -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
|
## Thanks
|
||||||
|
|
||||||
- [adgoji](https://www.adgoji.com/) for financial support
|
- [adgoji](https://www.adgoji.com/) for financial support
|
||||||
|
|
|
||||||
77
examples/tree.clj
Executable file
77
examples/tree.clj
Executable 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"))
|
||||||
|
|
@ -1 +1 @@
|
||||||
0.0.37-SNAPSHOT
|
0.0.37
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,8 @@ Everything after that is bound to *command-line-args*."))
|
||||||
conch me.raynes.conch.low-level
|
conch me.raynes.conch.low-level
|
||||||
async clojure.core.async
|
async clojure.core.async
|
||||||
csv clojure.data.csv}
|
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.tools.cli tools-cli-namespace
|
||||||
'clojure.edn {'read-string edn/read-string}
|
'clojure.edn {'read-string edn/read-string}
|
||||||
'clojure.java.shell {'sh shell/sh}
|
'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
|
'me.raynes.conch.low-level conch-namespace
|
||||||
'clojure.core.async async-namespace
|
'clojure.core.async async-namespace
|
||||||
'clojure.data.csv csv/csv-namespace}
|
'clojure.data.csv csv/csv-namespace}
|
||||||
:bindings {'*command-line-args* command-line-args
|
:bindings {'java.lang.System/exit exit ;; override exit, so we have more control
|
||||||
'java.lang.System/exit exit ;; override exit, so we have more control
|
|
||||||
'System/exit exit}
|
'System/exit exit}
|
||||||
:env env
|
:env env
|
||||||
:features #{:bb}
|
:features #{:bb}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue