LCOV - code coverage report
Current view: top level - dashql-pack/src - release_version.rs Coverage Total Hit
Test: DashQL 6e74948 Lines: 97.7 % 44 43
Test Date: 2026-11-06 17:46:50

            Line data    Source code
       1              : use anyhow::{anyhow, Result};
       2              : use clap::ValueEnum;
       3              : use semver::Version;
       4              : use std::fmt;
       5              : use uuid::Uuid;
       6              : 
       7              : /// The channel a release is published to, named by the workflow that publishes it
       8              : #[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)]
       9              : pub enum ReleaseChannel {
      10              :     Stable,
      11              :     Latest,
      12              : }
      13              : 
      14              : impl fmt::Display for ReleaseChannel {
      15            1 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
      16            1 :         match self {
      17            0 :             ReleaseChannel::Stable => write!(f, "stable"),
      18            1 :             ReleaseChannel::Latest => write!(f, "latest"),
      19              :         }
      20            1 :     }
      21              : }
      22              : 
      23              : /// The version, id and channel of a release
      24              : pub struct ReleaseVersion {
      25              :     /// The semantic version the artifacts were built with
      26              :     pub version: Version,
      27              :     /// The release id, a UUID v5 of the version string
      28              :     pub id: Uuid,
      29              :     /// The release channel
      30              :     pub channel: ReleaseChannel,
      31              : }
      32              : 
      33              : const RELEASE_ID_NAMESPACE: Uuid = uuid::uuid!("444560d1-4268-44be-8016-b09f95eadbba");
      34              : 
      35           22 : pub fn build_release_version(version: Version, channel: ReleaseChannel) -> ReleaseVersion {
      36           22 :     let id = Uuid::new_v5(&RELEASE_ID_NAMESPACE, version.to_string().as_bytes());
      37           22 :     ReleaseVersion { version, id, channel }
      38           22 : }
      39              : 
      40              : /// Read the version of an electron-builder update manifest (latest-mac.yml)
      41           21 : pub fn read_manifest_version(manifest: &str) -> Result<Version> {
      42           21 :     let version = manifest
      43           21 :         .lines()
      44           21 :         .find_map(|line| line.strip_prefix("version: "))
      45           21 :         .ok_or_else(|| anyhow!("update manifest has no version"))?;
      46           20 :     Version::parse(version.trim()).map_err(|e| anyhow!("invalid version in update manifest: {}: {}", version, e))
      47           21 : }
      48              : 
      49              : #[cfg(test)]
      50              : mod tests {
      51              :     use super::*;
      52              : 
      53            6 :     fn version(text: &str) -> Version {
      54            6 :         Version::parse(text).unwrap()
      55            6 :     }
      56              : 
      57              :     #[test]
      58            1 :     fn keeps_the_version_and_the_channel() {
      59            1 :         let release = build_release_version(version("1.2.4-dev.4"), ReleaseChannel::Latest);
      60            1 :         assert_eq!(release.version.to_string(), "1.2.4-dev.4");
      61            1 :         assert_eq!(release.channel.to_string(), "latest");
      62            1 :     }
      63              : 
      64              :     #[test]
      65            1 :     fn a_prerelease_sorts_after_the_tag_and_before_the_next_tag() {
      66            1 :         let prerelease = version("1.2.4-dev.4");
      67            1 :         assert!(prerelease > Version::new(1, 2, 3));
      68            1 :         assert!(prerelease < Version::new(1, 2, 4));
      69            1 :     }
      70              : 
      71              :     #[test]
      72            1 :     fn the_release_id_only_depends_on_the_version() {
      73            1 :         let id = build_release_version(version("1.2.4-dev.4"), ReleaseChannel::Latest).id;
      74            1 :         assert_eq!(build_release_version(version("1.2.4-dev.4"), ReleaseChannel::Stable).id, id);
      75            1 :         assert_ne!(build_release_version(version("1.2.4-dev.5"), ReleaseChannel::Latest).id, id);
      76            1 :     }
      77              : 
      78              :     #[test]
      79            1 :     fn reads_the_top_level_version_of_a_manifest() {
      80            1 :         let manifest = "version: 1.2.4-dev.4\nfiles:\n  - url: DashQL.zip\n    version: 9.9.9\npath: DashQL.zip\n";
      81            1 :         assert_eq!(read_manifest_version(manifest).unwrap(), version("1.2.4-dev.4"));
      82            1 :     }
      83              : 
      84              :     #[test]
      85            1 :     fn refuses_a_manifest_without_a_valid_version() {
      86            1 :         let error = read_manifest_version("path: DashQL.zip\n").unwrap_err();
      87            1 :         assert!(error.to_string().contains("has no version"), "{error}");
      88            1 :         let error = read_manifest_version("version: nightly\n").unwrap_err();
      89            1 :         assert!(error.to_string().contains("invalid version"), "{error}");
      90            1 :     }
      91              : }
        

Generated by: LCOV version 2.0-1