feat(gcs): add Google Cloud Storage support (#443)

* feat(gcs): add Google Cloud Storage support

Closes #436

* fix: honor configured protocol and finalization errors

* ci: remove TruffleHog checks
This commit is contained in:
Christian Visintin
2026-08-30 18:58:17 +02:00
committed by GitHub
parent 98a1ce42dc
commit 974b6d6917
51 changed files with 2101 additions and 96 deletions
+65 -1
View File
@@ -379,7 +379,9 @@ mod tests {
use tempfile::TempDir;
use super::*;
use crate::filetransfer::params::{AwsS3Params, GenericProtocolParams};
use crate::filetransfer::params::{
AwsS3Params, DEFAULT_GCS_ENDPOINT, GenericProtocolParams, GoogleCloudStorageParams,
};
use crate::filetransfer::{FileTransferProtocol, ProtocolParams};
#[test]
@@ -526,6 +528,58 @@ mod tests {
assert_eq!(params.secret_access_key, None);
}
#[test]
fn should_preserve_gcs_service_account_path_for_saved_bookmarks() {
for save_password in [true, false] {
let tmp_dir: tempfile::TempDir = TempDir::new().ok().unwrap();
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
let mut client =
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16, true).unwrap();
client
.add_bookmark(
"gcs-bucket",
make_gcs_ftparams(Some("/keys/archive.json")),
save_password,
)
.unwrap();
let bookmark = client.get_bookmark("gcs-bucket").unwrap();
let params = bookmark.params.gcs_params().unwrap();
assert_eq!(params.bucket_name, "archive-bucket");
assert_eq!(params.endpoint, DEFAULT_GCS_ENDPOINT);
assert_eq!(
params.service_account_key.as_deref(),
Some("/keys/archive.json")
);
assert_eq!(bookmark.password_missing(), false);
}
}
#[test]
fn should_make_gcs_recent_without_password() {
let tmp_dir: tempfile::TempDir = TempDir::new().ok().unwrap();
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
let mut client =
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16, true).unwrap();
client
.add_recent(make_gcs_ftparams(Some("/keys/archive.json")).remote_path(Some("/backups")))
.unwrap();
let recent_key = client.iter_recents().next().unwrap().clone();
let recent = client.get_recent(&recent_key).unwrap();
let params = recent.params.gcs_params().unwrap();
assert_eq!(params.bucket_name, "archive-bucket");
assert_eq!(params.endpoint, DEFAULT_GCS_ENDPOINT);
assert_eq!(
params.service_account_key.as_deref(),
Some("/keys/archive.json")
);
assert_eq!(recent.password_missing(), false);
assert_eq!(recent.remote_path.as_deref(), Some(Path::new("/backups")));
}
#[test]
fn test_system_bookmarks_manipulate_bookmarks() {
@@ -932,6 +986,16 @@ mod tests {
)
}
fn make_gcs_ftparams(service_account_key: Option<&str>) -> FileTransferParams {
FileTransferParams::new(
FileTransferProtocol::GoogleCloudStorage,
ProtocolParams::GoogleCloudStorage(
GoogleCloudStorageParams::new("archive-bucket")
.service_account_key(service_account_key),
),
)
}
fn ftparams_to_tup(
params: FileTransferParams,
) -> (String, u16, FileTransferProtocol, String, Option<String>) {
+17
View File
@@ -532,6 +532,23 @@ mod tests {
);
}
#[test]
fn should_round_trip_gcs_as_default_protocol() {
let tmp_dir: TempDir = TempDir::new().ok().unwrap();
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
let mut client = ConfigClient::new(cfg_path.as_path(), key_path.as_path())
.ok()
.unwrap();
client.set_default_protocol(FileTransferProtocol::GoogleCloudStorage);
assert_eq!(
client.get_default_protocol(),
FileTransferProtocol::GoogleCloudStorage
);
assert_eq!(client.config.user_interface.default_protocol, "GCS");
}
#[test]
fn test_system_config_show_hidden_files() {
let tmp_dir: TempDir = TempDir::new().ok().unwrap();