Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - feat: fvm show and fvm current command #3601

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/fluvio-hub-util/src/fvm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ mod tests {
#[test]
fn performs_comparisons_between_tags() {
let ver_a = Channel::parse("0.10.10").unwrap();
let ver_b = Channel::parse("0.10.13").unwrap();
let ver_b = Channel::parse("0.10.13-mirroring347239873+20231016").unwrap();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update test to validate tags support.


assert!(ver_b > ver_a);
}
Expand Down
4 changes: 4 additions & 0 deletions crates/fluvio-version-manager/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ anyhow = { workspace = true }
async-std = { workspace = true, features = ["attributes"] }
clap = { workspace = true, features = ["std", "color", "derive", "env", "help"] }
colored = { workspace = true }
comfy-table = { workspace = true }
dialoguer = { workspace = true }
dirs = { workspace = true }
hex = { workspace = true }
Expand All @@ -36,3 +37,6 @@ url = { workspace = true }
# Workspace Crates
fluvio-hub-util = { workspace = true }
fluvio-future = { workspace = true, features = ["subscriber"] }

[dev-dependencies]
fs_extra = "1.3.0"
2 changes: 2 additions & 0 deletions crates/fluvio-version-manager/fixtures/version/0.10.15/fluvio
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
echo "Fluvio Test Executable 0.10.15"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"channel": {
"tag": "0.10.15"
sehz marked this conversation as resolved.
Show resolved Hide resolved
},
"version": "0.10.15"
}
2 changes: 2 additions & 0 deletions crates/fluvio-version-manager/fixtures/version/stable/fluvio
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
echo "Fluvio Test Executable STABLE"
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"channel": "stable",
sehz marked this conversation as resolved.
Show resolved Hide resolved
"version": "0.10.16"
}
36 changes: 36 additions & 0 deletions crates/fluvio-version-manager/src/command/current.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//! Show Intalled Versions Command
//!
//! The `show` command is responsible of listing all the installed Fluvio Versions

use anyhow::Result;
use clap::Parser;
use colored::Colorize;

use fluvio_hub_util::fvm::Channel;

use crate::common::notify::Notify;
use crate::common::settings::Settings;

#[derive(Debug, Parser)]
pub struct CurrentOpt;

impl CurrentOpt {
pub async fn process(&self, notify: Notify) -> Result<()> {
let settings = Settings::open()?;

if let (Some(channel), Some(version)) = (settings.channel, settings.version) {
match channel {
Channel::Latest | Channel::Stable => println!("{} ({})", version, channel),
Channel::Tag(_) => println!("{}", version),
}
} else {
notify.warn("No active version set");
notify.help(format!(
"You can use {} to set the active version",
"fvm switch".bold()
));
}

Ok(())
}
}
2 changes: 2 additions & 0 deletions crates/fluvio-version-manager/src/command/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pub mod current;
pub mod install;
pub mod itself;
pub mod show;
pub mod switch;
81 changes: 81 additions & 0 deletions crates/fluvio-version-manager/src/command/show.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//! Show Intalled Versions Command
//!
//! The `show` command is responsible of listing all the installed Fluvio Versions

use anyhow::{Result, anyhow};
use clap::Parser;
use colored::Colorize;
use comfy_table::{Table, Row};

use crate::common::manifest::VersionManifest;
use crate::common::notify::Notify;
use crate::common::settings::Settings;
use crate::common::version_directory::VersionDirectory;
use crate::common::workdir::fvm_versions_path;

#[derive(Debug, Parser)]
pub struct ShowOpt;

