diff --git a/src/bb_utils/core.bb b/src/bb_utils/core.bb index 803a8e2..27b015d 100755 --- a/src/bb_utils/core.bb +++ b/src/bb_utils/core.bb @@ -1,18 +1,29 @@ #!/usr/bin/env bb + (ns bb-utils.core (:require [babashka.cli :as cli] - [bb-utils.string :refer [from-base64 from-hex]])) + [bb-utils.string :refer [from-base64 from-hex]] + [bb-utils.git :refer [get-repos pull-all]])) (defn help [_] (println "Usage: bbut [...args]") (println "\nAvailable commands:") - (println " string from-base64 Convert Base64 to string") - (println " string from-hex Convert hex to string") + (println " string from-base64 Convert Base64 to string") + (println " string from-hex Convert hex to string") + (println " git get-repos [path] Lists all git repos at path. Default path '.'") + (println " git pull-all [path] [branch] Pull all repos at path. Default path '.'. Default branch is current branch") + (println " Options:") + (println "TODO [branch] Checkout the branch and pull") + (println "TODO --include-changed Stashes changes, pull, then apply the changes") + (println "TODO --reset-branch Returns repo to original branch, if combined with --include-changed will apply changes on original branch") + (println "TODO --merge Use with [branch] and if current branch is not original branch it will merge original branch into given branch") (println "\nUse 'bbut --help' for help.")) (def table [{:cmds ["string" "from-hex"] :fn (fn [{:keys [args]}] (println (from-hex (first args))))} {:cmds ["string" "from-base64"] :fn (fn [{:keys [args]}] (println (from-base64 (first args))))} + {:cmds ["git" "get-repos"] :fn (fn [{:keys [args]}] (run! println (get-repos (first args))))} + {:cmds ["git" "pull-all"] :fn (fn [{:keys [args]}] (pull-all (first args)))} {:cmds ["--help"] :fn help} {:cmds [] :fn help}]) @@ -26,3 +37,4 @@ (when (= *file* (System/getProperty "babashka.file")) (apply -main *command-line-args*)) + diff --git a/src/bb_utils/git.bb b/src/bb_utils/git.bb new file mode 100644 index 0000000..36efa1a --- /dev/null +++ b/src/bb_utils/git.bb @@ -0,0 +1,73 @@ +#!/usr/bin/env bb + +(ns bb-utils.git + (:require [babashka.process :refer [shell]] + [babashka.fs :as fs] + [clojure.string :as str])) + +(defn git-branch + [repo-path] + (shell {:out :string :dir repo-path} "git" "branch")) + +(defn git-status-short + [repo-path] + (shell {:out :string :dir repo-path} "git" "status" "--short")) + +(defn git-pull + [repo-path] + (shell {:out :string :dir repo-path} "git" "pull")) + +(defn get-path-or-default + ([path] + (get-path-or-default path nil)) + ([path rest] + (let [path (or path "./") + rest (or rest nil)] + (str/replace (str path rest) "/./" "/")))) + +(defn filter-current-branch + [output] + (let [branches (str/split-lines output)] + (first (filter #(str/starts-with? % "*") branches)))) + +(defn get-current-branch + ;; TODO: Detached head doesn't seem right. + ;; Probably should skip this if it happens + [repo-path] + (let [branch (filter-current-branch (git-branch repo-path))] + (if branch + (subs branch 2) + nil))) + +(defn changes? [line] + (and (not-empty line) + (and (>= (count line) 2) + (not (= (subs line 0 2) "??"))))) + +(defn any-changes? + [repo-path] + (some changes? (str/split-lines (str (git-status-short repo-path))))) + +(defn git-repo? + [repo-path] + (and (fs/directory? repo-path) + (fs/exists? (str repo-path "/.git")))) + +(defn get-repos + [path] + (let [base-path (get-path-or-default path)] + (map #(.toString %) (filter git-repo? (fs/list-dir base-path))))) + +(defn pull + [repo-path] + (if (any-changes? repo-path) + (println (str "Skipping " repo-path ". Uncommitted changes found.")) + (git-pull repo-path))) + +(defn pull-all + [path] + (let [path (get-path-or-default path) + repos (get-repos path)] + (doseq [repo-path repos] + (let [full-repo-path (get-path-or-default path repo-path)] + (pull full-repo-path))))) diff --git a/src/bb_utils/string.bb b/src/bb_utils/string.bb index c48f4c6..632b320 100644 --- a/src/bb_utils/string.bb +++ b/src/bb_utils/string.bb @@ -1,4 +1,5 @@ #!/usr/bin/env bb + (ns bb-utils.string (:import [java.util Base64])) diff --git a/test/bb_utils/git_test.bb b/test/bb_utils/git_test.bb new file mode 100644 index 0000000..c26d011 --- /dev/null +++ b/test/bb_utils/git_test.bb @@ -0,0 +1,8 @@ +#!/usr/bin/env bb + +(ns bb-utils.git-test + (:require [clojure.test :refer [deftest is]] + [bb-utils.git :as git])) + +(deftest test-get-current-branch + (let []))