From 0609deba8835ed1cbe5f5929d025ea20c3f05197 Mon Sep 17 00:00:00 2001 From: Esteban Borai Date: Fri, 23 Feb 2024 21:57:59 -0300 Subject: [PATCH] feat(fvm): list included artifacts with `fvm list ` (#3877) * feat(fvm): list included artifacts with `fvm list ` * fix: doc comment * feat(fvm): use artifact versions heading in list * chore(test): test artifact listing --- .../src/command/list.rs | 44 ++++++++++++++++++- .../src/common/manifest.rs | 36 +++++++++++++-- .../src/common/settings.rs | 1 + .../src/common/version_installer.rs | 15 +++++-- tests/cli/fvm_smoke_tests/fvm_basic.bats | 12 +++++ 5 files changed, 99 insertions(+), 9 deletions(-) diff --git a/crates/fluvio-version-manager/src/command/list.rs b/crates/fluvio-version-manager/src/command/list.rs index db82589008..96fd850355 100644 --- a/crates/fluvio-version-manager/src/command/list.rs +++ b/crates/fluvio-version-manager/src/command/list.rs @@ -7,6 +7,8 @@ use clap::Parser; use colored::Colorize; use comfy_table::{Table, Row}; +use fluvio_hub_util::fvm::Channel; + use crate::common::manifest::VersionManifest; use crate::common::notify::Notify; use crate::common::settings::Settings; @@ -14,7 +16,11 @@ use crate::common::version_directory::VersionDirectory; use crate::common::workdir::fvm_versions_path; #[derive(Debug, Parser)] -pub struct ListOpt; +pub struct ListOpt { + /// List included artifacts for this installed version if available + #[arg(index = 1)] + channel: Option, +} impl ListOpt { pub async fn process(&self, notify: Notify) -> Result<()> { @@ -30,6 +36,41 @@ impl ListOpt { return Err(anyhow!("No versions installed")); } + if let Some(channel) = &self.channel { + let (manifests, _) = VersionDirectory::scan_versions_manifests(versions_path, None)?; + if let Some(manifest) = manifests.iter().find(|m| m.channel == *channel) { + if let Some(contents) = &manifest.contents { + if matches!(manifest.channel, Channel::Tag(_)) { + println!( + "Artifacts in version {}", + manifest.version.to_string().bold() + ); + } else { + println!( + "Artifacts in channel {} version {}", + manifest.channel.to_string().bold(), + manifest.version.to_string().bold() + ); + } + + for art in contents { + println!("{}@{}", art.name, art.version); + } + + return Ok(()); + } + + let suggested_command = format!("{} {}", "fvm install", channel); + + notify.help(format!( + "No version contents recorded. You can upadate included artifact details by reinstalling this version. {}", + suggested_command.bold(), + )); + } + + return Ok(()); + } + let settings = Settings::open()?; let (manifests, maybe_active) = VersionDirectory::scan_versions_manifests(versions_path, settings.channel)?; @@ -45,7 +86,6 @@ impl ListOpt { } Self::render_table(manifests, maybe_active); - Ok(()) } diff --git a/crates/fluvio-version-manager/src/common/manifest.rs b/crates/fluvio-version-manager/src/common/manifest.rs index 4e505a8cd8..65342e1a33 100644 --- a/crates/fluvio-version-manager/src/common/manifest.rs +++ b/crates/fluvio-version-manager/src/common/manifest.rs @@ -17,15 +17,35 @@ use fluvio_hub_util::fvm::Channel; /// The name of the manifest file for the Package Set pub const PACKAGE_SET_MANIFEST_FILENAME: &str = "manifest.json"; +#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)] +pub struct VersionedArtifact { + pub name: String, + pub version: String, +} + +impl VersionedArtifact { + pub fn new>(name: S, version: S) -> Self { + Self { + name: name.into(), + version: version.into(), + } + } +} + #[derive(Debug, Deserialize, Serialize, PartialEq, Eq)] pub struct VersionManifest { pub channel: Channel, pub version: Version, + pub contents: Option>, } impl VersionManifest { - pub fn new(channel: Channel, version: Version) -> Self { - Self { channel, version } + pub fn new(channel: Channel, version: Version, contents: Vec) -> Self { + Self { + channel, + version, + contents: Some(contents), + } } /// Opens the `manifest.json` file and parses it into a `VersionManifest` struct @@ -67,7 +87,11 @@ mod test { "version": "0.8.0" }"#; let tempdir = TempDir::new().unwrap(); - let version_manifest = VersionManifest::new(Channel::Stable, Version::new(0, 8, 0)); + let version_manifest = VersionManifest::new( + Channel::Stable, + Version::new(0, 8, 0), + vec![VersionedArtifact::new("fluvio", "0.11.4")], + ); let manifest = version_manifest.write(tempdir.path()).unwrap(); let have = read_to_string(manifest).unwrap(); @@ -77,7 +101,11 @@ mod test { #[test] fn reads_manifest_from_json() { let tempdir = TempDir::new().unwrap(); - let version_manifest = VersionManifest::new(Channel::Stable, Version::new(0, 8, 0)); + let version_manifest = VersionManifest::new( + Channel::Stable, + Version::new(0, 8, 0), + vec![VersionedArtifact::new("fluvio", "0.11.4")], + ); let json = serde_json::to_string_pretty(&version_manifest).unwrap(); let manifest = version_manifest.write(tempdir.path()).unwrap(); let read_manifest = VersionManifest::open(manifest).unwrap(); diff --git a/crates/fluvio-version-manager/src/common/settings.rs b/crates/fluvio-version-manager/src/common/settings.rs index ce69f88704..19db49fd7c 100644 --- a/crates/fluvio-version-manager/src/common/settings.rs +++ b/crates/fluvio-version-manager/src/common/settings.rs @@ -238,6 +238,7 @@ version = "0.12.0" let manifest = VersionManifest { channel: Channel::Stable, version: Version::parse(VERSION).unwrap(), + contents: None, }; let mut settings = Settings::open().unwrap(); diff --git a/crates/fluvio-version-manager/src/common/version_installer.rs b/crates/fluvio-version-manager/src/common/version_installer.rs index 5e7134e4ec..3a1a3defd7 100644 --- a/crates/fluvio-version-manager/src/common/version_installer.rs +++ b/crates/fluvio-version-manager/src/common/version_installer.rs @@ -6,7 +6,7 @@ use tempfile::TempDir; use fluvio_hub_util::fvm::{PackageSet, Download, Channel}; -use super::manifest::VersionManifest; +use super::manifest::{VersionedArtifact, VersionManifest}; use super::notify::Notify; use super::version_directory::VersionDirectory; use super::workdir::fvm_versions_path; @@ -46,8 +46,17 @@ impl VersionInstaller { } let version_path = self.store_artifacts(&tmp_dir, &self.package_set).await?; - let manifest = - VersionManifest::new(self.channel.to_owned(), self.package_set.pkgset.clone()); + let contents = self + .package_set + .artifacts + .iter() + .map(|art| VersionedArtifact::new(art.name.to_owned(), art.version.to_string())) + .collect::>(); + let manifest = VersionManifest::new( + self.channel.to_owned(), + self.package_set.pkgset.clone(), + contents, + ); manifest.write(&version_path)?; self.notify.done(format!( diff --git a/tests/cli/fvm_smoke_tests/fvm_basic.bats b/tests/cli/fvm_smoke_tests/fvm_basic.bats index c2044f7537..3e0641c2f7 100644 --- a/tests/cli/fvm_smoke_tests/fvm_basic.bats +++ b/tests/cli/fvm_smoke_tests/fvm_basic.bats @@ -422,6 +422,18 @@ setup_file() { assert_line --index 2 --partial " 0.10.14 0.10.14" assert_success + # Checks contents for the stable channel + run bash -c 'fvm list stable' + assert_line --index 0 --partial "Artifacts in channel stable version $STABLE_VERSION" + assert_line --index 1 --partial "fluvio@$STABLE_VERSION" + assert_success + + # Checks contents for the version 0.10.14 + run bash -c 'fvm list 0.10.14' + assert_line --index 0 --partial "Artifacts in version 0.10.14" + assert_line --index 1 --partial "fluvio@0.10.14" + assert_success + # Checks current command output run bash -c 'fvm current' assert_line --index 0 "$STABLE_VERSION (stable)"