pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/AL-Rami/git-Al-Rami-ht/commit/65c10aa8d5000e0ecab34a9652056f0520fe51ed

gin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-9c8f61f9f58ad7b2.css" /> libgit: add higher-level libgit crate · AL-Rami/git-Al-Rami-ht@65c10aa · GitHub
Skip to content

Commit 65c10aa

Browse files
calvin-wan-googlesteadmon
authored andcommitted
libgit: add higher-level libgit crate
The C functions exported by libgit-sys do not provide an idiomatic Rust interface. To make it easier to use these functions via Rust, add a higher-level "libgit" crate, that wraps the lower-level configset API with an interface that is more Rust-y. This combination of $X and $X-sys crates is a common pattern for FFI in Rust, as documented in "The Cargo Book" [1]. [1] https://doc.rust-lang.org/cargo/reference/build-scripts.html#-sys-packages Co-authored-by: Josh Steadmon <steadmon@google.com> Signed-off-by: Josh Steadmon <steadmon@google.com> Signed-off-by: Calvin Wan <calvinwan@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent d76eb0d commit 65c10aa

13 files changed

Lines changed: 242 additions & 8 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,4 +250,5 @@ Release/
250250
/git.VC.db
251251
*.dSYM
252252
/contrib/buildsystems/out
253+
/contrib/libgit-rs/target
253254
/contrib/libgit-sys/target

Makefile

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ include shared.mak
417417
# programs in oss-fuzz/.
418418
#
419419
# Define INCLUDE_LIBGIT_RS if you want `make all` and `make test` to build and
420-
# test the Rust crate in contrib/libgit-sys.
420+
# test the Rust crates in contrib/libgit-sys and contrib/libgit-rs.
421421
#
422422
# === Optional library: libintl ===
423423
#
@@ -3742,7 +3742,7 @@ clean: profile-clean coverage-clean cocciclean
37423742
$(RM) $(htmldocs).tar.gz $(manpages).tar.gz
37433743
$(MAKE) -C Documentation/ clean
37443744
$(RM) Documentation/GIT-EXCLUDED-PROGRAMS
3745-
$(RM) -r contrib/libgit-sys/target
3745+
$(RM) -r contrib/libgit-sys/target contrib/libgit-rs/target
37463746
$(RM) contrib/libgit-sys/partial_symbol_export.o
37473747
$(RM) contrib/libgit-sys/hidden_symbol_export.o
37483748
$(RM) contrib/libgit-sys/libgitpub.a
@@ -3908,14 +3908,14 @@ build-unit-tests: $(UNIT_TEST_PROGS) $(CLAR_TEST_PROG)
39083908
unit-tests: $(UNIT_TEST_PROGS) $(CLAR_TEST_PROG) t/helper/test-tool$X
39093909
$(MAKE) -C t/ unit-tests
39103910

3911-
.PHONY: libgit-sys
3912-
libgit-sys:
3911+
.PHONY: libgit-sys libgit-rs
3912+
libgit-sys libgit-rs:
39133913
$(QUIET)(\
3914-
cd contrib/libgit-sys && \
3914+
cd contrib/$@ && \
39153915
cargo build \
39163916
)
39173917
ifdef INCLUDE_LIBGIT_RS
3918-
all:: libgit-sys
3918+
all:: libgit-sys libgit-rs
39193919
endif
39203920

39213921
LIBGIT_PUB_OBJS += contrib/libgit-sys/public_symbol_export.o

contrib/libgit-rs/Cargo.lock

Lines changed: 77 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contrib/libgit-rs/Cargo.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "libgit"
3+
version = "0.1.0"
4+
edition = "2021"
5+
build = "build.rs"
6+
rust-version = "1.63" # TODO: Once we hit 1.84 or newer, we may want to remove Cargo.lock from
7+
# version control. See https://lore.kernel.org/git/Z47jgK-oMjFRSslr@tapette.crustytoothpaste.net/
8+
9+
10+
[lib]
11+
path = "src/lib.rs"
12+
13+
[dependencies]
14+
libgit-sys = { version = "0.1.0", path = "../libgit-sys" }
15+
16+
[build-dependencies]
17+
autocfg = "1.4.0"

contrib/libgit-rs/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# libgit-rs
2+
3+
Proof-of-concept Git bindings for Rust.
4+
5+
```toml
6+
[dependencies]
7+
libgit = "0.1.0"
8+
```
9+
10+
## Rust version requirements
11+
12+
libgit-rs should support Rust versions at least as old as the version included
13+
in Debian stable (currently 1.63).

