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}