I'm trying to use Babashka to replace a few Bash scripts I use to deploy functions on GCP Cloud Functions.
The script below is working, but I wonder if there is a better way to execute the gcloud
shell command:
#!/usr/bin/env bb
(require '[cheshire.core :as json]
'[clojure.java.shell :refer [sh]])
(let [package-json (json/parse-string (slurp "package.json") true)
name (:name package-json)
entry-point "entryPoint"
region "europe-west3"
memory "128MB"
runtime "nodejs14"
source "dist"
service-account "sa-function-invoker@prj-kitchen-sink.iam.gserviceaccount.com"
timeout "10s"]
(println "deploy function" name "with entry point" entry-point "to GCP Cloud Functions." "Attach service account" service-account)
(let [output (sh "gcloud" "functions" "deploy" name "--region" region "--entry-point" entry-point "--memory" memory "--runtime" runtime "--service-account" service-account "--source" source "--trigger-http" "--timeout" timeout)]
(if (= "" (:err output))
(println (:out output))
(println (:err output)))))
As a comparison, the Bash script I was using is easier to read:
#!/bin/bash
set -euo pipefail
FUNCTION_NAME=$(cat package.json | jq '{name}' | jq '.name' | sed 's/"//g')
FUNCTION_ENTRY_POINT=entryPoint
ATTACHED_SA=sa-function-invoker@prj-kitchen-sink.iam.gserviceaccount.com
MEMORY=128MB
echo "deploy function `${FUNCTION_NAME}` with entry point `${FUNCTION_ENTRY_POINT}` to GCP Cloud Functions. Attach service account `${ATTACHED_SA}`"
gcloud functions deploy ${FUNCTION_NAME} \
--project ${GCP_PROJECT_ID} \
--region ${GCP_REGION} \
--memory ${MEMORY} \
--runtime nodejs14 \
--service-account ${ATTACHED_SA} \
--source dist \
--entry-point ${FUNCTION_ENTRY_POINT} \
--timeout 10s
I guess my question is not very specific to Babashka or gcloud, but it's about how to construct commands with clojure.java.shell in general...
If you want to execute the shell command and see the direct output as it appears, I recommend using babashka.process/process
or babashka.tasks/shell
:
@(babashka.process/process ["ls" "-la"] {:out :inherit :err :inherit})
@(babashka.process/process ["ls" "-la"] {:inherit true})
(babashka.tasks/shell "ls -la")
The above invocations do pretty much the same, but shell
also applied babashka.process/check
which throws if the exit code was non-zero. The @
sign before the invocation is the same as calling deref
which means: wait for the process to finish. If you don't prepend that, than the process is going to run asynchronously.
More info: