Help utilizing babashka tasks globally

Hi all,

Attempting to make babashka tasks usuable from a more global standpoint and I’ve run into what I think is a dependency resolver issue with my setup wrt third party deps.

The first thing I did was setup some environment variables for calling bb with the classpath and edn file to source:

bb:sys() {
    BABASHKA_CLASSPATH=$BABASHKA_CLASSPATH:$HOME/configs/syslib BABASHKA_EDN=$HOME/configs/bb.edn bb [email protected]
}

Then in my $HOME/configs/syslib I have this file:

$HOME/configs/syslib/helper/cli.clj

(ns helper.cli
  (:require [clojure.edn :as edn]
            [clojure.string :as str]
            [babashka.fs :as fs]
            [babashka.tasks :refer [shell current-task run]]
            [lread.status-line :as status]))

(defn print-public-task [k]
  (let [{:keys [:private :name]} (current-task)]
    (when-not private
      (status/line :head (str (case k :enter "☐" "✓") " " name)))))

(defn print-help []
  "Prints the help output along with a usage if provided"
  (let [tasks (-> (or (System/getenv "BABASHKA_EDN") "bb.edn")
                  slurp
                  edn/read-string
                  :tasks)
        task (first *command-line-args*)]
    (if-let [task-map (get tasks (symbol task))]
      (println (format "%s\n\n\tUsage: bb %s%s\n"
                       (:doc task-map)
                       task
                       (if-let [usage (:usage task-map)]
                         (str " " usage)
                         "")))
      (do
        (println "Error: No such task exists")
        (System/exit 1)))))

In this file I’m using the lread.status-line library and this is the depedency giving me an error when attempting to utilize bb:sys tasks outside of $HOME/configs/bb.edn

bb:sys help repo:update
----- Error --------------------------------------------------------------------
Type:     java.lang.Exception
Message:  Could not find namespace: lread.status-line.
Location: /Users/adam/configs/syslib/helper/cli.clj:2:3

----- Context ------------------------------------------------------------------
1: (ns helper.cli
2:   (:require [clojure.edn :as edn]
     ^--- Could not find namespace: lread.status-line.
3:             [clojure.string :as str]
4:             [babashka.fs :as fs]
5:             [babashka.tasks :refer [shell current-task run]]
6:             [lread.status-line :as status]))
7:

----- Stack trace --------------------------------------------------------------
helper.cli                                - /Users/adam/configs/syslib/helper/cli.clj:2:3
user-3b27268b-63dc-441b-b303-b89e8b704f48 - <expr>:5:47

For completeness here is my $HOME/configs/bb.edn

{:min-bb-version "0.5.0"
 :paths ["syslib"]
 :deps {lread/status-line {:git/url "https://github.com/lread/status-line.git"
                           :sha "35ed39645038e81b42cb15ed6753b8462e60a06d"}}
 :tasks {
         :requires (
                    [helper.cli :as cli])

         :enter (cli/print-public-task :enter)
         :leave (cli/print-public-task :leave)

         help
         {:doc "Print a task's help"
          :task (cli/print-help)}

         system:update {:doc "Updates the package manager cache"
                        :task (shell "brew update")}
         system:upgrade {:doc "Upgrades system"
                         :task (shell "brew upgrade")}
         system:outdated {:doc "Show outdated packages"
                          :task (shell "brew outdated")}}}

My question: Is this something that is doable, if so, am I missing something here to make this work? My intention was to be able to have several useful tasks that would apply to different things depending on what Im doing and would like to have access to bb tasks as a global interface for speeding up my daily workflows.

Perhaps making a small bash script that cds into the system-wide bb.edn project and then calls bb from there might be easier.

In /usr/local/bin or whatever dir is on the path:

/usr/local/bin/bbsys:

#!/usr/bin/env bash

cd $(dirname $0)
bb [email protected]

/usr/local/bin/bb.edn:

{:deps {medley/medley {:mvn/version "1.3.0"}}
 :tasks {:requires ([medley.core :as medley])
         a (prn (medley/index-by :id [{:id 1} {:id 2}]))}}

Then from anywhere:

$ bbsys a
{1 {:id 1}, 2 {:id 2}}
1 Like

Thanks @borkdude that does indeed work. I guess the alternative would be to make these uberscripts utilizing babashka and convert the tasks to cli arguments and subcommands.

Another idea I had was to possibly package up tasks into a library and make them composable so that I have a bb.edn in whatever directory with the required tasks for that particular project/folder? I think Ruby Rake/Rails does something similar with gems including rake tasks?

There is a discussion about a similar topic here: Ability to specify a non standard bb.edn file path · Discussion #869 · babashka/babashka · GitHub