Using spaces

spaces executes starlark scripts in two phases:

  • Checkout Phase: collects everything from source code to tools into a workspace folder
    • git repos are checked out in the workspace (either direct clones or using worktrees)
    • Archives (including platform binaries) are downloaded to $HOME/.spaces/store. Contents are hardlinked to the workspace sysroot.
  • Run Phase: execute user-defined rules to build, test, run and/or deploy your project

Spaces Starlark SDK

The spaces starlark SDK is added in a preload script during checkout. spaces checkout can process multiple scripts in order. The first script cannot use any load statements because nothing has been populated in the workspace. The first script populates the workspace with the SDK. Subsequent checkout scripts can load functions populated in the workspace by preceding scripts.

spaces checkout --script=preload --script=my-project --name=build-my-project
# preload.spaces.star

# checkout.add_repo() is a built-in: use `spaces docs` to see documentation of built-in functions
# checkout_add_repo() is a convenience wrapper function defined in https://github.com/work-spaces/sdk.
# Scripts that run after this one, can use `load("//@star/sdk/star/checkout.star", "checkout_add_repo")`
# instead of calling the built-in directly.
checkout.add_repo(
    rule = {"name": "@star/sdk"},  # stores this repo in the workspaces at `@star/sdk`
                                   #   the `@star` folder is a conventional location for
                                   #   common, loadable starlark code
    repo = {
        "url": "https://github.com/work-spaces/sdk",
        "rev": "main",
        "checkout": "Revision",
        "clone": "Blobless"
    }
)
# my-project.spaces.star

load("//@star/sdk/star/checkout.star", "checkout_add_repo")

# This is easier to use than checkout.add_repo() but isn't available in the initial script
checkout_add_repo(
  "my-project",
  url = "https://github.com/my-org/my-project",
  rev = "main
)

More About Checkout

During checkout, spaces populates a workspace by evaulating the checkout rules. The workspace will look something like:

  • @star: dedicated folder for preloaded starlark files
  • .spaces: folder with logs and config files
  • env: Use source ./env to configure the command line for inner-loop development
  • env.spaces.star: starlark file generated by spaces containing env info.
  • preload.spaces.star: copy of the preload workflow script
  • my-project.spaces.star: copy of the project workflow script
  • sysroot: hardlinks to what you normally put in /usr/local with precise versions for your project
  • source folders: source code repositories checked out based on the rules in my-project.spaces.star
  • assets: checkout rules can add arbitrary files to the workspace
    • For example, rules can populate .vscode/settings.json for easy IDE bring-up
    • create local git hooks.
    • create hard/soft links to system resources

checkout.add_repo() adds a repository to the workspace. spaces transitively evaluates scripts matching *spaces.star found in the root folder of checked-out repos.

Run phase

Run rules build a dependency graph of targets. Run rules have:

  • A Rule:
    • name: the way to refer to this task when adding dependencies to other tasks
    • deps: explicit dependencies that must run before this task
    • type: Setup, Run (default), or Optional.
      • Non-setup rules depend on Setup rules.
      • Optional rules only run if needed (similar to “Exclude from all”).
    • inputs: globs for specifying rule inputs.
      • Use None (the default) to run the rule everytime
      • Use [] to run the rule once (nice for Setup rules)
      • Use a glob such as ["+my-project/**", "-my-project/tmp/**"] to run if any matching changes
  • An Action
    • For example, run.add_exec() adds a process (command and args) to the depedency graph.

Execute rules includes with //:all plus their depedencies.

spaces run
# equivalent to
spaces run //:all

Execute a specific rule plus dependencies:

spaces run //my-project:build

To enter the spaces execution environment used by spaces run, use:

source ./env

spaces unsets all other variables. source ./env does not unset values.