Skip to main content

load

The load statement imports names from another file so scripts can share functions and constants. It is a statement of the language rather than a function: it appears at the top level of a file, and it binds the names you list into that file.

For a namespace containing all public names, use module.load:

kube = module.load("lib/kube.star")
kube.get("pods")

Usage​

load("file.star", "name", alias = "name")

Arguments​

"file.star"

Required. The path of the module to load, as a string literal. A relative path, including one with .. segments, resolves against the directory of the file that contains the load statement. For an inline script in a YAML step, it resolves against the current script directory (initially the step's working_directory, updated by os.chdir). An absolute path is used as given.

"name"

(Optional, repeatable) The name of a global in the module to bind under the same name. At least one name or alias is needed for the statement to be useful.

alias = "name"
(Optional, repeatable) Binds the module's global name under a different local name, alias.

Behavior​

  • Each module is evaluated once per run and cached by its cleaned absolute path, so loading it from several files does not run it again. The cache is shared with module.load().
  • A module can load other modules. Relative paths in a module resolve against that module's own directory.
  • Cyclic loads fail with cyclic load of <path>.
  • The globals of a loaded module are frozen. A loaded list or dictionary cannot be modified by the importer.
  • A module sees the same predeclared names as the entry script, such as ui, exec, json, regex, fs, log, and steps, so shared helpers can call them.
  • Functions loaded from a module can be passed to steps.parallel and steps.task.

Examples​

Share helpers between files​

The file lib/text.star:

def slug(value):
return regex.replace("[^a-z0-9]+", "-", value.lower())

The file lib/naming.star, which loads another module and uses ui:

load("text.star", "slug")

PREFIX = "acme"

def resource_name(stack, component):
ui.info("naming " + component)
return PREFIX + "-" + slug(stack) + "-" + component

The file app/main.star, which loads with a relative path, renames an import, and calls the loaded function from parallel tasks:

load("../lib/naming.star", "resource_name", prefix = "PREFIX")

names = steps.parallel(functions = [
lambda: resource_name("Prod US East", "vpc"),
lambda: resource_name("Dev", "eks"),
])
print(prefix)
output = names
[lambda[0]] ▶ naming vpc
[lambda[1]] ▶ naming eks
acme
["acme-prod-us-east-vpc","acme-dev-eks"]

The lines that start with [lambda appear on stderr and can arrive in either order. The other lines are on stdout.

Load from an inline script​

workflows:
loaded:
steps:
- name: label
type: script
interpreter: starlark
working_directory: scripts
script: |
load("helpers.star", "region_label")
output = region_label("us-east-1")

With scripts/helpers.star containing:

def region_label(region):
return "region:" + region

The step value is region:us-east-1.

Errors​

  • A module that cannot be read fails with cannot read module: ..., followed by the operating system reason and the resolved path. The message is prefixed with cannot load <name>.
  • Modules that load each other, directly or through a chain, fail with cyclic load of <path>.
  • Modifying a value imported from a module, such as appending to a loaded list, fails with cannot append to frozen list.
  • A name that the module does not define fails when the statement runs.