Fixup diagnostic_endpoint setting to be more flexible (#374)

* Fixup diagnostic_endpoint setting to be more flexible

* Fixup doctests
This commit is contained in:
Ana Hobden 2023-03-27 11:56:44 -07:00 committed by GitHub
parent b7839953dc
commit 709e81565c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 52 additions and 15 deletions

View file

@ -163,7 +163,7 @@ impl Planner for MyPlanner {
.into_keys() .into_keys()
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
self.common.ssl_cert_file.clone(), self.common.ssl_cert_file.clone(),
)) )?)
} }
} }

View file

@ -65,18 +65,22 @@ pub struct DiagnosticData {
impl DiagnosticData { impl DiagnosticData {
pub fn new( pub fn new(
endpoint: Option<Url>, endpoint: Option<String>,
planner: String, planner: String,
configured_settings: Vec<String>, configured_settings: Vec<String>,
ssl_cert_file: Option<PathBuf>, ssl_cert_file: Option<PathBuf>,
) -> Self { ) -> Result<Self, DiagnosticError> {
let endpoint = match endpoint {
Some(endpoint) => diagnostic_endpoint_parser(&endpoint)?,
None => None,
};
let (os_name, os_version) = match OsRelease::new() { let (os_name, os_version) = match OsRelease::new() {
Ok(os_release) => (os_release.name, os_release.version), Ok(os_release) => (os_release.name, os_release.version),
Err(_) => ("unknown".into(), "unknown".into()), Err(_) => ("unknown".into(), "unknown".into()),
}; };
let is_ci = is_ci::cached() let is_ci = is_ci::cached()
|| std::env::var("NIX_INSTALLER_CI").unwrap_or_else(|_| "0".into()) == "1"; || std::env::var("NIX_INSTALLER_CI").unwrap_or_else(|_| "0".into()) == "1";
Self { Ok(Self {
endpoint, endpoint,
version: env!("CARGO_PKG_VERSION").into(), version: env!("CARGO_PKG_VERSION").into(),
planner, planner,
@ -87,7 +91,7 @@ impl DiagnosticData {
is_ci, is_ci,
ssl_cert_file, ssl_cert_file,
failure_chain: None, failure_chain: None,
} })
} }
pub fn failure(mut self, err: &NixInstallerError) -> Self { pub fn failure(mut self, err: &NixInstallerError) -> Self {
@ -215,6 +219,13 @@ pub enum DiagnosticError {
#[source] #[source]
reqwest::Error, reqwest::Error,
), ),
/// Parsing URL
#[error("Parsing URL")]
Parse(
#[source]
#[from]
url::ParseError,
),
#[error("Write path `{0}`")] #[error("Write path `{0}`")]
Write(std::path::PathBuf, #[source] std::io::Error), Write(std::path::PathBuf, #[source] std::io::Error),
#[error("Serializing receipt")] #[error("Serializing receipt")]
@ -237,3 +248,24 @@ impl ErrorDiagnostic for DiagnosticError {
return static_str.to_string(); return static_str.to_string();
} }
} }
pub fn diagnostic_endpoint_parser(input: &str) -> Result<Option<Url>, DiagnosticError> {
match Url::parse(input) {
Ok(v) => match v.scheme() {
"https" | "http" | "file" => Ok(Some(v)),
_ => Err(DiagnosticError::UnknownUrlScheme),
},
Err(url_error) if url_error == url::ParseError::RelativeUrlWithoutBase => {
match Url::parse(&format!("file://{input}")) {
Ok(v) => Ok(Some(v)),
Err(file_error) => Err(file_error)?,
}
},
Err(url_error) => Err(url_error)?,
}
}
pub fn diagnostic_endpoint_validator(input: &str) -> Result<String, DiagnosticError> {
let _ = diagnostic_endpoint_parser(input)?;
Ok(input.to_string())
}

View file

@ -135,7 +135,7 @@ impl Planner for Linux {
.into_keys() .into_keys()
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
self.settings.ssl_cert_file.clone(), self.settings.ssl_cert_file.clone(),
)) )?)
} }
} }

