Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 0 additions & 5 deletions crates/spk-workspace/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,15 @@ description = { workspace = true }
[lints]
workspace = true

[features]
sentry = ["spk-solve/sentry"]

[dependencies]
bracoxide = { workspace = true }
dunce = { workspace = true }
format_serde_error = { workspace = true }
glob = { workspace = true }
itertools = { workspace = true }
miette = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_yaml = { workspace = true }
spk-schema = { workspace = true }
spk-solve = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }

Expand Down
2 changes: 1 addition & 1 deletion crates/spk-workspace/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
// https://github.com/spkenv/spk

//! Find and/or build workspaces.
//! Discover and assemble a [`super::Workspace`] from spec files on disk.

use std::collections::HashMap;

Expand Down
10 changes: 7 additions & 3 deletions crates/spk-workspace/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
// SPDX-License-Identifier: Apache-2.0
// https://github.com/spkenv/spk

//! SPK workspaces are used to build a network of packages together.
//! An SPK workspace groups the recipe spec files in a directory tree so
//! that spk commands can find them by package name, version, or path.
//!
//! The [`WorkspaceFile`] is used to load [`Workspace`] configurations from
//! yaml files on disk.
//! A [`WorkspaceFile`] (`workspace.spk.yaml`) declares which spec files
//! belong to the workspace via glob patterns, and is loaded into a
//! [`Workspace`] for resolution. When no workspace file is present,
//! callers typically fall back to a virtual workspace scoped to the
//! current directory.

#![deny(missing_docs)]

Expand Down
13 changes: 6 additions & 7 deletions crates/spk-workspace/src/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@ use crate::error::{self, BuildError};
#[path = "workspace_test.rs"]
mod workspace_test;

/// A collection of recipes and build targets.
/// A collection of recipe spec templates discovered on disk.
///
/// Workspaces are used to define and build many recipes
/// together, helping to produce complete environments
/// with shared compatibility requirements. Workspaces
/// can be used to determine the number and order of
/// packages to be built in order to efficiently satisfy
/// and entire set of requirements for an environment.
/// A workspace gathers the recipe spec files referenced by a
/// [`crate::WorkspaceFile`] (or a set of glob patterns) so that
/// they can be resolved by package name, version, or file path.
/// A single package may be represented by more than one template,
/// and each template may declare the set of versions it can produce.
#[derive(Debug, Default)]
pub struct Workspace {
/// Spec templates available in this workspace.
Expand Down
86 changes: 86 additions & 0 deletions docs/use/workspaces.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
title: Workspaces
summary: Group recipe spec files so spk can find them by name, version, or path.
weight: 80
---

A _workspace_ is an optional way to tell spk about a collection of recipe spec
files that live together in a directory tree. When a workspace is defined, spk
commands can locate a recipe by package name or version rather than requiring
the exact path to its `*.spk.yaml` file.

Workspaces are entirely optional. When no workspace file is present, spk falls
back to looking for spec files in the current directory, which is the default
behaviour for a single-package checkout.

### The Workspace File

A workspace is declared by a `workspace.spk.yaml` file at the root of the
directory tree. spk discovers it by searching the current directory and its
parents, so commands run from any subdirectory share the same workspace.

The `recipes` field lists one or more glob patterns identifying the spec files
that belong to the workspace:

```yaml
api: v0/workspace

recipes:
# collect every recipe under the packages directory
- packages/**/*.spk.yaml
```

Once the workspace is defined, a recipe can be referenced by its package name
from anywhere within the tree:

```sh
spk build cmake # finds packages/cmake/cmake.spk.yaml
spk build python # finds packages/python/python3.spk.yaml
```

### Recipes That Produce Many Versions

A single recipe spec is often reused to build many versions of a package by
templating the version from a build option (see
[Spec Variables and Templating]({{< ref "create/template" >}})):

```yaml
# {% set opt = opt | default_opts(version="3.7.3") %}
pkg: python/{{ opt.version }}
```

Because the version isn't hard-coded in the file, the workspace needs to be
told which versions such a recipe is allowed to produce. This is done by
providing a mapping form of the `recipes` entry with a `versions` list. The
`versions` values support bash-style brace expansion so that ranges can be
written compactly:

```yaml
recipes:
- packages/**/*.spk.yaml

# augment a recipe that was already collected above with the
# specific versions it can build
- path: packages/python/python2.spk.yaml
versions: [2.7.18]

- path: packages/python/python3.spk.yaml
versions:
- '3.7.{0..17}'
- '3.8.{0..20}'
- '3.9.{0..21}'
- '3.10.{0..16}'
- '3.11.{0..11}'
- '3.12.{0..8}'
- '3.13.{0..1}'
```

With the versions declared, a request that includes a version selects the
matching recipe:

```sh
spk build python/3.11 # rendered from packages/python/python3.spk.yaml
```

A recipe that hard-codes its own version, or that should accept any version,
does not need to declare `versions`.
Loading