Skip to content

Commit 1ca480a

Browse files
authored
Merge pull request #1752 from GitoxideLabs/git-shell
git login shell
2 parents 8d84818 + 3aff1e5 commit 1ca480a

File tree

30 files changed

+141
-114
lines changed

30 files changed

+141
-114
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ jobs:
318318

319319
strategy:
320320
matrix:
321-
target: [ wasm32-unknown-unknown, wasm32-wasi ]
321+
target: [ wasm32-unknown-unknown, wasm32-wasip1 ]
322322

323323
env:
324324
TARGET: ${{ matrix.target }}

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -394,3 +394,4 @@ stable_sort_primitive = "allow" # x1
394394
no_effect_underscore_binding = "allow" # x1
395395
empty_docs = "allow"
396396
too_long_first_doc_paragraph = "allow"
397+
large_stack_arrays = "allow"

gitoxide-core/src/repository/attributes/query.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ pub(crate) mod function {
8989
let entry = cache.at_entry(
9090
path,
9191
Some(is_dir_to_mode(
92-
workdir.map_or(false, |wd| wd.join(gix::path::from_bstr(path)).is_dir())
92+
workdir.is_some_and(|wd| wd.join(gix::path::from_bstr(path)).is_dir())
9393
|| pattern.signature.contains(gix::pathspec::MagicSignature::MUST_BE_DIR),
9494
)),
9595
)?;

gitoxide-core/src/repository/clean.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,10 @@ pub(crate) mod function {
128128
let pathspec_includes_entry = match pathspec.as_mut() {
129129
None => entry
130130
.pathspec_match
131-
.map_or(false, |m| m != gix::dir::entry::PathspecMatch::Excluded),
131+
.is_some_and(|m| m != gix::dir::entry::PathspecMatch::Excluded),
132132
Some(pathspec) => pathspec
133133
.pattern_matching_relative_path(entry.rela_path.as_bstr(), entry.disk_kind.map(|k| k.is_dir()))
134-
.map_or(false, |m| !m.is_excluded()),
134+
.is_some_and(|m| !m.is_excluded()),
135135
};
136136
pruned_entries += usize::from(!pathspec_includes_entry);
137137
if !pathspec_includes_entry && debug {

gitoxide-core/src/repository/config.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub fn list(
3232
}
3333

3434
let meta = section.meta();
35-
if last_meta.map_or(true, |last| last != meta) {
35+
if last_meta != Some(meta) {
3636
write_meta(meta, &mut out)?;
3737
}
3838
last_meta = Some(meta);
@@ -41,9 +41,10 @@ pub fn list(
4141
for event in matter {
4242
event.write_to(&mut out)?;
4343
}
44-
if it.peek().map_or(false, |(next_section, _)| {
45-
next_section.header().name() != section.header().name()
46-
}) {
44+
if it
45+
.peek()
46+
.is_some_and(|(next_section, _)| next_section.header().name() != section.header().name())
47+
{
4748
writeln!(&mut out)?;
4849
}
4950
}

gitoxide-core/src/repository/exclude.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ pub fn query(
9393
let entry = cache.at_entry(
9494
path,
9595
Some(is_dir_to_mode(
96-
workdir.map_or(false, |wd| wd.join(gix::path::from_bstr(path)).is_dir())
96+
workdir.is_some_and(|wd| wd.join(gix::path::from_bstr(path)).is_dir())
9797
|| pattern.signature.contains(gix::pathspec::MagicSignature::MUST_BE_DIR),
9898
)),
9999
)?;

gitoxide-core/src/repository/fetch.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ pub(crate) mod function {
305305
for fix in &map.fixes {
306306
match fix {
307307
Fix::MappingWithPartialDestinationRemoved { name, spec } => {
308-
if prev_spec.map_or(true, |prev_spec| prev_spec != spec) {
308+
if prev_spec.is_some_and(|prev_spec| prev_spec != spec) {
309309
prev_spec = spec.into();
310310
spec.to_ref().write_to(&mut err)?;
311311
writeln!(err)?;

gitoxide-core/src/repository/index/entries.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ pub(crate) mod function {
198198
sms_by_path
199199
.iter()
200200
.find_map(|(path, sm)| (path == entry_path).then_some(sm))
201-
.filter(|sm| sm.git_dir_try_old_form().map_or(false, |dot_git| dot_git.exists()))
201+
.filter(|sm| sm.git_dir_try_old_form().is_ok_and(|dot_git| dot_git.exists()))
202202
})
203203
{
204204
let sm_path = gix::path::to_unix_separators_on_windows(sm.path()?);

gitoxide-core/src/repository/remote.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ mod refs_impl {
190190
for fix in &map.fixes {
191191
match fix {
192192
Fix::MappingWithPartialDestinationRemoved { name, spec } => {
193-
if prev_spec.map_or(true, |prev_spec| prev_spec != spec) {
193+
if prev_spec.is_some_and(|prev_spec| prev_spec != spec) {
194194
prev_spec = spec.into();
195195
spec.to_ref().write_to(&mut err)?;
196196
writeln!(err)?;

gitoxide-core/src/repository/revision/list.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ pub(crate) mod function {
108108
}
109109
}
110110
progress.inc();
111-
if limit.map_or(false, |limit| limit == progress.step()) {
111+
if limit.is_some_and(|limit| limit == progress.step()) {
112112
break;
113113
}
114114
}

gix-dir/src/walk/classify.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ pub fn path(
215215

216216
let is_dir = if symlinks_to_directories_are_ignored_like_directories
217217
&& ctx.excludes.is_some()
218-
&& kind.map_or(false, |ft| ft == entry::Kind::Symlink)
218+
&& kind == Some(entry::Kind::Symlink)
219219
{
220220
path.metadata().ok().map(|md| is_dir_to_mode(md.is_dir()))
221221
} else {

gix-filter/examples/arrow.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
1919

2020
match sub_command.as_str() {
2121
"process" => {
22-
let disallow_delay = next_arg.as_deref().map_or(false, |arg| arg == "disallow-delay");
22+
let disallow_delay = next_arg.as_deref() == Some("disallow-delay");
2323
let mut srv = gix_filter::driver::process::Server::handshake(
2424
stdin(),
2525
stdout(),

gix-filter/src/driver/process/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl Status {
8383

8484
/// Returns true if this is an `abort` status.
8585
pub fn is_abort(&self) -> bool {
86-
self.message().map_or(false, |m| m == "abort")
86+
self.message() == Some("abort")
8787
}
8888

8989
/// Return true if the status is explicitly set to indicated delayed output processing

gix-pack/src/multi_index/chunk.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub mod index_names {
6969
ascii_path.is_ascii(),
7070
"must use ascii bytes for correct size computation"
7171
);
72-
count += (ascii_path.as_bytes().len() + 1/* null byte */) as u64;
72+
count += (ascii_path.len() + 1/* null byte */) as u64;
7373
}
7474

7575
let needed_alignment = CHUNK_ALIGNMENT - (count % CHUNK_ALIGNMENT);
@@ -89,7 +89,7 @@ pub mod index_names {
8989
let path = path.as_ref().to_str().expect("UTF-8 path");
9090
out.write_all(path.as_bytes())?;
9191
out.write_all(&[0])?;
92-
written_bytes += path.as_bytes().len() as u64 + 1;
92+
written_bytes += path.len() as u64 + 1;
9393
}
9494

9595
let needed_alignment = CHUNK_ALIGNMENT - (written_bytes % CHUNK_ALIGNMENT);

gix-packetline-blocking/src/line/async_io.rs

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gix-packetline/src/line/async_io.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use futures_io::AsyncWrite;
44

55
use crate::{encode, BandRef, Channel, ErrorRef, PacketLineRef, TextRef};
66

7-
impl<'a> BandRef<'a> {
7+
impl BandRef<'_> {
88
/// Serialize this instance to `out`, returning the amount of bytes written.
99
///
1010
/// The data written to `out` can be decoded with [`Borrowed::decode_band()]`.
@@ -18,14 +18,14 @@ impl<'a> BandRef<'a> {
1818
}
1919
}
2020

21-
impl<'a> TextRef<'a> {
21+
impl TextRef<'_> {
2222
/// Serialize this instance to `out`, appending a newline if there is none, returning the amount of bytes written.
2323
pub async fn write_to(&self, out: impl AsyncWrite + Unpin) -> io::Result<usize> {
2424
encode::text_to_write(self.0, out).await
2525
}
2626
}
2727

28-
impl<'a> ErrorRef<'a> {
28+
impl ErrorRef<'_> {
2929
/// Serialize this line as error to `out`.
3030
///
3131
/// This includes a marker to allow decoding it outside of a side-band channel, returning the amount of bytes written.
@@ -34,7 +34,7 @@ impl<'a> ErrorRef<'a> {
3434
}
3535
}
3636

37-
impl<'a> PacketLineRef<'a> {
37+
impl PacketLineRef<'_> {
3838
/// Serialize this instance to `out` in git `packetline` format, returning the amount of bytes written to `out`.
3939
pub async fn write_to(&self, out: impl AsyncWrite + Unpin) -> io::Result<usize> {
4040
match self {

gix-path/src/env/mod.rs

+17
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,23 @@ pub fn installation_config_prefix() -> Option<&'static Path> {
2828
installation_config().map(git::config_to_base_path)
2929
}
3030

31+
/// Return the shell that Git would prefer as login shell, the shell to execute Git commands from.
32+
///
33+
/// On Windows, this is the `bash.exe` bundled with it, and on Unix it's the shell specified by `SHELL`,
34+
/// or `None` if it is truly unspecified.
35+
pub fn login_shell() -> Option<&'static Path> {
36+
static PATH: Lazy<Option<PathBuf>> = Lazy::new(|| {
37+
if cfg!(windows) {
38+
installation_config_prefix()
39+
.and_then(|p| p.parent())
40+
.map(|p| p.join("usr").join("bin").join("bash.exe"))
41+
} else {
42+
std::env::var_os("SHELL").map(PathBuf::from)
43+
}
44+
});
45+
PATH.as_deref()
46+
}
47+
3148
/// Return the name of the Git executable to invoke it.
3249
/// If it's in the `PATH`, it will always be a short name.
3350
///

gix-path/tests/path.rs

-80
This file was deleted.
File renamed without changes.

gix-path/tests/path/env.rs

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#[test]
2+
fn exe_invocation() {
3+
let actual = gix_path::env::exe_invocation();
4+
assert!(
5+
!actual.as_os_str().is_empty(),
6+
"it finds something as long as git is installed somewhere on the system (or a default location)"
7+
);
8+
}
9+
10+
#[test]
11+
fn login_shell() {
12+
// On CI, the $SHELL variable isn't necessarily set. Maybe other ways to get the login shell should be used then.
13+
if !gix_testtools::is_ci::cached() {
14+
assert!(gix_path::env::login_shell()
15+
.expect("There should always be the notion of a shell used by git")
16+
.exists());
17+
}
18+
}
19+
20+
#[test]
21+
fn installation_config() {
22+
assert_ne!(
23+
gix_path::env::installation_config().map(|p| p.components().count()),
24+
gix_path::env::installation_config_prefix().map(|p| p.components().count()),
25+
"the prefix is a bit shorter than the installation config path itself"
26+
);
27+
}
28+
29+
#[test]
30+
fn system_prefix() {
31+
assert_ne!(
32+
gix_path::env::system_prefix(),
33+
None,
34+
"git should be present when running tests"
35+
);
36+
}
37+
38+
#[test]
39+
fn home_dir() {
40+
assert_ne!(
41+
gix_path::env::home_dir(),
42+
None,
43+
"we find a home on every system these tests execute"
44+
);
45+
}
46+
47+
mod xdg_config {
48+
use std::ffi::OsStr;
49+
50+
#[test]
51+
fn prefers_xdg_config_bases() {
52+
let actual = gix_path::env::xdg_config("test", &mut |n| {
53+
(n == OsStr::new("XDG_CONFIG_HOME")).then(|| "marker".into())
54+
})
55+
.expect("set");
56+
#[cfg(unix)]
57+
assert_eq!(actual.to_str(), Some("marker/git/test"));
58+
#[cfg(windows)]
59+
assert_eq!(actual.to_str(), Some("marker\\git\\test"));
60+
}
61+
62+
#[test]
63+
fn falls_back_to_home() {
64+
let actual = gix_path::env::xdg_config("test", &mut |n| (n == OsStr::new("HOME")).then(|| "marker".into()))
65+
.expect("set");
66+
#[cfg(unix)]
67+
assert_eq!(actual.to_str(), Some("marker/.config/git/test"));
68+
#[cfg(windows)]
69+
assert_eq!(actual.to_str(), Some("marker\\.config\\git\\test"));
70+
}
71+
}

0 commit comments

Comments
 (0)