Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion registry/snyk.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
backends = ["aqua:snyk/cli", "asdf:nirfuchs/asdf-snyk"]
backends = ["aqua:snyk/cli", "github:snyk/cli", "asdf:nirfuchs/asdf-snyk"]
description = "Snyk CLI scans and monitors your projects for security vulnerabilities"
12 changes: 8 additions & 4 deletions src/backend/asset_matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,15 +176,19 @@ pub struct AssetPicker {
}

impl AssetPicker {
/// Create an AssetPicker with an explicit libc setting
/// Create an AssetPicker with an explicit libc setting.
/// When no explicit libc is provided, uses runtime detection via Platform::current()
/// to determine the system's libc (musl vs glibc), rather than compile-time checks.
pub fn with_libc(target_os: String, target_arch: String, libc: Option<String>) -> Self {
let target_libc = libc.unwrap_or_else(|| {
if target_os == "windows" {
"msvc".to_string()
} else if cfg!(target_env = "musl") {
"musl".to_string()
} else {
"gnu".to_string()
let current = crate::platform::Platform::current();
match current.qualifier.as_deref() {
Some("musl") | Some("musl-baseline") => "musl".to_string(),
_ => "gnu".to_string(),
}
Comment thread
cursor[bot] marked this conversation as resolved.
Outdated
}
});

Expand Down
8 changes: 3 additions & 5 deletions src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,12 +373,10 @@ pub trait Backend: Debug + Send + Sync {
fn ba(&self) -> &Arc<BackendArg>;

/// Generates a platform key for lockfile storage.
/// Default implementation uses os-arch format, but backends can override for more specific keys.
/// Default implementation uses the current platform key (os-arch or os-arch-qualifier),
/// which includes the libc qualifier on musl systems.
fn get_platform_key(&self) -> String {
let settings = Settings::get();
let os = settings.os();
let arch = settings.arch();
format!("{os}-{arch}")
Platform::current().to_key()
Comment thread
cursor[bot] marked this conversation as resolved.
}

/// Resolves the lockfile options for a tool request on a target platform.
Expand Down
45 changes: 41 additions & 4 deletions src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,20 @@ impl Platform {
}
}

/// Get the current platform from system information
/// Get the current platform from system information.
/// On Linux, detects musl vs glibc at runtime and sets the qualifier accordingly.
pub fn current() -> Self {
let settings = Settings::get();
let os = settings.os().to_string();
let qualifier = if os == "linux" && is_musl_system() {
Some("musl".to_string())
} else {
None
};
Platform {
os: settings.os().to_string(),
os,
arch: settings.arch().to_string(),
qualifier: None,
qualifier,
}
}

Expand Down Expand Up @@ -117,7 +124,9 @@ impl Platform {
pub fn common_platforms() -> Vec<Self> {
vec![
Platform::parse("linux-x64").unwrap(),
Platform::parse("linux-x64-musl").unwrap(),
Platform::parse("linux-arm64").unwrap(),
Platform::parse("linux-arm64-musl").unwrap(),
Platform::parse("macos-x64").unwrap(),
Platform::parse("macos-arm64").unwrap(),
Platform::parse("windows-x64").unwrap(),
Expand Down Expand Up @@ -174,6 +183,32 @@ impl From<&str> for Platform {
}
}

/// Detect whether the system uses musl libc at runtime.
/// Checks for the musl dynamic linker in /lib, which is present on musl-based
/// systems like Alpine Linux. This is a runtime check (not compile-time) so a
/// statically-linked or musl-built mise binary running on a glibc system will
/// correctly detect glibc, and vice versa.
#[cfg(target_os = "linux")]
fn is_musl_system() -> bool {
use std::sync::LazyLock;
static IS_MUSL: LazyLock<bool> = LazyLock::new(|| {
if let Ok(entries) = std::fs::read_dir("/lib") {
for entry in entries.flatten() {
if entry.file_name().to_string_lossy().starts_with("ld-musl-") {
return true;
}
}
}
false

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The logic for checking for musl can be made more concise and idiomatic by using iterator methods like any() and map() on the Result from read_dir.

        std::fs::read_dir("/lib")
            .map(|entries| {
                entries.flatten().any(|entry| {
                    entry
                        .file_name()
                        .to_string_lossy()
                        .starts_with("ld-musl-")
                })
            })
            .unwrap_or(false)

});
*IS_MUSL
}
Comment thread
cursor[bot] marked this conversation as resolved.

#[cfg(not(target_os = "linux"))]
fn is_musl_system() -> bool {
false
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -283,11 +318,13 @@ mod tests {
#[test]
fn test_common_platforms() {
let platforms = Platform::common_platforms();
assert_eq!(platforms.len(), 5);
assert_eq!(platforms.len(), 7);

let keys: Vec<String> = platforms.iter().map(|p| p.to_key()).collect();
assert!(keys.contains(&"linux-x64".to_string()));
assert!(keys.contains(&"linux-x64-musl".to_string()));
assert!(keys.contains(&"linux-arm64".to_string()));
assert!(keys.contains(&"linux-arm64-musl".to_string()));
assert!(keys.contains(&"macos-x64".to_string()));
assert!(keys.contains(&"macos-arm64".to_string()));
assert!(keys.contains(&"windows-x64".to_string()));
Expand Down
Loading