From aefdbfc2530c41d20df2059332df00de9a05d7df Mon Sep 17 00:00:00 2001 From: Alys Brooks Date: Mon, 16 Aug 2021 14:53:11 -0500 Subject: [PATCH 01/16] Add tests. --- test/lambdaisland/shellutils_test.clj | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/lambdaisland/shellutils_test.clj b/test/lambdaisland/shellutils_test.clj index 095077f..5054b67 100644 --- a/test/lambdaisland/shellutils_test.clj +++ b/test/lambdaisland/shellutils_test.clj @@ -56,3 +56,24 @@ (is (= [txt-path clj-path] (map str (s/glob (str temp "/*"))) )) (is (= [txt-path clj-path] (map str (s/glob (str temp "/*.{txt,clj}"))) )) (is (= [txt-path] (map str (s/glob (str temp "/*.txt"))) )))) + +(deftest join-string-test + + (testing "combine with empty" + (is (= (str (s/join "foo" "")) "foo"))) + (testing "combine two strings" + (is (= (str (s/join "foo" "bar")) "foo/bar")))) + +(deftest join-file-test + (testing "combine with empty" + (is (= (str (s/join (File. "foo" ) (File. ""))) "foo"))) + (testing "combine two strings" + (is (= (str (s/join (File. "foo") (File. "bar"))) "foo/bar"))) + ) + +(deftest join-path-test + (testing "combine with empty" + (is (= (str (s/join (Paths/get "foo" (into-array String [])) (Paths/get "" (into-array String [])))) "foo"))) + (testing "combine two strings" + (is (= (str (s/join (Paths/get "foo" (into-array String [])) (Paths/get "bar" (into-array String [])))) "foo/bar"))) + ) From 970586bb5fa3a7281e2b271da24f9e6379041f04 Mon Sep 17 00:00:00 2001 From: Alys Brooks Date: Mon, 16 Aug 2021 19:27:09 -0500 Subject: [PATCH 02/16] Use join in glob-test. --- test/lambdaisland/shellutils_test.clj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/lambdaisland/shellutils_test.clj b/test/lambdaisland/shellutils_test.clj index 5054b67..28ec775 100644 --- a/test/lambdaisland/shellutils_test.clj +++ b/test/lambdaisland/shellutils_test.clj @@ -48,8 +48,8 @@ (deftest glob-test (let [temp (temp-dir) - txt-path (str (.resolve temp "test.txt" )) - clj-path ( str (.resolve temp "test.clj" )) ] + txt-path (str (s/join temp "test.txt" )) + clj-path (str (s/join temp "test.clj" ))] (spit txt-path ".") (spit clj-path ".") From b07efd93c742bcd5e8e8a2e5103b682fa8d31b57 Mon Sep 17 00:00:00 2001 From: Arne Brasseur Date: Wed, 25 Aug 2021 08:50:49 +0200 Subject: [PATCH 03/16] Fix tests --- bin/kaocha | 2 +- test/lambdaisland/shellutils_test.clj | 22 ++++++++++------------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/bin/kaocha b/bin/kaocha index a783726..1015f85 100755 --- a/bin/kaocha +++ b/bin/kaocha @@ -1,2 +1,2 @@ #!/bin/bash -clojure -A:test -m kaocha.runner "$@" +clojure -M -A:test -m kaocha.runner "$@" diff --git a/test/lambdaisland/shellutils_test.clj b/test/lambdaisland/shellutils_test.clj index 28ec775..b42cad2 100644 --- a/test/lambdaisland/shellutils_test.clj +++ b/test/lambdaisland/shellutils_test.clj @@ -15,14 +15,14 @@ (deftest absolute-test (testing "Test an absolute path." - (is (s/absolute? + (is (s/absolute? (.getAbsoluteFile (File. (System/getProperty "user.dir")))))) (testing "Test a (made-up) relative path." (is (not (s/absolute? (File. "fake/")))))) (deftest relative-test (testing "Test an absolute path." - (is (not (s/relative? + (is (not (s/relative? (.getAbsoluteFile (File. (System/getProperty "user.dir"))))))) (testing "Test a (made-up) relative path." (is (s/relative? (File. "fake/"))))) @@ -47,18 +47,18 @@ (is (= (s/extension "test") "test")))) (deftest glob-test - (let [temp (temp-dir) + (let [temp (temp-dir) txt-path (str (s/join temp "test.txt" )) - clj-path (str (s/join temp "test.clj" ))] + clj-path (str (s/join temp "test.clj"))] (spit txt-path ".") (spit clj-path ".") - (is (= [txt-path clj-path] (map str (s/glob (str temp "/*"))) )) - (is (= [txt-path clj-path] (map str (s/glob (str temp "/*.{txt,clj}"))) )) - (is (= [txt-path] (map str (s/glob (str temp "/*.txt"))) )))) + (is (= #{txt-path clj-path} (set (map str (s/glob (str temp "/*")))))) + (is (= #{txt-path clj-path} (set (map str (s/glob (str temp "/*.{txt,clj}")))))) + (is (= [txt-path] (map str (s/glob (str temp "/*.txt"))))))) (deftest join-string-test - + (testing "combine with empty" (is (= (str (s/join "foo" "")) "foo"))) (testing "combine two strings" @@ -68,12 +68,10 @@ (testing "combine with empty" (is (= (str (s/join (File. "foo" ) (File. ""))) "foo"))) (testing "combine two strings" - (is (= (str (s/join (File. "foo") (File. "bar"))) "foo/bar"))) - ) + (is (= (str (s/join (File. "foo") (File. "bar"))) "foo/bar")))) (deftest join-path-test (testing "combine with empty" (is (= (str (s/join (Paths/get "foo" (into-array String [])) (Paths/get "" (into-array String [])))) "foo"))) (testing "combine two strings" - (is (= (str (s/join (Paths/get "foo" (into-array String [])) (Paths/get "bar" (into-array String [])))) "foo/bar"))) - ) + (is (= (str (s/join (Paths/get "foo" (into-array String [])) (Paths/get "bar" (into-array String [])))) "foo/bar")))) From 91ddd3b4684ec41831f9720b103c6dd9cf1e01b5 Mon Sep 17 00:00:00 2001 From: Arne Brasseur Date: Wed, 25 Aug 2021 08:54:43 +0200 Subject: [PATCH 04/16] Prep for first release --- CHANGELOG.md | 9 +++-- bin/kaocha | 2 +- src/lambdaisland/shellutils.clj | 50 +++++++++++++-------------- test/lambdaisland/shellutils_test.clj | 2 +- 4 files changed, 34 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9bafe4..e2094c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Added -## Fixed +First release with basic shell utility API -## Changed +- glob +- canonicalize/relativize +- ls +- basename/extension/strip-ext +- mkdir-p +- ... diff --git a/bin/kaocha b/bin/kaocha index 1015f85..f519e6c 100755 --- a/bin/kaocha +++ b/bin/kaocha @@ -1,2 +1,2 @@ #!/bin/bash -clojure -M -A:test -m kaocha.runner "$@" +clojure -A:test -M -m kaocha.runner "$@" diff --git a/src/lambdaisland/shellutils.clj b/src/lambdaisland/shellutils.clj index 54b4989..54c879c 100644 --- a/src/lambdaisland/shellutils.clj +++ b/src/lambdaisland/shellutils.clj @@ -36,7 +36,6 @@ File (join [this that] (.toPath (io/file this (str that))))) - (defn absolute? "The File contains an absolute path" [^File f] @@ -57,28 +56,6 @@ f (io/file *cwd* path)))) -(defn- glob->regex - "Takes a glob-format string and returns a regex." - [s] - (loop [stream s - re "" - curly-depth 0] - (let [[c j] stream] - (cond - (nil? c) (re-pattern (str "^" (if (= \. (first s)) "" "(?=[^\\.])") re "$")) - (= c \\) (recur (nnext stream) (str re c c) curly-depth) - (= c \/) (recur (next stream) (str re (if (= \. j) c "/(?=[^\\.])")) - curly-depth) - (= c \*) (recur (next stream) (str re "[^/]*") curly-depth) - (= c \?) (recur (next stream) (str re "[^/]") curly-depth) - (= c \{) (recur (next stream) (str re \() (inc curly-depth)) - (= c \}) (recur (next stream) (str re \)) (dec curly-depth)) - (and (= c \,) (< 0 curly-depth)) (recur (next stream) (str re \|) - curly-depth) - (#{\. \( \) \| \+ \^ \$ \@ \%} c) (recur (next stream) (str re \\ c) - curly-depth) - :else (recur (next stream) (str re c) curly-depth))))) - (defn- get-root-file [root-name] (file (str root-name "/"))) @@ -123,7 +100,7 @@ (defn extension "Get the extension of the file without the dot - + This function does not have special handling for files that start with a dot (hidden files on Unix-family systems)." @@ -138,6 +115,28 @@ 0 (.lastIndexOf (str file) "."))) +(defn- glob->regex + "Takes a glob-format string and returns a regex." + [s] + (loop [stream s + re "" + curly-depth 0] + (let [[c j] stream] + (cond + (nil? c) (re-pattern (str "^" (if (= \. (first s)) "" "(?=[^\\.])") re "$")) + (= c \\) (recur (nnext stream) (str re c c) curly-depth) + (= c \/) (recur (next stream) (str re (if (= \. j) c "/(?=[^\\.])")) + curly-depth) + (= c \*) (recur (next stream) (str re "[^/]*") curly-depth) + (= c \?) (recur (next stream) (str re "[^/]") curly-depth) + (= c \{) (recur (next stream) (str re \() (inc curly-depth)) + (= c \}) (recur (next stream) (str re \)) (dec curly-depth)) + (and (= c \,) (< 0 curly-depth)) (recur (next stream) (str re \|) + curly-depth) + (#{\. \( \) \| \+ \^ \$ \@ \%} c) (recur (next stream) (str re \\ c) + curly-depth) + :else (recur (next stream) (str re c) curly-depth))))) + (defn glob "Returns a seq of java.io.File instances that match the given glob pattern. Ignores dot files unless explicitly included. @@ -146,6 +145,8 @@ Based on https://github.com/jkk/clj-glob/blob/b1df67efb003f0e372c914346209d41c6df78e20/src/org/satta/glob.clj + + but with some improvements. " [pattern] (let [[root & _ :as parts] (.split #"[\\/]" pattern) @@ -171,4 +172,3 @@ (mapcat #(filter-files (ls %) (glob->regex pattern)) files))) [start-dir] patterns))) - diff --git a/test/lambdaisland/shellutils_test.clj b/test/lambdaisland/shellutils_test.clj index b42cad2..68b5b16 100644 --- a/test/lambdaisland/shellutils_test.clj +++ b/test/lambdaisland/shellutils_test.clj @@ -34,7 +34,7 @@ (is (= (s/basename "foo/bar/baz") "baz")) (is (= (s/basename "/foo/bar/baz") "baz")))) -(deftest ^:kaocha/pending extension-test +(deftest extension-test (testing "relatively typical files" (is (= (s/extension "test.txt") "txt")) (is (= (s/extension "/foo/bar/test.txt") "txt"))) From 4e4e8ea43edabb8aeb54f41fcac3b533ebd0df6d Mon Sep 17 00:00:00 2001 From: Arne Brasseur Date: Wed, 25 Aug 2021 08:54:56 +0200 Subject: [PATCH 05/16] # 0.0.10 (2021-08-25 / 91ddd3b) ## Added First release with basic shell utility API - glob - canonicalize/relativize - ls - basename/extension/strip-ext - mkdir-p - ... --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2094c0..d43284b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# Unreleased +# 0.0.10 (2021-08-25 / 91ddd3b) ## Added @@ -9,4 +9,4 @@ First release with basic shell utility API - ls - basename/extension/strip-ext - mkdir-p -- ... +- ... \ No newline at end of file From f628d1e642a462e3702dce6bb403192cd9d74c31 Mon Sep 17 00:00:00 2001 From: Arne Brasseur Date: Wed, 25 Aug 2021 08:55:17 +0200 Subject: [PATCH 06/16] Update pom.xml and add CHANGELOG.md placeholders --- CHANGELOG.md | 8 +++++ pom.xml | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 pom.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index d43284b..62375a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# Unreleased + +## Added + +## Fixed + +## Changed + # 0.0.10 (2021-08-25 / 91ddd3b) ## Added diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..d5c0be8 --- /dev/null +++ b/pom.xml @@ -0,0 +1,91 @@ + + + 4.0.0 + com.lambdaisland + shellutils + 0.0.10 + shellutils + Globbing and other shell/file utils + https://github.com/lambdaisland/shellutils + 2021 + + Lambda Island + https://lambdaisland.com + + + + MPL-2.0 + https://www.mozilla.org/media/MPL/2.0/index.txt + + + + https://github.com/lambdaisland/shellutils + scm:git:git://github.com/lambdaisland/shellutils.git + scm:git:ssh://git@github.com/lambdaisland/shellutils.git + 4e4e8ea43edabb8aeb54f41fcac3b533ebd0df6d + + + + org.clojure + clojure + 1.10.3 + + + + src + + + src + + + resources + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + + 4e4e8ea43edabb8aeb54f41fcac3b533ebd0df6d + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + + + + clojars + https://repo.clojars.org/ + + + + + clojars + Clojars repository + https://clojars.org/repo + + + \ No newline at end of file From af376365621753c496dc6c4a0d2f96e63dd50b3c Mon Sep 17 00:00:00 2001 From: Arne Brasseur Date: Mon, 19 Feb 2024 10:28:52 +0100 Subject: [PATCH 07/16] Update project tooling & add subshell helpers --- CHANGELOG.md | 6 +- bb.edn | 3 + bb_deps.edn | 4 - bin/bb | 125 -------------------------------- bin/proj | 6 +- deps.edn | 4 +- src/lambdaisland/shellutils.clj | 98 +++++++++++++++++++++++-- 7 files changed, 100 insertions(+), 146 deletions(-) create mode 100644 bb.edn delete mode 100644 bb_deps.edn delete mode 100755 bin/bb diff --git a/CHANGELOG.md b/CHANGELOG.md index 62375a9..3ad91f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,7 @@ ## Added -## Fixed - -## Changed +- Added subshell utilities # 0.0.10 (2021-08-25 / 91ddd3b) @@ -17,4 +15,4 @@ First release with basic shell utility API - ls - basename/extension/strip-ext - mkdir-p -- ... \ No newline at end of file +- ... diff --git a/bb.edn b/bb.edn new file mode 100644 index 0000000..640ec31 --- /dev/null +++ b/bb.edn @@ -0,0 +1,3 @@ +{:deps + {lambdaisland/open-source {:git/url "https://github.com/lambdaisland/open-source" + :git/sha "7ce125cbd14888590742da7ab3b6be9bba46fc7a"}}} diff --git a/bb_deps.edn b/bb_deps.edn deleted file mode 100644 index fdacb60..0000000 --- a/bb_deps.edn +++ /dev/null @@ -1,4 +0,0 @@ -{:deps - {lambdaisland/open-source {:git/url "https://github.com/lambdaisland/open-source" - :sha "bf3856d2a082f8cc99e5d6a714d506787029c56c" - #_#_:local/root "../open-source"}}} diff --git a/bin/bb b/bin/bb deleted file mode 100755 index 7d2dbd0..0000000 --- a/bin/bb +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/env bash - -# Wrapper script for babashka to be dropped into projects, will run `bb` from -# the PATH if it exists, or otherwise download it and store it inside the -# project. When using the system `bb` it will do a version check and warn if the -# version is older than what is requested. -# -# Will look for a `bb_deps.edn` and run that through `clojure` to compute a -# classpath. -# -# Will use rlwrap if it is available. - -name=babashka -babashka_version="0.3.8" -store_dir="$(pwd)/.store" -install_dir="${store_dir}/$name-$babashka_version" - -system_bb="$(which bb)" -set -e - -# https://stackoverflow.com/questions/4023830/how-to-compare-two-strings-in-dot-separated-version-format-in-bash -vercomp () { - if [[ $1 == $2 ]] - then - return 0 - fi - local IFS=. - local i ver1=($1) ver2=($2) - # fill empty fields in ver1 with zeros - for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)) - do - ver1[i]=0 - done - for ((i=0; i<${#ver1[@]}; i++)) - do - if [[ -z ${ver2[i]} ]] - then - # fill empty fields in ver2 with zeros - ver2[i]=0 - fi - if ((10#${ver1[i]} > 10#${ver2[i]})) - then - return 1 - fi - if ((10#${ver1[i]} < 10#${ver2[i]})) - then - return 2 - fi - done - return 0 -} - -if [[ -f "$system_bb" ]]; then - bb_path="$system_bb" -elif [[ -f "$install_dir/bb" ]]; then - bb_path="$install_dir/bb" -else - case "$(uname -s)" in - Linux*) - ext=tar.gz - unpack_bb() { - tar -xzf "bb.$ext" -C "$install_dir" - } - platform=linux;; - Darwin*) - ext=tar.gz - unpack_bb() { - tar -xzf "bb.$ext" -C "$install_dir" - } - platform=macos;; - MINGW64*) - ext=zip - unpack_bb() { - unzip -qqo "bb.$ext" -d "$install_dir" - } - platform=windows;; - esac - - echo "$name $babashka_version not found, installing to $install_dir..." - download_url="https://github.com/borkdude/babashka/releases/download/v$babashka_version/babashka-$babashka_version-$platform-amd64.$ext" - - mkdir -p "$install_dir" - echo -e "Downloading $download_url." - curl -o "bb.$ext" -sL "$download_url" - unpack_bb - rm "bb.$ext" - bb_path="$install_dir/bb" -fi - -set +e -actual_version="$($bb_path --version | sed 's/babashka v//')" - -vercomp $actual_version $babashka_version -case $? in - 0) ;; # = - 1) ;; # > - 2) echo "WARNING: babashka version is $actual_version, expected $babashka_version" ;; # < -esac -set -e - -try_exec_rlwrap() { - if [ -x "$(command -v rlwrap)" ]; then - exec "rlwrap" "$@" - else - exec "$@" - fi -} - -deps_clj="$(pwd)/.store/deps.clj" - -ensure_deps_clj() { - if [[ ! -f "${deps_clj}" ]]; then - mkdir -p "${store_dir}" - curl -sL https://raw.githubusercontent.com/borkdude/deps.clj/master/deps.clj -o "${deps_clj}" - fi -} - -if [[ -f bb_deps.edn ]]; then - ensure_deps_clj - # Note this will install clojure-tools in ~/.deps.clj/ClojureTools - cp="$($bb_path $deps_clj -Srepro -Sdeps-file bb_deps.edn -Spath)" - try_exec_rlwrap "$bb_path" "-cp" "${cp}" "$@" -else - try_exec_rlwrap "$bb_path" "$@" -fi diff --git a/bin/proj b/bin/proj index 4702e57..b084c6e 100755 --- a/bin/proj +++ b/bin/proj @@ -1,4 +1,4 @@ -#!bin/bb +#!/usr/bin/env bb (ns proj (:require [lioss.main :as lioss])) @@ -8,7 +8,3 @@ :inception-year 2021 :description "Globbing and other shell/file utils" :group-id "com.lambdaisland"}) - -;; Local Variables: -;; mode:clojure -;; End: diff --git a/deps.edn b/deps.edn index 5b96650..482641b 100644 --- a/deps.edn +++ b/deps.edn @@ -1,7 +1,7 @@ {:paths ["src" "resources"] :deps - {org.clojure/clojure {:mvn/version "1.10.3"}} + {org.clojure/clojure {:mvn/version "1.11.1"}} :aliases {:dev @@ -10,4 +10,4 @@ :test {:extra-paths ["test"] - :extra-deps {lambdaisland/kaocha {:mvn/version "1.0.861"}}}}} + :extra-deps {lambdaisland/kaocha {:mvn/version "1.87.1366"}}}}} diff --git a/src/lambdaisland/shellutils.clj b/src/lambdaisland/shellutils.clj index 54c879c..aa8ed5b 100644 --- a/src/lambdaisland/shellutils.clj +++ b/src/lambdaisland/shellutils.clj @@ -1,18 +1,104 @@ (ns lambdaisland.shellutils - "Globbing and other shell-like filename handling + "Globbing and other shell-like filename handling, and subshell handling Extracted from https://github.com/lambdaisland/open-source and further improved" - (:require [clojure.java.io :as io]) - (:import (java.io File) - (java.nio.file Path Paths))) + (:require + [clojure.java.io :as io] + [clojure.string :as str]) + (:import + (java.io File) + (java.nio.file Path Paths))) + +(defn cli-opts + "Options map from lambdaisland.cli, if it is used. We auto-detect certain flags, + like --dry-run." + [] + (some-> (try (requiring-resolve 'lambdaisland.cli/*opts*) (catch Exception _)) deref)) (def ^:dynamic *cwd* "Current working directory - Relative paths are resolved starting from this location. Defaults to the CWD - of the JVM, as exposed through the 'user.dir' property." + Relative paths are resolved starting from this location, and it is used for + subshells. Defaults to the CWD of the JVM, as exposed through the 'user.dir' + property." (System/getProperty "user.dir")) +(defmacro with-cwd [cwd & body] + `(let [prev# *cwd* + cwd# (File. *cwd* ~cwd)] + (binding [*cwd* cwd#] + (try + (System/setProperty "user.dir" (str cwd#)) + ~@body + (finally + (System/setProperty "user.dir" prev#)))))) + +(defmacro with-temp-cwd + "Same as with-cwd except that it creates a temp dir + in *cwd* and evals the body inside it. + + It cleans up the temp dir afterwards also removing + any temp files created within it." + [& body] + ;; FIXME: use Files/createTempDirectory + `(let [cwd# ".temp" + dir# (File. *cwd* cwd#)] + (.mkdirs dir#) + (with-cwd cwd# ~@body) + (delete-recursively dir#))) + +(defn slurp-cwd [f] + (slurp (File. *cwd* f))) + +(defn spit-cwd [f c] + (spit (File. *cwd* f) c)) + +(defn fatal [& msg] + (apply println "[\033[0;31mFATAL\033[0m] " msg) + (System/exit -1)) + +(defn process-builder [args] + (doto (ProcessBuilder. args) + (.inheritIO))) + +;; (def windows? (str/starts-with? (System/getProperty "os.name") "Windows")) + +(defn- cmd->str [args] + (str/join " " (map #(if (str/includes? % " ") (pr-str %) %) args))) + +(defn spawn + "Like [[clojure.java.shell/sh]], but inherit IO stream from the parent process, + and prints out the invocation. By default terminates when a command + fails (non-zero exit code). + + If the last argument is a map, it is used for options + - `:dir` Directory to execute in + - `:continue-on-error?` Should a non-zero exit code be ignored. + - `:fail-message` Error message to show when the command returns a non-zero exit code" + [& args] + (let [[opts args] (if (map? (last args)) + [(last args) (butlast args)] + [{} args]) + dir (:dir opts *cwd*) + ;; args (if windows? (cons "winpty" args) args) + ] + (println "=>" (cmd->str args) (str "(in " dir ")") "") + (when-not (:dry-run (cli-opts)) + (let [res (-> (process-builder args) + (cond-> dir + (.directory (io/file dir))) + .start + .waitFor)] + (when (and (not= 0 res) (not (:continue-on-error? opts))) + (fatal (:fail-message opts "command failed") res)) + res)))) + +(defn bash + "Interpret the command as a bash script, allows using redirects, pipes and other + bash features." + [& args] + (spawn "bash" "-c" (str/join " " args))) + (defmacro with-cwd "Execute `body` with [[*cwd*]] set to `cwd`." [cwd & body] From ac5fea41c2ddc3a22358cf6fd51df138abf5e5a2 Mon Sep 17 00:00:00 2001 From: Arne Brasseur Date: Mon, 19 Feb 2024 10:30:58 +0100 Subject: [PATCH 08/16] # 0.1.13 (2024-02-19 / af37636) ## Added - Added subshell utilities --- .VERSION_PREFIX | 1 + CHANGELOG.md | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 .VERSION_PREFIX diff --git a/.VERSION_PREFIX b/.VERSION_PREFIX new file mode 100644 index 0000000..ceab6e1 --- /dev/null +++ b/.VERSION_PREFIX @@ -0,0 +1 @@ +0.1 \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ad91f5..0a91fe2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# Unreleased +# 0.1.13 (2024-02-19 / af37636) ## Added @@ -15,4 +15,4 @@ First release with basic shell utility API - ls - basename/extension/strip-ext - mkdir-p -- ... +- ... \ No newline at end of file From 79ecaa4f6330edbd9d334a9419938484ba114586 Mon Sep 17 00:00:00 2001 From: Arne Brasseur Date: Mon, 19 Feb 2024 10:31:26 +0100 Subject: [PATCH 09/16] Update pom.xml and add CHANGELOG.md placeholders --- CHANGELOG.md | 8 ++++++++ pom.xml | 15 +++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a91fe2..0fcf333 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# Unreleased + +## Added + +## Fixed + +## Changed + # 0.1.13 (2024-02-19 / af37636) ## Added diff --git a/pom.xml b/pom.xml index d5c0be8..1117720 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.lambdaisland shellutils - 0.0.10 + 0.1.13 shellutils Globbing and other shell/file utils https://github.com/lambdaisland/shellutils @@ -12,6 +12,9 @@ Lambda Island https://lambdaisland.com + + UTF-8 + MPL-2.0 @@ -22,13 +25,13 @@ https://github.com/lambdaisland/shellutils scm:git:git://github.com/lambdaisland/shellutils.git scm:git:ssh://git@github.com/lambdaisland/shellutils.git - 4e4e8ea43edabb8aeb54f41fcac3b533ebd0df6d + ac5fea41c2ddc3a22358cf6fd51df138abf5e5a2 org.clojure clojure - 1.10.3 + 1.11.1 @@ -46,6 +49,10 @@ org.apache.maven.plugins maven-compiler-plugin 3.8.1 + + 1.8 + 1.8 + org.apache.maven.plugins @@ -54,7 +61,7 @@ - 4e4e8ea43edabb8aeb54f41fcac3b533ebd0df6d + ac5fea41c2ddc3a22358cf6fd51df138abf5e5a2 From 7f8477775f396d0266ed24fe89ab80ef726a1816 Mon Sep 17 00:00:00 2001 From: Arne Brasseur Date: Thu, 22 Feb 2024 13:55:01 +0100 Subject: [PATCH 10/16] Add temp-dir --- src/lambdaisland/shellutils.clj | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/lambdaisland/shellutils.clj b/src/lambdaisland/shellutils.clj index aa8ed5b..e9c9f1a 100644 --- a/src/lambdaisland/shellutils.clj +++ b/src/lambdaisland/shellutils.clj @@ -7,7 +7,8 @@ [clojure.string :as str]) (:import (java.io File) - (java.nio.file Path Paths))) + (java.nio.file Files Path Paths) + (java.nio.file.attribute FileAttribute))) (defn cli-opts "Options map from lambdaisland.cli, if it is used. We auto-detect certain flags, @@ -258,3 +259,9 @@ (mapcat #(filter-files (ls %) (glob->regex pattern)) files))) [start-dir] patterns))) + +(defn temp-dir + ([] + (temp-dir "li_shellutils")) + ([path] + (Files/createTempDirectory path (into-array FileAttribute [])))) From b261d1685a2a5dc58122009f6437023d3fcba9d5 Mon Sep 17 00:00:00 2001 From: Arne Brasseur Date: Mon, 26 Feb 2024 11:52:57 +0100 Subject: [PATCH 11/16] CHANGELOG --- CHANGELOG.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fcf333..895dc0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,7 @@ ## Added -## Fixed - -## Changed +- Add `temp-dir` # 0.1.13 (2024-02-19 / af37636) @@ -23,4 +21,4 @@ First release with basic shell utility API - ls - basename/extension/strip-ext - mkdir-p -- ... \ No newline at end of file +- ... From 59d09d756fe944ec3d2931576996c30c1bd2bb80 Mon Sep 17 00:00:00 2001 From: Arne Brasseur Date: Mon, 26 Feb 2024 11:54:04 +0100 Subject: [PATCH 12/16] # 0.2.17 (2024-02-26 / b261d16) ## Added - Add `temp-dir` --- .VERSION_PREFIX | 2 +- CHANGELOG.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.VERSION_PREFIX b/.VERSION_PREFIX index ceab6e1..2f45361 100644 --- a/.VERSION_PREFIX +++ b/.VERSION_PREFIX @@ -1 +1 @@ -0.1 \ No newline at end of file +0.2 \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 895dc0e..71dc22e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# Unreleased +# 0.2.17 (2024-02-26 / b261d16) ## Added @@ -21,4 +21,4 @@ First release with basic shell utility API - ls - basename/extension/strip-ext - mkdir-p -- ... +- ... \ No newline at end of file From 7f923d624863ba60eeaec52f54c86ea83988bc05 Mon Sep 17 00:00:00 2001 From: Arne Brasseur Date: Mon, 26 Feb 2024 11:54:15 +0100 Subject: [PATCH 13/16] Update pom.xml and add CHANGELOG.md placeholders --- CHANGELOG.md | 8 ++++++++ pom.xml | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71dc22e..c1f1abc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# Unreleased + +## Added + +## Fixed + +## Changed + # 0.2.17 (2024-02-26 / b261d16) ## Added diff --git a/pom.xml b/pom.xml index 1117720..9518212 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.lambdaisland shellutils - 0.1.13 + 0.2.17 shellutils Globbing and other shell/file utils https://github.com/lambdaisland/shellutils @@ -25,7 +25,7 @@ https://github.com/lambdaisland/shellutils scm:git:git://github.com/lambdaisland/shellutils.git scm:git:ssh://git@github.com/lambdaisland/shellutils.git - ac5fea41c2ddc3a22358cf6fd51df138abf5e5a2 + 59d09d756fe944ec3d2931576996c30c1bd2bb80 @@ -61,7 +61,7 @@ - ac5fea41c2ddc3a22358cf6fd51df138abf5e5a2 + 59d09d756fe944ec3d2931576996c30c1bd2bb80 From eff4d1bdca2a09f50961f4f69195f75e02218a4b Mon Sep 17 00:00:00 2001 From: Arne Brasseur Date: Mon, 17 Jun 2024 13:39:40 +0200 Subject: [PATCH 14/16] Add shellquote --- CHANGELOG.md | 6 ++---- src/lambdaisland/shellutils.clj | 25 +++++++++++++++++++------ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1f1abc..f405293 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,7 @@ ## Added -## Fixed - -## Changed +- Add `shellquote` # 0.2.17 (2024-02-26 / b261d16) @@ -29,4 +27,4 @@ First release with basic shell utility API - ls - basename/extension/strip-ext - mkdir-p -- ... \ No newline at end of file +- ... diff --git a/src/lambdaisland/shellutils.clj b/src/lambdaisland/shellutils.clj index e9c9f1a..d2dbad7 100644 --- a/src/lambdaisland/shellutils.clj +++ b/src/lambdaisland/shellutils.clj @@ -64,8 +64,23 @@ ;; (def windows? (str/starts-with? (System/getProperty "os.name") "Windows")) -(defn- cmd->str [args] - (str/join " " (map #(if (str/includes? % " ") (pr-str %) %) args))) +(defn shellquote [a] + (let [a (str a)] + (cond + (and (str/includes? a "\"") + (str/includes? a "'")) + (str "'" + (str/replace a "'" "'\"'\"'") + "'") + + (str/includes? a "'") + (str "\"" a "\"") + + (re-find #"\s|\"" a) + (str "'" a "'") + + :else + a))) (defn spawn "Like [[clojure.java.shell/sh]], but inherit IO stream from the parent process, @@ -80,10 +95,8 @@ (let [[opts args] (if (map? (last args)) [(last args) (butlast args)] [{} args]) - dir (:dir opts *cwd*) - ;; args (if windows? (cons "winpty" args) args) - ] - (println "=>" (cmd->str args) (str "(in " dir ")") "") + dir (:dir opts *cwd*)] + (println "=>" (str/join " " (map shellquote args)) (str "(in " dir ")") "") (when-not (:dry-run (cli-opts)) (let [res (-> (process-builder args) (cond-> dir From 3689acafe850b0b208782d58bf99716cd9c7e237 Mon Sep 17 00:00:00 2001 From: Arne Brasseur Date: Mon, 17 Jun 2024 13:39:55 +0200 Subject: [PATCH 15/16] # 0.3.20 (2024-06-17 / eff4d1b) ## Added - Add `shellquote` --- .VERSION_PREFIX | 2 +- CHANGELOG.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.VERSION_PREFIX b/.VERSION_PREFIX index 2f45361..1d71ef9 100644 --- a/.VERSION_PREFIX +++ b/.VERSION_PREFIX @@ -1 +1 @@ -0.2 \ No newline at end of file +0.3 \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index f405293..e39b786 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# Unreleased +# 0.3.20 (2024-06-17 / eff4d1b) ## Added @@ -27,4 +27,4 @@ First release with basic shell utility API - ls - basename/extension/strip-ext - mkdir-p -- ... +- ... \ No newline at end of file From 94eecbab1aea26ed2d564736d863be4e5813b1d2 Mon Sep 17 00:00:00 2001 From: Arne Brasseur Date: Mon, 17 Jun 2024 13:40:14 +0200 Subject: [PATCH 16/16] Update pom.xml and add CHANGELOG.md placeholders --- CHANGELOG.md | 8 ++++++++ pom.xml | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e39b786..f046911 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# Unreleased + +## Added + +## Fixed + +## Changed + # 0.3.20 (2024-06-17 / eff4d1b) ## Added diff --git a/pom.xml b/pom.xml index 9518212..6c1fc39 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.lambdaisland shellutils - 0.2.17 + 0.3.20 shellutils Globbing and other shell/file utils https://github.com/lambdaisland/shellutils @@ -25,7 +25,7 @@ https://github.com/lambdaisland/shellutils scm:git:git://github.com/lambdaisland/shellutils.git scm:git:ssh://git@github.com/lambdaisland/shellutils.git - 59d09d756fe944ec3d2931576996c30c1bd2bb80 + 3689acafe850b0b208782d58bf99716cd9c7e237 @@ -61,7 +61,7 @@ - 59d09d756fe944ec3d2931576996c30c1bd2bb80 + 3689acafe850b0b208782d58bf99716cd9c7e237