Skip to content

Commit 20e188f

Browse files
committed
Merge branch 'config-output'
2 parents 0700b09 + 0a7391a commit 20e188f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1810
-1106
lines changed

Diff for: Makefile

+9-14
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,6 @@ help: ## Display this help
44

55
always:
66

7-
##@ Publishing & Versioning
8-
9-
try-publish-all: ## Dry-run publish all crates in the currently set version if they are not published yet.
10-
(cd cargo-smart-release && cargo build --bin cargo-smart-release) && cargo-smart-release/target/debug/cargo-smart-release smart-release gitoxide
11-
12-
try-bump-minor-version: ## Show how updating the minor version of PACKAGE=<name> would look like.
13-
(cd cargo-smart-release && cargo build --bin cargo-smart-release) && cargo-smart-release/target/debug/cargo-smart-release smart-release --update-crates-index --bump minor --no-dependencies --no-publish --no-tag --no-push -v $(PACKAGE)
14-
15-
bump-minor-version: ## Similar to try-bump-minor-version, but actually performs the operation on PACKAGE=<name>
16-
(cd cargo-smart-release && cargo build --bin cargo-smart-release) && cargo-smart-release/target/debug/cargo-smart-release smart-release --update-crates-index --bump minor --no-dependencies --skip-publish --skip-tag --skip-push -v $(PACKAGE) --execute
17-
187
##@ Release Builds
198

209
release-all: release release-lean release-small ## all release builds
@@ -67,9 +56,6 @@ clippy: ## Run cargo clippy on all crates
6756
check-msrv: ## run cargo msrv to validate the current msrv requirements, similar to what CI does
6857
cd git-repository && cargo check --package git-repository --no-default-features --features async-network-client,unstable,local-time-support,max-performance
6958

70-
check-win: ## see that windows compiles, provided the x86_64-pc-windows-msvc target and cargo-xwin are present.
71-
cargo xwin build --target x86_64-pc-windows-msvc --no-default-features --features small
72-
7359
check: ## Build all code in suitable configurations
7460
cargo check --all
7561
cargo check --no-default-features --features small
@@ -169,6 +155,9 @@ unit-tests: ## run all unit tests
169155
&& cargo test
170156
cd gitoxide-core && cargo test --lib
171157

158+
nextest: ## run tests with `cargo nextest` (all unit-tests, no doc-tests, faster)
159+
cargo nextest run --all
160+
172161
continuous-unit-tests: ## run all unit tests whenever something changes
173162
watchexec -w src $(MAKE) unit-tests
174163

@@ -323,3 +312,9 @@ check-size: ## Run cargo-diet on all crates to see that they are still in bound
323312
fmt: ## run nightly rustfmt for its extra features, but check that it won't upset stable rustfmt
324313
cargo +nightly fmt --all -- --config-path rustfmt-nightly.toml
325314
cargo +stable fmt --all -- --check
315+
316+
##@ Publishing & Versioning
317+
318+
try-publish-all: ## Dry-run publish all crates in the currently set version if they are not published yet.
319+
(cd cargo-smart-release && cargo build --bin cargo-smart-release) && cargo-smart-release/target/debug/cargo-smart-release smart-release gitoxide
320+

Diff for: git-config/src/file/access/low_level/mod.rs

-2
This file was deleted.

Diff for: git-config/src/file/access/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
mod comfort;
2-
mod low_level;
2+
mod mutate;
33
mod raw;
4+
mod read_only;
5+
mod write;

Diff for: git-config/src/file/access/low_level/mutating.rs renamed to git-config/src/file/access/mutate.rs

+15-31
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::borrow::Cow;
22