contrib/libgit-rs/build.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pub fn main() {
2+
let ac = autocfg::new();
3+
ac.emit_has_path("std::ffi::c_char");
4+
}

contrib/libgit-rs/src/config.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
use std::ffi::{c_void, CStr, CString};
2+
use std::path::Path;
3+
4+
#[cfg(has_std__ffi__c_char)]
5+
use std::ffi::{c_char, c_int};
6+
7+
#[cfg(not(has_std__ffi__c_char))]
8+
#[allow(non_camel_case_types)]
9+
type c_char = i8;
10+
11+
#[cfg(not(has_std__ffi__c_char))]
12+
#[allow(non_camel_case_types)]
13+
type c_int = i32;
14+
15+
use libgit_sys::*;
16+
17+
//github.com/ A ConfigSet is an in-memory cache for config-like files such as `.gitmodules` or `.gitconfig`.
18+
//github.com/ It does not support all config directives; notably, it will not process `include` or
19+
//github.com/ `includeIf` directives (but it will store them so that callers can choose whether and how to
20+
//github.com/ handle them).
21+
pub struct ConfigSet(*mut libgit_config_set);
22+
impl ConfigSet {
23+
//github.com/ Allocate a new ConfigSet
24+
pub fn new() -> Self {
25+
unsafe { ConfigSet(libgit_configset_alloc()) }
26+
}
27+
28+
//github.com/ Load the given files into the ConfigSet; conflicting directives in later files will
29+
//github.com/ override those given in earlier files.
30+
pub fn add_files(&mut self, files: &[&Path]) {
31+
for file in files {
32+
let pstr = file.to_str().expect("Invalid UTF-8");
33+
let rs = CString::new(pstr).expect("Couldn't convert to CString");
34+
unsafe {
35+
libgit_configset_add_file(self.0, rs.as_ptr());
36+
}
37+
}
38+
}
39+
40+
//github.com/ Load the value for the given key and attempt to parse it as an i32. Dies with a fatal error
41+
//github.com/ if the value cannot be parsed. Returns None if the key is not present.
42+
pub fn get_int(&mut self, key: &str) -> Option<i32> {
43+
let key = CString::new(key).expect("Couldn't convert to CString");
44+
let mut val: c_int = 0;
45+
unsafe {
46+
if libgit_configset_get_int(self.0, key.as_ptr(), &mut val as *mut c_int) != 0 {
47+
return None;
48+
}
49+
}
50+
51+
Some(val.into())
52+
}
53+
54+
//github.com/ Clones the value for the given key. Dies with a fatal error if the value cannot be
55+
//github.com/ converted to a String. Returns None if the key is not present.
56+
pub fn get_string(&mut self, key: &str) -> Option<String> {
57+
let key = CString::new(key).expect("Couldn't convert key to CString");
58+
let mut val: *mut c_char = std::ptr::null_mut();
59+
unsafe {
60+
if libgit_configset_get_string(self.0, key.as_ptr(), &mut val as *mut *mut c_char) != 0
61+
{
62+
return None;
63+
}
64+
let borrowed_str = CStr::from_ptr(val);
65+
let owned_str =
66+
String::from(borrowed_str.to_str().expect("Couldn't convert val to str"));
67+
free(val as *mut c_void); // Free the xstrdup()ed pointer from the C side
68+
Some(owned_str)
69+
}
70+
}
71+
}
72+
73+
impl Default for ConfigSet {
74+
fn default() -> Self {
75+
Self::new()
76+
}
77+
}
78+
79+
impl Drop for ConfigSet {
80+
fn drop(&mut self) {
81+
unsafe {
82+
libgit_configset_free(self.0);
83+
}
84+
}
85+
}
86+
87+
#[cfg(test)]
88+
mod tests {
89+
use super::*;
90+
91+
#[test]
92+
fn load_configs_via_configset() {
93+
let mut cs = ConfigSet::new();
94+
cs.add_files(&[
95+
Path::new("testdata/config1"),
96+
Path::new("testdata/config2"),
97+
Path::new("testdata/config3"),
98+
]);
99+
// ConfigSet retrieves correct value
100+
assert_eq!(cs.get_int("trace2.eventTarget"), Some(1));
101+
// ConfigSet respects last config value set
102+
assert_eq!(cs.get_int("trace2.eventNesting"), Some(3));
103+
// ConfigSet returns None for missing key
104+
assert_eq!(cs.get_string("foo.bar"), None);
105+
}
106+
}

contrib/libgit-rs/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod config;

contrib/libgit-rs/testdata/config1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[trace2]
2+
eventNesting = 1

contrib/libgit-rs/testdata/config2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[trace2]
2+
eventTarget = 1

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy