Skip to main content

abbaye/builders/
mod.rs

1use miette::Result;
2use serde::{Deserialize, Serialize};
3use std::path::PathBuf;
4
5pub mod archive;
6pub mod cargo;
7
8use archive::{ArchiveBuilder, ArchiveBuilderConfig};
9use cargo::{CargoBuilder, CargoBuilderConfig, CargoDocBuilder, CargoDocBuilderConfig};
10
11#[derive(Debug, Clone, Deserialize, Serialize)]
12#[serde(tag = "type", rename_all = "snake_case")]
13pub enum AnyBuilder {
14    /// Creates a `.tar.gz` archive of the source tree, automatically excluding
15    /// files and directories matched by any `.gitignore` found in the hierarchy.
16    ///
17    /// ```toml
18    /// [[builders]]
19    /// type = "archive"
20    /// source_dir = "."                      # optional, defaults to CWD
21    /// output = "myproject-1.0.0.tar.gz"     # optional, defaults to source.tar.gz
22    /// prefix = "myproject-1.0.0"            # optional, defaults to source_dir name
23    /// ```
24    Archive(ArchiveBuilderConfig),
25
26    /// Compiles the crate in release mode with `cargo build --release`.
27    /// One or more target triples can be specified for cross-compilation;
28    /// omitting `targets` builds for the host platform.
29    ///
30    /// ```toml
31    /// [[builders]]
32    /// type = "cargo"
33    /// targets = ["x86_64-unknown-linux-musl", "aarch64-unknown-linux-musl"]
34    /// manifest_path = "Cargo.toml"          # optional
35    /// ```
36    Cargo(CargoBuilderConfig),
37
38    /// Generates API documentation with `cargo doc`.
39    /// Returns the per-crate doc directory (e.g. `target/doc/my_crate`) as an
40    /// artifact so it can be published or archived by a later pipeline step.
41    ///
42    /// ```toml
43    /// [[builders]]
44    /// type = "cargo_doc"
45    /// no_deps = true                        # optional, skip dependency docs
46    /// manifest_path = "Cargo.toml"          # optional
47    /// ```
48    CargoDoc(CargoDocBuilderConfig),
49}
50
51impl AnyBuilder {
52    pub async fn build(&self) -> Result<Vec<ArtifactPath>> {
53        match self {
54            Self::Archive(config) => ArchiveBuilder.build(config.clone()).await,
55            Self::Cargo(config) => CargoBuilder.build(config.clone()).await,
56            Self::CargoDoc(config) => CargoDocBuilder.build(config.clone()).await,
57        }
58    }
59}
60
61pub struct ArtifactPath {
62    pub path: PathBuf,
63    pub name: String,
64    /// Lowercase hexadecimal SHA1 digest of the artifact's contents, if computed.
65    pub hash: Option<String>,
66}
67
68#[allow(async_fn_in_trait)]
69pub trait Builder {
70    type ConfigType: Default + for<'de> Deserialize<'de> + Clone;
71
72    async fn build(&self, config: Self::ConfigType) -> Result<Vec<ArtifactPath>>;
73}