Implement update check functionality with version comparison and archive listing
- Added `check.rs` to handle package update checks, including logic for determining available updates from remote git repositories and archive listings. - Introduced `versions.rs` to manage version patterns, comparison logic, and extraction of candidate versions from git refs and archive listings. - Implemented `hex.rs` for encoding byte arrays to lowercase hexadecimal strings.
This commit is contained in:
@@ -134,6 +134,9 @@ pub fn build(
|
||||
let expanded = expand_configure_arg(spec, arg, &env_vars);
|
||||
configure_cmd.arg(expanded);
|
||||
}
|
||||
for arg in crate::builder::static_build_args_for(crate::package::BuildType::Autotools)? {
|
||||
configure_cmd.arg(arg);
|
||||
}
|
||||
|
||||
let status = crate::interrupts::command_status(&mut configure_cmd)
|
||||
.with_context(|| format!("Failed to run configure in {}", build_dir.display()))?;
|
||||
@@ -441,6 +444,9 @@ pub(crate) fn ensure_host_build(
|
||||
let expanded = expand_configure_arg(&host_spec, arg, &env_vars);
|
||||
configure_cmd.arg(expanded);
|
||||
}
|
||||
for arg in crate::builder::static_build_args_for(crate::package::BuildType::Autotools)? {
|
||||
configure_cmd.arg(arg);
|
||||
}
|
||||
|
||||
let status = crate::interrupts::command_status(&mut configure_cmd)
|
||||
.with_context(|| format!("Failed to run host configure in {}", build_dir.display()))?;
|
||||
|
||||
+151
-45
@@ -44,8 +44,7 @@ pub fn build(
|
||||
}
|
||||
|
||||
// Extract prefix from configure flags (cmake-style -DCMAKE_INSTALL_PREFIX=)
|
||||
let prefix = cmake_cache_entry_value(&flags.configure, "CMAKE_INSTALL_PREFIX")
|
||||
.unwrap_or(flags.prefix.as_str());
|
||||
let prefix = effective_cmake_install_prefix(flags);
|
||||
|
||||
// Generate toolchain file if cross-compiling
|
||||
let toolchain_file = if let Some(cc_cfg) = cross {
|
||||
@@ -68,7 +67,7 @@ pub fn build(
|
||||
cmake_cmd.arg("-B").arg(&build_dir);
|
||||
cmake_cmd.arg(format!("-DCMAKE_INSTALL_PREFIX={}", prefix));
|
||||
cmake_cmd.arg("-DCMAKE_BUILD_TYPE=Release");
|
||||
for arg in cmake_install_dir_args(flags) {
|
||||
for arg in cmake_install_dir_args(flags, prefix) {
|
||||
cmake_cmd.arg(arg);
|
||||
}
|
||||
for arg in cmake_lib32_target_args(flags, cross) {
|
||||
@@ -98,6 +97,9 @@ pub fn build(
|
||||
let expanded = expand_with_envs(flag, &env_vars);
|
||||
cmake_cmd.arg(&expanded);
|
||||
}
|
||||
for arg in crate::builder::static_build_args_for(crate::package::BuildType::CMake)? {
|
||||
cmake_cmd.arg(arg);
|
||||
}
|
||||
|
||||
crate::builder::prepare_tool_command(&mut cmake_cmd, &env_vars);
|
||||
|
||||
@@ -280,8 +282,7 @@ pub(crate) fn ensure_host_build(
|
||||
|
||||
let env_vars =
|
||||
crate::builder::standard_build_env(&host_spec, None, true, export_compiler_flags);
|
||||
let prefix = cmake_cache_entry_value(&flags.configure, "CMAKE_INSTALL_PREFIX")
|
||||
.unwrap_or(flags.prefix.as_str());
|
||||
let prefix = effective_cmake_install_prefix(flags);
|
||||
|
||||
let mut state = StateTracker::new_with_namespace(&actual_src, Some("host"))?;
|
||||
|
||||
@@ -296,7 +297,7 @@ pub(crate) fn ensure_host_build(
|
||||
cmake_cmd.arg("-B").arg(&build_dir);
|
||||
cmake_cmd.arg(format!("-DCMAKE_INSTALL_PREFIX={}", prefix));
|
||||
cmake_cmd.arg("-DCMAKE_BUILD_TYPE=Release");
|
||||
for arg in cmake_install_dir_args(flags) {
|
||||
for arg in cmake_install_dir_args(flags, prefix) {
|
||||
cmake_cmd.arg(arg);
|
||||
}
|
||||
|
||||
@@ -316,6 +317,9 @@ pub(crate) fn ensure_host_build(
|
||||
let expanded = expand_with_envs(flag, &env_vars);
|
||||
cmake_cmd.arg(&expanded);
|
||||
}
|
||||
for arg in crate::builder::static_build_args_for(crate::package::BuildType::CMake)? {
|
||||
cmake_cmd.arg(arg);
|
||||
}
|
||||
|
||||
crate::builder::prepare_tool_command(&mut cmake_cmd, &env_vars);
|
||||
|
||||
@@ -446,21 +450,72 @@ fn cmake_cache_entry_value<'a>(flags: &'a [String], variable: &str) -> Option<&'
|
||||
})
|
||||
}
|
||||
|
||||
fn cmake_install_dir_args(flags: &crate::package::BuildFlags) -> Vec<String> {
|
||||
fn effective_cmake_install_prefix(flags: &crate::package::BuildFlags) -> &str {
|
||||
cmake_cache_entry_value(&flags.configure, "CMAKE_INSTALL_PREFIX")
|
||||
.unwrap_or(flags.prefix.as_str())
|
||||
}
|
||||
|
||||
fn cmake_dir_value_for_prefix(prefix: &str, value: String) -> String {
|
||||
let prefix_path = Path::new(prefix);
|
||||
let value_path = Path::new(&value);
|
||||
|
||||
if prefix_path.is_absolute()
|
||||
&& value_path.is_absolute()
|
||||
&& let Ok(relative) = value_path.strip_prefix(prefix_path)
|
||||
{
|
||||
let relative = relative.to_string_lossy().replace('\\', "/");
|
||||
return if relative.is_empty() {
|
||||
".".to_string()
|
||||
} else {
|
||||
relative
|
||||
};
|
||||
}
|
||||
|
||||
value
|
||||
}
|
||||
|
||||
fn cmake_install_dir_args(flags: &crate::package::BuildFlags, prefix: &str) -> Vec<String> {
|
||||
let dirs = crate::builder::install_dirs(flags);
|
||||
let defaults = [
|
||||
("CMAKE_INSTALL_BINDIR", dirs.bindir),
|
||||
("CMAKE_INSTALL_SBINDIR", dirs.sbindir),
|
||||
("CMAKE_INSTALL_LIBDIR", dirs.libdir),
|
||||
("CMAKE_INSTALL_LIBEXECDIR", dirs.libexecdir),
|
||||
(
|
||||
"CMAKE_INSTALL_BINDIR",
|
||||
cmake_dir_value_for_prefix(prefix, dirs.bindir),
|
||||
),
|
||||
(
|
||||
"CMAKE_INSTALL_SBINDIR",
|
||||
cmake_dir_value_for_prefix(prefix, dirs.sbindir),
|
||||
),
|
||||
(
|
||||
"CMAKE_INSTALL_LIBDIR",
|
||||
cmake_dir_value_for_prefix(prefix, dirs.libdir),
|
||||
),
|
||||
(
|
||||
"CMAKE_INSTALL_LIBEXECDIR",
|
||||
cmake_dir_value_for_prefix(prefix, dirs.libexecdir),
|
||||
),
|
||||
("CMAKE_INSTALL_SYSCONFDIR", dirs.sysconfdir),
|
||||
("CMAKE_INSTALL_LOCALSTATEDIR", dirs.localstatedir),
|
||||
("CMAKE_INSTALL_SHAREDSTATEDIR", dirs.sharedstatedir),
|
||||
("CMAKE_INSTALL_INCLUDEDIR", dirs.includedir),
|
||||
("CMAKE_INSTALL_DATAROOTDIR", dirs.datarootdir),
|
||||
("CMAKE_INSTALL_DATADIR", dirs.datadir),
|
||||
("CMAKE_INSTALL_MANDIR", dirs.mandir),
|
||||
("CMAKE_INSTALL_INFODIR", dirs.infodir),
|
||||
(
|
||||
"CMAKE_INSTALL_INCLUDEDIR",
|
||||
cmake_dir_value_for_prefix(prefix, dirs.includedir),
|
||||
),
|
||||
(
|
||||
"CMAKE_INSTALL_DATAROOTDIR",
|
||||
cmake_dir_value_for_prefix(prefix, dirs.datarootdir),
|
||||
),
|
||||
(
|
||||
"CMAKE_INSTALL_DATADIR",
|
||||
cmake_dir_value_for_prefix(prefix, dirs.datadir),
|
||||
),
|
||||
(
|
||||
"CMAKE_INSTALL_MANDIR",
|
||||
cmake_dir_value_for_prefix(prefix, dirs.mandir),
|
||||
),
|
||||
(
|
||||
"CMAKE_INSTALL_INFODIR",
|
||||
cmake_dir_value_for_prefix(prefix, dirs.infodir),
|
||||
),
|
||||
];
|
||||
|
||||
defaults
|
||||
@@ -710,15 +765,41 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmake_install_dir_args_include_defaults() {
|
||||
let args = cmake_install_dir_args(&BuildFlags::default());
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_BINDIR=/usr/bin"));
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_SBINDIR=/usr/bin"));
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_LIBDIR=/usr/lib"));
|
||||
assert!(
|
||||
args.iter()
|
||||
.any(|a| a == "-DCMAKE_INSTALL_LIBEXECDIR=/usr/lib")
|
||||
fn test_effective_cmake_install_prefix_prefers_explicit_configure_flag() {
|
||||
let flags = BuildFlags {
|
||||
prefix: "/usr".into(),
|
||||
configure: vec!["-DCMAKE_INSTALL_PREFIX=/opt/soundtouch".into()],
|
||||
..BuildFlags::default()
|
||||
};
|
||||
|
||||
assert_eq!(effective_cmake_install_prefix(&flags), "/opt/soundtouch");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmake_dir_value_for_prefix_converts_prefix_owned_absolute_paths() {
|
||||
assert_eq!(cmake_dir_value_for_prefix("/usr", "/usr/lib".into()), "lib");
|
||||
assert_eq!(
|
||||
cmake_dir_value_for_prefix("/usr", "/usr/share/man".into()),
|
||||
"share/man"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmake_dir_value_for_prefix_keeps_non_prefix_absolute_paths() {
|
||||
assert_eq!(cmake_dir_value_for_prefix("/usr", "/etc".into()), "/etc");
|
||||
assert_eq!(
|
||||
cmake_dir_value_for_prefix("/opt/pkg", "/usr/bin".into()),
|
||||
"/usr/bin"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmake_install_dir_args_include_prefix_relative_defaults() {
|
||||
let args = cmake_install_dir_args(&BuildFlags::default(), "/usr");
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_BINDIR=bin"));
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_SBINDIR=bin"));
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_LIBDIR=lib"));
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_LIBEXECDIR=lib"));
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_SYSCONFDIR=/etc"));
|
||||
assert!(
|
||||
args.iter()
|
||||
@@ -730,23 +811,17 @@ mod tests {
|
||||
);
|
||||
assert!(
|
||||
args.iter()
|
||||
.any(|a| a == "-DCMAKE_INSTALL_INCLUDEDIR=/usr/include")
|
||||
.any(|a| a == "-DCMAKE_INSTALL_INCLUDEDIR=include")
|
||||
);
|
||||
assert!(
|
||||
args.iter()
|
||||
.any(|a| a == "-DCMAKE_INSTALL_DATAROOTDIR=/usr/share")
|
||||
.any(|a| a == "-DCMAKE_INSTALL_DATAROOTDIR=share")
|
||||
);
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_DATADIR=share"));
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_MANDIR=share/man"));
|
||||
assert!(
|
||||
args.iter()
|
||||
.any(|a| a == "-DCMAKE_INSTALL_DATADIR=/usr/share")
|
||||
);
|
||||
assert!(
|
||||
args.iter()
|
||||
.any(|a| a == "-DCMAKE_INSTALL_MANDIR=/usr/share/man")
|
||||
);
|
||||
assert!(
|
||||
args.iter()
|
||||
.any(|a| a == "-DCMAKE_INSTALL_INFODIR=/usr/share/info")
|
||||
.any(|a| a == "-DCMAKE_INSTALL_INFODIR=share/info")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -757,15 +832,9 @@ mod tests {
|
||||
..BuildFlags::default()
|
||||
};
|
||||
|
||||
let args = cmake_install_dir_args(&flags);
|
||||
assert!(
|
||||
args.iter()
|
||||
.any(|a| a == "-DCMAKE_INSTALL_LIBDIR=/usr/lib32")
|
||||
);
|
||||
assert!(
|
||||
args.iter()
|
||||
.any(|a| a == "-DCMAKE_INSTALL_LIBEXECDIR=/usr/lib32")
|
||||
);
|
||||
let args = cmake_install_dir_args(&flags, "/usr");
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_LIBDIR=lib32"));
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_LIBEXECDIR=lib32"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -832,7 +901,7 @@ mod tests {
|
||||
..BuildFlags::default()
|
||||
};
|
||||
|
||||
let args = cmake_install_dir_args(&flags);
|
||||
let args = cmake_install_dir_args(&flags, "/usr");
|
||||
assert!(
|
||||
!args
|
||||
.iter()
|
||||
@@ -848,7 +917,44 @@ mod tests {
|
||||
.iter()
|
||||
.any(|a| a.starts_with("-DCMAKE_INSTALL_DATADIR="))
|
||||
);
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_BINDIR=bin"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmake_install_dir_args_convert_custom_prefix_owned_dirs() {
|
||||
let flags = BuildFlags {
|
||||
prefix: "/opt/soundtouch".into(),
|
||||
bindir: "/opt/soundtouch/bin".into(),
|
||||
libdir: "/opt/soundtouch/lib64".into(),
|
||||
includedir: "/opt/soundtouch/include/soundtouch".into(),
|
||||
datadir: "/opt/soundtouch/share".into(),
|
||||
mandir: "/opt/soundtouch/share/man".into(),
|
||||
..BuildFlags::default()
|
||||
};
|
||||
|
||||
let args = cmake_install_dir_args(&flags, effective_cmake_install_prefix(&flags));
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_BINDIR=bin"));
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_LIBDIR=lib64"));
|
||||
assert!(
|
||||
args.iter()
|
||||
.any(|a| a == "-DCMAKE_INSTALL_INCLUDEDIR=include/soundtouch")
|
||||
);
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_DATADIR=share"));
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_MANDIR=share/man"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmake_install_dir_args_keep_absolute_dirs_outside_prefix() {
|
||||
let flags = BuildFlags {
|
||||
prefix: "/opt/soundtouch".into(),
|
||||
bindir: "/usr/bin".into(),
|
||||
sysconfdir: "/etc".into(),
|
||||
..BuildFlags::default()
|
||||
};
|
||||
|
||||
let args = cmake_install_dir_args(&flags, effective_cmake_install_prefix(&flags));
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_BINDIR=/usr/bin"));
|
||||
assert!(args.iter().any(|a| a == "-DCMAKE_INSTALL_SYSCONFDIR=/etc"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -65,6 +65,9 @@ pub fn build(
|
||||
for arg in meson_setup_args(flags, cross_file.as_deref(), &env_vars) {
|
||||
meson_cmd.arg(arg);
|
||||
}
|
||||
for arg in crate::builder::static_build_args_for(crate::package::BuildType::Meson)? {
|
||||
meson_cmd.arg(arg);
|
||||
}
|
||||
|
||||
crate::builder::prepare_tool_command(&mut meson_cmd, &env_vars);
|
||||
|
||||
@@ -229,6 +232,9 @@ pub(crate) fn ensure_host_build(
|
||||
for arg in meson_setup_args(flags, None, &env_vars) {
|
||||
meson_cmd.arg(arg);
|
||||
}
|
||||
for arg in crate::builder::static_build_args_for(crate::package::BuildType::Meson)? {
|
||||
meson_cmd.arg(arg);
|
||||
}
|
||||
|
||||
crate::builder::prepare_tool_command(&mut meson_cmd, &env_vars);
|
||||
|
||||
|
||||
@@ -184,6 +184,47 @@ pub(crate) fn host_build_spec(spec: &PackageSpec) -> PackageSpec {
|
||||
host_spec
|
||||
}
|
||||
|
||||
pub(crate) fn requested_static_build() -> Result<Option<bool>> {
|
||||
crate::build_options::requested_static_build()
|
||||
}
|
||||
|
||||
pub(crate) fn static_build_args_for(build_type: BuildType) -> Result<Vec<String>> {
|
||||
let Some(enabled) = requested_static_build()? else {
|
||||
return Ok(Vec::new());
|
||||
};
|
||||
|
||||
let args = match build_type {
|
||||
BuildType::Autotools => vec![if enabled {
|
||||
"--enable-static".to_string()
|
||||
} else {
|
||||
"--disable-static".to_string()
|
||||
}],
|
||||
BuildType::CMake => vec![format!(
|
||||
"-DBUILD_SHARED_LIBS={}",
|
||||
if enabled { "OFF" } else { "ON" }
|
||||
)],
|
||||
BuildType::Meson => vec![format!(
|
||||
"-Ddefault_library={}",
|
||||
if enabled { "static" } else { "shared" }
|
||||
)],
|
||||
BuildType::Perl => vec![format!(
|
||||
"LINKTYPE={}",
|
||||
if enabled { "static" } else { "dynamic" }
|
||||
)],
|
||||
_ => Vec::new(),
|
||||
};
|
||||
|
||||
Ok(args)
|
||||
}
|
||||
|
||||
pub(crate) fn build_tool_package_option(build_type: BuildType) -> Option<&'static str> {
|
||||
crate::build_options::build_tool_package_option(build_type)
|
||||
}
|
||||
|
||||
pub(crate) fn requested_build_tool_package(build_type: BuildType) -> Option<String> {
|
||||
crate::build_options::requested_build_tool_package(build_type)
|
||||
}
|
||||
|
||||
fn configured_install_dir(value: &str, default: &str) -> String {
|
||||
let trimmed = value.trim();
|
||||
if trimmed.is_empty() {
|
||||
@@ -889,6 +930,19 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_tool_package_option_maps_supported_builders() {
|
||||
assert_eq!(
|
||||
build_tool_package_option(BuildType::Meson),
|
||||
Some("DEPOT_MESON_PACKAGE")
|
||||
);
|
||||
assert_eq!(
|
||||
build_tool_package_option(BuildType::CMake),
|
||||
Some("DEPOT_CMAKE_PACKAGE")
|
||||
);
|
||||
assert_eq!(build_tool_package_option(BuildType::Bin), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_standard_build_env_exports_native_linker_and_cpp() {
|
||||
let mut spec = mk_spec(Vec::new(), Vec::new());
|
||||
|
||||
@@ -59,6 +59,9 @@ pub fn build(
|
||||
for arg in &flags.configure {
|
||||
configure_cmd.arg(spec.expand_vars(arg));
|
||||
}
|
||||
for arg in crate::builder::static_build_args_for(crate::package::BuildType::Perl)? {
|
||||
configure_cmd.arg(arg);
|
||||
}
|
||||
crate::builder::prepare_tool_command(&mut configure_cmd, &env_vars);
|
||||
|
||||
let status = command_status_with_sh_fallback(&mut configure_cmd).with_context(|| {
|
||||
|
||||
Reference in New Issue
Block a user