abbaye/config.rs
1use std::path::PathBuf;
2
3use figment::{
4 Figment,
5 providers::{Format, Toml},
6};
7use miette::{IntoDiagnostic, Result};
8use serde::{Deserialize, Serialize};
9
10use schemars::JsonSchema;
11
12use crate::{
13 builders::AnyBuilder, changelog::ChangelogConfig, version_extractors::AnyVersionExtractor,
14};
15
16/// General website metadata.
17#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema)]
18pub struct SiteConfig {
19 /// Display name of the project, used in page titles and headings.
20 pub name: String,
21 /// Path to the README file rendered on each version page.
22 /// Defaults to `README.md` in the current working directory.
23 pub readme: Option<PathBuf>,
24 /// Canonical base URL of the published site (e.g. `"https://example.com"`).
25 /// When set, the generated `releases.atom` feed will include absolute links
26 /// and proper entry IDs. Trailing slashes are stripped automatically.
27 pub base_url: Option<String>,
28 /// URL of the project's repository (e.g. `"https://git.sr.ht/~ololduck/abbaye"`).
29 /// When set, we will show the repository link in the generated website.
30 pub repo_url: Option<String>,
31 /// An optional language code for the website (e.g. `"en"` or `"fr"`).
32 /// When set, the generated HTML will include a `lang` attribute on the `<html>` tag. Defaults to `"en"`.
33 pub lang: Option<String>,
34 /// If you have a Fediverse account, you can set this to your username to enable Fediverse integration. (don't forget the starting '@' !)
35 pub fediverse_creator: Option<String>,
36 /// OpenGraph configuration for the website.
37 pub opengraph: Option<OpenGraphConfig>,
38}
39
40/// OpenGraph configuration for the website.
41#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema)]
42pub struct OpenGraphConfig {
43 /// OpenGraph type of the website. It will be used as the `og:type` meta tag.
44 /// Note: by default, the value "website" will be enforced for the version listing page and "article" for the release notes page.
45 pub r#type: Option<String>,
46 /// URL of the website's image.
47 pub image: String,
48 /// Alt text for the website's image.
49 pub image_alt_text: Option<String>,
50 /// URL of the website. If not set, the `base_url` will be used instead. If `base_url` is not set either, the world explodes. Think of the kittens.
51 pub url: Option<String>,
52 /// Author of the website. Used on release notes pages to indicate the author.
53 pub author: Option<String>,
54}
55
56/// A full configuration for the Abbaye site generator.
57///
58/// Here's a sample configuration that works well as a starting point for rust projects:
59///
60/// ```toml
61/// [site]
62/// name = "Abbaye"
63///
64/// [version_extractor]
65/// type = "cargo" # extract version from Cargo.toml
66///
67/// [changelog]
68/// # let's use the default changelog extractor
69///
70/// [[builders]]
71/// type = "cargo" # calls `cargo build --release` for each target
72/// targets = ["x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl"]
73/// [[builders]]
74/// type = "cargo_doc" # generates documentation using `cargo doc`
75/// no_deps = true
76///
77/// [[builders]]
78/// type = "archive" # creates a compressed tarball of the source code
79/// ```
80///
81/// You can learn more about each builder type in the [builders module documentation](crate::builders).
82///
83#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema)]
84pub struct AbbayeConfig {
85 /// Metadata about the site.
86 pub site: SiteConfig,
87 /// which version extractor to use to extract the version(s) of the project
88 pub version_extractor: AnyVersionExtractor,
89 /// Configuration for the changelog extractor.
90 pub changelog: ChangelogConfig,
91 /// Builders to run during the build process.
92 pub builders: Vec<AnyBuilder>,
93 /// Where to output generated files. Defaults to `public`.
94 #[serde(default = "abbaye_output_dir")]
95 pub output_dir: Option<PathBuf>,
96}
97
98fn abbaye_output_dir() -> Option<PathBuf> {
99 Some(PathBuf::from("public"))
100}
101
102/// Load the Abbaye2 configuration from the current working directory.
103///
104/// Looks for `.abbaye.toml` first, then `abbaye.toml`; when both are present
105/// `abbaye.toml` takes precedence (last merge wins).
106pub fn load_config() -> Result<AbbayeConfig> {
107 let cwd = std::env::current_dir().into_diagnostic()?;
108 Figment::new()
109 .merge(Toml::file(cwd.join(".abbaye.toml")))
110 .merge(Toml::file(cwd.join("abbaye.toml")))
111 .merge(Toml::file(cwd.join(".abbaye").join("abbaye.toml")))
112 .extract()
113 .into_diagnostic()
114}