View file

@ -211,7 +211,7 @@ impl Planner for Macos {
.into_keys() .into_keys()
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
self.settings.ssl_cert_file.clone(), self.settings.ssl_cert_file.clone(),
)) )?)
} }
} }

View file

@ -79,7 +79,7 @@ impl Planner for MyPlanner {
.into_keys() .into_keys()
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
self.common.ssl_cert_file.clone(), self.common.ssl_cert_file.clone(),
)) )?)
} }
} }
@ -317,6 +317,9 @@ pub enum PlannerError {
NixExists, NixExists,
#[error("WSL1 is not supported, please upgrade to WSL2: https://learn.microsoft.com/en-us/windows/wsl/install#upgrade-version-from-wsl-1-to-wsl-2")] #[error("WSL1 is not supported, please upgrade to WSL2: https://learn.microsoft.com/en-us/windows/wsl/install#upgrade-version-from-wsl-1-to-wsl-2")]
Wsl1, Wsl1,
#[cfg(feature = "diagnostics")]
#[error(transparent)]
Diagnostic(#[from] crate::diagnostics::DiagnosticError),
} }
impl HasExpectedErrors for PlannerError { impl HasExpectedErrors for PlannerError {
@ -334,6 +337,8 @@ impl HasExpectedErrors for PlannerError {
this @ PlannerError::NixOs => Some(Box::new(this)), this @ PlannerError::NixOs => Some(Box::new(this)),
this @ PlannerError::NixExists => Some(Box::new(this)), this @ PlannerError::NixExists => Some(Box::new(this)),
this @ PlannerError::Wsl1 => Some(Box::new(this)), this @ PlannerError::Wsl1 => Some(Box::new(this)),
#[cfg(feature = "diagnostics")]
PlannerError::Diagnostic(diagnostic_error) => Some(Box::new(diagnostic_error)),
} }
} }
} }

View file

@ -287,7 +287,7 @@ impl Planner for SteamDeck {
.into_keys() .into_keys()
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
self.settings.ssl_cert_file.clone(), self.settings.ssl_cert_file.clone(),
)) )?)
} }
} }

View file

@ -214,14 +214,16 @@ pub struct CommonSettings {
/// "status": "Success" /// "status": "Success"
/// } /// }
/// ///
/// To disable diagnostic reporting, unset the default with `--diagnostic-endpoint=` /// To disable diagnostic reporting, unset the default with `--diagnostic-endpoint ""`, or `NIX_INSTALLER_DIAGNOSTIC_ENDPOINT=""`
#[clap( #[clap(
long, long,
env = "NIX_INSTALLER_DIAGNOSTIC_ENDPOINT", env = "NIX_INSTALLER_DIAGNOSTIC_ENDPOINT",
global = true, global = true,
default_value = "https://install.determinate.systems/nix/diagnostic" value_parser = crate::diagnostics::diagnostic_endpoint_validator,
num_args = 0..=1, // Required to allow `--diagnostic-endpoint` or `NIX_INSTALLER_DIAGNOSTIC_ENDPOINT=""`
default_missing_value = "https://install.determinate.systems/nix/diagnostic"
)] )]
pub diagnostic_endpoint: Option<Url>, pub diagnostic_endpoint: Option<String>,
} }
impl CommonSettings { impl CommonSettings {
@ -285,9 +287,7 @@ impl CommonSettings {
force: false, force: false,
ssl_cert_file: Default::default(), ssl_cert_file: Default::default(),
#[cfg(feature = "diagnostics")] #[cfg(feature = "diagnostics")]
diagnostic_endpoint: Some( diagnostic_endpoint: Some("https://install.determinate.systems/nix/diagnostic".into()),
"https://install.determinate.systems/nix/diagnostic".try_into()?,
),
}) })
} }