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::BuilderEntry, changelog::ChangelogConfig, version_extractors::AnyVersionExtractor,
14};
15
16/// General website metadata.
17#[derive(Debug, Default, Clone, Deserialize, Serialize, JsonSchema)]
18pub struct SiteConfig {
19 /// Display name of the project, used in page titles and headings.
20 pub name: String,
21 /// Where to output generated files. Defaults to `public`.
22 #[serde(default = "abbaye_output_dir")]
23 pub output_dir: PathBuf,
24 /// Path to the README file rendered on each version page.
25 /// Defaults to `README.md` in the current working directory.
26 pub readme: Option<PathBuf>,
27 /// Canonical base URL of the published site (e.g. `"https://example.com"`).
28 /// When set, the generated `releases.atom` feed will include absolute links
29 /// and proper entry IDs. Trailing slashes are stripped automatically.
30 pub base_url: Option<String>,
31 /// URL of the project's repository (e.g. `"https://git.sr.ht/~ololduck/abbaye"`).
32 /// When set, we will show the repository link in the generated website.
33 pub repo_url: Option<String>,
34 /// An optional language code for the website (e.g. `"en"` or `"fr"`).
35 /// When set, the generated HTML will include a `lang` attribute on the `<html>` tag. Defaults to `"en"`.
36 pub lang: Option<String>,
37 /// If you have a Fediverse account, you can set this to your username to enable Fediverse integration. (don't forget the starting '@' !)
38 pub fediverse_creator: Option<String>,
39 /// OpenGraph configuration for the website.
40 pub opengraph: Option<OpenGraphConfig>,
41}
42
43/// OpenGraph configuration for the website.
44#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema)]
45pub struct OpenGraphConfig {
46 /// OpenGraph type of the website. It will be used as the `og:type` meta tag.
47 /// Note: by default, the value "website" will be enforced for the version listing page and "article" for the release notes page.
48 pub r#type: Option<String>,
49 /// URL of the website's image.
50 pub image: String,
51 /// Alt text for the website's image.
52 pub image_alt_text: Option<String>,
53 /// 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.
54 pub url: Option<String>,
55 /// Author of the website. Used on release notes pages to indicate the author.
56 pub author: Option<String>,
57}
58
59/// Configuration for the git repository web UI.
60#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema)]
61pub struct GitUiConfig {
62 #[serde(default = "default_branch")]
63 pub default_branch: String,
64 /// Maximum number of commits to show in the log page. Defaults to 200.
65 #[serde(default = "default_max_commits")]
66 pub max_commits: usize,
67 /// Path to the git repository to read. Defaults to `.` (the current directory).
68 pub repo_path: Option<PathBuf>,
69 /// Explicit clone URL displayed in the UI (e.g. `"https://example.com/repository.git"`).
70 /// When absent, derived from `site.base_url` by appending `/repository.git`.
71 pub clone_url: Option<String>,
72}
73
74fn default_branch() -> String {
75 "main".to_string()
76}
77
78fn default_max_commits() -> usize {
79 200
80}
81
82/// A full configuration for the Abbaye site generator.
83///
84/// Here's a sample configuration that works well as a starting point for rust projects:
85///
86/// ```toml
87/// [site]
88/// name = "Abbaye"
89///
90/// [version_extractor]
91/// type = "cargo" # extract version from Cargo.toml
92///
93/// [changelog]
94/// # let's use the default changelog extractor
95///
96/// [[builders]]
97/// type = "cargo" # calls `cargo build --release` for each target
98/// targets = ["x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl"]
99/// [[builders]]
100/// type = "cargo_doc" # generates documentation using `cargo doc`
101/// no_deps = true
102///
103/// [[builders]]
104/// type = "archive" # creates a compressed tarball of the source code
105/// ```
106///
107/// You can learn more about each builder type in the [builders module documentation](crate::builders).
108///
109#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema)]
110pub struct AbbayeConfig {
111 /// Metadata about the site.
112 pub site: SiteConfig,
113 /// which version extractor to use to extract the version(s) of the project
114 pub version_extractor: AnyVersionExtractor,
115 /// Configuration for the changelog extractor.
116 pub changelog: ChangelogConfig,
117 /// Builders to run during the build process.
118 pub builders: Vec<BuilderEntry>,
119 /// Optional git repository web UI. When present, abbaye generates browsable HTML
120 /// pages at `<output>/repository/` and a clonable bare repository at
121 /// `<output>/repository.git/`.
122 #[serde(default)]
123 pub git_ui: Option<GitUiConfig>,
124}
125
126fn abbaye_output_dir() -> PathBuf {
127 PathBuf::from("public")
128}
129
130/// Load the Abbaye2 configuration from the current working directory.
131///
132/// Looks for `.abbaye.toml` first, then `abbaye.toml`; when both are present
133/// `abbaye.toml` takes precedence (last merge wins).
134pub fn load_config() -> Result<AbbayeConfig> {
135 let cwd = std::env::current_dir().into_diagnostic()?;
136 Figment::new()
137 .merge(Toml::file(cwd.join(".abbaye.toml")))
138 .merge(Toml::file(cwd.join("abbaye.toml")))
139 .merge(Toml::file(cwd.join(".abbaye").join("abbaye.toml")))
140 .extract()
141 .into_diagnostic()
142}