From 5890765aa81c079b2304cee9548ed3a6e2f6be1e Mon Sep 17 00:00:00 2001 From: Alexandre Rebert Date: Wed, 28 Oct 2020 21:46:57 -0400 Subject: [PATCH 1/2] S3: Add GCS support --- CHANGELOG.md | 1 + README.md | 2 +- src/backends/s3.rs | 60 ++++++++++++++++++++++++---------------------- src/lib.rs | 2 +- 4 files changed, 35 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d48f29..71664ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [unreleased] ### Added +- Add GCS support to S3 backend ### Changed - Fixed docs refering to github in s3 backend ### Removed diff --git a/README.md b/README.md index 46a8b26..6e6dfd7 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ fn update() -> Result<(), Box<::std::error::Error>> { Run the above example to see `self_update` in action: `cargo run --example github --features "archive-tar compression-flate2"`. There's also an equivalent example for gitlab: `cargo run --example gitlab --features "archive-tar compression-flate2"`. -Amazon S3 and DigitalOcean Spaces are also supported through the `S3` backend to check for new releases. Provided a `bucket_name` +Amazon S3, Google GCS, and DigitalOcean Spaces are also supported through the `S3` backend to check for new releases. Provided a `bucket_name` and `asset_prefix` string, `self_update` will look up all matching files using the following format as a convention for the filenames: `[directory/]--.`. Leading directories will be stripped from the file name allowing the use of subdirectories in the S3 bucket, diff --git a/src/backends/s3.rs b/src/backends/s3.rs index 29dd3bb..491d1fd 100644 --- a/src/backends/s3.rs +++ b/src/backends/s3.rs @@ -20,10 +20,11 @@ const MAX_KEYS: u8 = 100; /// The service end point. /// -/// Currently S3 and DigitalOcean Spaces supported. +/// Currently S3, GCS, and DigitalOcean Spaces supported. #[derive(Clone, Copy, Debug)] pub enum EndPoint { S3, + GCS, DigitalOceanSpaces, } @@ -83,11 +84,7 @@ impl ReleaseListBuilder { } else { bail!(Error::Config, "`bucket_name` required") }, - region: if let Some(ref region) = self.region { - region.to_owned() - } else { - bail!(Error::Config, "`region` required") - }, + region: self.region.clone(), asset_prefix: self.asset_prefix.clone(), target: self.target.clone(), }) @@ -102,7 +99,7 @@ pub struct ReleaseList { bucket_name: String, asset_prefix: Option, target: Option, - region: String, + region: Option, } impl ReleaseList { @@ -334,11 +331,7 @@ impl UpdateBuilder { } else { bail!(Error::Config, "`bucket_name` required") }, - region: if let Some(ref region) = self.region { - region.to_owned() - } else { - bail!(Error::Config, "`region` required") - }, + region: self.region.clone(), asset_prefix: self.asset_prefix.clone(), target: self .target @@ -378,7 +371,7 @@ pub struct Update { bucket_name: String, asset_prefix: Option, target: String, - region: String, + region: Option, current_version: String, target_version: Option, bin_name: String, @@ -498,33 +491,44 @@ impl ReleaseUpdate for Update { fn fetch_releases_from_s3( end_point: EndPoint, bucket_name: &str, - region: &str, + region: &Option, asset_prefix: &Option, ) -> Result> { let prefix = match asset_prefix { Some(prefix) => format!("&prefix={}", prefix), None => "".to_string(), }; - let api_url = match end_point { - EndPoint::S3 => format!( - "https://{}.s3.amazonaws.com/?list-type=2&max-keys={}{}", - bucket_name, MAX_KEYS, prefix - ), - EndPoint::DigitalOceanSpaces => format!( - "https://{}.{}.digitaloceanspaces.com/?list-type=2&max-keys={}{}", - bucket_name, region, MAX_KEYS, prefix - ), - }; - - debug!("using api url: {:?}", api_url); let download_base_url = match end_point { - EndPoint::S3 => format!("https://{}.s3.{}.amazonaws.com/", bucket_name, region), + EndPoint::S3 => { + let region = if let Some(region) = region { + region + } else { + bail!(Error::Config, "`region` required") + }; + format!("https://{}.s3.{}.amazonaws.com/", bucket_name, region) + } EndPoint::DigitalOceanSpaces => { - format!("https://{}.{}.digitaloceanspaces.com/", bucket_name, region,) + let region = if let Some(region) = region { + region + } else { + bail!(Error::Config, "`region` required") + }; + format!("https://{}.{}.digitaloceanspaces.com/", bucket_name, region) } + EndPoint::GCS => format!("https://storage.googleapis.com/{}/", bucket_name), }; + let api_url = match end_point { + EndPoint::S3 | EndPoint::DigitalOceanSpaces => format!( + "{}?list-type=2&max-keys={}{}", + download_base_url, MAX_KEYS, prefix + ), + EndPoint::GCS => format!("{}?max-keys={}{}", download_base_url, MAX_KEYS, prefix), + }; + + debug!("using api url: {:?}", api_url); + let resp = reqwest::blocking::Client::new().get(&api_url).send()?; if !resp.status().is_success() { bail!( diff --git a/src/lib.rs b/src/lib.rs index b453a3e..d5e4e2f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,7 +54,7 @@ fn update() -> Result<(), Box<::std::error::Error>> { Run the above example to see `self_update` in action: `cargo run --example github --features "archive-tar compression-flate2"`. There's also an equivalent example for gitlab: `cargo run --example gitlab --features "archive-tar compression-flate2"`. -Amazon S3 and DigitalOcean Spaces are also supported through the `S3` backend to check for new releases. Provided a `bucket_name` +Amazon S3, Google GCS, and DigitalOcean Spaces are also supported through the `S3` backend to check for new releases. Provided a `bucket_name` and `asset_prefix` string, `self_update` will look up all matching files using the following format as a convention for the filenames: `[directory/]--.`. Leading directories will be stripped from the file name allowing the use of subdirectories in the S3 bucket, From e210c990efff2e31d8f3df8ee15cf799c2066084 Mon Sep 17 00:00:00 2001 From: Alexandre Rebert Date: Thu, 29 Oct 2020 11:26:32 -0400 Subject: [PATCH 2/2] fix clippy lints --- src/lib.rs | 10 ++-------- src/update.rs | 5 +---- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d5e4e2f..19dd576 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -202,18 +202,12 @@ impl Status { /// Returns `true` if `Status::UpToDate` pub fn uptodate(&self) -> bool { - match *self { - Status::UpToDate(_) => true, - _ => false, - } + matches!(*self, Status::UpToDate(_)) } /// Returns `true` if `Status::Updated` pub fn updated(&self) -> bool { - match *self { - Status::Updated(_) => true, - _ => false, - } + matches!(*self, Status::Updated(_)) } } diff --git a/src/update.rs b/src/update.rs index 8281245..c54fcf4 100644 --- a/src/update.rs +++ b/src/update.rs @@ -34,10 +34,7 @@ impl UpdateStatus { /// Returns `true` if `Status::UpToDate` pub fn uptodate(&self) -> bool { - match *self { - UpdateStatus::UpToDate => true, - _ => false, - } + matches!(*self, UpdateStatus::UpToDate) } /// Returns `true` if `Status::Updated`