oranda/config/components/artifacts/mod.rs
1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use crate::config::{ApplyLayer, ApplyValExt};
5
6mod package_managers;
7pub use package_managers::{PackageManagersConfig, PackageManagersLayer};
8
9#[derive(Debug, Deserialize, JsonSchema)]
10#[serde(rename_all = "lowercase")]
11enum ArtifactSystem {
12 Windows,
13 Windows64,
14 WindowsArm,
15
16 Mac,
17 MacPpc,
18 Mac32,
19 MacSilicon,
20
21 Linux,
22 LinuxUbuntu,
23 LinuxDebian,
24 LinuxMandriva,
25 LinuxRedhat,
26 LinuxFedora,
27 LinuxSuse,
28 LinuxGentoo,
29
30 Ios,
31 Android,
32
33 Freebsd,
34}
35
36/// Info about downloadable artifacts / installers / package-managers (complete version)
37#[derive(Debug, Clone)]
38pub struct ArtifactsConfig {
39 pub auto: bool,
40 pub cargo_dist: bool,
41 pub match_package_names: bool,
42 pub package_managers: PackageManagersConfig,
43 pub hidden: Vec<String>,
44}
45
46/// Setting for downloadable artifacts, installers, and package-managers
47#[derive(Debug, Default, Serialize, Deserialize, JsonSchema)]
48#[serde(deny_unknown_fields)]
49pub struct ArtifactsLayer {
50 /// Whether to enable auto-detection of artifacts/installers in your Releases
51 ///
52 /// This allows us to look at the assets listed in a Release and use their
53 /// names to guess their platforms and what they're for.
54 ///
55 /// If `cargo_dist` is also enabled, that data source will be preferred over this one
56 /// for the assets that cargo-dist knows about, as it should presumably be more reliable.
57 ///
58 /// Artifact auto-detection currently includes the following concepts:
59 ///
60 /// * **platforms**: if an artifact name contains a [rust target triple][triple] then we will
61 /// assume it's specific to that platform. Otherwise we will infer platform using extension
62 /// (with rules like "ps1 scripts are for windows, sh scripts are for unix").
63 /// * **archives**: if a platform-specific artifact name ends with an archive format
64 /// (.tar.*, .zip .7z, .rar...) then we will assume it contains the binaries
65 /// for that platform and recommend its download accordingly.
66 /// * **scripts**: if an artifact name contains "install" and ends with ".sh" or ".ps1"
67 /// we will assume it's an install script and generate an appropriate `curl | sh` for
68 /// it (`irm | iex` for ps1)
69 /// * **bundles**: if an artifact name ends with a known format for some kind of
70 /// installer/bundle we will recommend its download at a higher priority, assuming
71 /// this is a very good way to install your app. This includes ".msi", ".app", ".dmg",
72 /// ".deb", ".rpm", ".pkg.tar.*", ".flatpak", and ".snap".
73 ///
74 /// [triple]: https://doc.rust-lang.org/nightly/rustc/platform-support.html
75 pub auto: Option<bool>,
76 /// Whether to enable cargo-dist integration
77 ///
78 /// If enabled, we will check every Release of your project for a dist-manifest.json
79 /// and use that as the authoritative source of information on the artifacts uploaded to your
80 /// Release.
81 ///
82 /// This integration only works if `project.repository` points to a GitHub repo (see that field's
83 /// docs for details).
84 ///
85 /// We default this to true if we find `[workspace.metadata.dist]` in your Cargo.toml
86 pub cargo_dist: Option<bool>,
87 /// Whether to only show releases that contain the project name in their tag name
88 ///
89 /// This is useful if you have multiple projects in the same repo and want to only
90 /// show releases for that specific project on the generated project page.
91 ///
92 /// This defaults to false.
93 pub match_package_names: Option<bool>,
94 /// Snippets saying how to install your project using various package-managers
95 ///
96 /// These are grouped into "preferred" and "additional"
97 ///
98 /// - "additional" packages only show up on the install page
99 /// - "preferred" packages show up as options in the install widget
100 ///
101 /// Both are ordered maps of "label": "one-liner script"
102 ///
103 /// For example:
104 ///
105 /// ```json
106 /// {
107 /// "components": {
108 /// "artifacts": {
109 /// "package_managers": {
110 /// "preferred": {
111 /// "npm": "npm -i @axodotdev/axolotlsay",
112 /// "cargo": "cargo install axolotlsay"
113 /// },
114 /// "additional": {
115 /// "binstall": "cargo binstall axolotlsay"
116 /// }
117 /// }
118 /// }
119 /// }
120 /// }
121 /// ```
122 ///
123 /// If a package_manager has the same name as an auto-detected installer,
124 /// it will overwrite the auto-detected result, allowing you to specify something
125 /// more preferrable (relevant to cargo-dist npm packages).
126 pub package_managers: Option<PackageManagersLayer>,
127 /// Artifact/installer listings to supress from the install widget's tabs
128 /// and the install page's package-manager/script listings.
129 ///
130 /// Currently this won't supress them from the install page's "downloads" table
131 ///
132 /// Example (hide auto-detect shell scripts): `"hidden": ["shell", "powershell"]`
133 pub hidden: Option<Vec<String>>,
134}
135
136impl Default for ArtifactsConfig {
137 fn default() -> Self {
138 ArtifactsConfig {
139 auto: false,
140 cargo_dist: false,
141 match_package_names: false,
142 package_managers: PackageManagersConfig::default(),
143 hidden: vec![],
144 }
145 }
146}
147impl ApplyLayer for ArtifactsConfig {
148 type Layer = ArtifactsLayer;
149 fn apply_layer(&mut self, layer: Self::Layer) {
150 // This is intentionally written slightly cumbersome to make you update this
151 let ArtifactsLayer {
152 auto,
153 cargo_dist,
154 match_package_names,
155 package_managers,
156 hidden,
157 } = layer;
158
159 self.auto.apply_val(auto);
160 self.cargo_dist.apply_val(cargo_dist);
161 self.match_package_names.apply_val(match_package_names);
162 self.package_managers.apply_val_layer(package_managers);
163 // In the future this might want to be `extend`
164 self.hidden.apply_val(hidden);
165 }
166}
167
168impl ArtifactsConfig {
169 pub fn has_some(&self) -> bool {
170 self.cargo_dist || self.auto || !self.package_managers.is_empty()
171 }
172}