Builtin Functions
The contents of this page can be generated using:
spaces docs
Spaces Built-in Functions API Documentation
Table of Contents
Rule Options
Platforms
All rules can be run on a list of platforms (default is all). Specify a platform as:
macos-aarch64
macos-x86_64
linux-aarch64
linux-x86_64
windows-aarch64
windows-x86_64
Rule Types
Checkout
: Assigned by default to all checkout rulesSetup
: Assign to a run rule to make all other run rules depend on itRun
: Assigned by default to run rules.Optional
: Assign to run rules that are not required to run. Useadd_exec_if()
to conditionally run the rule.
Inspect (evaluate) scripts without executing rules:
# show rules with a `help` entry
spaces inspect --has-help
# show all rules
spaces --verbosity=message inspect
# show all rules with all details
spaces --verbosity=debug inspect
Checkout Rules
You use checkout rules to build a workspace. You can fetch git repositories and archives. You can also add assets (local files) to the workspace root folder (not under version control).
abort
def abort(message) -> None
Abort script evaluation with a message.
message
: Abort message to show the user.
Example
checkout.abort("Failed to do something")
add_archive
def add_archive(rule, archive) -> None
Adds an archive to the workspace.
rule
: dictname
: rule name as stringdeps
: list of dependenciesplatforms
: optional list of platforms to run on. If not provided, rule will run on all platforms. See above for detailstype
: Checkout|Optional|Setup|Run: see above for detailstype
: Setup|Run (default)|Optionalhelp
: Optional help text show withspaces evaluate
archive
: dict valueurl
: url to zip|tar.xz|tar.gz|tar.bz2 file (can also be an uncompressed file with no suffix)sha256
: hash of the filelink
: None|Hard: create hardlinks of the archive from the spaces store to the workspaceglobs
: optional list of globs prefix with+
to include and-
to excludestrip_prefix
: optional prefix to strip from the archive pathadd_prefix
: optional prefix to add in the workspace (e.g. sysroot/share)
Example
checkout.add_archive(
# the rule name is the path in the workspace where the archive will be extracted
rule = {"name": "llvm-project"},
archive = {
"url": "https://github.com/llvm/llvm-project/archive/refs/tags/llvmorg-{}.zip".format(version),
"sha256": "27b5c7c745ead7e9147c78471b9053d4f6fc3bed94baf45f4e8295439f564bb8",
"link": "Hard",
"strip_prefix": "llvm-project-llvmorg-{}".format(version),
"add_prefix": "llvm-project",
},
)
add_asset
def add_asset(rule, asset) -> None
Adds a file to the workspace. This is useful for providing a top-level build file that orchestrates the entire workspace. It can also be used to create a top-level README how the workflow works.
rule
: dictname
: rule name as stringdeps
: list of dependenciesplatforms
: optional list of platforms to run on. If not provided, rule will run on all platforms. See above for detailstype
: Checkout|Optional|Setup|Run: see above for detailstype
: Setup|Run (default)|Optionalhelp
: Optional help text show withspaces evaluate
asset
: dict withcontent
: file contents as a stringdestination
: relative path where asset will live in the workspace
Example
content = """
# README
This is how to use this workspace.
"""
checkout.add_asset(
rule = {"name": "README.md"},
asset = {
"destination": "README.md",
"content": content,
},
)
add_cargo_bin
def add_cargo_bin(rule, cargo_bin) -> str
Adds a binary crate using cargo-binstall. The binaries are installed in the spaces store and hardlinked to the workspace.
rule
: dictname
: rule name as stringdeps
: list of dependenciesplatforms
: optional list of platforms to run on. If not provided, rule will run on all platforms. See above for detailstype
: Checkout|Optional|Setup|Run: see above for detailstype
: Setup|Run (default)|Optionalhelp
: Optional help text show withspaces evaluate
cargo_bin
: dict withcrate
: The name of the binary crateversion
: The crate version to installbins
: List of binaries to install
Example
checkout.add_cargo_bin(
rule = {"name": "probe-rs-tools"},
cargo_bin = {
"crate": "probe-rs-tools",
"version": "0.24.0",
"bins": ["probe-rs", "cargo-embed", "cargo-flash"]
},
)
add_hard_link_asset
def add_hard_link_asset(rule, asset) -> None
Adds a hardlink from anywhere on the system to the workspace
rule
: dictname
: rule name as stringdeps
: list of dependenciesplatforms
: optional list of platforms to run on. If not provided, rule will run on all platforms. See above for detailstype
: Checkout|Optional|Setup|Run: see above for detailstype
: Setup|Run (default)|Optionalhelp
: Optional help text show withspaces evaluate
asset
: dict withsource
: the source of the hard linkdestination
: relative path where asset will live in the workspace
Example
checkout.add_hard_link_asset(
rule = { "name": "which_pkg_config" },
asset = {
"source": "<path to asset>",
"destination": "sysroot/asset/my_asset"
}
)
add_platform_archive
def add_platform_archive(rule, platforms) -> None
Adds an archive to the workspace based on the platform.
rule
: dictname
: rule name as stringdeps
: list of dependenciesplatforms
: optional list of platforms to run on. If not provided, rule will run on all platforms. See above for detailstype
: Checkout|Optional|Setup|Run: see above for detailstype
: Setup|Run (default)|Optionalhelp
: Optional help text show withspaces evaluate
platforms
: dict with platform keysmacos-aarch64
: dict with same entries as archive in add_archive()macos-x86_64
: same as macos-aarch64windows-aarch64
: same as macos-aarch64windows-x86_64
: same as macos-aarch64linux-aarch64
: same as macos-aarch64linux-x86_64
: same as macos-aarch64
Example
base = {
"add_prefix": "sysroot/bin",
"strip_prefix": "target/release",
"link": "Hard",
}
macos_x86_64 = base | {
"url": "https://github.com/work-spaces/spaces/releases/download/v0.6.0-beta.13/spaces-macos-latest-x86_64-v0.6.0-beta.13.zip",
"sha256": "47d325145e6f7f870426f1b123c781f89394b0458bb43f5abe2d36ac3543f7ef",
}
macos_aarch64 = base | {
"url": "https://github.com/work-spaces/spaces/releases/download/v0.6.0-beta.13/spaces-macos-latest-aarch64-v0.6.0-beta.13.zip",
"sha256": "6dd972454942faa609670679c53b6876ab8e66bcfd0b583ee5a8d13c93b2e879",
}
windows_x86_64 = base | {
"url": "https://github.com/work-spaces/spaces/releases/download/v0.6.0-beta.13/spaces-windows-latest-x86_64-v0.6.0-beta.13.exe",
"sha256": "b93dc96b2c66fcfc4aef851db2064f6e6ecb54b29968ca5174f6b892b99651c8",
}
windows_aarch64 = base | {
"url": "https://github.com/work-spaces/spaces/releases/download/v0.6.0-beta.13/spaces-windows-latest-aarch64-v0.6.0-beta.13.exe",
"sha256": "c67c7b23897e0949843e248465d5444428fb287f89dcd45cec76dde4b2cdc6a9",
}
linux_x86_64 = base | {
"url": "https://github.com/work-spaces/spaces/releases/download/v0.6.0-beta.13/spaces-linux-gnu-x86_64-v0.6.0-beta.13.zip",
"sha256": "39030124f18b338eceee09061fb305b522ada76f6a0562f9926ea0747b3ad440",
}
checkout.add_platform_archive(
# rule name is only the path in the workspace if add_prefix is not set
rule = {"name": "spaces"},
platforms = {
"macos-x86_64": macos_x86_64,
"macos-aarch64": macos_aarch64,
"windows-x86_64": windows_x86_64,
"windows-aarch64": windows_aarch64,
"linux-x86_64": linux_x86_64,
},
)
add_repo
def add_repo(rule, repo) -> str
returns the name of the current platform
rule
: dictname
: rule name as stringdeps
: list of dependenciesplatforms
: optional list of platforms to run on. If not provided, rule will run on all platforms. See above for detailstype
: Checkout|Optional|Setup|Run: see above for detailstype
: Setup|Run (default)|Optionalhelp
: Optional help text show withspaces evaluate
repo
: dict withurl
: ssh or https path to repositoryrev
: repository revision as a branch, tag or commitcheckout
: Revision: checkout detached at commit or branch|NewBranch: create a new branch based at revclone
: Default|Worktree|Shallowis_evaluate_spaces_modules
: True|False to check the repo for spaces.star files to evaluate
Example
checkout.add_repo(
# the rule name is also the path in the workspace where the clone will be
rule = { "name": "spaces" },
repo = {
"url": "https://github.com/work-spaces/spaces",
"rev": "main",
"checkout": "Revision",
"clone": "Default",
"is_evaluate_spaces_modules": True
}
)
add_soft_link_asset
def add_soft_link_asset(rule, asset) -> None
Adds a softlink from anywhere on the system to the workspace
rule
: dictname
: rule name as stringdeps
: list of dependenciesplatforms
: optional list of platforms to run on. If not provided, rule will run on all platforms. See above for detailstype
: Checkout|Optional|Setup|Run: see above for detailstype
: Setup|Run (default)|Optionalhelp
: Optional help text show withspaces evaluate
asset
: dict withsource
: the source of the software linkdestination
: relative path where asset will live in the workspace
Example
checkout.add_hard_link_asset(
rule = { "name": "which_pkg_config" },
asset = {
"source": "<path to asset>",
"destination": "sysroot/asset/my_asset"
}
)
add_target
def add_target(rule) -> None
Adds a target. There is no specific action for the target, but this rule can be useful for organizing dependencies.
rule
: dictname
: rule name as stringdeps
: list of dependenciesplatforms
: optional list of platforms to run on. If not provided, rule will run on all platforms. See above for detailstype
: Checkout|Optional|Setup|Run: see above for detailstype
: Setup|Run (default)|Optionalhelp
: Optional help text show withspaces evaluate
Example
checkout.add_target(
rule = {"name": "my_rule", "deps": ["my_other_rule"]},
)
add_which_asset
def add_which_asset(rule, asset) -> None
Adds a hardlink to an executable file available on the PATH
when checking out the workspace. This is useful for building tools that have complex dependencies.
Avoid using this when creating a workspace for your project. It creates system dependencies
that break workspace hermicity.
rule
: dictname
: rule name as stringdeps
: list of dependenciesplatforms
: optional list of platforms to run on. If not provided, rule will run on all platforms. See above for detailstype
: Checkout|Optional|Setup|Run: see above for detailstype
: Setup|Run (default)|Optionalhelp
: Optional help text show withspaces evaluate
asset
: dict withwhich
: name of system executable to search fordestination
: relative path where asset will live in the workspace
Example
checkout.add_which_asset(
rule = { "name": "which_pkg_config" },
asset = {
"which": "pkg-config",
"destination": "sysroot/bin/pkg-config"
}
)
update_asset
def update_asset(rule, asset) -> None
Creates or updates an existing file containing structured data in the workspace. This rules supports json|toml|yaml files. Different rules can update the same file and the content will be preserved (as long as the keys are unique).
rule
: dictname
: rule name as stringdeps
: list of dependenciesplatforms
: optional list of platforms to run on. If not provided, rule will run on all platforms. See above for detailstype
: Checkout|Optional|Setup|Run: see above for detailstype
: Setup|Run (default)|Optionalhelp
: Optional help text show withspaces evaluate
asset
: dict withdestination
: path to the asset in the workspaceformat
: json|toml|yamlvalue
: dict containing the structured data to be added to the asset
Example
cargo_vscode_task = {
"type": "cargo",
"problemMatcher": ["$rustc"],
"group": "build",
}
# Add some VS code tasks
checkout.update_asset(
rule = {"name": "vscode_tasks"},
asset = {
"destination": ".vscode/tasks.json",
"format": "json",
"value": {
"tasks": [
cargo_vscode_task | {
"command": "build",
"args": ["--manifest-path=spaces/Cargo.toml"],
"label": "build:spaces",
},
cargo_vscode_task | {
"command": "install",
"args": ["--path=spaces", "--root=${userHome}/.local", "--profile=dev"],
"label": "install_dev:spaces",
}
],
},
}
)
# tell cargo to use sccache
checkout.update_asset(
rule = {"name": "cargo_config"},
asset = {
"destination": ".cargo/config.toml",
"format": "toml",
"value": {
"build": {"rustc-wrapper": "sccache"},
},
},
)
update_env
def update_env(rule, env) -> None
Creates or updates the environment file in the workspace.
Spaces creates two mechanisms for managing the workspace environment.
- It generates an
env
file that can be sourced from the command line. - When running
spaces run
it executes rules using the same environment values.
The rules allows you to add variables and paths to the environment.
At a minimum, your-workspace/sysroot/bin
should be added to the path.
In the workspace, you can start a workspace bash shell using:
bash # or the shell of your preference
source env
rule
: dictname
: rule name as stringdeps
: list of dependenciesplatforms
: optional list of platforms to run on. If not provided, rule will run on all platforms. See above for detailstype
: Checkout|Optional|Setup|Run: see above for detailstype
: Setup|Run (default)|Optionalhelp
: Optional help text show withspaces evaluate
env
: dict withvars
: dict of variables to add to the environmentpaths
: list of paths required
Example
checkout.update_env(
rule = {"name": "update_env"},
env = {
"paths": [],
"system_paths": ["/usr/bin", "/bin"],
"vars": {
"PS1": '"(spaces) $PS1"',
},
"inherited_vars": ["HOME", "SHELL", "USER"],
},
)
Run Rules
You use run rules to execute tasks in the workspace.
abort
def abort(message) -> None
Abort script evaluation with a message.
message
: Abort message to show the user.
Example
run.abort("Failed to do something")
add_exec
def add_exec(rule, exec) -> None
Adds a rule that will execute a process.
rule
: dictname
: rule name as stringdeps
: list of dependenciesplatforms
: optional list of platforms to run on. If not provided, rule will run on all platforms. See above for detailstype
: Checkout|Optional|Setup|Run: see above for detailstype
: Setup|Run (default)|Optionalhelp
: Optional help text show withspaces evaluate
exec
: dict withcommand
: name of the command to executeargs
: optional list of argumentsenv
: optional dict of environment variablesworking_directory
: optional working directory (default is the workspace)expect
: Failure: expect non-zero return code|Success: expect zero return code|Any: don’t check the return coderedirect_stdout
: optional file to redirect stdout to
Example
run.add_exec(
rule = {"name": name, "type": "Setup", "deps": ["sysroot-python:venv"]},
exec = {
"command": "pip3",
"args": ["install"] + packages,
},
)
add_exec_if
def add_exec_if(rule, exec_if) -> None
Adds a rule to execute if a condition is met.
rule
: dictname
: rule name as stringdeps
: list of dependenciesplatforms
: optional list of platforms to run on. If not provided, rule will run on all platforms. See above for detailstype
: Checkout|Optional|Setup|Run: see above for detailstype
: Setup|Run (default)|Optionalhelp
: Optional help text show withspaces evaluate
exec_if
: dict withif
: this is anexec
object used with add_exec()then
: list of optional targets to enable if the command has the expected resultelse
: optional list of optional targets to enable if the command has the unexpected result
Example
run.add_exec(
rule = {"name": create_file, "type": "Optional" },
exec = {
"command": "touch",
"args": ["some_file"],
},
)
run.add_exec_if(
rule = {"name": check_file, "deps": []},
exec_if = {
"if": {
"command": "ls",
"args": [
"some_file",
],
"expect": "Failure",
},
"then": ["create_file"],
}
)
add_kill_exec
def add_kill_exec(rule, kill) -> None
Adds a rule that will kill the execution of another rule.
rule
: dictname
: rule name as stringdeps
: list of dependenciesplatforms
: optional list of platforms to run on. If not provided, rule will run on all platforms. See above for detailstype
: Checkout|Optional|Setup|Run: see above for detailstype
: Setup|Run (default)|Optionalhelp
: Optional help text show withspaces evaluate
kill
: dict withsignal
: Hup|Int|Quit|Abort|Kill|Alarm|Terminate|User1|User2target
: the name of the rule to killexpect
: Failure: expect non-zero return code|Success: expect zero return code|Any: don’t check the return code
Example
run.add_exec(
rule = {"name": name, "type": "Setup", "deps": ["sysroot-python:venv"]},
exec = {
"command": "pip3",
"args": ["install"] + packages,
},
)
add_target
def add_target(rule) -> None
Adds a target. There is no specific action for the target, but this rule can be useful for organizing dependencies.
rule
: dictname
: rule name as stringdeps
: list of dependenciesplatforms
: optional list of platforms to run on. If not provided, rule will run on all platforms. See above for detailstype
: Checkout|Optional|Setup|Run: see above for detailstype
: Setup|Run (default)|Optionalhelp
: Optional help text show withspaces evaluate
Example
run.add_target(
rule = {"name": "my_rule", "deps": ["my_other_rule"]},
)
Workspace Functions
Description
The workspace
functions provide information about the workspace
during checkout and run. Workspaces functions are executed immediately. They are not rule definitions.
Functions
get_absolute_path_to_workspace
def get_absolute_path_to_workspace() -> str
returns the absolute path to the workspace
get_build_archive_info
def get_build_archive_info(rule_name, archive) -> dict['archive_path': str, 'sha256_path': str]
returns the path to where run.create_archive() creates the sha256 txt file
rule_name
: The name of the rule used to create the archivearchive
: The archive info used to create the archive
get_digest
def get_digest() -> str
returns the digest of the workspace. This is only meaningful if the workspace is reproducible (which can’t be known until after checkout)
get_env_var
def get_env_var(var) -> str
returns the value of the workspace environment variable
var
: The name of the environment variable
get_path_to_build_archive
def get_path_to_build_archive(rule_name, archive) -> str
returns the path to where run.create_archive() creates the output archive
rule_name
: The name of the rule used to create the archivearchive
: The archive info used to create the archive
get_path_to_build_checkout
def get_path_to_build_checkout() -> str
returns the path to the workspace build folder for the current script
get_path_to_checkout
def get_path_to_checkout() -> str
returns the path where the current script is located in the workspace
get_path_to_log_file
def get_path_to_log_file(name) -> str
returns the relative workspace path to the log file for the target
name
: The name of the rule to get the log file
get_path_to_member
def get_path_to_member(member) -> str
returns a string to the workspace member matching the specified requirement (error if not found)
member
: The requirements for the memberurl:str
: The url of the memberrequired:dict
: {‘Revision’: <git/sha256 hash>}|{‘SemVer’:}
is_path_to_member_available
def is_path_to_member_available(member) -> bool
returns true if the workspace satisfies the requirments
member
: The requirements for the memberurl:str
: The url of the memberrequired:dict
: {‘Revision’: <git/sha256 hash>}|{‘SemVer’:}
Info Functions
Description
The info
functions provide information about spaces and the platform.
Info functions are executed immediately. They are not rule definitions.
Functions
get_cpu_count
def get_cpu_count() -> int
returns the number of CPUs on the current machine
get_log_divider_string
def get_log_divider_string() -> str
returns a string representing the end of the log header
get_path_to_store
def get_path_to_store() -> str
returns the path to the spaces store (typically $HOME/.spaces/store)
get_platform_name
def get_platform_name() -> str
returns the name of the current platform: macos-aarch64|macos-x86_64|linux-x86_64|linux-aarch64|windows-x86_64|windows-aarch64
get_supported_platforms
def get_supported_platforms() -> list[str]
returns a list of the supported platforms
is_ci
def is_ci() -> int
returns true if --ci
is passed on the command line
is_platform_linux
def is_platform_linux() -> bool
returns true if platform is linux
is_platform_macos
def is_platform_macos() -> bool
returns true if platform is macos
is_platform_windows
def is_platform_windows() -> bool
returns true if platform is Windows
parse_log_file
def parse_log_file(path) -> dict['header': dict, 'lines': list[str]]
Parses the log file header from yaml and puts the lines into an array
path
: The path to the spaces log file
set_max_queue_count
def set_max_queue_count(count) -> int
sets the maxiumum number of items to queue at one time
count
: the maximum number of items to queue at one time
set_minimum_version
def set_minimum_version(version) -> None
sets the minimum version of spaces required to run the script
version
: the minimum version of spaces required to run the script
set_required_semver
def set_required_semver(semver) -> None
sets the spaces
semver required to run the workspace
semver
: The semantic version required for this workspace
Spaces Starlark Standard Functions
Description
The spaces starlark standard library includes functions for doing things like accessing the filesystem. The functions in this library are executed immediately.
fs
Functions
append_string_to_file
def append_string_to_file(path, content) -> None
Appends a string to a file. Creates the file if it doesn’t exist.
path
: path relative to the workspace rootcontent
: contents to write
exists
def exists(path) -> bool
Checks if the file/directory exists
path
: path relative to the workspace root
is_directory
def is_directory(path) -> bool
Checks if a path is a directory
path
: path relative to the workspace root
is_file
def is_file(path) -> bool
Checks a path is a file
path
: path relative to the workspace root
is_symlink
def is_symlink(path) -> bool
Checks if a path is a symlink
path
: path relative to the workspace root
read_directory
def read_directory(path) -> [str]
Reads the entries of a directory
path
: path relative to the workspace root
read_file_to_string
def read_file_to_string(path) -> str
Reads the contents of the file as a string
path
: path relative to the workspace root
read_json_to_dict
def read_json_to_dict(path) -> dict with parsed json
Reads and parses a json file
path
: path relative to the workspace root
read_toml_to_dict
def read_toml_to_dict(path) -> str
Reads and parses a toml file
path
: path relative to the workspace root
read_yaml_to_dict
def read_yaml_to_dict(path) -> dict with parsed yaml
Reads and parses a yaml file
path
: path relative to the workspace root
write_string_to_file
def write_string_to_file(path, content) -> None
Writes a string to a file. Truncates the file if it exists. Creates it if it doesn’t.
path
: path relative to the workspace rootcontent
: contents to write
hash
Functions
compute_sha256_from_file
def compute_sha256_from_file(file_path) -> String
Computes the sha256 checksum for the contents of a file and returns the digest as a string.
file_path
: path to the file
compute_sha256_from_string
def compute_sha256_from_string(input) -> String
Computes the sha256 checksum of the given string.
input
: input string to hash
json
Functions
string_to_dict
def string_to_dict(content) -> dict
Converts a JSON formatted string to a dict.
content
: The JSON string to convert
to_string
def to_string(value) -> dict
Converts a dict to a JSON formatted string.
value
: The Starlark value to convert
to_string_pretty
def to_string_pretty(value) -> dict
Converts a dict to a JSON formatted string (multi-line, idented).
value
: The Starlark value to convert
process
Functions
exec
def exec(exec) -> dict # with members `status`, `stdout`, and `stderr`
Executes a process
exec
: dict with memberscommand
: name of the command to executeargs
: optional list of argumentsenv
: optional dict of environment variablesworking_directory
: optional working directory (default is the workspace)stdin
: optional string to pipe to the process stdin
script
Functions
abort
def abort(message) -> None
Abort execution. Exit with a non-zero code. Print a message to stderr
message
: str: abort message.
get_arg
def get_arg(offset) -> str
Gets the argument at the specified offset (an empty string is returned if the argument doesn’t exist).
offset
: int: offset of the argument to get.
get_args
def get_args(offset) -> dict
Gets the arguments as a dict with ‘ordered’ and ’named’ keys. ordered
is a list of arguments that do not contain =, named
is a map of key value pairs separated by =.
offset
: int: offset of the argument to get.
def print(content) -> None
Prints a string to the stdout. Only use in a script.
content
: str: string content to print.
set_exit_code
def set_exit_code(offset) -> none
Sets the exit code of the script. Use zero for success and non-zero for failure. This doesn’t exit the script.
offset
: int: offset of the argument to get.