impl ShowOpt {
pub async fn process(&self, notify: Notify) -> Result<()> {
let versions_path = fvm_versions_path()?;

if !versions_path.exists() {
notify.warn("Cannot list installed versions because there are no versions installed");
notify.help(format!(
"You can install a Fluvio version using the command {}",
"fvm install".bold()
));

return Err(anyhow!("No versions installed"));
}

let settings = Settings::open()?;
let (manifests, maybe_active) =
VersionDirectory::scan_versions_manifests(versions_path, settings.channel)?;

if manifests.is_empty() && maybe_active.is_none() {
notify.warn("No installed versions found");
notify.help(format!(
"You can install a Fluvio version using the command {}",
"fvm install".bold()
));

return Ok(());
}

Self::render_table(manifests, maybe_active);

Ok(())
}

/// Creates a `Table` and renders it to the terminal.
fn render_table(manifests: Vec<VersionManifest>, maybe_active: Option<VersionManifest>) {
let mut table = Table::new();

table.set_header(Row::from([" ", "CHANNEL", "VERSION"]));

if let Some(active) = maybe_active {
table.add_row(Row::from([
"✓".to_string(),
active.channel.to_string(),
active.version.to_string(),
]));
}

let mut sorted_manifests = manifests;
sorted_manifests.sort_by(|a, b| b.channel.cmp(&a.channel));

for manifest in sorted_manifests {
table.add_row(Row::from([
" ".to_string(),
manifest.channel.to_string(),
manifest.version.to_string(),
]));
}

table.load_preset(comfy_table::presets::NOTHING);

println!("{}", table);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@
//!
//! The `switch` command is responsible of changing the active Fluvio Version

mod version_directory;

use anyhow::Result;
use clap::Parser;
use colored::Colorize;

use fluvio_hub_util::fvm::Channel;

use crate::common::workdir::fvm_versions_path;
use crate::common::notify::Notify;

use self::version_directory::VersionDirectory;
use crate::common::version_directory::VersionDirectory;
use crate::common::workdir::fvm_versions_path;

#[derive(Debug, Parser)]
pub struct SwitchOpt {
Expand Down
1 change: 1 addition & 0 deletions crates/fluvio-version-manager/src/common/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod manifest;
pub mod notify;
pub mod settings;
pub mod version_directory;
pub mod workdir;

use std::path::PathBuf;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use std::path::PathBuf;

use anyhow::Result;

use fluvio_hub_util::fvm::Channel;

use crate::common::manifest::{PACKAGE_SET_MANIFEST_FILENAME, VersionManifest};
use crate::common::settings::Settings;
use crate::common::workdir::fluvio_binaries_path;
Expand Down Expand Up @@ -80,6 +82,41 @@ impl VersionDirectory {

Ok(())
}

/// Retrieves the sorted list of installed versions [`VersionManifest`]
/// instances. In parallel, it also retrieves the active version if any.
///
/// If theres any Active Version, the [`VersionManifest`] is not included
/// as part of the first tuple value, instead it is returned as the second
/// tuple value.
pub fn scan_versions_manifests(
versions_path: PathBuf,
maybe_active: Option<Channel>,
) -> Result<(Vec<VersionManifest>, Option<VersionManifest>)> {
let dir_entries = versions_path.read_dir()?;
let mut manifests: Vec<VersionManifest> = Vec::new();
let mut active_version: Option<VersionManifest> = None;

for entry in dir_entries {
let entry = entry?;
let path = entry.path();

if path.is_dir() {
let version_dir = VersionDirectory::open(path.to_path_buf())?;

if let Some(ref active_channel) = maybe_active {
if *active_channel == version_dir.manifest.channel {
active_version = Some(version_dir.manifest);
continue;
}
}

manifests.push(version_dir.manifest);
}
}

Ok((manifests, active_version))
}
}

#[cfg(test)]
Expand All @@ -88,7 +125,7 @@ mod tests {
use std::path::Path;

use anyhow::Result;

use fs_extra::dir::{copy as copy_dir, CopyOptions};
use tempfile::TempDir;

use fluvio_hub_util::sha256_digest;
Expand Down Expand Up @@ -129,6 +166,19 @@ mod tests {
Ok(tmp)
}

/// Creates a Temporal Directory with the contents of `fixtures/version`
/// directory
fn make_versions_directory() -> Result<TempDir> {
let fixtures_path = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("fixtures")
.join("version");
let tmp = TempDir::new()?;

copy_dir(fixtures_path, tmp.path(), &CopyOptions::default())?;

Ok(tmp)
}

#[test]
fn opens_directory_as_version_dir() {
let tmpdir = make_version_directory().unwrap();
Expand Down Expand Up @@ -224,4 +274,34 @@ mod tests {

delete_fvm_dir();
}

#[test]
fn lists_versions_in_dir() {
let tmpdir = make_versions_directory().unwrap();
let (manifests, _) = VersionDirectory::scan_versions_manifests(
tmpdir.path().to_path_buf().join("version"),
None,
)
.unwrap();
let expected_versions = vec!["0.10.14", "0.10.15", "stable"];

for ver in expected_versions {
assert!(
manifests.iter().any(|m| m.channel.to_string() == ver),
"version {ver} not found",
);
}
}

#[test]
fn determines_active_version() {
let tmpdir = make_versions_directory().unwrap();
let (_, active) = VersionDirectory::scan_versions_manifests(
tmpdir.path().to_path_buf().join("version"),
Some(Channel::Stable),
)
.unwrap();

assert_eq!(active.unwrap().channel, Channel::Stable);
}
}
10 changes: 10 additions & 0 deletions crates/fluvio-version-manager/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ mod common;

use anyhow::Result;
use clap::Parser;
use command::current::CurrentOpt;
use command::show::ShowOpt;

use self::command::install::InstallOpt;
use self::command::itself::SelfOpt;
Expand Down Expand Up @@ -35,12 +37,18 @@ pub struct Cli {

#[derive(Debug, Parser)]
pub enum Command {
/// Print the current active Fluvio Version
#[command(name = "current")]
Current(CurrentOpt),
/// Manage FVM
#[command(name = "self")]
Itself(SelfOpt),
/// Install a Fluvio Version
#[command(name = "install")]
Install(InstallOpt),
/// List installed Fluvio Versions
#[command(name = "show")]
Show(ShowOpt),
/// Set a installed Fluvio Version as active
#[command(name = "switch")]
Switch(SwitchOpt),
Expand All @@ -53,8 +61,10 @@ impl Cli {
let notify = Notify::new(self.quiet);

match command {
Command::Current(cmd) => cmd.process(notify).await,
Command::Itself(cmd) => cmd.process(notify).await,
Command::Install(cmd) => cmd.process(notify).await,
Command::Show(cmd) => cmd.process(notify).await,
Command::Switch(cmd) => cmd.process(notify).await,
}
}
Expand Down
Loading
Loading