:foo-bar |
"baz" |
The standard library is the set of modules that come with Bass.
The ground module is inherited by all modules. It provides basic language constructs and the standard toolkit for running thunks.
$ |
constructs a thunk with args |
* |
multiplies numbers |
+ |
sums numbers |
- |
subtracts ys from x |
-> |
passes a value through a series of function calls |
< |
returns true if the numbers are in ascending order |
<= |
returns true if the numbers are in ascending or equal order |
= |
returns true if the values are all equal |
> |
returns true if the numbers are in descending order |
>= |
returns true if the numbers are in descending or equal order |
across |
returns a pipe source that yields a list of values across all the given sources |
always |
returns a function that returns x for any value |
and |
returns a truthy value if none of the conds return a falsy value |
append |
joins all given lists into one list |
applicative? |
returns true if the value is an applicative |
apply |
call an applicative's underlying operative with a list of arguments |
assoc |
assoc[iate] keys with values in a clone of a scope |
bind |
attempts to bind values in the scope |
binds? |
returns true if the scope has a value bound to the given symbol |
boolean? |
returns true if the value is true or false |
cache-dir |
returns a cache directory corresponding to the string identifier |
case |
evaluates the branch that successfully binds the given value |
cd |
chain a sequence of thunks with a given working directory |
combiner? |
returns true if the value is a combiner |
cond |
if-then-else, but with many clauses |
conj |
conjoins values onto the end of a list |
cons |
construct a pair from the given values |
current-scope |
returns the scope of the caller |
curryfn |
returns a fn which accepts args one value at a time |
def |
bind symbols to values in the current scope |
defn |
construct a function and bind it to a symbol |
defop |
construct an operative and bind it to a symbol |
do |
evaluate a sequence, returning the last value |
doc |
print docs for symbols |
dump |
encodes a value as JSON to stderr |
each |
calls f for every value read from the source |
emit |
emits a value to a sink |
empty? |
returns true if the value is an empty list, a zero-length string, an empty scope, or null |
error |
errors with the given message |
eval |
evaluate a value in a scope |
filter |
returns only values from xs which satisfy the predicate |
first |
return the first value in a pair |
fn |
construct a function |
foldl |
reduces xs, leftmost values first, with initial value z |
foldr |
reduces xs, rightmost values first, with initial value z |
for |
loops over values from sources |
from |
chain a sequence of thunks starting from an initial image |
id |
identity function; returns its argument |
if |
if then else (branching logic) |
ignore? |
returns true if the value is _ ("ignore") |
import |
binds symbols in the current scope to their values from the source scope |
insecure! |
sets the :insecure field of the thunk to true |
json |
returns a string containing val encoded as JSON |
keys |
collects the bindings from a scope |
last |
returns the last value from the source |
length |
return the length of the given list |
let |
binds values in a child scope |
linux |
a path root for resolving Linux images |
list |
construct a list from a sequence of values |
list* |
prepend a sequence of values to a list given as the final argument |
list->scope |
constructs an object from a list of flat keyword/value pairs |
list->source |
creates a pipe source from a list of values in chronological order |
list? |
returns true if the value is a linked list |
load |
load a thunk as a module |
log |
logs a string message or arbitrary value to stderr |
make-scope |
construct a scope with the given parents |
map |
returns a list containing the result of applying f to each member of xs |
map-pairs |
calls a function with alternating pairs in a flat list (i.e. with pairs ungrouped) |
mask |
shrouds a string in secrecy |
max |
returns the largest number |
memo |
memo[ize]s a function |
merge |
returns a scope containing the union of the given scopes |
meta |
returns the meta attached to the value |
min |
returns the smallest number |
mkfile |
returns an in-memory file with the given content |
mkfs |
returns a dir path backed by an in-memory filesystem |
module |
returns a scope with only the specified bindings from a child scope |
next |
receive the next value from a source |
not |
negates the given bool-ish value |
now |
returns the current UTC time truncated to the given seconds |
null? |
returns true if the value is null |
number? |
returns true if the value is a number |
op |
construct an operative |
operative? |
returns true if the value is an operative |
or |
returns the first truthy value returned by evaluating conds |
pair? |
returns true if the value is a pair |
path-base |
returns the path-name converted into a file path |
path-name |
returns the base name of the path |
path-stem |
returns the base name of the path, without any extension |
path? |
returns true if the value is a path |
provide |
provide bindings to the current scope from a nested scope |
read |
returns a stream producing values read from a thunk's output or a file's content |
recall-memo |
fetches the result of a memoized function call |
reduce-kv |
reduces a scope |
resolve |
resolve an image reference to its most exact form |
rest |
return the second value in a pair, i.e. the rest of a linked list |
run |
runs a thunk |
scope->list |
returns a flat list alternating a scope's keys and values |
scope? |
returns true if the value is a scope |
second |
return the second member of a linked list |
sink? |
returns true if the value is a sink |
source? |
returns true if the value is a source |
start |
starts running a thunk asynchronously |
store-memo |
stores the result of a memoized function call |
str |
returns the concatenation of all given strings or values |
string->cmd-path |
converts a string to a command or file path |
string->dir |
converts a string to a directory path |
string->fs-path |
parses a string value into a file or directory path |
string->symbol |
convert a string to a symbol |
string? |
returns true if the value is a string |
subpath |
extend path with another path |
substring |
returns a portion of a string |
succeeds? |
returns true if the thunk successfully runs (i.e. exit code 0) |
symbol->string |
convert a symbol to a string |
symbol? |
returns true if the value is a symbol |
take |
reads the next n values from the source into a list |
third |
return third member of a linked list |
thunk-args |
returns the thunk's args |
thunk-cmd |
returns the thunk's command |
thunk? |
returns true if the value is a valid thunk |
trim |
removes whitespace from both ends of a string |
unwrap |
returns an applicative's underlying combiner |
use |
loads each thunk and binds it as the name from the thunk's command path |
vals |
collects the values from a scope |
when |
evaluates the body if test returns true |
with-args |
returns thunk with args set to args |
with-cmd |
returns thunk with cmd set to cmd |
with-dir |
returns thunk with the working directory set to dir |
with-env |
returns thunk with env set to the given env |
with-image |
returns thunk with the base image set to image |
with-insecure |
returns thunk with the insecure flag set to bool |
with-label |
returns thunk with the label set to val |
with-meta |
returns val with the given scope as its metadata |
with-mount |
returns thunk with a mount from source to the target path |
with-stdin |
returns thunk with stdin set to vals |
wrap |
construct an applicative from a combiner (typically an operative) |
wrap-cmd |
prepend a command + args to a thunk's command + args |
(mkfs & file-content-kv)
applicative? combiner?
returns a dir path backed by an in-memory filesystem
Takes alternating file paths and their content, which must be a text string, and returns the root directory of an in-memory filesystem containing the specified files.
All embedded files have 0644 Unix file permissions and a zero (Unix epoch) mtime.
=> resolve image config for docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> mkfile /file CACHED [0.00s]=> docker-image://docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c CACHED [0.00s]-> resolve docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> cat <fs>/file [0.17s]=> exporting to client [0.00s]-> copying files 29B [0.00s]
"hey"
(log val & fields)
applicative? combiner?
(error msg & fields)
applicative? combiner?
errors with the given message
Accepts key-value fields for structured error data.
(error "oh no!")
error! call trace (oldest first):┆ <fs>/literate-4:1:0..1:161 │ (error "oh no!")^^^^^^^^^^^^^^^^oh no!
(error "oh no!" :exit-code 2)
error! call trace (oldest first):┆ <fs>/literate-4:1:0..1:291 │ (error "oh no!" :exit-code 2)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^oh no!:exit-code 2
(wrap comb)
applicative? combiner?
(make-scope & parents)
applicative? combiner?
construct a scope with the given parents
(make-scope {:a 1} {:b 2})
{
{
} |
|||
{
} |
}
(eval [+ :a :b] (make-scope {:a 1} {:b 2}))
3
(bind scope formals val)
applicative? combiner?
attempts to bind values in the scope
Returns true if the binding succeeded, otherwise false.
(if (bind (current-scope) :abc 123) abc :mismatch)
123
(if (bind (current-scope) [] 123) _ :mismatch)
mismatch
(doc & symbols)
operative? combiner?
(applicative? val)
applicative? combiner?
(operative? val)
applicative? combiner?
returns true if the value is an operative
An operative is a combiner that is given the caller's scope.
An operative may decide whether and how to evaluate its arguments. They are typically used to define new syntactic constructs.
false
(operative? op)
true
(list->source list)
applicative? combiner?
creates a pipe source from a list of values in chronological order
(list->source [1 2 3])
<source: 1 2 3>
(across & sources)
applicative? combiner?
returns a pipe source that yields a list of values across all the given sources
Each list has the last value for each source. Values from each source are never skipped, but not every combination will be produced.
(def evens (list->source [0 2 4]))
evens
(def odds (list->source [1 3 5]))
odds
(next src & default)
applicative? combiner?
receive the next value from a source
If the source has ended, no value will be available. A default value may be provided, otherwise an error is raised.
(next (list->source [1]) :eof)
1
(next *stdin* :eof)
eof
(reduce-kv f init kv)
applicative? combiner?
(symbol->string sym)
applicative? combiner?
convert a symbol to a string
(symbol->string :hello!)
"hello!"
(string->symbol str)
applicative? combiner?
convert a string to a symbol
(string->symbol "hello!")
hello!
(scope->list obj)
applicative? combiner?
returns a flat list alternating a scope's keys and values
The returned list is the same form accepted by (assoc).
(scope->list {:a 1 :b 2 :c 3})
(
a
1
b
2
c
3
)
(apply assoc (cons {:d 4} (scope->list {:a 1 :b 2 :c 3})))
{
:d |
4 |
:a |
1 |
:b |
2 |
:c |
3 |
}
(string->fs-path str)
applicative? combiner?
parses a string value into a file or directory path
(string->fs-path "./file")
./file
(string->fs-path "file")
./file
(string->fs-path "dir/")
./dir/
(string->cmd-path str)
applicative? combiner?
converts a string to a command or file path
If the value contains a /, it is converted into a file path.
Otherwise, the given value is converted into a command path.
(string->cmd-path "scripts/foo")
./scripts/foo
(string->cmd-path "bash")
.bash
(string->dir str)
applicative? combiner?
converts a string to a directory path
A trailing slash is not required; the path is always assumed to be a directory.
(string->dir "dir")
./dir/
(string->dir "dir/")
./dir/
(path-name path)
applicative? combiner?
returns the base name of the path
For a command path, this returns the command name.
For a file or dir path, it returns the file or dir name.
For a file path, it returns the file name.
For a thunk, it returns the thunk's hash.
(path-name .bash)
"bash"
(path-name ./some/file)
"file"
(path-name ./some/dir/)
"dir"
(path-name (.tests))
"hpdBgidbxFI="
(with-image thunk image)
applicative? combiner?
returns thunk with the base image set to image
Image is either a thunk? or an image ref.
Recurses when thunk's image is another thunk, setting the deepest ref or unset image.
See also (from).
(with-image ($ go test ./...) (linux/golang))
{
:image |
{
} |
||||||||||
:cmd |
.go |
||||||||||
:args |
(
) |
}
(with-dir thunk dir)
applicative? combiner?
returns thunk with the working directory set to dir
Unlike (cd), the value of (with-dir) is resolved at runtime, meaning it can use container-local paths.
If the thunk needs to write to its output directory, the output path passed to the command must be relative to the given dir. Thunk paths and other mounts will always be 1 level deep in the output directory, so use ../ to refer to back to the output directory, repeated for each additional level of depth. If the depth is unknown, you should use (cd) instead.
(with-dir (.tests) ./src/)
{
:cmd |
.tests |
:dir |
./src/ |
}
(with-stdin thunk vals)
applicative? combiner?
returns thunk with stdin set to vals
(with-stdin ($ jq ".a") [{:a 1} {:a 2}])
{
:cmd |
.jq |
||||
:args |
(
) |
||||
:stdin |
(
) |
}
(with-insecure thunk bool)
applicative? combiner?
returns thunk with the insecure flag set to bool
The insecure flag determines whether the thunk runs with elevated privileges, and is named to be indicate the reduced security assumptions.
(with-insecure (.boom) true)
{
:insecure |
true |
:cmd |
.boom |
}
(= (.boom) (with-insecure (.boom) false))
true
(with-label thunk name val)
applicative? combiner?
returns thunk with the label set to val
Labels are typically used to control caching. Two thunks that differ only in labels will evaluate separately and produce independent results.
(with-label ($ sleep 10) :at (now 10))
{
:cmd |
.sleep |
||
:args |
(
) |
||
:labels |
{
} |
}
(with-mount thunk source target)
applicative? combiner?
returns thunk with a mount from source to the target path
(with-mount ($ find ./inputs/) *dir*/inputs/ ./inputs/)
{
:cmd |
.find |
||||
:args |
(
) |
||||
:mounts |
(
) |
}
(thunk-args thunk)
applicative? combiner?
returns the thunk's args
(thunk-args ($ foo abc))
(
"abc"
)
(thunk-args ($ foo))
(
)
(resolve platform ref)
applicative? combiner?
resolve an image reference to its most exact form
(resolve {:platform {:os "linux"} :repository "golang" :tag "latest"})
=> resolve image config for docker.io/library/golang:latest [0.45s]
{
:platform |
{
} |
||
:repository |
"golang" |
||
:tag |
"latest" |
||
:digest |
"sha256:9349ed889adb906efa5ebc06485fe1b6a12fb265a01c9266a137bb1352565560" |
}
(start thunk handler)
applicative? combiner?
starts running a thunk asynchronously
If the thunk errors or exits nonzero the handler is called with a combiner that raises the error when called.
If the thunk runs succeeds the handler is called with null.
=> docker-image://docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c CACHED [0.00s]-> resolve docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> resolve image config for docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> banana ERROR [0.17s]▕ run error: exec: "banana": executable file not found in $PATH!!! banana5: [0.15s] run error: exec: "banana": executable file not found in $PATH
false
=> resolve image config for docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> docker-image://docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c CACHED [0.00s]-> resolve docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> echo [0.10s]▕
true
=> resolve image config for docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> docker-image://docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c CACHED [0.00s]-> resolve docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> banana ERROR [0.12s]▕ run error: exec: "banana": executable file not found in $PATH!!! banana5: [0.10s] run error: exec: "banana": executable file not found in $PATHerror! call trace (oldest first):┆ <fs>/literate-9:1:0..1:491 │ ((start (from (linux/alpine) ($ banana)) raiser))^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^build failed: exit code: 1run summary:=> resolve image config for docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> docker-image://docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c=> banana [0.13s]run error: exec: "banana": executable file not found in $PATHERROR: exit code: 1for more information, refer to the full output above
=> resolve image config for docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> docker-image://docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c CACHED [0.00s]-> resolve docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> echo [0.17s]▕
null
(read thunk-or-file protocol)
applicative? combiner?
returns a stream producing values read from a thunk's output or a file's content
=> resolve image config for docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> docker-image://docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c CACHED [0.00s]-> resolve docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> echo 42 [0.15s]=> exporting to client [0.00s]-> copying files 29B [0.00s]
42
=> resolve image config for docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> docker-image://docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c CACHED [0.00s]-> resolve docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> sh -c "echo 42 > file" [0.14s]=> exporting to client [0.00s]-> sending tarball [0.00s]
42
(binds? scope sym)
applicative? combiner?
returns true if the scope has a value bound to the given symbol
(binds? {:x 1} :x)
true
(binds? {} :x)
false
(binds? (current-scope) :binds?)
true
(mask secret name)
applicative? combiner?
shrouds a string in secrecy
Prevents the string from being revealed when the value is displayed.
Prevents the string from being revealed in a serialized thunk or thunk path.
Does NOT currently prevent the string's value from being displayed in log output; you still have to be careful there.
(mask "super secret" :github-token)
<secret: github-token (12 bytes)>
(current-scope)
operative? combiner?
returns the scope of the caller
{
:*memos* |
<host: bass.lock> |
||||||||||||
{
} |
}
(eval [current-scope] {:a 1})
{
:a |
1 |
}
(map-pairs f ps)
applicative? combiner?
(let bindings & body)
operative? combiner?
(list->scope kwargs)
applicative? combiner?
constructs an object from a list of flat keyword/value pairs
(list->scope [:a 1 :b 2 :c 3])
{
:a |
1 |
:b |
2 |
:c |
3 |
}
(cond & clauses)
operative? combiner?
if-then-else, but with many clauses
Takes a flat pair sequence alternating tests to evaluate and an expression to evaluate if the test returns a truthy value.
Returns the result of the evaluated branch, or null if no tests were true.
By convention, :else is used as the final catch-all test, though any truthy value works.
(cond false :a false :b :else :c)
c
(cond true :a false :b :else :c)
a
(apply appv arg & opt)
applicative? combiner?
call an applicative's underlying operative with a list of arguments
A scope may be provided as the third argument. If not specified, the operative will be called in a new empty scope.
Used to call an applicative with pre-evaluated arguments, skipping the normal evaluation the applicative would perform prior to calling the underlying operative.
(-> x f & fs)
operative? combiner?
passes a value through a series of function calls
Given an input value and a series of functions, calls the first function with the input value, passing the output to the second function, and so on, returning the final value. Typically used to flatten a deeply nested function call to make it easier to read.
Functions are either a single form (i.e. a symbol) or a pair. A single form is called with the input value as the only argument. A pair is called with the input value prepended to the rest of the pair, i.e. inserted as the first argument.
(memo memos thunk binding)
applicative? combiner?
memo[ize]s a function
Returns a function equivalent to (binding (load thunk)) which caches its results to/from memos, a path to a file on the host (read-write) or from a thunk (read-only).
This is a utility for caching dependency version resolution, such as image tags and git refs. It is technically the only way to perform writes against the host filesystem.
The intended practice is to commit memos into source control to facilitate reproducible builds.
(def memos *dir*/bass.lock)
memos
(upper-cache "hello")
"HELLO"
=> resolve image config for docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> docker-image://docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c CACHED [0.01s]-> resolve docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.02s]=> local:///tmp/bass-scope3421689081 [0.04s]-> transferring /tmp/bass-scope3421689081: 417B [0.00s]=> copy /bass.lock /bass.lock CACHED [0.00s]=> cat <host: /tmp/bass-scope3421689081/bass.lock> [0.18s]▕ memos: {▕ module: {▕ cmd: {▕ command: {▕ name: "strings"▕ }▕ }▕ }▕ calls: {▕ binding: "upper-case"▕ results: {▕ input: {▕ array: {▕ values: {▕ string: {▕ value: "hello"▕ }▕ }▕ }▕ }▕ output: {▕ string: {▕ value: "HELLO"▕ }▕ }▕ }▕ }▕ }
null
(succeeds? thunk)
applicative? combiner?
returns true if the thunk successfully runs (i.e. exit code 0)
returns false if it fails (i.e. exit code nonzero)
Used for running a thunk as a conditional instead of erroring when it fails.
=> resolve image config for docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> docker-image://docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c CACHED [0.00s]-> resolve docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> false ERROR [0.10s]!!! false
false
=> resolve image config for docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> docker-image://docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c CACHED [0.00s]-> resolve docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> true [0.11s]
true
(run thunk)
applicative? combiner?
runs a thunk
Raises an error if the thunk's command fails (i.e. exit code 0)
Returns null.
=> resolve image config for docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> docker-image://docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c CACHED [0.00s]-> resolve docker.io/library/alpine@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c [0.01s]=> echo "Hello, world!" [0.15s]▕ Hello, world!
null
(last source & default)
applicative? combiner?
returns the last value from the source
As with (next), a default may be provided to be returned when the source is empty. If not provided, an error will be raised if the source is empty.
(last (list->source [1 2 3]))
3
(each source f)
applicative? combiner?
(for bindings & body)
operative? combiner?
loops over values from sources
Takes a list alternating bindings and their sources, similar to (let). Reads values across all sources and evaluates the body for each set of values as they are read with (next).
Returns null when the source reaches its end.
(def evens (list->source [0 2 4]))
evens
(def odds (list->source [1 3 5]))
odds
(take n source)
applicative? combiner?
reads the next n values from the source into a list
(take 2 (list->source [1 2 3]))
(
1
2
)
(from image & thunks)
applicative? combiner?
chain a sequence of thunks starting from an initial image
(cd dir thunk & thunks)
applicative? combiner?
chain a sequence of thunks with a given working directory
Shorthand for setting (with-mount dir ./) in the first thunk and chaining them with (from).
Typically used within an outer (from) which sets the first thunk's image in order to join it into the chain.
{
:image |
{
} |
||||||||||
:cmd |
.find |
||||||||||
:args |
(
) |
||||||||||
:mounts |
(
) |
}
(linux & args)
operative? combiner?
a path root for resolving Linux images
Memoizes image resolution into the caller's *memos*, if set.
(linux/ubuntu)
{
:platform |
{
} |
||
:repository |
"ubuntu" |
||
:tag |
"latest" |
||
:digest |
"sha256:b6b83d3c331794420340093eb706a6f152d9c1fa51b262d9bf34594887c2c7ac" |
}
(linux/ubuntu :18.04)
{
:platform |
{
} |
||
:repository |
"ubuntu" |
||
:tag |
"18.04" |
||
:digest |
"sha256:478caf1bec1afd54a58435ec681c8755883b7eb843a8630091890130b15a79af" |
}
(linux/docker.io/library/ubuntu :18.04)
{
:platform |
{
} |
||
:repository |
"docker.io/library/ubuntu" |
||
:tag |
"18.04" |
||
:digest |
"sha256:478caf1bec1afd54a58435ec681c8755883b7eb843a8630091890130b15a79af" |
}
Bass modules always run as commands. Either a user runs the script with the bass
command, or another Bass module runs it as a thunk.
When a module is run as a script, the values reflect the system values available to the bass
command, and main
is called with the arguments passed to bass
.
When a module is run as a thunk, the values reflect the values set in the thunk, and main
is called with the thunk's args.
*dir* |
current working directory |
*env* |
environment variables |
*stdin* |
standard input stream |
*stdout* |
standard output sink |
main |
script entrypoint |
*env*
scope?
environment variables
System environment variables are only available to the entrypoint script. To propagate them further they must be explicitly passed to thunks using (with-env).
System environment variables are unset from the physical OS process as part of initialization to ensure they cannot be leaked.
{
:SECRET_TOKEN |
"im a spooky value" |
}
(main)
applicative? combiner?
script entrypoint
The (main) function is called with any provided command-line args when running a Bass script.
Scripts should define it to capture system arguments and run the script's desired effects.
Putting effects in (main) instead of running them at the toplevel makes the Bass language server happier.
Simple functions for manipulating UTF-8 encoded strings.
(load (.strings))
<scope: <thunk u_ap1YarZN8=: (.strings)>>
includes? |
returns true if str includes substr |
join |
joins a list of strings together with delim in between |
split |
split a string on a delimiter |
upper-case |
capitalizes all letters in the string |
.git
module
Bare essentials for fetching Git repositories, using the git
CLI from an image passed on stdin
.
This module is limited to functions necessary for fetching other Bass scripts, i.e. bootstrapping.
checkout |
returns the repo checked out to the given ref |
github |
a path root for repos hosted at github.com |
ls-remote |
resolves a ref to a sha at the remote repo |
path |
returns a path root for repos at the given base URL |
(ls-remote repo ref & timestamp)
applicative? combiner?
resolves a ref to a sha at the remote repo
Does not cache. Used to resolve the ref at a point in time.
(git:ls-remote "https://github.com/vito/bass" "main")
=> resolve image config for docker.io/alpine/git@sha256:23dcd3edfd1d9c7cbb14f7823d07a4934716cfa4d4dbc402d37ee011c440a685 [0.01s]=> docker-image://docker.io/alpine/git@sha256:23dcd3edfd1d9c7cbb14f7823d07a4934716cfa4d4dbc402d37ee011c440a685 CACHED [0.00s]-> resolve docker.io/alpine/git@sha256:23dcd3edfd1d9c7cbb14f7823d07a4934716cfa4d4dbc402d37ee011c440a685 [0.01s]=> git ls-remote https://github.com/vito/bass main [0.38s]=> exporting to client [0.00s]-> copying files 83B [0.00s]
"6c037a9d134c8b60d61fcd0023494358b94e265f"
(checkout repo ref)
applicative? combiner?
returns the repo checked out to the given ref
The thunk for cloning the repo is labeled with the given ref. If the ref refers to a branch, you may want to resolve it to a sha first with (ls-remote) so that it's not cached forever.
Submodules are always initialized.
(git:checkout "https://github.com/vito/bass" "ea8cae6d4c871cb14448d7254843d86dbab8505f")
{
:image |
{
} |
||||||||||||||||||||||||||||
:cmd |
.git |
||||||||||||||||||||||||||||
:args |
(
) |
}
./
(path root memos)
applicative? combiner?
returns a path root for repos at the given base URL
Please omit the trailing slash. (TODO: would be nice to just strip it or somehow make it a non-issue.)
(def gh (git:path "https://github.com" null))
gh
gh/vito/bass/ref/main/
=> resolve image config for docker.io/alpine/git@sha256:23dcd3edfd1d9c7cbb14f7823d07a4934716cfa4d4dbc402d37ee011c440a685 [0.01s]=> docker-image://docker.io/alpine/git@sha256:23dcd3edfd1d9c7cbb14f7823d07a4934716cfa4d4dbc402d37ee011c440a685 CACHED [0.00s]-> resolve docker.io/alpine/git@sha256:23dcd3edfd1d9c7cbb14f7823d07a4934716cfa4d4dbc402d37ee011c440a685 [0.01s]=> git ls-remote https://github.com/vito/bass main [0.45s]=> exporting to client [0.00s]-> copying files 83B [0.00s]
{
:image |
{
} |
||||||||||||||||||||||||||||
:cmd |
.git |
||||||||||||||||||||||||||||
:args |
(
) |
}
./
(github & args)
operative? combiner?
a path root for repos hosted at github.com
Memoizes ref resolution into the caller's *memos*, if set.
git:github/vito/bass/sha/ea8cae6d4c871cb14448d7254843d86dbab8505f/
{
:image |
{
} |
||||||||||||||||||||||||||||
:cmd |
.git |
||||||||||||||||||||||||||||
:args |
(
) |
}
./
(git:github/vito/bass/sha/ "ea8cae6d4c871cb14448d7254843d86dbab8505f")
{
:image |
{
} |
||||||||||||||||||||||||||||
:cmd |
.git |
||||||||||||||||||||||||||||
:args |
(
) |
}
./
git:github/vito/bass/ref/main/
{
:image |
{
} |
||||||||||||||||||||||||||||
:cmd |
.git |
||||||||||||||||||||||||||||
:args |
(
) |
}
./
bind symbols to values in the current scope
Supports destructuring assignment.
abc
(
a
b
c
)
(
"it's easy as"
1
2
3
)