Documentation
¶
Overview ¶
Package rust provides Shipwright's Rust-toolchain capability implementations as their own standalone Go module (github.com/pablogore/shipwright/providers/rust), implementing Shipwright's Layer 1 capability interfaces (pkg/shipwright) and nothing else. Every type in this flat package implements exactly one capability and carries no shared "stack" identity, mirroring providers/go's own design.md D-F rationale: a preset registry keyed by a stack name, or a nested rustservice/ subdirectory, would make the path itself a bundling identity. See naming_test.go for the enforcing golden test.
This package imports nothing from internal/**, enforced by internalimport_test.go — the public contract (pkg/shipwright) is sufficient on its own to implement every capability here, from outside the core module.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ContainerPublisher ¶
type ContainerPublisher struct {
// Client is the Dagger client used to construct the runtime image.
Client daggerkit.DaggerClient
// Config carries the registry username used alongside the creds
// secret passed to Publish.
Config shipwright.ArtifactConfig
}
ContainerPublisher packages a build-output Directory into a minimal container image and publishes it to a registry. Structural mirror of providers/go's ContainerPublisher, whose logic is otherwise generic (source-agnostic Dagger container packaging) and needed no Rust-specific change beyond the base image above and the binary path convention shared with RustBuilder.
func (*ContainerPublisher) Publish ¶
func (p *ContainerPublisher) Publish(ctx context.Context, build *dagger.Directory, ref string, creds *dagger.Secret) (string, error)
Publish packages build into a minimal container image, authenticates against the target registry when creds is provided, and publishes it to ref, returning the resolved published reference.
type RustBuilder ¶
type RustBuilder struct {
// Client is the Dagger client used to construct the build container.
Client daggerkit.DaggerClient
// Config configures the output binary name (BinaryName) and cargo
// build profile (BuildMode, e.g. "release", "debug", or a custom
// named profile).
Config shipwright.BuildConfig
// RustVersion selects the Rust toolchain image tag. Kept as its own
// field rather than overloading Config.GoVersion, because
// shipwright.BuildConfig has no Rust-specific version field
// (pkg/shipwright/config.go) — the same reasoning providers/go's
// GoUnitTester applies to its own GoVersion field. Defaults to
// defaultRustVersion when left empty.
RustVersion string
// ManifestPath selects a Cargo.toml other than the source root's own,
// mirroring `cargo build --manifest-path`. Needed to build a single
// member out of a large workspace (e.g. ego-rs's
// examples/reference-app/Cargo.toml) without cd'ing into it.
ManifestPath string
// Package restricts the build to one workspace member via `cargo build
// --package`, e.g. ego-rs's "reference-app" among its 19 members.
Package string
// Bin selects one binary target within the package via `cargo build
// --bin`, needed when a package defines more than one (e.g.
// examples/reference-app/src/bin/server.rs).
Bin string
// Locked maps to `--locked`, forbidding Cargo from updating
// Cargo.lock so the same lockfile always produces the same dependency
// graph in CI.
Locked bool
}
RustBuilder builds a Rust source Directory (a Cargo package or workspace) into a Directory containing the compiled binary. Structural mirror of providers/go's GoBuilder, adapted for cargo.
Behavioral judgment call, same as GoBuilder: RustBuilder always performs the binary-compile path; producing and publishing a container image from the resulting Directory is ContainerPublisher's job (Artifactor.Publish).
type RustCommand ¶ added in v1.1.0
type RustCommand struct {
// Client is the Dagger client used to construct the command container.
Client daggerkit.DaggerClient
// RustVersion selects the Rust toolchain image. Defaults to
// defaultRustVersion when left empty, same convention as every other
// Tester in this package.
RustVersion string
// ManifestPath selects a Cargo.toml other than the source root's own.
// The provider — not the caller — turns this into `--manifest-path`,
// inserted right after the subcommand, so a manifest never duplicates
// the same information inside Command (e.g. writing both
// `manifestPath: integration-tests/Cargo.toml` and `--manifest-path
// integration-tests/Cargo.toml` inside Command).
ManifestPath string
// Command is the Cargo invocation to run, without the leading "cargo"
// (e.g. "run -p xtask -- verify-layers"). Required — Test rejects an
// empty Command rather than running bare `cargo` with no subcommand.
Command string
// Docker opts into attaching a real Docker-in-Docker daemon (see
// dockerdaemon.go) to the command container, giving it a
// network-reachable DOCKER_HOST. Unlike RustIntegrationTester, where
// Docker access is inherent to the capability and always attached, most
// Cargo commands (xtask-style workspace tooling) must NOT get a Docker
// daemon at all, so this defaults to false. Set it for a command that
// needs one, e.g. a Testcontainers-backed run-suite binary.
Docker bool
// CacheKey isolates this step's `target` cache volume from every other
// RustCommand step. Left empty, every RustCommand shares one default
// cache volume — fine when a workflow only ever runs commands against
// the same Cargo workspace. Two RustCommand steps against different
// workspaces (e.g. the main workspace's xtask vs.
// integration-tests/Cargo.toml's run-suite) must set distinct CacheKeys,
// the same way rustIntegrationTesterTargetCacheKey is kept separate
// from rustUnitTesterTargetCacheKey (cargocache.go) — otherwise
// incremental-compilation state from one workspace corrupts the other's
// target directory.
CacheKey string
}
RustCommand runs an arbitrary `cargo <args>` invocation against a source Directory and returns the captured output as the report File. It exists because RustBuilder/RustUnitTester/RustLinter/RustVulnScanner/ RustIntegrationTester each encode one fixed Cargo invocation shape (`cargo build`, `cargo test`, `cargo clippy`, `cargo audit`) and cannot express an arbitrary subcommand like `cargo run -p xtask -- verify-layers` or a project-specific binary like `cargo run --bin run-suite` without a new, equally narrow Tester per invocation. RustCommand is the general primitive those are conveniences over — it does not replace them.
Registered under the "test" capability (RegisterTester), coexisting with "rust-test"/"rust-integration-test"/"clippy"/"cargo-audit" — see rustintegrationtester.go's own doc comment for why a new Cargo invocation shape is a new provider name under the existing five-entry (now seven) capability allowlist, never a new capability kind.
Deliberately NOT a shell executor: Command is tokenized on whitespace (cargoCommandArgsFor) and passed to Dagger's WithExec as argv, never through `sh -c`. A manifest author cannot smuggle in pipes, redirects, `&&`, or `$VAR` expansion this way — those characters simply become literal (almost always invalid) argv tokens to cargo, because no shell is ever invoked to interpret them. The trade-off: an argument containing a literal space (e.g. a quoted string) cannot be expressed in v1, since whitespace-splitting has no quoting support. Accepted because every known real invocation (`run -p xtask -- verify-layers`, `run --bin run-suite`, `run --manifest-path ... --bin run-suite`) space-delimits flags and values with no embedded-space arguments, and introducing a hand-rolled quote-aware tokenizer for a case with no known caller would be exactly the "fragile bespoke parser to avoid sh -c" this design explicitly avoids. A future version can add quoting support (or a list-typed manifest field, if one is ever added to interp.Kind) if a real need appears.
func (*RustCommand) Test ¶ added in v1.1.0
Test runs `cargo` + Command (plus --manifest-path when ManifestPath is set) against the source Directory, optionally with a Docker-in-Docker daemon attached, and returns the captured output as the report File. Pass/fail is exclusively the exit code Dagger reports for the exec: a non-nil error here always means the underlying cargo invocation failed (or the container never ran at all), never a partial or inferred result.
type RustIntegrationTester ¶
type RustIntegrationTester struct {
// Client is the Dagger client used to construct the test container.
Client daggerkit.DaggerClient
// RustVersion selects the Rust toolchain image. Defaults to
// defaultRustVersion when left empty, same convention as
// RustUnitTester.RustVersion.
RustVersion string
// ManifestPath selects the integration workspace's own Cargo.toml
// (e.g. "integration-tests/Cargo.toml"), distinct from the main
// workspace cargo test never touches.
ManifestPath string
// Package restricts the run to one member of the integration
// workspace via `cargo test --package`. Leaving it empty runs
// `--workspace` against ManifestPath instead.
Package string
// Features lists the Cargo features to enable via `--features` —
// e.g. ego-rs's own crash-test-failpoint, which its Cargo.toml
// documents as belonging only inside this isolated workspace.
// Ignored when AllFeatures is set.
Features []string
// AllFeatures maps to `--all-features`.
AllFeatures bool
// Locked maps to `--locked`.
Locked bool
}
RustIntegrationTester runs a Rust workspace's service-dependent integration suite (e.g. ego-rs's integration-tests/Cargo.toml, built on testcontainers + testcontainers-modules against real PostgreSQL) and returns the captured test output as the report File.
Registered under the "test" capability (RegisterTester), NOT a new "integration-test" capability kind: internal/workflow/manifest/ validate.go's validCapabilities is a fixed five-entry allowlist mirroring pkg/shipwright's five public Layer 1 interfaces (design.md D-H, "capability Is The Contract, uses Is The Implementation") — adding a sixth kind would mean amending that versioned public contract, not just this provider. Coexisting as another Tester alongside RustUnitTester/RustLinter/ RustVulnScanner under the same "test" capability, distinguished only by provider name ("rust-integration-test"), gets the same practical outcome — a separate workflow step — without touching Layer 1.
Docker access is inherent to this capability and always attached: a privileged Docker-in-Docker daemon (see dockerdaemon.go) is bound into the test container so testcontainers-rs talks to a real, network-reachable Docker daemon, with no changes to ego-rs's existing integration-tests suite. A later iteration replacing this with Dagger-native `services:` bindings (Postgres as a service dependency, no Docker daemon at all) does not change this Tester's public shape.
func (*RustIntegrationTester) Test ¶
func (t *RustIntegrationTester) Test(ctx context.Context, source *dagger.Directory) (*dagger.File, error)
Test runs the source Directory's integration suite (ManifestPath's workspace) with a Docker-in-Docker daemon attached, and returns the captured test output as the report File.
type RustLinter ¶
type RustLinter struct {
// Client is the Dagger client used to construct the lint container.
Client daggerkit.DaggerClient
// RustVersion selects the Rust toolchain image tag. Unlike
// golangci-lint (a standalone binary distributed in its own image),
// clippy is a rustup component bound to a specific toolchain, so this
// implementation needs its own version knob. Defaults to
// defaultRustVersion when left empty.
RustVersion string
}
RustLinter runs cargo clippy against a source Directory and returns its output as the report File. Structural mirror of providers/go's GoLinter — one of three independent Tester implementations, none privileged, for the Rust toolchain.
type RustUnitTester ¶
type RustUnitTester struct {
// Client is the Dagger client used to construct the test container.
Client daggerkit.DaggerClient
// Config carries the minimum required test coverage percentage.
Config shipwright.TestConfig
// RustVersion selects the Rust toolchain image. Kept as its own field
// rather than reusing BuildConfig, mirroring GoUnitTester.GoVersion's
// own rationale (TestConfig intentionally has no toolchain-version
// field). Defaults to defaultRustVersion when left empty.
RustVersion string
// ManifestPath selects a Cargo.toml other than the source root's own,
// mirroring `cargo test --manifest-path`. Needed for a workspace like
// ego-rs's, which keeps its Testcontainers-backed integration suite in
// a deliberately separate, non-member workspace
// (integration-tests/Cargo.toml) precisely so `cargo test --workspace`
// never touches Docker.
ManifestPath string
// Package restricts the run to one workspace member (`cargo test
// --package`) instead of the whole workspace. Mutually exclusive with
// --workspace in practice, so set it leaves --workspace off entirely
// (see cargoTestArgs).
Package string
// Features lists the Cargo features to enable via `--features`.
// Ignored when AllFeatures is set.
Features []string
// AllFeatures maps to `--all-features`. Left false by default
// (previously always forced on) because a provider must not decide a
// consumer's feature policy: ego-rs's own crash-test-failpoint feature
// is documented to stay off outside its isolated integration-tests
// workspace, which --all-features would silently violate.
AllFeatures bool
// Locked maps to `--locked`, forbidding Cargo from updating
// Cargo.lock so the same lockfile always produces the same dependency
// graph in CI.
Locked bool
}
RustUnitTester runs `cargo test` against a source Directory and returns the captured test output as the report File, optionally enforcing a minimum coverage threshold via cargo-tarpaulin. Structural mirror of providers/go's GoUnitTester — one of three independent Tester implementations, none privileged, for the Rust toolchain.
-race analog: not applicable. Rust's ownership and borrow checker statically rule out data races in safe code at compile time — the same guarantee `go test -race` checks dynamically at runtime — so no race-detector flag is threaded through cargo test.
type RustVulnScanner ¶
type RustVulnScanner struct {
// Client is the Dagger client used to construct the scan container.
Client daggerkit.DaggerClient
// RustVersion selects the Rust toolchain image used to install and run
// cargo-audit. Defaults to defaultRustVersion when left empty.
RustVersion string
}
RustVulnScanner runs cargo-audit against a source Directory and returns its output as the report File. Structural mirror of providers/go's GoVulnScanner — one of three independent Tester implementations, none privileged, for the Rust toolchain.
Design decision: cargo-audit over cargo-deny. cargo-deny is a broader policy tool (licenses, bans, duplicate versions, advisories); cargo-audit does one thing — scan Cargo.lock against the RustSec advisory database — making it the direct, single-purpose analog to govulncheck, which GoVulnScanner mirrors.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package daggerkit provides adapters to convert real Dagger types to interfaces, mirroring the root module's internal/daggerkit/adapter.go.
|
Package daggerkit provides adapters to convert real Dagger types to interfaces, mirroring the root module's internal/daggerkit/adapter.go. |