-
-
Notifications
You must be signed in to change notification settings - Fork 93
Expand file tree
/
Copy pathutil.rs
More file actions
143 lines (124 loc) · 4.27 KB
/
util.rs
File metadata and controls
143 lines (124 loc) · 4.27 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
use std::collections::HashSet;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::str;
use color_eyre::{eyre, Result};
use tempfile::TempDir;
/// Retrieves the installed Nix version as a string.
///
/// This function executes the `nix --version` command, parses the output to extract the version string,
/// and returns it. If the version string cannot be found or parsed, it returns an error.
///
/// # Returns
///
/// * `Result<String>` - The Nix version string or an error if the version cannot be retrieved.
pub fn get_nix_version() -> Result<String> {
let output = Command::new("nix").arg("--version").output()?;
let output_str = str::from_utf8(&output.stdout)?;
let version_str = output_str
.lines()
.next()
.ok_or_else(|| eyre::eyre!("No version string found"))?;
// Extract the version substring using a regular expression
let re = regex::Regex::new(r"\d+\.\d+\.\d+")?;
if let Some(captures) = re.captures(version_str) {
let version = captures
.get(0)
.ok_or_else(|| eyre::eyre!("No version match found"))?
.as_str();
return Ok(version.to_string());
}
Err(eyre::eyre!("Failed to extract version"))
}
/// Determines if the Nix binary is actually Lix
///
/// # Returns
///
/// * `Result<bool>` - True if the binary is Lix, false if it's standard Nix
pub fn is_lix() -> Result<bool> {
let output = Command::new("nix").arg("--version").output()?;
let output_str = str::from_utf8(&output.stdout)?.to_lowercase();
Ok(output_str.contains("lix"))
}
/// Represents an object that may be a temporary path
pub trait MaybeTempPath: std::fmt::Debug {
fn get_path(&self) -> &Path;
}
impl MaybeTempPath for PathBuf {
fn get_path(&self) -> &Path {
self.as_ref()
}
}
impl MaybeTempPath for (PathBuf, TempDir) {
fn get_path(&self) -> &Path {
self.0.as_ref()
}
}
/// Gets the hostname of the current system
///
/// # Returns
///
/// * `Result<String>` - The hostname as a string or an error
pub fn get_hostname() -> Result<String> {
#[cfg(not(target_os = "macos"))]
{
use color_eyre::eyre::Context;
Ok(hostname::get()
.context("Failed to get hostname")?
.to_str()
.unwrap()
.to_string())
}
#[cfg(target_os = "macos")]
{
use color_eyre::eyre::bail;
use system_configuration::{
core_foundation::{base::TCFType, string::CFString},
sys::dynamic_store_copy_specific::SCDynamicStoreCopyLocalHostName,
};
let ptr = unsafe { SCDynamicStoreCopyLocalHostName(std::ptr::null()) };
if ptr.is_null() {
bail!("Failed to get hostname");
}
let name = unsafe { CFString::wrap_under_get_rule(ptr) };
Ok(name.to_string())
}
}
/// Retrieves all enabled experimental features in Nix.
///
/// This function executes the `nix config show experimental-features` command and returns
/// a HashSet of the enabled features.
///
/// # Returns
///
/// * `Result<HashSet<String>>` - A HashSet of enabled experimental features or an error.
pub fn get_nix_experimental_features() -> Result<HashSet<String>> {
let output = Command::new("nix")
.args(["config", "show", "experimental-features"])
.output()?;
if !output.status.success() {
return Err(eyre::eyre!(
"Failed to get experimental features: {}",
String::from_utf8_lossy(&output.stderr)
));
}
let output_str = str::from_utf8(&output.stdout)?;
let enabled_features: HashSet<String> =
output_str.split_whitespace().map(String::from).collect();
Ok(enabled_features)
}
/// Checks if all specified experimental features are enabled in Nix.
///
/// # Arguments
///
/// * `features` - A slice of string slices representing the features to check for.
///
/// # Returns
///
/// * `Result<bool>` - True if all specified features are enabled, false otherwise.
pub fn has_all_experimental_features(features: &[&str]) -> Result<bool> {
let enabled_features = get_nix_experimental_features()?;
let features_set: HashSet<String> = features.iter().map(|&s| s.to_string()).collect();
// Check if features_set is a subset of enabled_features
Ok(features_set.is_subset(&enabled_features))
}