3-
use bstr::BStr;
4-
3+
use crate::file::rename_section;
54
use crate::{
65
file::{MutableSection, SectionBody},
76
lookup,
@@ -51,21 +50,23 @@ impl<'event> File<'event> {
5150
/// # use git_config::File;
5251
/// # use std::convert::TryFrom;
5352
/// # use bstr::ByteSlice;
53+
/// # use git_config::parse::section;
5454
/// let mut git_config = git_config::File::default();
55-
/// let mut section = git_config.new_section("hello", Some("world".into()));
56-
/// section.push("a".into(), b"b".as_bstr().into());
57-
/// assert_eq!(git_config.to_string(), "[hello \"world\"]\n a=b\n");
55+
/// let mut section = git_config.new_section("hello", Some("world".into()))?;
56+
/// section.push(section::Key::try_from("a")?, b"b".as_bstr().into());
57+
/// assert_eq!(git_config.to_string(), "[hello \"world\"]\n\ta = b\n");
5858
/// let _section = git_config.new_section("core", None);
59-
/// assert_eq!(git_config.to_string(), "[hello \"world\"]\n a=b\n[core]\n");
59+
/// assert_eq!(git_config.to_string(), "[hello \"world\"]\n\ta = b\n[core]\n");
60+
/// # Ok::<(), Box<dyn std::error::Error>>(())
6061
/// ```
6162
pub fn new_section(
6263
&mut self,
6364
section_name: impl Into<Cow<'event, str>>,
6465
subsection_name: impl Into<Option<Cow<'event, str>>>,
65-
) -> MutableSection<'_, 'event> {
66-
let mut section = self.push_section(section_name, subsection_name, SectionBody::default());
66+
) -> Result<MutableSection<'_, 'event>, section::header::Error> {
67+
let mut section = self.push_section(section_name, subsection_name, SectionBody::default())?;
6768
section.push_newline();
68-
section
69+
Ok(section)
6970
}
7071

7172
/// Removes the section, returning the events it had, if any. If multiple
@@ -131,42 +132,25 @@ impl<'event> File<'event> {
131132
section_name: impl Into<Cow<'event, str>>,
132133
subsection_name: impl Into<Option<Cow<'event, str>>>,
133134
section: SectionBody<'event>,
134-
) -> MutableSection<'_, 'event> {
135-
let subsection_name = subsection_name.into().map(into_cow_bstr);
136-
self.push_section_internal(
137-
section::Header {
138-
name: section::Name(into_cow_bstr(section_name.into())),
139-
separator: subsection_name.is_some().then(|| Cow::Borrowed(" ".into())),
140-
subsection_name,
141-
},
142-
section,
143-
)
135+
) -> Result<MutableSection<'_, 'event>, section::header::Error> {
136+
Ok(self.push_section_internal(section::Header::new(section_name, subsection_name)?, section))
144137
}
145138

146139
/// Renames a section, modifying the last matching section.
147140
pub fn rename_section<'a>(
148141
&mut self,
149142
section_name: &str,
150143
subsection_name: impl Into<Option<&'a str>>,
151-
new_section_name: impl Into<section::Name<'event>>,
144+
new_section_name: impl Into<Cow<'event, str>>,
152145
new_subsection_name: impl Into<Option<Cow<'event, str>>>,
153-
) -> Result<(), lookup::existing::Error> {
146+
) -> Result<(), rename_section::Error> {
154147
let id = self
155148
.section_ids_by_name_and_subname(section_name, subsection_name.into())?
156149
.rev()
157150
.next()
158151
.expect("list of sections were empty, which violates invariant");
159152
let header = self.section_headers.get_mut(&id).expect("known section-id");
160-
header.name = new_section_name.into();
161-
header.subsection_name = new_subsection_name.into().map(into_cow_bstr);
162-
153+
*header = section::Header::new(new_section_name, new_subsection_name)?;
163154
Ok(())
164155
}
165156
}
166-
167-
fn into_cow_bstr(c: Cow<'_, str>) -> Cow<'_, BStr> {
168-
match c {
169-
Cow::Borrowed(s) => Cow::Borrowed(s.into()),
170-
Cow::Owned(s) => Cow::Owned(s.into()),
171-
}
172-
}

Diff for: git-config/src/file/access/raw.rs

+26-29
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use std::{borrow::Cow, collections::HashMap};
22

3-
use bstr::{BStr, BString};
3+
use bstr::BStr;
44

5+
use crate::file::mutable::value::EntryData;
56
use crate::{
6-
file::{value::EntryData, Index, MutableMultiValue, MutableSection, MutableValue, Size},
7+
file::{Index, MutableMultiValue, MutableSection, MutableValue, Size},
78
lookup,
89
parse::{section, Event},
910
File,
@@ -24,10 +25,9 @@ impl<'event> File<'event> {
2425
subsection_name: Option<&str>,
2526
key: &str,
2627
) -> Result<Cow<'_, BStr>, lookup::existing::Error> {
27-
let key = section::Key(Cow::<BStr>::Borrowed(key.into()));
2828
let section_ids = self.section_ids_by_name_and_subname(section_name, subsection_name)?;
2929
for section_id in section_ids.rev() {
30-
if let Some(v) = self.sections.get(&section_id).expect("known section id").value(&key) {
30+
if let Some(v) = self.sections.get(&section_id).expect("known section id").value(key) {
3131
return Ok(v);
3232
}
3333
}
@@ -52,23 +52,22 @@ impl<'event> File<'event> {
5252
let key = section::Key(Cow::<BStr>::Borrowed(key.into()));
5353

5454
while let Some(section_id) = section_ids.next() {
55-
let mut size = 0;
5655
let mut index = 0;
56+
let mut size = 0;
5757
let mut found_key = false;
5858
for (i, event) in self
5959
.sections
6060
.get(&section_id)
61-
.expect("sections does not have section id from section ids")
61+
.expect("known section id")
6262
.as_ref()
63-
// todo: iter backwards
6463
.iter()
6564
.enumerate()
6665
{
6766
match event {
6867
Event::SectionKey(event_key) if *event_key == key => {
6968
found_key = true;
70-
size = 1;
7169
index = i;
70+
size = 1;
7271
}
7372
Event::Newline(_) | Event::Whitespace(_) | Event::ValueNotDone(_) if found_key => {
7473
size += 1;
@@ -77,7 +76,10 @@ impl<'event> File<'event> {
7776
found_key = false;
7877
size += 1;
7978
}
80-
_ => (),
79+
Event::KeyValueSeparator if found_key => {
80+
size += 1;
81+
}
82+
_ => {}
8183
}
8284
}
8385

@@ -141,12 +143,7 @@ impl<'event> File<'event> {
141143
let mut values = Vec::new();
142144
let section_ids = self.section_ids_by_name_and_subname(section_name, subsection_name)?;
143145
for section_id in section_ids {
144-
values.extend(
145-
self.sections
146-
.get(&section_id)
147-
.expect("known section id")
148-
.values(&section::Key(Cow::<BStr>::Borrowed(key.into()))),
149-
);
146+
values.extend(self.sections.get(&section_id).expect("known section id").values(key));
150147
}
151148

152149
if values.is_empty() {
@@ -188,7 +185,7 @@ impl<'event> File<'event> {
188185
/// ]
189186
/// );
190187
///
191-
/// git_config.raw_values_mut("core", None, "a")?.set_str_all("g");
188+
/// git_config.raw_values_mut("core", None, "a")?.set_all("g");
192189
///
193190
/// assert_eq!(
194191
/// git_config.raw_values("core", None, "a")?,
@@ -306,10 +303,10 @@ impl<'event> File<'event> {
306303
section_name: &str,
307304
subsection_name: Option<&str>,
308305
key: &str,
309-
new_value: BString,
306+
new_value: &BStr,
310307
) -> Result<(), lookup::existing::Error> {
311308
self.raw_value_mut(section_name, subsection_name, key)
312-
.map(|mut entry| entry.set_bytes(new_value))
309+
.map(|mut entry| entry.set(new_value))
313310
}
314311

315312
/// Sets a multivar in a given section, optional subsection, and key value.
@@ -347,9 +344,9 @@ impl<'event> File<'event> {
347344
/// # use bstr::BStr;
348345
/// # let mut git_config = git_config::File::try_from("[core]a=b\n[core]\na=c\na=d").unwrap();
349346
/// let new_values = vec![
350-
/// Cow::<BStr>::Borrowed("x".into()),
351-
/// Cow::<BStr>::Borrowed("y".into()),
352-
/// Cow::<BStr>::Borrowed("z".into()),
347+
/// "x".into(),
348+
/// "y".into(),
349+
/// "z".into(),
353350
/// ];
354351
/// git_config.set_raw_multi_value("core", None, "a", new_values.into_iter())?;
355352
/// let fetched_config = git_config.raw_values("core", None, "a")?;
@@ -368,8 +365,8 @@ impl<'event> File<'event> {
368365
/// # use bstr::BStr;
369366
/// # let mut git_config = git_config::File::try_from("[core]a=b\n[core]\na=c\na=d").unwrap();
370367
/// let new_values = vec![
371-
/// Cow::<BStr>::Borrowed("x".into()),
372-
/// Cow::<BStr>::Borrowed("y".into()),
368+
/// "x".into(),
369+
/// "y".into(),
373370
/// ];
374371
/// git_config.set_raw_multi_value("core", None, "a", new_values.into_iter())?;
375372
/// let fetched_config = git_config.raw_values("core", None, "a")?;
@@ -387,21 +384,21 @@ impl<'event> File<'event> {
387384
/// # use bstr::BStr;
388385
/// # let mut git_config = git_config::File::try_from("[core]a=b\n[core]\na=c\na=d").unwrap();
389386
/// let new_values = vec![
390-
/// Cow::<BStr>::Borrowed("x".into()),
391-
/// Cow::<BStr>::Borrowed("y".into()),
392-
/// Cow::<BStr>::Borrowed("z".into()),
393-
/// Cow::<BStr>::Borrowed("discarded".into()),
387+
/// "x".into(),
388+
/// "y".into(),
389+
/// "z".into(),
390+
/// "discarded".into(),
394391
/// ];
395392
/// git_config.set_raw_multi_value("core", None, "a", new_values)?;
396393
/// assert!(!git_config.raw_values("core", None, "a")?.contains(&Cow::<BStr>::Borrowed("discarded".into())));
397394
/// # Ok::<(), git_config::lookup::existing::Error>(())
398395
/// ```
399-
pub fn set_raw_multi_value(
396+
pub fn set_raw_multi_value<'a>(
400397
&mut self,
401398
section_name: &str,
402399
subsection_name: Option<&str>,
403400
key: &str,
404-
new_values: impl IntoIterator<Item = Cow<'event, BStr>>,
401+
new_values: impl IntoIterator<Item = &'a BStr>,
405402
) -> Result<(), lookup::existing::Error> {
406403
self.raw_values_mut(section_name, subsection_name, key)
407404
.map(|mut v| v.set_values(new_values))

Diff for: git-config/src/file/access/low_level/read_only.rs renamed to git-config/src/file/access/read_only.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -215,15 +215,15 @@ impl<'event> File<'event> {
215215
/// assert_eq!(url.map_or(0, |s| s.count()), 2);
216216
///
217217
/// for (i, (header, body)) in config.sections_by_name_with_header("url").unwrap().enumerate() {
218-
/// let url = header.subsection_name.as_ref();
219-
/// let instead_of = body.value(&section::Key::from("insteadOf"));
218+
/// let url = header.subsection_name().unwrap();
219+
/// let instead_of = body.value("insteadOf").unwrap();
220220
///
221221
/// if i == 0 {
222-
/// assert_eq!(instead_of.unwrap().as_ref(), "https://github.com/");
223-
/// assert_eq!(url.unwrap().as_ref(), "ssh://[email protected]/");
222+
/// assert_eq!(instead_of.as_ref(), "https://github.com/");
223+
/// assert_eq!(url, "ssh://[email protected]/");
224224
/// } else {
225-
/// assert_eq!(instead_of.unwrap().as_ref(), "https://bitbucket.org/");
226-
/// assert_eq!(url.unwrap().as_ref(), "ssh://[email protected]");
225+
/// assert_eq!(instead_of.as_ref(), "https://bitbucket.org/");
226+
/// assert_eq!(url, "ssh://[email protected]");
227227
/// }
228228
/// }
229229
/// # Ok::<(), Box<dyn std::error::Error>>(())

Diff for: git-config/src/file/access/write.rs

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use crate::File;
2+
use bstr::BString;
3+
4+
impl File<'_> {
5+
/// Serialize this type into a `BString` for convenience.
6+
///
7+
/// Note that `to_string()` can also be used, but might not be lossless.
8+
#[must_use]
9+
pub fn to_bstring(&self) -> BString {
10+
let mut buf = Vec::new();
11+
self.write_to(&mut buf).expect("io error impossible");
12+
buf.into()
13+
}
14+
15+
/// Stream ourselves to the given `out`, in order to reproduce this file mostly losslessly
16+
/// as it was parsed.
17+
pub fn write_to(&self, mut out: impl std::io::Write) -> std::io::Result<()> {
18+
for event in self.frontmatter_events.as_ref() {
19+
event.write_to(&mut out)?;
20+
}
21+
22+
for section_id in &self.section_order {
23+
self.section_headers
24+
.get(section_id)
25+
.expect("known section-id")
26+
.write_to(&mut out)?;
27+
28+
for event in self.sections.get(section_id).expect("known section-id").as_ref() {
29+
event.write_to(&mut out)?;
30+
}
31+
}
32+
33+
Ok(())
34+
}
35+
}

0 commit comments

Comments
 (0)