diff --git a/Cargo.lock b/Cargo.lock index 7999cfc45..fbdb86d2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5119,14 +5119,12 @@ dependencies = [ "dunce", "format_serde_error", "glob", - "itertools 0.14.0", "miette", "rstest", "serde", "serde_json", "serde_yaml 0.9.34+deprecated", "spk-schema", - "spk-solve", "tempfile", "thiserror 1.0.69", "tracing", diff --git a/crates/spk-workspace/Cargo.toml b/crates/spk-workspace/Cargo.toml index 85fb69fea..db9c48472 100644 --- a/crates/spk-workspace/Cargo.toml +++ b/crates/spk-workspace/Cargo.toml @@ -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 } diff --git a/crates/spk-workspace/src/builder.rs b/crates/spk-workspace/src/builder.rs index 5c2cd0170..1121c8c7f 100644 --- a/crates/spk-workspace/src/builder.rs +++ b/crates/spk-workspace/src/builder.rs @@ -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; diff --git a/crates/spk-workspace/src/lib.rs b/crates/spk-workspace/src/lib.rs index c8a038e11..e786d12e5 100644 --- a/crates/spk-workspace/src/lib.rs +++ b/crates/spk-workspace/src/lib.rs @@ -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)] diff --git a/crates/spk-workspace/src/workspace.rs b/crates/spk-workspace/src/workspace.rs index 0e620daf7..1f685b79e 100644 --- a/crates/spk-workspace/src/workspace.rs +++ b/crates/spk-workspace/src/workspace.rs @@ -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. diff --git a/docs/use/workspaces.md b/docs/use/workspaces.md new file mode 100644 index 000000000..d699382e3 --- /dev/null +++ b/docs/use/workspaces.md @@ -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`.