From a92336689a5f93912468a90cc50f9619e791c8c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fe=CC=81lix=20Saparelli?= Date: Wed, 16 Feb 2022 11:41:00 +1300 Subject: [PATCH] Add source name and prompt for third-party sources --- Cargo.lock | 1 + Cargo.toml | 1 + src/fetchers.rs | 6 ++++++ src/fetchers/gh_crate_meta.rs | 23 +++++++++++++++++++---- src/fetchers/quickinstall.rs | 7 +++++++ src/main.rs | 17 +++++++++++++++++ 6 files changed, 51 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b347dafa..39eb902c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -146,6 +146,7 @@ dependencies = [ "tempdir", "tinytemplate", "tokio", + "url", "xz2", "zip", ] diff --git a/Cargo.toml b/Cargo.toml index 5eccc5d3..0417b727 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ semver = "1.0.4" xz2 = "0.1.6" zip = "0.5.13" async-trait = "0.1.52" +url = "2.2.2" [dev-dependencies] env_logger = "0.9.0" diff --git a/src/fetchers.rs b/src/fetchers.rs index c6f32825..eedd920b 100644 --- a/src/fetchers.rs +++ b/src/fetchers.rs @@ -23,6 +23,12 @@ pub trait Fetcher { /// Return the package format fn pkg_fmt(&self) -> PkgFmt; + + /// A short human-readable name or descriptor for the package source + fn source_name(&self) -> String; + + /// Should return true if the remote is from a third-party source + fn is_third_party(&self) -> bool; } /// Data required to fetch a package diff --git a/src/fetchers/gh_crate_meta.rs b/src/fetchers/gh_crate_meta.rs index 1b3164d4..8ee3ad0f 100644 --- a/src/fetchers/gh_crate_meta.rs +++ b/src/fetchers/gh_crate_meta.rs @@ -3,12 +3,13 @@ use std::path::Path; use log::{debug, info}; use reqwest::Method; use serde::Serialize; +use url::Url; use super::Data; use crate::{download, remote_exists, PkgFmt, Template}; pub struct GhCrateMeta { - url: String, + url: Url, pkg_fmt: PkgFmt, } @@ -26,24 +27,38 @@ impl super::Fetcher for GhCrateMeta { debug!("Using context: {:?}", ctx); Ok(Box::new(Self { - url: ctx.render(&data.meta.pkg_url)?, + url: Url::parse(&ctx.render(&data.meta.pkg_url)?)?, pkg_fmt: data.meta.pkg_fmt, })) } async fn check(&self) -> Result { info!("Checking for package at: '{}'", self.url); - remote_exists(&self.url, Method::HEAD).await + remote_exists(self.url.as_str(), Method::HEAD).await } async fn fetch(&self, dst: &Path) -> Result<(), anyhow::Error> { info!("Downloading package from: '{}'", self.url); - download(&self.url, dst).await + download(self.url.as_str(), dst).await } fn pkg_fmt(&self) -> PkgFmt { self.pkg_fmt } + + fn source_name(&self) -> String { + if let Some(domain) = self.url.domain() { + domain.to_string() + } else if let Some(host) = self.url.host_str() { + host.to_string() + } else { + self.url.to_string() + } + } + + fn is_third_party(&self) -> bool { + false + } } /// Template for constructing download paths diff --git a/src/fetchers/quickinstall.rs b/src/fetchers/quickinstall.rs index beb2a1b2..cbea5f9d 100644 --- a/src/fetchers/quickinstall.rs +++ b/src/fetchers/quickinstall.rs @@ -41,6 +41,13 @@ impl super::Fetcher for QuickInstall { fn pkg_fmt(&self) -> PkgFmt { PkgFmt::Tgz } + + fn source_name(&self) -> String { + String::from("QuickInstall") + } + fn is_third_party(&self) -> bool { + true + } } impl QuickInstall { diff --git a/src/main.rs b/src/main.rs index bd735f50..9aed9e0c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -151,6 +151,23 @@ async fn main() -> Result<(), anyhow::Error> { anyhow::anyhow!("No viable remote package found") })?; + // Prompt user for third-party source + if fetcher.is_third_party() { + warn!( + "The package will be downloaded from third-party source {}", + fetcher.source_name() + ); + if !opts.no_confirm && !confirm()? { + warn!("Installation cancelled"); + return Ok(()); + } + } else { + info!( + "The package will be downloaded from {}", + fetcher.source_name() + ); + } + // Download package fetcher.fetch(&pkg_path).await?;