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