Side-by-side comparison of viable Clojure-on-Android approaches: - todo-expo/: ClojureScript + shadow-cljs + Expo + Reagent + re-frame - todo-flutter/: ClojureDart + Flutter Both apps feature: add/remove/check-off todos, SQLite persistence, categories, priorities, edit support, swipe-to-delete, filtering. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
118 lines
3.3 KiB
Plaintext
Executable File
118 lines
3.3 KiB
Plaintext
Executable File
#!/Usr/bin/env joker
|
|
|
|
;; Usage: toolchain-report
|
|
;;
|
|
;; This tool queries a set of defined packages in your "toolchain" and
|
|
;; reports the versions of those packages in a map. There are no
|
|
;; command line flags or options for this script.
|
|
|
|
(ns main
|
|
(:require [joker.os :as os]))
|
|
|
|
|
|
;; The "toolchain" is defined as a vector of maps that define how to
|
|
;; query for version. We expect every tool has some command line flag
|
|
;; that writes the version info to stdout or stderr, but each tool
|
|
;; might format that output in some unique way. Therefore we specify a
|
|
;; regular expression pattern that will be used to extract the version
|
|
;; from the output.
|
|
;;
|
|
;; Easiest to show an example:
|
|
;;
|
|
;; {
|
|
;; :key :yarn ; each tool has a unique key
|
|
;; :cmd ["yarn" "-v"] ; executing this prints the version
|
|
;; :pattern #"(.*)\n" ; this regexp extracts the version #
|
|
;; :output :out ; :out = stdout, :err = stderr
|
|
;; }
|
|
;;
|
|
;; The default is to grab everything from stdout up to the first
|
|
;; newline '\n', so our example can be shortened:
|
|
;;
|
|
;; {:key :yarn :cmd ["yarn" "-v"]}
|
|
;;
|
|
|
|
(def toolchain
|
|
[
|
|
;; operating system
|
|
{:key :os-name
|
|
:cmd ["clojure" "-e" "(System/getProperty \"os.name\")"]
|
|
:pattern #"\"(.*)\""}
|
|
{:key :os-version
|
|
:cmd ["clojure" "-e" "(System/getProperty \"os.version\")"]
|
|
:pattern #"\"(.*)\""}
|
|
{:key :todays-date
|
|
:cmd ["clojure" "-e" "(.toString (java.time.LocalDate/now))"]}
|
|
|
|
;; clojure/clojurescript tools
|
|
{:key :clojure
|
|
:cmd ["clj" "-Stree"]
|
|
:pattern #"org.clojure/clojure\s+(.*)\n"}
|
|
{:key :clojurescript
|
|
:cmd ["clj" "-Stree"]
|
|
:pattern #"org.clojure/clojurescript\s+(.*)\n"}
|
|
{:key :shadow-cljs-jar
|
|
:cmd ["shadow-cljs" "info"]
|
|
:pattern #"jar:\s+(.*)\n"}
|
|
{:key :shadow-cljs-cli
|
|
:cmd ["shadow-cljs" "info"]
|
|
:pattern #"cli:\s+(.*)\n"}
|
|
|
|
;; react native toolchain
|
|
{:key :expo-cli :cmd ["expo-cli" "-V"]}
|
|
|
|
;; javascript tools
|
|
{:key :node :cmd ["node" "-v"]}
|
|
{:key :yarn :cmd ["yarn" "-v"]}
|
|
|
|
;; libraries / packages
|
|
{:key :expo-js
|
|
:cmd ["yarn" "list"]
|
|
:pattern #"\s+expo@(.*)\n"}
|
|
{:key :react
|
|
:cmd ["yarn" "list"]
|
|
:pattern #"\s+react@(.*)\n"}
|
|
{:key :react-native
|
|
:cmd ["yarn" "list"]
|
|
:pattern #"\s+react-native@(.*)\n"}
|
|
{:key :reagent
|
|
:cmd ["clj" "-Stree"]
|
|
:pattern #"reagent/reagent\s+(.*)\n"}
|
|
{:key :re-frame
|
|
:cmd ["clj" "-Stree"]
|
|
:pattern #"re-frame/re-frame\s+(.*)\n"}
|
|
|
|
;; java jdk
|
|
{:key :jdk-vendor
|
|
:cmd ["java" "-version"]
|
|
:output :err
|
|
:pattern #"(.*)\s+version"}
|
|
{:key :jdk-version
|
|
:cmd ["java" "-version"]
|
|
:output :err
|
|
:pattern #"version\s+\"(.*)\"\n"}
|
|
])
|
|
|
|
(def sh-memoized (memoize #(apply os/sh %)))
|
|
|
|
(defn check [{:keys [key cmd output pattern]
|
|
:or {output :out pattern #"(.*)\n"}}]
|
|
(let [result (try (sh-memoized cmd)
|
|
(catch Error e {:success nil}))]
|
|
(if (:success result)
|
|
{key (-> (re-find pattern (output result))
|
|
(get 1))}
|
|
{key nil})))
|
|
|
|
(defn print-sorted-keys [m]
|
|
;; hack because joker doesn't provide sorted-map
|
|
(println "{")
|
|
(doseq [k (sort (keys m))]
|
|
(printf " %s \"%s\"\n" k (k m)))
|
|
(println "}"))
|
|
|
|
;; run all queries and print the result
|
|
(print-sorted-keys (->> (map check toolchain)
|
|
(apply merge)))
|
|
|