use anyhow::{anyhow, bail, Context, Result};
use semver::{BuildMetadata, Version};
use std::path::PathBuf;
use url::Url;
pub fn get_juliaserver_base_url() -> Result<Url> {
let base_url = if let Ok(val) = std::env::var("JULIAUP_SERVER") {
if val.ends_with('/') {
val
} else {
format!("{}/", val)
}
} else {
"https://julialang-s3.julialang.org".to_string()
};
let parsed_url = Url::parse(&base_url).with_context(|| {
format!(
"Failed to parse the value of JULIAUP_SERVER '{}' as a uri.",
base_url
)
})?;
Ok(parsed_url)
}
pub fn get_bin_dir() -> Result<PathBuf> {
let entry_sep = if std::env::consts::OS == "windows" {
';'
} else {
':'
};
let path = match std::env::var("JULIAUP_BIN_DIR") {
Ok(val) => {
let path = PathBuf::from(val.split(entry_sep).next().unwrap());
if !path.is_absolute() {
bail!("The `JULIAUP_BIN_DIR` environment variable contains a value that resolves to an an invalid path `{}`.", path.display());
};
path
}
Err(_) => {
let mut path = std::env::current_exe()
.with_context(|| "Could not determine the path of the running exe.")?
.parent()
.ok_or_else(|| anyhow!("Could not determine parent."))?
.to_path_buf();
if let Some(home_dir) = dirs::home_dir() {
if !path.starts_with(&home_dir) {
path = home_dir.join(".local").join("bin");
if !path.is_absolute() {
bail!(
"The system returned an invalid home directory path `{}`.",
path.display()
);
};
}
}
path
}
};
Ok(path)
}
pub fn get_arch() -> Result<String> {
if std::env::consts::ARCH == "x86" {
return Ok("x86".to_string());
} else if std::env::consts::ARCH == "x86_64" {
return Ok("x64".to_string());
} else if std::env::consts::ARCH == "aarch64" {
return Ok("aarch64".to_string());
}
bail!("Running on an unknown arch: {}.", std::env::consts::ARCH)
}
pub fn parse_versionstring(value: &String) -> Result<(String, Version)> {
let version = Version::parse(value).unwrap();
let build_parts: Vec<&str> = version.build.split('.').collect();
if build_parts.len() != 4 {
bail!(
"`{}` is an invalid version specifier: the build part must have four parts.",
value
);
}
let version_without_build = semver::Version {
major: version.major,
minor: version.minor,
patch: version.patch,
pre: version.pre,
build: BuildMetadata::EMPTY,
};
let platform = build_parts[1];
Ok((platform.to_string(), version_without_build))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_versionstring() {
let s = "1.1.1";
assert!(parse_versionstring(&s.to_owned()).is_err());
let s = "1.1.1+0.x86.apple.darwin14";
let (p, v) = parse_versionstring(&s.to_owned()).unwrap();
assert_eq!(p, "x86");
assert_eq!(v, Version::new(1, 1, 1));
let s = "1.1.1+0.x64.apple.darwin14";
let (p, v) = parse_versionstring(&s.to_owned()).unwrap();
assert_eq!(p, "x64");
assert_eq!(v, Version::new(1, 1, 1));
}
}