mirror of
https://github.com/block/goose.git
synced 2026-06-01 22:11:07 +02:00
Add Linux musl CLI builds (#9240)
Signed-off-by: jh-block <jhugo@block.xyz>
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
# Platform Build Strategy:
|
||||
# - Linux standard: Uses native Ubuntu 22.04 runners to keep glibc compatibility with Ubuntu 22.04 LTS
|
||||
# - Linux Vulkan: Uses native Ubuntu 24.04 runners for newer Vulkan headers/tooling
|
||||
# - Linux musl: Uses native Ubuntu 22.04 runners with reduced features for musl compatibility
|
||||
# - macOS: Uses native macOS runners for each architecture
|
||||
# - Windows: Uses Windows runner with native MSVC build
|
||||
on:
|
||||
@@ -42,6 +43,16 @@ jobs:
|
||||
target-suffix: unknown-linux-gnu
|
||||
build-on: ubuntu-22.04-arm
|
||||
variant: standard
|
||||
- platform: linux
|
||||
architecture: x86_64
|
||||
target-suffix: unknown-linux-musl
|
||||
build-on: ubuntu-22.04
|
||||
variant: musl
|
||||
- platform: linux
|
||||
architecture: aarch64
|
||||
target-suffix: unknown-linux-musl
|
||||
build-on: ubuntu-22.04-arm
|
||||
variant: musl
|
||||
- platform: linux
|
||||
architecture: x86_64
|
||||
target-suffix: unknown-linux-gnu
|
||||
@@ -104,6 +115,10 @@ jobs:
|
||||
glslc
|
||||
fi
|
||||
|
||||
if [ "${{ matrix.variant }}" = "musl" ]; then
|
||||
sudo apt-get install -y musl-tools
|
||||
fi
|
||||
|
||||
- name: Cache Cargo artifacts (Linux/macOS)
|
||||
if: matrix.platform != 'windows'
|
||||
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
|
||||
@@ -133,7 +148,14 @@ jobs:
|
||||
if [ "${{ matrix.variant }}" = "vulkan" ]; then
|
||||
FEATURE_ARGS=(--features vulkan)
|
||||
fi
|
||||
cargo build --release --target ${TARGET} -p goose-cli "${FEATURE_ARGS[@]}"
|
||||
|
||||
if [ "${{ matrix.variant }}" = "musl" ]; then
|
||||
cargo build --release --target ${TARGET} -p goose-cli --bin goose \
|
||||
--no-default-features \
|
||||
--features portable-default
|
||||
else
|
||||
cargo build --release --target ${TARGET} -p goose-cli "${FEATURE_ARGS[@]}"
|
||||
fi
|
||||
|
||||
- name: Setup Rust (Windows)
|
||||
if: matrix.platform == 'windows'
|
||||
@@ -233,7 +255,7 @@ jobs:
|
||||
- name: Upload CLI artifact
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: goose-${{ matrix.architecture }}-${{ matrix.target-suffix }}${{ matrix.variant != 'standard' && format('-{0}', matrix.variant) || '' }}
|
||||
name: goose-${{ matrix.architecture }}-${{ matrix.target-suffix }}${{ matrix.variant != 'standard' && matrix.variant != 'musl' && format('-{0}', matrix.variant) || '' }}
|
||||
path: |
|
||||
${{ env.ARTIFACT_BZ2 }}
|
||||
${{ env.ARTIFACT_GZ }}
|
||||
|
||||
@@ -138,6 +138,8 @@ jobs:
|
||||
Download CLI builds for different platforms:
|
||||
- [📦 Linux (x86_64, Ubuntu 22.04-compatible)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-x86_64-unknown-linux-gnu.zip)
|
||||
- [📦 Linux (aarch64, Ubuntu 22.04-compatible)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-aarch64-unknown-linux-gnu.zip)
|
||||
- [📦 Linux musl (x86_64)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-x86_64-unknown-linux-musl.zip)
|
||||
- [📦 Linux musl (aarch64)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-aarch64-unknown-linux-musl.zip)
|
||||
- [📦 Linux Vulkan (x86_64, Ubuntu 24.04+)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-x86_64-unknown-linux-gnu-vulkan.zip)
|
||||
- [📦 Linux Vulkan (aarch64, Ubuntu 24.04+)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-aarch64-unknown-linux-gnu-vulkan.zip)
|
||||
- [📦 macOS (x86_64)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-x86_64-apple-darwin.zip)
|
||||
|
||||
@@ -69,7 +69,15 @@ clap_complete_nushell = "4.6.0"
|
||||
winapi = { workspace = true }
|
||||
|
||||
[features]
|
||||
default = ["code-mode", "local-inference", "aws-providers", "telemetry", "otel", "rustls-tls"]
|
||||
default = [
|
||||
"code-mode",
|
||||
"local-inference",
|
||||
"aws-providers",
|
||||
"telemetry",
|
||||
"otel",
|
||||
"rustls-tls",
|
||||
"system-keyring",
|
||||
]
|
||||
code-mode = ["goose/code-mode"]
|
||||
local-inference = ["goose/local-inference"]
|
||||
aws-providers = ["goose/aws-providers"]
|
||||
@@ -77,6 +85,8 @@ cuda = ["goose/cuda", "local-inference"]
|
||||
vulkan = ["goose/vulkan", "local-inference"]
|
||||
telemetry = ["goose/telemetry"]
|
||||
otel = ["goose/otel"]
|
||||
system-keyring = ["goose/system-keyring"]
|
||||
portable-default = ["rustls-tls", "aws-providers", "telemetry", "otel"]
|
||||
# disables the update command
|
||||
disable-update = []
|
||||
rustls-tls = [
|
||||
|
||||
@@ -18,14 +18,22 @@ fn asset_name() -> &'static str {
|
||||
{
|
||||
"goose-x86_64-apple-darwin.tar.bz2"
|
||||
}
|
||||
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
|
||||
#[cfg(all(target_os = "linux", target_arch = "x86_64", target_env = "gnu"))]
|
||||
{
|
||||
"goose-x86_64-unknown-linux-gnu.tar.bz2"
|
||||
}
|
||||
#[cfg(all(target_os = "linux", target_arch = "aarch64"))]
|
||||
#[cfg(all(target_os = "linux", target_arch = "aarch64", target_env = "gnu"))]
|
||||
{
|
||||
"goose-aarch64-unknown-linux-gnu.tar.bz2"
|
||||
}
|
||||
#[cfg(all(target_os = "linux", target_arch = "x86_64", target_env = "musl"))]
|
||||
{
|
||||
"goose-x86_64-unknown-linux-musl.tar.bz2"
|
||||
}
|
||||
#[cfg(all(target_os = "linux", target_arch = "aarch64", target_env = "musl"))]
|
||||
{
|
||||
"goose-aarch64-unknown-linux-musl.tar.bz2"
|
||||
}
|
||||
#[cfg(all(target_os = "windows", target_arch = "x86_64", feature = "cuda"))]
|
||||
{
|
||||
"goose-x86_64-pc-windows-msvc-cuda.zip"
|
||||
|
||||
@@ -12,7 +12,15 @@ description.workspace = true
|
||||
workspace = true
|
||||
|
||||
[features]
|
||||
default = ["code-mode", "local-inference", "aws-providers", "telemetry", "otel", "rustls-tls"]
|
||||
default = [
|
||||
"code-mode",
|
||||
"local-inference",
|
||||
"aws-providers",
|
||||
"telemetry",
|
||||
"otel",
|
||||
"rustls-tls",
|
||||
"system-keyring",
|
||||
]
|
||||
code-mode = ["goose/code-mode"]
|
||||
local-inference = ["goose/local-inference"]
|
||||
aws-providers = ["goose/aws-providers"]
|
||||
@@ -20,6 +28,8 @@ cuda = ["goose/cuda", "local-inference"]
|
||||
vulkan = ["goose/vulkan", "local-inference"]
|
||||
telemetry = ["goose/telemetry"]
|
||||
otel = ["goose/otel"]
|
||||
system-keyring = ["goose/system-keyring"]
|
||||
portable-default = ["rustls-tls", "aws-providers", "telemetry", "otel"]
|
||||
rustls-tls = [
|
||||
"reqwest/rustls",
|
||||
"tokio-tungstenite/rustls-tls-native-roots",
|
||||
|
||||
+15
-5
@@ -9,7 +9,15 @@ repository.workspace = true
|
||||
description.workspace = true
|
||||
|
||||
[features]
|
||||
default = ["code-mode", "local-inference", "aws-providers", "telemetry", "otel", "rustls-tls"]
|
||||
default = [
|
||||
"code-mode",
|
||||
"local-inference",
|
||||
"aws-providers",
|
||||
"telemetry",
|
||||
"otel",
|
||||
"rustls-tls",
|
||||
"system-keyring",
|
||||
]
|
||||
telemetry = []
|
||||
otel = [
|
||||
"dep:tracing-opentelemetry",
|
||||
@@ -59,6 +67,8 @@ native-tls = [
|
||||
"oauth2/reqwest",
|
||||
"oauth2/native-tls",
|
||||
]
|
||||
system-keyring = ["dep:keyring"]
|
||||
portable-default = ["rustls-tls", "aws-providers", "telemetry", "otel"]
|
||||
|
||||
|
||||
[lints]
|
||||
@@ -110,7 +120,7 @@ opentelemetry_sdk = { workspace = true, optional = true }
|
||||
opentelemetry-appender-tracing = { workspace = true, optional = true }
|
||||
opentelemetry-otlp = { workspace = true, optional = true }
|
||||
opentelemetry-stdout = { workspace = true, optional = true }
|
||||
keyring = { version = "3.6.2", features = ["vendored"] }
|
||||
keyring = { version = "3.6.2", features = ["vendored"], optional = true }
|
||||
serde_yaml = { workspace = true }
|
||||
strum = { workspace = true }
|
||||
once_cell = { workspace = true }
|
||||
@@ -203,17 +213,17 @@ rustls = { version = "0.23", features = ["aws_lc_rs"], optional = true }
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
winapi = { workspace = true }
|
||||
keyring = { version = "3.6.2", features = ["windows-native"] }
|
||||
keyring = { version = "3.6.2", features = ["windows-native"], optional = true }
|
||||
|
||||
# Platform-specific GPU acceleration for Whisper and local inference
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
candle-core = { version = "0.10.2", default-features = false, features = ["metal"], optional = true }
|
||||
candle-nn = { version = "0.10.2", default-features = false, features = ["metal"], optional = true }
|
||||
llama-cpp-2 = { version = "0.1.145", features = ["sampler", "metal", "mtmd"], optional = true }
|
||||
keyring = { version = "3.6.2", features = ["apple-native"] }
|
||||
keyring = { version = "3.6.2", features = ["apple-native"], optional = true }
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
keyring = { version = "3.6.2", features = ["sync-secret-service"] }
|
||||
keyring = { version = "3.6.2", features = ["sync-secret-service"], optional = true }
|
||||
libc = "0.2.186"
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::config::paths::Paths;
|
||||
use crate::config::GooseMode;
|
||||
use fs2::FileExt;
|
||||
#[cfg(feature = "system-keyring")]
|
||||
use keyring::Entry;
|
||||
use once_cell::sync::OnceCell;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -34,7 +35,9 @@ fn write_secrets_file(path: &Path, content: &str) -> std::io::Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "system-keyring")]
|
||||
const KEYRING_SERVICE: &str = "goose";
|
||||
#[cfg(feature = "system-keyring")]
|
||||
const KEYRING_USERNAME: &str = "secrets";
|
||||
pub const CONFIG_YAML_NAME: &str = "config.yaml";
|
||||
|
||||
@@ -68,6 +71,7 @@ impl From<serde_yaml::Error> for ConfigError {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "system-keyring")]
|
||||
impl From<keyring::Error> for ConfigError {
|
||||
fn from(err: keyring::Error) -> Self {
|
||||
ConfigError::KeyringError(err.to_string())
|
||||
@@ -131,8 +135,13 @@ pub struct Config {
|
||||
}
|
||||
|
||||
enum SecretStorage {
|
||||
Keyring { service: String },
|
||||
File { path: PathBuf },
|
||||
#[cfg(feature = "system-keyring")]
|
||||
Keyring {
|
||||
service: String,
|
||||
},
|
||||
File {
|
||||
path: PathBuf,
|
||||
},
|
||||
}
|
||||
|
||||
// Global instance
|
||||
@@ -175,19 +184,11 @@ impl Default for Config {
|
||||
secrets_cache: Arc::new(Mutex::new(None)),
|
||||
};
|
||||
|
||||
let secrets = if env::var("GOOSE_DISABLE_KEYRING").is_ok()
|
||||
let keyring_disabled = env::var("GOOSE_DISABLE_KEYRING").is_ok()
|
||||
|| no_secrets_config
|
||||
.get_param::<serde_yaml::Value>("GOOSE_DISABLE_KEYRING")
|
||||
.is_ok_and(|v| keyring_disabled_value(&v))
|
||||
{
|
||||
SecretStorage::File {
|
||||
path: config_dir.join("secrets.yaml"),
|
||||
}
|
||||
} else {
|
||||
SecretStorage::Keyring {
|
||||
service: KEYRING_SERVICE.to_string(),
|
||||
}
|
||||
};
|
||||
.is_ok_and(|v| keyring_disabled_value(&v));
|
||||
let secrets = secret_storage(&config_dir, keyring_disabled, default_keyring_service());
|
||||
Self {
|
||||
config_paths,
|
||||
secrets,
|
||||
@@ -350,6 +351,40 @@ fn keyring_disabled_in_config(config_path: &Path) -> bool {
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[cfg(feature = "system-keyring")]
|
||||
fn default_keyring_service() -> &'static str {
|
||||
KEYRING_SERVICE
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "system-keyring"))]
|
||||
fn default_keyring_service() -> &'static str {
|
||||
""
|
||||
}
|
||||
|
||||
fn secrets_file_path_in(config_dir: &Path) -> PathBuf {
|
||||
config_dir.join("secrets.yaml")
|
||||
}
|
||||
|
||||
#[cfg(feature = "system-keyring")]
|
||||
fn secret_storage(config_dir: &Path, keyring_disabled: bool, service: &str) -> SecretStorage {
|
||||
if keyring_disabled {
|
||||
SecretStorage::File {
|
||||
path: secrets_file_path_in(config_dir),
|
||||
}
|
||||
} else {
|
||||
SecretStorage::Keyring {
|
||||
service: service.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "system-keyring"))]
|
||||
fn secret_storage(config_dir: &Path, _keyring_disabled: bool, _service: &str) -> SecretStorage {
|
||||
SecretStorage::File {
|
||||
path: secrets_file_path_in(config_dir),
|
||||
}
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// Get the global configuration instance.
|
||||
///
|
||||
@@ -365,21 +400,13 @@ impl Config {
|
||||
/// to manage multiple configuration files.
|
||||
pub fn new<P: AsRef<Path>>(config_path: P, service: &str) -> Result<Self, ConfigError> {
|
||||
let config_path = config_path.as_ref().to_path_buf();
|
||||
let secrets = if env::var("GOOSE_DISABLE_KEYRING").is_ok()
|
||||
|| keyring_disabled_in_config(&config_path)
|
||||
{
|
||||
let config_dir = config_path
|
||||
.parent()
|
||||
.map(Path::to_path_buf)
|
||||
.unwrap_or_else(Paths::config_dir);
|
||||
SecretStorage::File {
|
||||
path: config_dir.join("secrets.yaml"),
|
||||
}
|
||||
} else {
|
||||
SecretStorage::Keyring {
|
||||
service: service.to_string(),
|
||||
}
|
||||
};
|
||||
let keyring_disabled =
|
||||
env::var("GOOSE_DISABLE_KEYRING").is_ok() || keyring_disabled_in_config(&config_path);
|
||||
let config_dir = config_path
|
||||
.parent()
|
||||
.map(Path::to_path_buf)
|
||||
.unwrap_or_else(Paths::config_dir);
|
||||
let secrets = secret_storage(&config_dir, keyring_disabled, service);
|
||||
Ok(Config {
|
||||
config_paths: vec![config_path],
|
||||
secrets,
|
||||
@@ -598,6 +625,7 @@ impl Config {
|
||||
tracing::debug!("secrets cache miss, fetching from storage");
|
||||
|
||||
let loaded = match &self.secrets {
|
||||
#[cfg(feature = "system-keyring")]
|
||||
SecretStorage::Keyring { service } => {
|
||||
let result =
|
||||
self.handle_keyring_operation(|entry| entry.get_password(), service, None);
|
||||
@@ -857,6 +885,7 @@ impl Config {
|
||||
|
||||
fn write_all_secrets(&self, values: &HashMap<String, Value>) -> Result<(), ConfigError> {
|
||||
match &self.secrets {
|
||||
#[cfg(feature = "system-keyring")]
|
||||
SecretStorage::Keyring { service } => {
|
||||
let json_value = serde_json::to_string(values)?;
|
||||
match self.handle_keyring_operation(
|
||||
@@ -975,17 +1004,20 @@ impl Config {
|
||||
}
|
||||
|
||||
/// Get the path to the secrets storage file
|
||||
#[cfg(feature = "system-keyring")]
|
||||
fn secrets_file_path() -> PathBuf {
|
||||
Paths::config_dir().join("secrets.yaml")
|
||||
secrets_file_path_in(&Paths::config_dir())
|
||||
}
|
||||
|
||||
/// Fall back to file storage when keyring is unavailable
|
||||
#[cfg(feature = "system-keyring")]
|
||||
fn fallback_to_file_storage(&self) -> Result<HashMap<String, Value>, ConfigError> {
|
||||
let path = Self::secrets_file_path();
|
||||
self.read_secrets_from_file(&path)
|
||||
}
|
||||
|
||||
/// Write secrets to file storage (used for fallback)
|
||||
#[cfg(feature = "system-keyring")]
|
||||
fn write_secrets_to_file(&self, values: &HashMap<String, Value>) -> Result<(), ConfigError> {
|
||||
std::fs::create_dir_all(Paths::config_dir())?;
|
||||
let path = Self::secrets_file_path();
|
||||
@@ -1000,6 +1032,7 @@ impl Config {
|
||||
}
|
||||
|
||||
/// Check if an error string indicates a keyring availability issue that should trigger fallback
|
||||
#[cfg(feature = "system-keyring")]
|
||||
fn is_keyring_availability_error(&self, error_str: &str) -> bool {
|
||||
let lower = error_str.to_lowercase();
|
||||
lower.contains("keyring")
|
||||
@@ -1010,11 +1043,13 @@ impl Config {
|
||||
}
|
||||
|
||||
/// Get a keyring entry for the specified service
|
||||
#[cfg(feature = "system-keyring")]
|
||||
fn get_keyring_entry(service: &str) -> Result<keyring::Entry, keyring::Error> {
|
||||
Entry::new(service, KEYRING_USERNAME)
|
||||
}
|
||||
|
||||
/// Handle keyring errors with automatic fallback to file storage
|
||||
#[cfg(feature = "system-keyring")]
|
||||
fn handle_keyring_fallback_error<T>(
|
||||
&self,
|
||||
keyring_err: &keyring::Error,
|
||||
@@ -1036,6 +1071,7 @@ impl Config {
|
||||
}
|
||||
|
||||
/// Handle keyring operation with automatic fallback to file storage
|
||||
#[cfg(feature = "system-keyring")]
|
||||
fn handle_keyring_operation<T>(
|
||||
&self,
|
||||
operation: impl FnOnce(keyring::Entry) -> Result<T, keyring::Error>,
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
//!
|
||||
|
||||
use super::errors::ProviderError;
|
||||
#[cfg(feature = "local-inference")]
|
||||
use super::local_inference::LOCAL_LLM_MODEL_CONFIG_KEY;
|
||||
use super::ollama::OLLAMA_DEFAULT_PORT;
|
||||
use super::ollama::OLLAMA_HOST;
|
||||
@@ -52,6 +53,8 @@ use uuid::Uuid;
|
||||
pub const DEFAULT_INTERPRETER_MODEL_OLLAMA: &str = "mistral-nemo";
|
||||
pub const TOOLSHIM_BACKEND_ENV_VAR: &str = "GOOSE_TOOLSHIM_BACKEND";
|
||||
pub const TOOLSHIM_LOCAL_MODEL_ENV_VAR: &str = "GOOSE_TOOLSHIM_MODEL";
|
||||
#[cfg(not(feature = "local-inference"))]
|
||||
const LOCAL_LLM_MODEL_CONFIG_KEY: &str = "LOCAL_LLM_MODEL";
|
||||
|
||||
const TOOL_CALLS_SECTION_BEGIN: &str = "<|tool_calls_section_begin|>";
|
||||
const TOOL_CALLS_SECTION_END: &str = "<|tool_calls_section_end|>";
|
||||
|
||||
+28
-4
@@ -18,7 +18,7 @@ set -eu
|
||||
# GOOSE_VERSION - Optional: specific version to install (e.g., "v1.0.25"). Overrides CANARY. Can be in the format vX.Y.Z, vX.Y.Z-suffix, or X.Y.Z
|
||||
# GOOSE_PROVIDER - Optional: provider for goose
|
||||
# GOOSE_MODEL - Optional: model for goose
|
||||
# GOOSE_LINUX_VARIANT - Optional: Linux package variant to install (`standard` or `vulkan`)
|
||||
# GOOSE_LINUX_VARIANT - Optional: Linux package variant to install (`standard`, `vulkan`, or `musl`)
|
||||
# GOOSE_WINDOWS_VARIANT - Optional: Windows package variant to install (`standard` or `cuda`)
|
||||
# CANARY - Optional: if set to "true", downloads from canary release instead of stable
|
||||
# CONFIGURE - Optional: if set to "false", disables running goose configure interactively
|
||||
@@ -69,7 +69,7 @@ fi
|
||||
GOOSE_BIN_DIR="${GOOSE_BIN_DIR:-$DEFAULT_BIN_DIR}"
|
||||
RELEASE="${CANARY:-false}"
|
||||
CONFIGURE="${CONFIGURE:-true}"
|
||||
GOOSE_LINUX_VARIANT="${GOOSE_LINUX_VARIANT:-standard}"
|
||||
GOOSE_LINUX_VARIANT="${GOOSE_LINUX_VARIANT:-}"
|
||||
GOOSE_WINDOWS_VARIANT="${GOOSE_WINDOWS_VARIANT:-standard}"
|
||||
if [ -n "${GOOSE_VERSION:-}" ]; then
|
||||
# Validate the version format
|
||||
@@ -141,6 +141,28 @@ case "$ARCH" in
|
||||
;;
|
||||
esac
|
||||
|
||||
detect_linux_musl() {
|
||||
if [[ "$OSTYPE" == "linux-musl"* ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if command -v ldd >/dev/null 2>&1 && ldd --version 2>&1 | grep -qi musl; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
if [ "$OS" = "linux" ] && [ -z "$GOOSE_LINUX_VARIANT" ]; then
|
||||
if detect_linux_musl; then
|
||||
GOOSE_LINUX_VARIANT="musl"
|
||||
else
|
||||
GOOSE_LINUX_VARIANT="standard"
|
||||
fi
|
||||
elif [ -z "$GOOSE_LINUX_VARIANT" ]; then
|
||||
GOOSE_LINUX_VARIANT="standard"
|
||||
fi
|
||||
|
||||
# Debug output (safely handle undefined variables)
|
||||
echo "WINDIR: ${WINDIR:-<not set>}"
|
||||
echo "OSTYPE: $OSTYPE"
|
||||
@@ -176,15 +198,17 @@ elif [ "$OS" = "windows" ]; then
|
||||
OUT_FILE="goose.exe"
|
||||
else
|
||||
case "$GOOSE_LINUX_VARIANT" in
|
||||
standard|vulkan) ;;
|
||||
standard|vulkan|musl) ;;
|
||||
*)
|
||||
echo "Error: Unsupported GOOSE_LINUX_VARIANT '$GOOSE_LINUX_VARIANT'. Expected 'standard' or 'vulkan'."
|
||||
echo "Error: Unsupported GOOSE_LINUX_VARIANT '$GOOSE_LINUX_VARIANT'. Expected 'standard', 'vulkan', or 'musl'."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
FILE="goose-$ARCH-unknown-linux-gnu.tar.bz2"
|
||||
if [ "$GOOSE_LINUX_VARIANT" = "vulkan" ]; then
|
||||
FILE="goose-$ARCH-unknown-linux-gnu-vulkan.tar.bz2"
|
||||
elif [ "$GOOSE_LINUX_VARIANT" = "musl" ]; then
|
||||
FILE="goose-$ARCH-unknown-linux-musl.tar.bz2"
|
||||
fi
|
||||
EXTRACT_CMD="tar"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user