oranda/config/components/mod.rs
1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4mod artifacts;
5mod changelog;
6mod funding;
7mod mdbooks;
8
9use crate::config::components::changelog::{ChangelogConfig, ChangelogLayer};
10pub use artifacts::{ArtifactsConfig, ArtifactsLayer, PackageManagersConfig, PackageManagersLayer};
11pub use funding::{FundingConfig, FundingLayer};
12pub use mdbooks::{MdBookConfig, MdBookLayer};
13
14use super::{ApplyBoolLayerExt, ApplyLayer, ApplyOptExt, BoolOr};
15
16/// Extra components (complete version)
17#[derive(Debug, Clone)]
18pub struct ComponentConfig {
19 /// Whether to enable the changelog page
20 ///
21 /// In the future this may become more complex, but for now this is it
22 pub changelog: Option<ChangelogConfig>,
23 /// The config for using mdbook for a "docs" page
24 ///
25 /// This defaults to Some(Default) and is set to None
26 /// if we fail to auto-detect necessary information or if the user
27 /// manually disables it.
28 pub mdbook: Option<MdBookConfig>,
29 /// The config for for the funding page
30 ///
31 /// This defaults to Some(Default) and is set to None
32 /// if we fail to auto-detect necessary information or if the user
33 /// manually disables it.
34 pub funding: Option<FundingConfig>,
35 /// The config for the "install" page and widget
36 ///
37 /// This defaults to Some(Default) and is set to None
38 /// if we fail to auto-detect necessary information or if the user
39 /// manually disables it.
40 pub artifacts: Option<ArtifactsConfig>,
41 /// Which source to fetch release data from.
42 pub source: Option<ReleasesSource>,
43}
44/// Extra components
45#[derive(Debug, Serialize, Deserialize, JsonSchema)]
46#[serde(deny_unknown_fields)]
47pub struct ComponentLayer {
48 /// Whether to enable the changelog page
49 ///
50 /// In the future this may become more complex, but for now this is just a bool
51 pub changelog: Option<BoolOr<ChangelogLayer>>,
52 /// The config for building and embedding an mdbook on your site
53 ///
54 /// The book will be linked as "docs" in the nav, and restyled to match
55 /// the theme you have for the rest of your oranda site. We use a vendored
56 /// copy of mdbook, and not the one you have installed on your system.
57 ///
58 /// This feature is enabled by default if we find a "book.toml" in
59 /// "./", "./book/", or "./docs/".
60 ///
61 /// It can be completely disabled by setting `"mdbook": false`.
62 ///
63 /// More precise settings can be used with `"mdbook": { ... }`.
64 pub mdbook: Option<BoolOr<MdBookLayer>>,
65 /// The config for for the "funding" page
66 ///
67 /// This feature is enabled by default if we find a file at "funding.md"
68 /// or "./.github/FUNDING.yml".
69 ///
70 /// It can be completely disabled by setting `"funding": false`.
71 ///
72 /// More precise settings can be used with `"funding": { ... }`.
73 pub funding: Option<BoolOr<FundingLayer>>,
74 /// The config for the "install" page and widget
75 ///
76 /// # Data Sources
77 ///
78 /// Once enabled we consider data for 3 possible data sources:
79 ///
80 /// * The `components.artifacts.package_managers` keys (see those configs for details)
81 /// * Your GitHub Releases (if we have a URL to a GitHub repo in `project.repository`)
82 /// * dist-manifest.json in your GitHub Releases (if cargo-dist support is enabled)
83 ///
84 /// These sources can give us:
85 ///
86 /// * Downloadable Files (`my-app-x86_64-pc-windows-msvc.zip`)
87 /// * Runnable One-Liners (`curl install.sh | sh`, `npm install ...`)
88 ///
89 /// Which can be known/assumed to be:
90 ///
91 /// * Runnable/Installable on specific platforms (don't recommend `install.sh` on windows)
92 /// * Preferred over others (install script nicer than downloadable tarballs)
93 /// * Have checksums (`my-app-x86_64-pc-windows-msvc.zip.sha256`)
94 /// * Be viewable (`install.sh`)
95 ///
96 /// GitHub Releses support will also get us a list of Releases these will be grouped into
97 /// We will try to intelligently pick a "Latest Release" to display up-front:
98 ///
99 /// * If there's cargo-dist releases, prefer the latest one of those (stable over prereleases)
100 /// * This is a hack to make monorepos behave better while we don't fully support them
101 /// * Otherwise if there's a stable release, pick the latest stable release
102 /// * Otherwise pick the latest prerelease
103 ///
104 /// Otherwise we will place all of this under one artifical "current release".
105 ///
106 ///
107 /// ## Github Releases
108 ///
109 /// GitHub Releases integration is a fuzzy system of auto-detection based on the filenames
110 /// of assets we find uploaded to each GitHub Release. If we find a filename contains
111 /// something that looks like a target triple ("x86_64-pc-windows-msvc") we will assume
112 /// the artifact is only for that platform.
113 ///
114 /// If we find files with names like "..install..sh" we will assume those are curl-sh
115 /// installer scripts.
116 ///
117 /// If we find a platform-specific tarball/zip, we will assume it's an archive containing
118 /// prebuilt binaries for that platform.
119 ///
120 /// We also experimentally detect things like .deb files but it's only half-baked right now.
121 ///
122 ///
123 /// # The Install Page
124 ///
125 /// The Install Page will show up in your nav if this feature is at all enabled.
126 ///
127 /// It will show:
128 ///
129 /// 1. The Install Widget (see below)
130 /// 2. All the Runnable One-Liners for the Latest Release
131 /// 3. A table of downloadable artifacts (tarballs/zips) for the Latest Release.
132 ///
133 ///
134 /// # The Install Widget
135 ///
136 /// The Install Widget will show up on your front page and install page if
137 /// this feature is at all enabled. Although currently it will auto-hide
138 /// if there's absolutely nothing to show (#305).
139 ///
140 /// It will autodetect the user's current platform and try to recommend an installation method.
141 ///
142 /// If there are multiple supported platforms with different installation methods,
143 /// a "platform" dropdown will appear to override the auto-detect.
144 ///
145 /// If there are multiple installation options for a platform, we will present them as tabs,
146 /// roughly in decreasing order of preference (first tab is always best).
147 ///
148 /// Preference is currently fuzzy, but roughly:
149 ///
150 /// * platform-native solutions like msi's or debs will be recommended first
151 /// * installer scripts will be shown after that
152 /// * custom package_managers will be shown after that
153 /// * tarballs/zips will be shown last
154 ///
155 /// If no installation methods are found for the user's platform, they will be linked to
156 /// the install page and offered the platform dropdown to override.
157 ///
158 ///
159 /// # Enabling / Disabling
160 ///
161 /// This feature is enabled if:
162 ///
163 /// * cargo-dist support is enabled
164 /// * `artifacts.cargo_dist: true` is set
165 /// * we find `[workspace.metadata.dist]` in your Cargo.toml
166 /// * you set a package_manager in `artifacts.package_managers`
167 ///
168 /// It can be completely disabled by setting `"artifacts": false`.
169 ///
170 /// More precise settings can be used with `"artifacts": { ... }`.
171 ///
172 /// FIXME(#397): there is currently an expressivity hole here: there is no way to *just*
173 /// turn on plain GitHub Releases integration. You either need to have cargo-dist
174 /// integration enabled, or add a random package_manager to make us enable it.
175 pub artifacts: Option<BoolOr<ArtifactsLayer>>,
176 /// Where we should attempt to fetch release data from.
177 pub source: Option<ReleasesSource>,
178}
179
180/// Denotes a host for releases. Historically, this has only been GitHub, but we now also
181/// support alternative providers.
182///
183/// - "github": Attempt to fetch releases from the GitHub repository the user set in their
184/// configuration.
185/// - "axodotdev": Attempt to fetch from axo Releases, using the GitHub repository the user
186/// has set in their configuration as the project name.
187#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)]
188#[serde(rename_all = "lowercase")]
189pub enum ReleasesSource {
190 GitHub,
191 Axodotdev,
192}
193
194impl Default for ComponentConfig {
195 fn default() -> Self {
196 ComponentConfig {
197 changelog: Some(ChangelogConfig::default()),
198 mdbook: Some(MdBookConfig::default()),
199 funding: Some(FundingConfig::default()),
200 artifacts: Some(ArtifactsConfig::default()),
201 source: Some(ReleasesSource::GitHub),
202 }
203 }
204}
205impl ApplyLayer for ComponentConfig {
206 type Layer = ComponentLayer;
207 fn apply_layer(&mut self, layer: Self::Layer) {
208 // This is intentionally written slightly cumbersome to make you update this
209 let ComponentLayer {
210 changelog,
211 mdbook,
212 funding,
213 artifacts,
214 source,
215 } = layer;
216 self.changelog.apply_bool_layer(changelog);
217 self.mdbook.apply_bool_layer(mdbook);
218 self.funding.apply_bool_layer(funding);
219 self.artifacts.apply_bool_layer(artifacts);
220 self.source.apply_opt(source);
221 }
222}
223impl ComponentConfig {
224 /// Convenience for checking if the artifacts component is actually enabled
225 /// because a ton of code was repeating this due to the extra Option.
226 pub fn artifacts_enabled(&self) -> bool {
227 self.artifacts
228 .as_ref()
229 .map(|a| a.has_some())
230 .unwrap_or(false)
231 }
232}