From: "ions via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Chris Torek <chris.torek@gmail.com>,
Phillip Wood <phillip.wood123@gmail.com>,
ions <zara.leonardo@gmail.com>
Subject: [PATCH v3 0/3] libgit-rs: add get_bool() method to ConfigSet
Date: Sat, 27 Sep 2025 03:51:48 +0000 [thread overview]
Message-ID: <pull.1977.v3.git.1758945111.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1977.v2.git.1758931659.gitgitgadget@gmail.com>
Purpose
This pull request introduces a get_bool() method to the ConfigSet module in
the libgit-rs library. The goal is to enhance the functionality of ConfigSet
by providing a way to fetch and handle boolean configuration values more
easily and consistently.
Implementation Details
• Added a get_bool() method to the ConfigSet module.
• The method retrieves configuration values as boolean values, ensuring
proper parsing and error handling.
• This addition simplifies the process of working with boolean
configurations for developers using the ConfigSet module.
Testing
• Added unit tests to verify the correctness of the get_bool() method.
• Tested edge cases to ensure robustness.
ionnss (3):
po: fix escaped underscores in README.md
libgit-rs: add get_bool() method to ConfigSet
libgit-rs: add get_ulong() and get_pathname() methods
contrib/libgit-rs/src/config.rs | 83 +++++++++++++++++++++++++++++-
contrib/libgit-rs/testdata/config3 | 2 +-
contrib/libgit-rs/testdata/config4 | 13 +++++
contrib/libgit-sys/src/lib.rs | 24 ++++++++-
po/README.md | 6 +--
5 files changed, 121 insertions(+), 7 deletions(-)
create mode 100644 contrib/libgit-rs/testdata/config4
base-commit: bb69721404348ea2db0a081c41ab6ebfe75bdec8
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1977%2Fionnss%2Fadd-rust-configset-get-bool-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1977/ionnss/add-rust-configset-get-bool-v3
Pull-Request: https://github.com/gitgitgadget/git/pull/1977
Range-diff vs v2:
1: d7810781fc = 1: d7810781fc po: fix escaped underscores in README.md
3: 43784e3ff9 ! 2: 479c263bc1 libgit-rs: address review feedback for get_bool()
@@ Metadata
Author: ionnss <zara.leonardo@gmail.com>
## Commit message ##
- libgit-rs: address review feedback for get_bool()
+ libgit-rs: add get_bool() method to ConfigSet
- - Use git_configset_get_bool() C function instead of reimplementing parsing
- - Fix libgit_configset_get_bool() function signature in bindings
- - Improve .expect() error messages to be more descriptive
- - Add comprehensive boolean tests including edge cases (00, 100, 007)
+ Add support for parsing boolean configuration values using Git's
+ git_configset_get_bool() C function. This ensures consistent behavior
+ with Git's native boolean parsing logic.
- This addresses feedback from Phillip Wood and Chris Torek about using
- Git's actual boolean parsing logic rather than duplicating it in Rust.
+ The method handles all Git boolean formats (true/false, yes/no, on/off,
+ 1/0) and edge cases like "00" and "100" correctly.
+
+ Includes comprehensive tests for various boolean formats and edge cases.
Signed-off-by: ionnss <zara.leonardo@gmail.com>
## contrib/libgit-rs/src/config.rs ##
@@ contrib/libgit-rs/src/config.rs: impl ConfigSet {
+ Some(owned_str)
}
}
-
++
+ /// Load the value for the given key and attempt to parse it as a boolean. Dies with a fatal error
+ /// if the value cannot be parsed. Returns None if the key is not present.
- pub fn get_bool(&mut self, key: &str) -> Option<bool> {
-- let key = CString::new(key).expect("Couldn't convert key to CString");
-- let mut val: *mut c_char = std::ptr::null_mut();
++ pub fn get_bool(&mut self, key: &str) -> Option<bool> {
+ let key = CString::new(key).expect("config key should be valid CString");
+ let mut val: c_int = 0;
- unsafe {
-- if libgit_configset_get_string(self.0, key.as_ptr(), &mut val as *mut *mut c_char) != 0
-- {
++ unsafe {
+ if libgit_configset_get_bool(self.0, key.as_ptr(), &mut val as *mut c_int) != 0 {
- return None;
- }
-- let borrowed_str = CStr::from_ptr(val);
-- let owned_str =
-- String::from(borrowed_str.to_str().expect("Couldn't convert val to str"));
-- free(val as *mut c_void); // Free the xstrdup()ed pointer from the C side
-- match owned_str.to_lowercase().as_str() {
-- "true" | "yes" | "on" | "1" => Some(true),
-- "false" | "no" | "off" | "0" => Some(false),
-- _ => None,
-- }
- }
++ return None;
++ }
++ }
+
+ Some(val != 0)
- }
++ }
}
+ impl Default for ConfigSet {
@@ contrib/libgit-rs/src/config.rs: mod tests {
Path::new("testdata/config1"),
Path::new("testdata/config2"),
@@ contrib/libgit-rs/src/config.rs: mod tests {
assert_eq!(cs.get_int("trace2.eventNesting"), Some(3));
// ConfigSet returns None for missing key
assert_eq!(cs.get_string("foo.bar"), None);
-- // Test boolean parsing
-- assert_eq!(cs.get_bool("test.booleanValue"), Some(true));
+ // Test boolean parsing - comprehensive tests
+ assert_eq!(cs.get_bool("test.boolTrue"), Some(true));
+ assert_eq!(cs.get_bool("test.boolFalse"), Some(false));
@@ contrib/libgit-rs/src/config.rs: mod tests {
+ assert_eq!(cs.get_bool("test.boolZero"), Some(false));
+ assert_eq!(cs.get_bool("test.boolZeroZero"), Some(false)); // "00" → false
+ assert_eq!(cs.get_bool("test.boolHundred"), Some(true)); // "100" → true
-+ assert_eq!(cs.get_bool("test.boolSeven"), Some(true)); // "007" → true
- // Test missing boolean key
- assert_eq!(cs.get_bool("missing.boolean"), None);
++ // Test missing boolean key
++ assert_eq!(cs.get_bool("missing.boolean"), None);
}
+ }
## contrib/libgit-rs/testdata/config3 ##
@@
[trace2]
- eventNesting = 3
--[test]
-- booleanValue = true
+ eventNesting = 3
\ No newline at end of file
@@ contrib/libgit-rs/testdata/config4 (new)
+ boolZero = 0
+ boolZeroZero = 00
+ boolHundred = 100
-+ boolSeven = 007
## contrib/libgit-sys/src/lib.rs ##
@@ contrib/libgit-sys/src/lib.rs: extern "C" {
2: a5904a2ac0 ! 3: 1ac8d76819 libgit-rs: add get_bool() method to ConfigSet
@@ Metadata
Author: ionnss <zara.leonardo@gmail.com>
## Commit message ##
- libgit-rs: add get_bool() method to ConfigSet
+ libgit-rs: add get_ulong() and get_pathname() methods
- Add support for parsing boolean configuration values in the Rust
- ConfigSet API. The method follows Git's standard boolean parsing
- rules, accepting true/yes/on/1 as true and false/no/off/0 as false.
+ Expand the ConfigSet API with additional configuration value types:
- The implementation reuses the existing get_string() infrastructure
- and adds case-insensitive boolean parsing logic.
+ - get_ulong(): Parse unsigned long integers for large numeric values
+ - get_pathname(): Parse file paths, returning PathBuf for type safety
+
+ Both functions follow the same pattern as existing get_* methods,
+ using Git's C functions for consistent parsing behavior.
+
+ Add comprehensive tests covering normal cases, edge cases, and
+ error handling for all new functionality.
Signed-off-by: ionnss <zara.leonardo@gmail.com>
## contrib/libgit-rs/src/config.rs ##
+@@
+ use std::ffi::{c_void, CStr, CString};
+-use std::path::Path;
++use std::path::{Path, PathBuf};
+
+ #[cfg(has_std__ffi__c_char)]
+-use std::ffi::{c_char, c_int};
++use std::ffi::{c_char, c_int, c_ulong};
+
+ #[cfg(not(has_std__ffi__c_char))]
+ #[allow(non_camel_case_types)]
+@@ contrib/libgit-rs/src/config.rs: type c_char = i8;
+ #[allow(non_camel_case_types)]
+ type c_int = i32;
+
++#[cfg(not(has_std__ffi__c_char))]
++#[allow(non_camel_case_types)]
++type c_ulong = u64;
++
+ use libgit_sys::*;
+
+ /// A ConfigSet is an in-memory cache for config-like files such as `.gitmodules` or `.gitconfig`.
@@ contrib/libgit-rs/src/config.rs: impl ConfigSet {
- Some(owned_str)
- }
+
+ Some(val != 0)
}
+
-+ pub fn get_bool(&mut self, key: &str) -> Option<bool> {
-+ let key = CString::new(key).expect("Couldn't convert key to CString");
++ /// Load the value for the given key and attempt to parse it as an unsigned long. Dies with a fatal error
++ /// if the value cannot be parsed. Returns None if the key is not present.
++ pub fn get_ulong(&mut self, key: &str) -> Option<u64> {
++ let key = CString::new(key).expect("config key should be valid CString");
++ let mut val: c_ulong = 0;
++ unsafe {
++ if libgit_configset_get_ulong(self.0, key.as_ptr(), &mut val as *mut c_ulong) != 0 {
++ return None;
++ }
++ }
++ Some(val as u64)
++ }
++
++ /// Load the value for the given key and attempt to parse it as a file path. Dies with a fatal error
++ /// if the value cannot be converted to a PathBuf. Returns None if the key is not present.
++ pub fn get_pathname(&mut self, key: &str) -> Option<PathBuf> {
++ let key = CString::new(key).expect("config key should be valid CString");
+ let mut val: *mut c_char = std::ptr::null_mut();
+ unsafe {
-+ if libgit_configset_get_string(self.0, key.as_ptr(), &mut val as *mut *mut c_char) != 0
++ if libgit_configset_get_pathname(self.0, key.as_ptr(), &mut val as *mut *mut c_char)
++ != 0
+ {
+ return None;
+ }
+ let borrowed_str = CStr::from_ptr(val);
-+ let owned_str =
-+ String::from(borrowed_str.to_str().expect("Couldn't convert val to str"));
++ let owned_str = String::from(
++ borrowed_str
++ .to_str()
++ .expect("config path should be valid UTF-8"),
++ );
+ free(val as *mut c_void); // Free the xstrdup()ed pointer from the C side
-+ match owned_str.to_lowercase().as_str() {
-+ "true" | "yes" | "on" | "1" => Some(true),
-+ "false" | "no" | "off" | "0" => Some(false),
-+ _ => None,
-+ }
++ Some(PathBuf::from(owned_str))
+ }
+ }
}
impl Default for ConfigSet {
@@ contrib/libgit-rs/src/config.rs: mod tests {
- assert_eq!(cs.get_int("trace2.eventNesting"), Some(3));
- // ConfigSet returns None for missing key
- assert_eq!(cs.get_string("foo.bar"), None);
-+ // Test boolean parsing
-+ assert_eq!(cs.get_bool("test.booleanValue"), Some(true));
-+ // Test missing boolean key
-+ assert_eq!(cs.get_bool("missing.boolean"), None);
+ assert_eq!(cs.get_bool("test.boolHundred"), Some(true)); // "100" → true
+ // Test missing boolean key
+ assert_eq!(cs.get_bool("missing.boolean"), None);
++ // Test ulong parsing
++ assert_eq!(cs.get_ulong("test.ulongSmall"), Some(42));
++ assert_eq!(cs.get_ulong("test.ulongBig"), Some(4294967296)); // > 32-bit int
++ assert_eq!(cs.get_ulong("missing.ulong"), None);
++ // Test pathname parsing
++ assert_eq!(
++ cs.get_pathname("test.pathRelative"),
++ Some(PathBuf::from("./some/path"))
++ );
++ assert_eq!(
++ cs.get_pathname("test.pathAbsolute"),
++ Some(PathBuf::from("/usr/bin/git"))
++ );
++ assert_eq!(cs.get_pathname("missing.path"), None);
}
}
- ## contrib/libgit-rs/testdata/config3 ##
+ ## contrib/libgit-rs/testdata/config4 ##
+@@
+ boolZero = 0
+ boolZeroZero = 00
+ boolHundred = 100
++ ulongSmall = 42
++ ulongBig = 4294967296
++ pathRelative = ./some/path
++ pathAbsolute = /usr/bin/git
+
+ ## contrib/libgit-sys/src/lib.rs ##
@@
- [trace2]
- eventNesting = 3
-+[test]
-+ booleanValue = true
+ use std::ffi::c_void;
+
+ #[cfg(has_std__ffi__c_char)]
+-use std::ffi::{c_char, c_int};
++use std::ffi::{c_char, c_int, c_ulong};
+
+ #[cfg(not(has_std__ffi__c_char))]
+ #[allow(non_camel_case_types)]
+@@ contrib/libgit-sys/src/lib.rs: pub type c_char = i8;
+ #[allow(non_camel_case_types)]
+ pub type c_int = i32;
+
++#[cfg(not(has_std__ffi__c_char))]
++#[allow(non_camel_case_types)]
++pub type c_ulong = u64;
++
+ extern crate libz_sys;
+
+ #[allow(non_camel_case_types)]
+@@ contrib/libgit-sys/src/lib.rs: extern "C" {
+ dest: *mut c_int,
+ ) -> c_int;
+
++ pub fn libgit_configset_get_ulong(
++ cs: *mut libgit_config_set,
++ key: *const c_char,
++ dest: *mut c_ulong,
++ ) -> c_int;
++
++ pub fn libgit_configset_get_pathname(
++ cs: *mut libgit_config_set,
++ key: *const c_char,
++ dest: *mut *mut c_char,
++ ) -> c_int;
++
+ }
+
+ #[cfg(test)]
--
gitgitgadget
next prev parent reply other threads:[~2025-09-27 3:51 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-25 11:44 [PATCH 0/2] libgit-rs: add get_bool() method to ConfigSet ions via GitGitGadget
2025-09-25 11:44 ` [PATCH 1/2] po: fix escaped underscores in README.md ionnss via GitGitGadget
2025-09-25 11:44 ` [PATCH 2/2] libgit-rs: add get_bool() method to ConfigSet ionnss via GitGitGadget
2025-09-26 6:43 ` Chris Torek
2025-09-26 9:58 ` Phillip Wood
2025-09-26 17:15 ` Junio C Hamano
2025-09-27 0:07 ` [PATCH v2 0/3] " ions via GitGitGadget
2025-09-27 0:07 ` [PATCH v2 1/3] po: fix escaped underscores in README.md ionnss via GitGitGadget
2025-09-27 0:07 ` [PATCH v2 2/3] libgit-rs: add get_bool() method to ConfigSet ionnss via GitGitGadget
2025-09-27 0:07 ` [PATCH v2 3/3] libgit-rs: address review feedback for get_bool() ionnss via GitGitGadget
2025-09-27 2:01 ` [PATCH v2 0/3] libgit-rs: add get_bool() method to ConfigSet Junio C Hamano
2025-09-27 3:51 ` ions via GitGitGadget [this message]
2025-09-27 3:51 ` [PATCH v3 1/3] po: fix escaped underscores in README.md ionnss via GitGitGadget
2025-09-29 13:26 ` Phillip Wood
2025-09-27 3:51 ` [PATCH v3 2/3] libgit-rs: add get_bool() method to ConfigSet ionnss via GitGitGadget
2025-09-29 13:23 ` Phillip Wood
2025-09-27 3:51 ` [PATCH v3 3/3] libgit-rs: add get_ulong() and get_pathname() methods ionnss via GitGitGadget
2025-09-29 13:23 ` Phillip Wood
2025-09-30 8:46 ` [PATCH v4] libgit-rs: add get_bool(), get_ulong(), " ions via GitGitGadget
2025-10-01 10:15 ` Phillip Wood
2025-10-06 21:20 ` brian m. carlson
2025-10-08 13:36 ` Phillip Wood
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pull.1977.v3.git.1758945111.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=chris.torek@gmail.com \
--cc=git@vger.kernel.org \
--cc=phillip.wood123@gmail.com \
--cc=zara.leonardo@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).