1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#![warn(missing_docs)]

//! A Rust implementation of [`gcloud config configurations`](https://cloud.google.com/sdk/gcloud/reference/config/configurations)
//! for managing different `gcloud` configurations for Google Cloud Platform. This is the library containing the core logic
//! which is used to build the associated [`gctx`](https://github.com/adamrodger/gctx) command line utility.
//!
//! **Note**: `gcloud-ctx` is independent and not affiliated with Google in any way.
//!
//! ## Usage
//!
//! ```rust
//! # // use a temp dir so that running doc tests doesn't change your real configurations
//! # use std::fs::File;
//! # let tmp = tempfile::tempdir().unwrap();
//! # File::create(tmp.path().join("active_config")).unwrap();
//! # let configs = tmp.path().join("configurations");
//! # std::fs::create_dir(&configs).unwrap();
//! # File::create(configs.join("config_foo")).unwrap();
//! # std::env::set_var("CLOUDSDK_CONFIG", tmp.path());
//! use gcloud_ctx::{ConfigurationStore, ConflictAction};
//!
//! let mut store = ConfigurationStore::with_default_location()?;
//!
//! // create a new configuration, optionally with a force overwrite
//! use gcloud_ctx::PropertiesBuilder;
//! let properties = PropertiesBuilder::default()
//!     .project("my-project")
//!     .account("a.user@example.org")
//!     .zone("europe-west1-d")
//!     .region("europe-west1")
//!     .build();
//!
//! store.create("foo", &properties, ConflictAction::Overwrite)?;
//!
//! // list configurations
//! for config in store.configurations() {
//!     println!("{}", config.name());
//! }
//!
//! // activate a configuration by name
//! store.activate("foo")?;
//!
//! // get the active configuration
//! println!("{}", store.active());
//!
//! // copy an existing configuration, with force overwrite
//! store.copy("foo", "bar", ConflictAction::Overwrite)?;
//!
//! // rename an existing configuration, with force overwrite
//! store.rename("bar", "baz", ConflictAction::Overwrite)?;
//!
//! // delete a configuration
//! store.delete("baz")?;
//!
//! // get properties of a configuration
//! let properties = store.describe("foo")?;
//! properties.to_writer(std::io::stdout())?;
//! # Ok::<(), gcloud_ctx::Error>(())
//! ```

mod configuration;
mod properties;

pub use configuration::*;
pub use properties::*;

use std::path::PathBuf;
use thiserror::Error;

/// gcloud-ctx result
pub type Result<T> = std::result::Result<T, Error>;

/// gcloud-ctx error
#[derive(Debug, Error)]
pub enum Error {
    /// The configuration directory was not found within the configuration store directory
    #[error("Unable to locate user configuration directory")]
    ConfigurationDirectoryNotFound,

    /// Unable to find the gcloud configuration root directory
    #[error("Unable to find the gcloud configuration directory at {0}\n\nIs gcloud installed?")]
    ConfigurationStoreNotFound(PathBuf),

    /// Attempted to delete the active configuration
    #[error("Unable to delete the configuration because it is currently active")]
    DeleteActiveConfiguration,

    /// Error loading properties from a configuration
    #[error("Unable to load properties")]
    LoadingProperties(#[from] serde_ini::de::Error),

    /// The operation would overwrite an existing configuration
    #[error("A configuration named '{0}' already exists. Use --force to overwrite it")]
    ExistingConfiguration(String),

    /// The configuration name is invalid
    #[error("'{0}' is invalid. Configuration names must only contain ASCII letters and numbers")]
    InvalidName(String),

    /// General I/O error
    #[error("I/O error")]
    Io(#[from] std::io::Error),

    /// Not configurations were found in the configuration store
    #[error("Unable to find any gcloud configurations in {0}")]
    NoConfigurationsFound(PathBuf),

    /// Error saving properties to a configuration
    #[error("Unable to save properties")]
    SavingProperties(#[from] serde_ini::ser::Error),

    /// A configuration with the given name wasn't found
    #[error("Unable to find configuration '{0}'")]
    UnknownConfiguration(String),
}