Skip to content

Commit

Permalink
added support for artifactory download
Browse files Browse the repository at this point in the history
  • Loading branch information
afujiwara-roblox committed Oct 10, 2023
1 parent 9b17551 commit b4dc4a0
Show file tree
Hide file tree
Showing 12 changed files with 241 additions and 63 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ toml = "0.5.9"
toml_edit = "0.14.4"
urlencoding = "2.1.0"
zip = "0.5"
url = "2.4.1"
artiaa_auth = { path = "./artiaa_auth" }

[target.'cfg(windows)'.dependencies]
command-group = "1.0.8"
Expand Down
8 changes: 3 additions & 5 deletions artiaa_auth/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mod error;
pub mod error;
mod fs;

use std::{collections::HashMap, path::Path};
Expand All @@ -10,8 +10,8 @@ use crate::error::{ArtifactoryAuthError, ArtifactoryAuthResult};

#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
pub struct Credentials {
username: String,
token: String,
pub username: String,
pub token: String,
}

/// Contains stored user tokens that are used to download artifacts from Artifactory.
Expand All @@ -21,7 +21,6 @@ pub struct Tokens {
}

impl Tokens {
#[allow(dead_code)]
pub fn load(path: &Path) -> ArtifactoryAuthResult<Self> {
if let Some(contents) = fs::try_read(path)? {
let tokens: Tokens = serde_json::from_slice(&contents)
Expand All @@ -34,7 +33,6 @@ impl Tokens {
}
}

#[allow(dead_code)]
pub fn get_credentials(&self, url: &Url) -> Option<&Credentials> {
if let Some(domain) = url.domain() {
self.tokens.get(domain)
Expand Down
1 change: 0 additions & 1 deletion src/auth_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::{
error::{ForemanError, ForemanResult},
fs,
};

pub static DEFAULT_AUTH_CONFIG: &str = include_str!("../resources/default-auth.toml");

/// Contains stored user tokens that Foreman can use to download tools.
Expand Down
68 changes: 41 additions & 27 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ use std::{
env, fmt,
};
use toml::Value;
use url::Url;

const GITHUB: &'static str = "https://github.com";
const GITLAB: &'static str = "https://gitlab.com";

#[derive(Debug, Clone, PartialEq)]
pub struct ToolSpec {
host: String,
host: Url,
path: String,
version: VersionReq,
protocol: Protocol,
Expand Down Expand Up @@ -70,7 +71,7 @@ impl ToolSpec {
});
}

let host = host_source.source.to_string();
let host = host_source.source.to_owned();
let path = path_val
.as_str()
.ok_or_else(|| ConfigFileParseError::Tool {
Expand Down Expand Up @@ -126,6 +127,10 @@ impl ToolSpec {
Protocol::Artifactory => Provider::Artifactory,
}
}

pub fn host(&self) -> &Url {
&self.host
}
}

impl fmt::Display for ToolSpec {
Expand All @@ -142,21 +147,18 @@ pub struct ConfigFile {

#[derive(Debug, PartialEq)]
pub struct Host {
source: String,
source: Url,
protocol: Protocol,
}

impl Host {
pub fn new<S: Into<String>>(source: S, protocol: Protocol) -> Self {
Self {
source: source.into(),
protocol,
}
pub fn new(source: Url, protocol: Protocol) -> Self {
Self { source, protocol }
}

pub fn from_value(value: &Value) -> ConfigFileParseResult<Self> {
if let Value::Table(mut map) = value.clone() {
let source = map
let source_string = map
.remove("source")
.ok_or_else(|| ConfigFileParseError::Host {
host: value.to_string(),
Expand All @@ -167,6 +169,9 @@ impl Host {
})?
.to_string();

let source = Url::parse(&source_string).map_err(|_| ConfigFileParseError::Host {
host: value.to_string(),
})?;
let protocol_value =
map.remove("protocol")
.ok_or_else(|| ConfigFileParseError::Host {
Expand Down Expand Up @@ -211,9 +216,18 @@ impl ConfigFile {
Self {
tools: BTreeMap::new(),
hosts: HashMap::from([
("source".to_string(), Host::new(GITHUB, Protocol::Github)),
("github".to_string(), Host::new(GITHUB, Protocol::Github)),
("gitlab".to_string(), Host::new(GITLAB, Protocol::Gitlab)),
(
"source".to_string(),
Host::new(Url::parse(GITHUB).unwrap(), Protocol::Github),
),
(
"github".to_string(),
Host::new(Url::parse(GITHUB).unwrap(), Protocol::Github),
),
(
"gitlab".to_string(),
Host::new(Url::parse(GITLAB).unwrap(), Protocol::Gitlab),
),
]),
}
}
Expand Down Expand Up @@ -332,7 +346,7 @@ mod test {

fn new_github<S: Into<String>>(github: S, version: VersionReq) -> ToolSpec {
ToolSpec {
host: GITHUB.to_string(),
host: Url::parse(GITHUB).unwrap(),
path: github.into(),
version: version,
protocol: Protocol::Github,
Expand All @@ -341,7 +355,7 @@ mod test {

fn new_gitlab<S: Into<String>>(gitlab: S, version: VersionReq) -> ToolSpec {
ToolSpec {
host: GITLAB.to_string(),
host: Url::parse(GITLAB).unwrap(),
path: gitlab.into(),
version: version,
protocol: Protocol::Gitlab,
Expand All @@ -350,7 +364,7 @@ mod test {

fn new_artifactory<S: Into<String>>(host: S, path: S, version: VersionReq) -> ToolSpec {
ToolSpec {
host: host.into(),
host: Url::parse(host.into().as_str()).unwrap(),
path: path.into(),
version: version,
protocol: Protocol::Artifactory,
Expand All @@ -367,26 +381,23 @@ mod test {
VersionReq::parse(string).unwrap()
}

fn new_host<S: Into<String>>(source: S, protocol: Protocol) -> Host {
Host {
source: source.into(),
protocol,
}
fn new_host(source: Url, protocol: Protocol) -> Host {
Host { source, protocol }
}

fn default_hosts() -> HashMap<String, Host> {
HashMap::from([
(
"source".to_string(),
Host::new(GITHUB.to_string(), Protocol::Github),
Host::new(Url::parse(GITHUB).unwrap(), Protocol::Github),
),
(
"github".to_string(),
Host::new(GITHUB.to_string(), Protocol::Github),
Host::new(Url::parse(GITHUB).unwrap(), Protocol::Github),
),
(
"gitlab".to_string(),
Host::new(GITLAB.to_string(), Protocol::Gitlab),
Host::new(Url::parse(GITLAB).unwrap(), Protocol::Gitlab),
),
])
}
Expand All @@ -395,7 +406,7 @@ mod test {
let mut hosts = default_hosts();
hosts.insert(
"artifactory".to_string(),
Host::new(ARTIFACTORY.to_string(), Protocol::Artifactory),
Host::new(Url::parse(ARTIFACTORY).unwrap(), Protocol::Artifactory),
);
hosts
}
Expand Down Expand Up @@ -469,7 +480,10 @@ mod test {
let host = Host::from_value(&value).unwrap();
assert_eq!(
host,
new_host("https://artifactory.com", Protocol::Artifactory)
new_host(
Url::parse("https://artifactory.com").unwrap(),
Protocol::Artifactory
)
)
}

Expand Down Expand Up @@ -546,7 +560,7 @@ mod test {
BTreeMap::from([(
"tool".to_string(),
ToolSpec {
host: "https://artifactory.com".to_string(),
host: Url::parse("https://artifactory.com").unwrap(),
path: "path/to/tool".to_string(),
version: VersionReq::parse("1.0.0").unwrap(),
protocol: Protocol::Artifactory
Expand All @@ -555,7 +569,7 @@ mod test {
HashMap::from([(
"artifactory".to_string(),
Host {
source: "https://artifactory.com".to_string(),
source: Url::parse("https://artifactory.com").unwrap(),
protocol: Protocol::Artifactory
}
)])
Expand Down
16 changes: 11 additions & 5 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{fmt, io, path::PathBuf};
use semver::Version;

use crate::config::{ConfigFile, ToolSpec};

use artiaa_auth::error::ArtifactoryAuthError;
pub type ForemanResult<T> = Result<T, ForemanError>;
pub type ConfigFileParseResult<T> = Result<T, ConfigFileParseError>;
#[derive(Debug)]
Expand Down Expand Up @@ -71,8 +71,11 @@ pub enum ForemanError {
ToolsNotDownloaded {
tools: Vec<String>,
},
Other {
message: String,
EnvVarNotFound {
env_var: String,
},
ArtiAAError {
error: ArtifactoryAuthError,
},
}

Expand Down Expand Up @@ -319,8 +322,11 @@ impl fmt::Display for ForemanError {
Self::ToolsNotDownloaded { tools } => {
write!(f, "The following tools were not installed:\n{:#?}", tools)
}
Self::Other { message } => {
write!(f, "{}", message)
Self::EnvVarNotFound { env_var } => {
write!(f, "Environment Variable not found: {}", env_var)
}
Self::ArtiAAError { error } => {
write!(f, "{}", error)
}
}
}
Expand Down
55 changes: 52 additions & 3 deletions src/paths.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
//! Contains all of the paths that Foreman needs to deal with.

use std::path::{Path, PathBuf};
use std::{
env,
path::{Path, PathBuf},
};

use crate::{auth_store::DEFAULT_AUTH_CONFIG, error::ForemanError, fs};
use crate::{
auth_store::DEFAULT_AUTH_CONFIG,
error::{ForemanError, ForemanResult},
fs,
};

static DEFAULT_USER_CONFIG: &str = include_str!("../resources/default-foreman.toml");

Expand All @@ -20,7 +27,7 @@ impl ForemanPaths {
.ok()
.and_then(|path| {
if path.is_dir() {
Some(Self { root_dir:path })
Some(Self { root_dir: path })
} else {
if path.exists() {
log::warn!(
Expand Down Expand Up @@ -87,6 +94,48 @@ impl ForemanPaths {

Ok(())
}

pub fn artiaa_path(&self) -> ForemanResult<PathBuf> {
get_artiaa_path_based_on_os()
}
}

#[cfg(target_os = "windows")]
fn get_artiaa_path_based_on_os() -> ForemanResult<PathBuf> {
let localappdata = env::var("LOCALAPPDATA").map_err(|_| ForemanError::EnvVarNotFound {
env_var: "%$LOCALAPPDATA%".to_string(),
})?;
Ok(PathBuf::from(format!(
"{}/ArtiAA/artiaa-tokens.json",
localappdata
)))
}

#[cfg(target_os = "macos")]
fn get_artiaa_path_based_on_os() -> ForemanResult<PathBuf> {
let home = env::var("HOME").map_err(|_| ForemanError::EnvVarNotFound {
env_var: "$HOME".to_string(),
})?;
Ok(PathBuf::from(format!(
"{}/Library/Application Support/ArtiAA/artiaa-tokens.json",
home
)))
}

#[cfg(all(not(target_os = "macos"), target_family = "unix"))]
fn get_artiaa_path_based_on_os() -> ForemanResult<PathBuf> {
let xdg_data_home = env::var("XDG_DATA_HOME").map_err(|_| ForemanError::EnvVarNotFound {
env_var: "$XDG_DATA_HOME".to_string(),
})?;
Ok(PathBuf::from(format!(
"{}/ArtiAA/artiaa-tokens.json",
xdg_data_home
)))
}

#[cfg(other)]
fn get_artiaa_path_based_on_os() -> PathBuf {
unimplemented!("artiaa_path is only defined for windows or unix operating systems")
}

impl Default for ForemanPaths {
Expand Down
2 changes: 1 addition & 1 deletion src/tool_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl ToolCache {
log::info!("Downloading {}", tool);

let provider = providers.get(&tool.provider());
let releases = provider.get_releases(tool.path())?;
let releases = provider.get_releases(tool.path(), tool.host())?;

// Filter down our set of releases to those that are valid versions and
// have release assets for our current platform.
Expand Down
Loading

0 comments on commit b4dc4a0

Please sign in to comment.