Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the bash_program() helper in gix-testtools a little more robust #1864

Merged
merged 7 commits into from
Mar 20, 2025

Conversation

EliahKagan
Copy link
Member

@EliahKagan EliahKagan commented Feb 26, 2025

Tasks:

  • Change it to prefer the shim (drop/rewind or undo 7c0af6a)
  • Figure out if and how is currently best to fall back to a non-shim (see outscoped)
  • Retest locally
  • Retest locally along with changes from #1862 (though they should be independent)
  • If #1862 comes in first, rebase for clearer history (optional, should not be needed)

Outscoped:

* The stakes here are low enough that I think that doesn't have to be investigated in detail. But the stakes in #1862 are higher, the shim vs. non-shim situation is similar, and we only surfaced one error case there, so I am going to examine the failures from here to become more confident in the improved solution there.


On Windows, since #1712, gix-testtools looks for a bash shell associated with Git for Windows, to run fixture scripts. This logic is broadly similar to gix_path::env::shell() (#1758), which it influenced (#1752 (comment)). But there are some differences, even beyond shell() in gix-path being for sh and bash_program() in gix-testtools being for bash. Some differences are stylistic, while others are behavioral.

It seems to me that they should be more similar than they are, and that there are also some improvements that should be applied to both in the same way. The changes proposed for shell() in #1862 include some that make it more similar to bash_program(), such as checking if the shell exists, as well as others such as preferring /, which neither shell() nor bash_program() yet do but which makes sense in both.

This PR is the gix-testtools counterpart to the gix-path changes in #1862. The topical similarity could justify including both in the same PR, but having separate feature branches is more flexible, and I think the effects are also independent. In addition, neither is ready, it is possible that one will be ready before the other, and I do not know which. Currently the changes in this PR are:

  • Refactor for clarity and to reduce unnecessary dissimilarity to gix_path::env::shell().
  • Prefer / over \ in building the path to bash.exe.
  • Add some more tests.
  • Look for the non-shim bash.exe in (git root)/usr/bin instead of the shim in (git root)/bin.

All but the last of those changes are done together, while the last is in its own commit. See commit messages for more details and rationale. Some code is analogous to code proposed for gix-path in #1862 but less commented. More comments could be added, especially if this PR ends up being merged without #1862 being merged or looking like it would be merged soon after.

All but the last of these changes also appear to be working fine on all tested systems. In contrast, using the non-shim bash.exe breaks at least one fixture and many tests when run locally on my Windows 10 development machine from PowerShell. The failing tests are not the ones introduced here, but preexisting tests that passed before, including when run in that environment. The failures appear to be due to errors in test fixture scripts. This situation is similar to the local failures currently blocking #1862 and I suspect the cause is the same. This is what I was referring to in #1758 (comment), and I'll try to give details of the failures (as an edit or comment here) soon.

I suspect that, for the sh.exe and bash.exe provided by Git for Windows, the shim behavior of adding bin directories associated with Git for Windows to the front of PATH is necessary to prevent scripts run in those shells from invoking the wrong implementations of commands, where multiple implementations are available. But I have not determined for sure that this is the case, so this PR is not ready yet.

If that is the case, then a possible solution could be to prefer the shims (both here and in #1862), though if the additional subprocess invocations inherent in doing so cause a performance problem, then the existing customization of the environment in both gix-command and gix-testtools could potentially be extended. If that performance degradation is not excessive, then the ideal solution may be to prefer the shims but fall back to the non-shim versions, which would preserve compatibility with the Git for Windows SDK in scenarios where it currently works (the SDK does not have the shims, noted in #1761 (comment), as observed in #1758 (comment) and rechecked in #1758 (comment)).

@EliahKagan
Copy link
Member Author

I've updated this with a list of remaining tasks. Right now I expect to finish #1862 and then finish this, though if further problems arise in #1862 then it could be in the other order. The tasks here will most likely, once I get to them, proceed quickly.

@EliahKagan EliahKagan force-pushed the run-ci/bash-program branch from 7c0af6a to bbd5a66 Compare March 14, 2025 05:41
@EliahKagan
Copy link
Member Author

The 90 failures when the non-shim (git root)/usr/bin/bash.exe is used (bbd5a66) can be grouped by direct cause into just a few groups. I have largely not analyzed them yet, but most of them are due to fatal: bad config line 10 in file ./config in make_remote_repos.sh.

This is the case for the failures in the first two groups: both the group labeled that way, but also the group where the direct cause was the inability to run that script because its associated lock timed out while it was being run unsuccessfully by so many other tests.

The other groups are not causally related to that fixture, but seem to relate to symlinks.

Full details are in this gist. As noted in the gist readme, the results are in two plain text files: grouped and full raw output.

I think the grouped view is more useful, but when I made it deliberately omitted details, which I think are sometimes significant. The grouped view is also shown here, split into groups by placing each in its own code block but otherwise the same as in the gist:

======================================================
FAILED in gix/tests/fixtures/make_remote_repos.sh with
fatal: bad config line 10 in file ./config
======================================================

gix remote::connection::fetch::refs::tests::update::fast_forwards_are_called_out_even_if_force_is_given
gix remote::connection::fetch::refs::tests::update::local_direct_refs_are_written_with_symbolic_ones
gix remote::connection::fetch::refs::tests::update::remote_refs_cannot_map_to_local_head
gix remote::connection::fetch::refs::tests::update::remote_symbolic_refs_can_always_be_set_as_there_is_no_scenario_where_it_could_be_nonexisting_and_rejected
gix remote::connection::fetch::refs::tests::update::remote_symbolic_refs_can_be_written_locally_and_point_to_tracking_branch
gix remote::connection::fetch::refs::tests::update::remote_symbolic_refs_with_locally_unavailable_target_dont_overwrite_valid_local_branches
gix remote::connection::fetch::refs::tests::update::unborn_remote_refs_dont_overwrite_valid_local_refs
gix remote::connection::fetch::refs::tests::update::various_valid_updates
gix::gix clone::blocking_io::fetch_and_checkout
gix::gix clone::blocking_io::fetch_and_checkout_specific_annotated_tag
gix::gix clone::blocking_io::fetch_and_checkout_specific_non_existing
gix::gix clone::blocking_io::fetch_and_checkout_specific_ref
gix::gix clone::blocking_io::fetch_only_with_configuration
gix::gix clone::blocking_io::fetch_only_without_configuration
gix::gix clone::blocking_io::fetch_shallow_no_checkout_then_unshallow
gix::gix clone::blocking_io::fetch_succeeds_despite_remote_head_ref
gix::gix clone::blocking_io::from_non_shallow_by_deepen_exclude_then_deepen_to_unshallow
gix::gix clone::blocking_io::from_non_shallow_then_deepen_then_deepen_since_to_unshallow
gix::gix clone::blocking_io::from_shallow_allowed_by_default
gix::gix clone::blocking_io::from_shallow_prohibited_with_option
gix::gix clone::clone_and_destination_must_be_empty
gix::gix clone::clone_and_early_persist_without_receive
gix::gix clone::clone_bare_into_empty_directory_and_early_drop
gix::gix clone::clone_into_empty_directory_and_early_drop
gix::gix head::into_remote::detached_is_none
gix::gix head::into_remote::unborn_is_none
gix::gix reference::remote::dot_remote_behind_symbol
gix::gix reference::remote::not_configured
gix::gix reference::remote::push_defaults_to_fetch
gix::gix reference::remote::separate_push_and_fetch
gix::gix reference::remote::url_as_remote_name
gix::gix remote::connect::blocking_io::protocol_allow::deny
gix::gix remote::connect::blocking_io::protocol_allow::user
gix::gix remote::fetch::blocking_and_async_io::collate_fetch_error
gix::gix remote::fetch::blocking_and_async_io::fetch_empty_pack
gix::gix remote::fetch::blocking_and_async_io::fetch_pack
gix::gix remote::fetch::blocking_and_async_io::fetch_pack_without_local_destination
gix::gix remote::fetch::blocking_and_async_io::fetch_shallow_deepen_not_possible
gix::gix remote::fetch::blocking_and_async_io::fetch_shallow_deepen_zero_does_not_fail
gix::gix remote::fetch::blocking_and_async_io::fetch_with_alternates_adds_tips_from_alternates
gix::gix remote::fetch::blocking_and_async_io::fetch_with_multi_round_negotiation
gix::gix remote::ref_map::blocking_and_async_io::all
gix::gix remote::save::save_to::named_remotes_save_as_is
gix::gix repository::config::config_snapshot::credential_helpers::any_url_calls_global
gix::gix repository::config::config_snapshot::credential_helpers::case_sensitive_host_matching
gix::gix repository::config::config_snapshot::credential_helpers::empty_core_askpass_is_ignored
gix::gix repository::config::config_snapshot::credential_helpers::empty_helper_clears_helper_list
gix::gix repository::config::config_snapshot::credential_helpers::host_globs_match_as_well
gix::gix repository::config::config_snapshot::credential_helpers::http_port_defaulting
gix::gix repository::config::config_snapshot::credential_helpers::http_urls_match_the_host_without_path_as_well
gix::gix repository::config::config_snapshot::credential_helpers::https_urls_match_the_host_without_path_as_well
gix::gix repository::config::config_snapshot::credential_helpers::invalid_urls_are_rejected_early
gix::gix repository::config::config_snapshot::credential_helpers::ssh_host_and_port_with_path_via_url_match
gix::gix repository::config::config_snapshot::credential_helpers::ssh_host_with_path_via_url_match
gix::gix repository::config::config_snapshot::credential_helpers::subdomain_globs_match_on_their_level
gix::gix repository::config::config_snapshot::credential_helpers::user_rules_only_match_urls_with_user
gix::gix repository::config::remote::remote_and_branch_names
gix::gix repository::config::remote::remote_default_name
gix::gix repository::remote::find_default_remote::works_on_detached_heads
gix::gix repository::remote::find_fetch_remote::symbol_name
gix::gix repository::remote::find_fetch_remote::urls
gix::gix repository::remote::find_remote::bad_url_rewriting_can_be_handled_much_like_git
gix::gix repository::remote::find_remote::instead_of_url_rewriting
gix::gix repository::remote::find_remote::many_fetchspecs
gix::gix repository::remote::find_remote::push_url_and_push_specs
gix::gix repository::remote::find_remote::tags_option
gix::gix repository::remote::find_remote::typical
gix::gix repository::remote::remote_at::url_and_push_url
gix::gix repository::remote::remote_at::url_rewrites_are_respected
gix::gix repository::remote::remote_at::url_rewrites_can_be_skipped
gix::gix repository::shallow::traverse::complex_graphs_can_be_iterated_despite_multiple_shallow_boundaries
==================================================================================================================================================
FAILED with
called `Result::unwrap()` on an `Err` value: PermanentlyLocked { resource_path: "make_remote_repos", mode: AfterDurationWithBackoff(360s), [...] }
==================================================================================================================================================

gix remote::connection::fetch::refs::tests::update::checked_out_branches_in_worktrees_are_rejected_with_additional_information
gix remote::connection::fetch::refs::tests::update::local_symbolic_refs_can_be_overwritten
gix remote::connection::fetch::refs::tests::update::non_fast_forward_is_rejected_but_appears_to_be_fast_forward_in_dryrun_mode
gix remote::connection::fetch::refs::tests::update::non_fast_forward_is_rejected_if_dry_run_is_disabled
gix remote::connection::fetch::refs::tests::update::remote_symbolic_refs_with_locally_unavailable_target_result_in_valid_peeled_branches
gix remote::connection::fetch::refs::tests::update::unborn_remote_branches_can_be_created_locally_if_they_are_new
gix remote::connection::fetch::refs::tests::update::unborn_remote_branches_can_update_local_unborn_branches
========================================================================================
FAILED after running basic.sh, with
thread 'from_tree::basic_usage_internal' panicked at gix-archive\tests\archive.rs:25:13:
assertion `left == right` failed
  left: 565
 right: 551
========================================================================================

gix-archive::archive from_tree::basic_usage_internal
=====================================================================================================================================================================================================================================================================================================================================================================================================
FAILED with
thread 'from_tree::basic_usage_tar' panicked at gix-archive\tests\archive.rs:117:13:
assertion `left == right` failed
  left: [("prefix/.gitattributes", Regular, 56, 420), ("prefix/a", Regular, 3, 420), ("prefix/symlink-to-a", Regular, 3, 420), ("prefix/dir/b", Regular, 3, 420), ("prefix/dir/subdir/exe", Regular, 0, 493), ("prefix/extra-file", Regular, 21, 420), ("prefix/extra-exe", Regular, 0, 420), ("prefix/extra-dir-empty", Directory, 0, 420), ("prefix/extra-dir/symlink-to-extra", Regular, 21, 420)]
 right: [("prefix/.gitattributes", Regular, 56, 420), ("prefix/a", Regular, 3, 420), ("prefix/symlink-to-a", Symlink, 0, 420), ("prefix/dir/b", Regular, 3, 420), ("prefix/dir/subdir/exe", Regular, 0, 493), ("prefix/extra-file", Regular, 21, 420), ("prefix/extra-exe", Regular, 0, 420), ("prefix/extra-dir-empty", Directory, 0, 420), ("prefix/extra-dir/symlink-to-extra", Symlink, 0, 420)]
=====================================================================================================================================================================================================================================================================================================================================================================================================

gix-archive::archive from_tree::basic_usage_tar
====================================================================================
FAILED with
thread 'from_tree::basic_usage_zip' panicked at gix-archive\tests\archive.rs:195:17:
symlinks are supported as well, but only on Unix
====================================================================================

gix-archive::archive from_tree::basic_usage_zip
==============================================================================================
FAILED in gix-dir/tests/fixtures/many-symlinks.sh with
/usr/bin/ln: failed to create symbolic link 'hide/breakout': Too many levels of symbolic links
==============================================================================================

gix-dir::dir walk::root_may_be_a_symlink_if_it_is_the_worktree
gix-dir::dir walk::root_may_not_lead_through_symlinks
gix-dir::dir walk::symlink_to_dir_can_be_excluded
gix-dir::dir walk::worktree_root_can_be_symlink
=======================================================================================================================================================================================================================================================================================================================================================================================================================
FAILED (the first one, marked * to distinguish it, after running status-changed.sh), with
thread 'index_as_worktree::modified' panicked at gix-status\tests\status\index_as_worktree.rs:215:5:
assertion `left == right` failed
  left: [("dir/content2", 1, Change(Modification { executable_bit_changed: false, content_change: Some(()), set_entry_stat_size_zero: false })), ("empty", 3, Change(Modification { executable_bit_changed: false, content_change: Some(()), set_entry_stat_size_zero: false })), ("executable", 4, Change(Modification { executable_bit_changed: false, content_change: Some(()), set_entry_stat_size_zero: false }))]
 right: [("dir/content2", 1, Change(Modification { executable_bit_changed: false, content_change: Some(()), set_entry_stat_size_zero: false })), ("empty", 3, Change(Type { worktree_mode: Mode(SYMLINK) })), ("executable", 4, Change(Modification { executable_bit_changed: false, content_change: Some(()), set_entry_stat_size_zero: false }))]
=======================================================================================================================================================================================================================================================================================================================================================================================================================

gix-status-tests::status index_as_worktree::modified *
gix-status-tests::status index_as_worktree::refresh


================================================================================================================================================
FAILED with
thread 'stack::paths_not_going_through_symlink_directories_are_ok_and_point_to_correct_item' panicked at gix-status\tests\status\stack.rs:27:13:
"root-filelink" expectation failed
================================================================================================================================================

gix-status-tests::status stack::paths_not_going_through_symlink_directories_are_ok_and_point_to_correct_item
====================================================================================================================================
FAILED with
thread 'state::checkout::overwriting_files_and_lone_directories_works' panicked at gix-worktree-state\tests\state\checkout.rs:263:9:
assertion failed: std::fs::symlink_metadata(&symlink)?.is_symlink()
====================================================================================================================================

gix-worktree-state-tests::worktree state::checkout::overwriting_files_and_lone_directories_works
=================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
FAILED with
thread 'from_tree::will_provide_all_information_and_respect_export_ignore' panicked at gix-worktree-stream\tests\stream.rs:118:9:
assertion `left == right` failed
  left: [(".gitattributes", Blob, Sha1(45c160c35c17ad264b96431cceb9793160396e99)), ("a", Blob, Sha1(45b983be36b73c0788dc9cbcb76cbb80fc7bb057)), ("bigfile", Blob, Sha1(4995fde49ed64e043977e22539f66a0d372dd129)), ("symlink-to-a", Blob, Sha1(45b983be36b73c0788dc9cbcb76cbb80fc7bb057)), ("dir/.gitattributes", Blob, Sha1(81b9a375276405703e05be6cecf0fc1c8b8eed64)), ("dir/b", Blob, Sha1(ab4a98190cf776b43cb0fe57cef231fb93fd07e6)), ("dir/subdir/exe", BlobExecutable, Sha1(e69de29bb2d1d6434b8b29ae775ad8c2e48c5391)), ("dir/subdir/streamed", Blob, Sha1(08991f58f4de5d85b61c0f87f3ac053c79d0e739)), ("extra-file", Blob, Sha1(0000000000000000000000000000000000000000)), ("extra-bigfile", Blob, Sha1(0000000000000000000000000000000000000000)), ("extra-exe", Blob, Sha1(0000000000000000000000000000000000000000)), ("extra-dir-empty", Tree, Sha1(0000000000000000000000000000000000000000)), ("extra-dir/symlink-to-extra", Blob, Sha1(0000000000000000000000000000000000000000))]
 right: [(".gitattributes", Blob, Sha1(45c160c35c17ad264b96431cceb9793160396e99)), ("a", Blob, Sha1(45b983be36b73c0788dc9cbcb76cbb80fc7bb057)), ("bigfile", Blob, Sha1(4995fde49ed64e043977e22539f66a0d372dd129)), ("symlink-to-a", Link, Sha1(2e65efe2a145dda7ee51d1741299f848e5bf752e)), ("dir/.gitattributes", Blob, Sha1(81b9a375276405703e05be6cecf0fc1c8b8eed64)), ("dir/b", Blob, Sha1(ab4a98190cf776b43cb0fe57cef231fb93fd07e6)), ("dir/subdir/exe", BlobExecutable, Sha1(e69de29bb2d1d6434b8b29ae775ad8c2e48c5391)), ("dir/subdir/streamed", Blob, Sha1(08991f58f4de5d85b61c0f87f3ac053c79d0e739)), ("extra-file", Blob, Sha1(0000000000000000000000000000000000000000)), ("extra-bigfile", Blob, Sha1(0000000000000000000000000000000000000000)), ("extra-exe", Blob, Sha1(0000000000000000000000000000000000000000)), ("extra-dir-empty", Tree, Sha1(0000000000000000000000000000000000000000)), ("extra-dir/symlink-to-extra", Link, Sha1(0000000000000000000000000000000000000000))]
=================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

gix-worktree-stream::stream from_tree::will_provide_all_information_and_respect_export_ignore

The other piece of information that I think it is interesting and relevant enough to include here is the full output from the make_remote_repos.sh fixture script. It is always the same. Here's the output of the first test that ran it, consisting mostly of output from that fixture:

        FAIL [   8.676s] gix remote::connection::fetch::refs::tests::update::remote_symbolic_refs_can_be_written_locally_and_point_to_tracking_branch
──── STDOUT:             gix remote::connection::fetch::refs::tests::update::remote_symbolic_refs_can_be_written_locally_and_point_to_tracking_branch

running 1 test
test remote::connection::fetch::refs::tests::update::remote_symbolic_refs_can_be_written_locally_and_point_to_tracking_branch ... FAILED

failures:

failures:
    remote::connection::fetch::refs::tests::update::remote_symbolic_refs_can_be_written_locally_and_point_to_tracking_branch

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 16 filtered out; finished in 8.66s

──── STDERR:             gix remote::connection::fetch::refs::tests::update::remote_symbolic_refs_can_be_written_locally_and_point_to_tracking_branch
Archive at 'tests\fixtures\generated-archives\make_remote_repos.tar' not found, creating fixture using script 'make_remote_repos.sh'

thread 'remote::connection::fetch::refs::tests::update::remote_symbolic_refs_can_be_written_locally_and_point_to_tracking_branch' panicked at tests\tools\src\lib.rs:587:17:
fixture script of "C:/Users/ek/scoop/apps/git/2.48.1/usr/bin/bash.exe" "C:\\Users\\ek\\source\\repos\\gitoxide\\gix\\tests\\fixtures\\make_remote_repos.sh" failed: stdout: Initialized empty Git repository in C:/Users/ek/source/repos/gitoxide/gix/tests/fixtures/generated-do-not-edit/make_remote_repos/1456912905-windows/base/.git/
[main (root-commit) eadd5ab] G
 Author: A U Thor <[email protected]>
 1 file changed, 1 insertion(+)
 create mode 100644 file
[h (root-commit) 460f427] H
 Author: A U Thor <[email protected]>
 1 file changed, 1 insertion(+)
 create mode 100644 file
Auto-merging file
CONFLICT (add/add): Merge conflict in file
Automatic merge failed; fix conflicts and then commit the result.
[main 82024b2] D
 Author: A U Thor <[email protected]>
[i (root-commit) 573a3ef] I
 Author: A U Thor <[email protected]>
 1 file changed, 1 insertion(+)
 create mode 100644 file
[j (root-commit) 6ec965c] J
 Author: A U Thor <[email protected]>
 1 file changed, 1 insertion(+)
 create mode 100644 file
Auto-merging file
CONFLICT (add/add): Merge conflict in file
Automatic merge failed; fix conflicts and then commit the result.
[i 27e7157] F
 Author: A U Thor <[email protected]>
[e (root-commit) b515286] E
 Author: A U Thor <[email protected]>
 1 file changed, 1 insertion(+)
 create mode 100644 file
Automatic merge failed; fix conflicts and then commit the result.
[main dfd0954] B
 Author: A U Thor <[email protected]>
[i 2d9d136] C
 Author: A U Thor <[email protected]>
 1 file changed, 1 insertion(+)
HEAD is now at 573a3ef I
Auto-merging file
CONFLICT (content): Merge conflict in file
Automatic merge failed; fix conflicts and then commit the result.
[main f99771f] A
 Author: A U Thor <[email protected]>
rm 'file'
[detached (root-commit) eb1b8e5] detached
 Author: A U Thor <[email protected]>
Deleted branch detached (was eb1b8e5).
[tmp d326732] something new
 Author: A U Thor <[email protected]>
Deleted branch tmp (was d326732).
Initialized empty Git repository in C:/Users/ek/source/repos/gitoxide/gix/tests/fixtures/generated-do-not-edit/make_remote_repos/1456912905-windows/url-rewriting/
Initialized empty Git repository in C:/Users/ek/source/repos/gitoxide/gix/tests/fixtures/generated-do-not-edit/make_remote_repos/1456912905-windows/bad-url-rewriting/

stderr: Switched to a new branch 'h'
Switched to branch 'main'
Switched to a new branch 'i'
Switched to a new branch 'j'
Switched to branch 'i'
Switched to a new branch 'e'
Switched to branch 'main'
Unable to find common commit with e
Switched to branch 'i'
Switched to branch 'main'
Switched to a new branch 'detached'
Switched to a new branch 'tmp'
Switched to branch 'main'
Cloning into 'base.shallow'...
Cloning into 'clone'...
done.
Cloning into 'head-ref'...
done.
warning: ignoring broken ref refs/heads/HEAD
Cloning into 'clone-no-tags'...
done.
Cloning into 'push-default'...
done.
Cloning into 'push-url'...
done.
Cloning into 'many-fetchspecs'...
done.
Cloning into 'branch-push-remote'...
done.
Cloning into 'branch-dot-remote'...
done.
fatal: bad config line 10 in file ./config

note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

That is the direct cause of 72 test failures and, in the manner described above, the close indirect cause of 8 others.

I am not yet clear on why this happens. I assume it is due to the wrong commands being run, probably from my other MSYS2 installation that is not part of Git for Windows (as in #1862 (comment), except less weird here) or other things being wrong in the environment. If so, then preferring the shim should fix it and #1862 should be ready to go (as should this, one it is made to use the shim again). But I want to look for other possible causes of failure, in case there is another problem that might affect #1862. (If there is another problem, it might affect this PR too, but I think this is lower stakes since it only affects gix-testtools.)

EliahKagan added a commit to EliahKagan/gitoxide that referenced this pull request Mar 16, 2025
The change in the previous commit of switching to the non-shim
`bash.exe` in `(git root)/usr/bin` causes problems, because the
environment may not be correct for shell commands and scripts.
In particular, the `PATH` might not enable standard POSIX tools to
be found, or the tools that are found may interoperate incorrectly
with the shell. The latter caused failures in GitoxideLabs#1862 in an analogous
choice of `sh.exe`, which were addressed by preferring the shim
when available. See:

- GitoxideLabs#1862 (comment)

Here, 90 tests started to fail when the test suite was run locally
from PowerShell (i.e. not a Git Bash environment) on a Windows 10
system that, in addition to a full Git for Windows installation,
contains a separate non-GfW MSYS2 installation whose `bin`
directories are in `PATH` even in non-MSYS2 environments. The
failures were described, and most of them investigated, as follows:

- GitoxideLabs#1864 (comment)
- https://gist.github.com/EliahKagan/3c5eebd091e66d8c912fddbce0a064cd
- https://gist.github.com/EliahKagan/17066ad1f7b0aa98e4fdf4642abe1d93

Most failures, including all those that were unintuitive, were
directly or indirectly due to the `make_remote_repos.sh` fixture
script encountering the error:

    fatal: bad config line 10 in file ./config

This happened due to the same incorrect behavior of `>>`, when used
by a shell that links to one `msys-2.0.dll` running a program that
links to a different `msys-2.0.dll` of another version or build, as
caused the failure encountered with the non-shim in GitoxideLabs#1862.

(It may be the handful of other failures are also caused by this
`>>` problem, but as of now that has not been examined.)

This commit temporarily instruments that fixture script so that,
when tests are run, the observations and analysis in the last gist
above can be confirmed. (These changes are also shown there.)
EliahKagan added a commit to EliahKagan/gitoxide that referenced this pull request Mar 16, 2025
The change in the previous commit of switching to the non-shim
`bash.exe` in `(git root)/usr/bin` causes problems, because the
environment may not be correct for shell commands and scripts.
In particular, the `PATH` might not enable standard POSIX tools to
be found, or the tools that are found may interoperate incorrectly
with the shell. The latter caused failures in GitoxideLabs#1862 in an analogous
choice of `sh.exe`, which were addressed by preferring the shim
when available. See:

- GitoxideLabs#1862 (comment)

Here, 90 tests started to fail when the test suite was run locally
from PowerShell (i.e. not a Git Bash environment) on a Windows 10
system that, in addition to a full Git for Windows installation,
contains a separate non-GfW MSYS2 installation whose `bin`
directories are in `PATH` even in non-MSYS2 environments. The
failures were described, and most of them investigated, as follows:

- GitoxideLabs#1864 (comment)
- https://gist.github.com/EliahKagan/3c5eebd091e66d8c912fddbce0a064cd
- https://gist.github.com/EliahKagan/17066ad1f7b0aa98e4fdf4642abe1d93

Most failures, including all those that were unintuitive, were
directly or indirectly due to the `make_remote_repos.sh` fixture
script encountering the error:

    fatal: bad config line 10 in file ./config

This happened due to the same incorrect behavior of `>>`, when used
by a shell that links to one `msys-2.0.dll` running a program that
links to a different `msys-2.0.dll` of another version or build, as
caused the failure encountered with the non-shim in GitoxideLabs#1862.

(It may be the handful of other failures are also caused by this
`>>` problem, but as of now that has not been examined.)

This commit temporarily instruments that fixture script so that,
when tests are run, the observations and analysis in the last gist
above can be confirmed. (These changes are also shown there.)
@EliahKagan EliahKagan force-pushed the run-ci/bash-program branch 2 times, most recently from e35cf14 to 55f6be2 Compare March 16, 2025 10:09
EliahKagan added a commit to EliahKagan/gitoxide that referenced this pull request Mar 16, 2025
The change in the previous commit of switching to the non-shim
`bash.exe` in `(git root)/usr/bin` causes problems, because the
environment may not be correct for shell commands and scripts.
In particular, the `PATH` might not enable standard POSIX tools to
be found, or the tools that are found may interoperate incorrectly
with the shell. The latter caused failures in GitoxideLabs#1862 in an analogous
choice of `sh.exe`, which were addressed by preferring the shim
when available. See:

- GitoxideLabs#1862 (comment)

Here, 90 tests started to fail when the test suite was run locally
from PowerShell (i.e. not a Git Bash environment) on a Windows 10
system that, in addition to a full Git for Windows installation,
contains a separate non-GfW MSYS2 installation whose `bin`
directories are in `PATH` even in non-MSYS2 environments. The
failures were described, and most of them investigated, as follows:

- GitoxideLabs#1864 (comment)
- https://gist.github.com/EliahKagan/3c5eebd091e66d8c912fddbce0a064cd
- https://gist.github.com/EliahKagan/17066ad1f7b0aa98e4fdf4642abe1d93

Most failures, including all those that were unintuitive, were
directly or indirectly due to the `make_remote_repos.sh` fixture
script encountering the error:

    fatal: bad config line 10 in file ./config

This happened due to the same incorrect behavior of `>>`, when used
by a shell that links to one `msys-2.0.dll` running a program that
links to a different `msys-2.0.dll` of another version or build, as
caused the failure encountered with the non-shim in GitoxideLabs#1862.

(It may be the handful of other failures are also caused by this
`>>` problem, but as of now that has not been examined.)

This commit temporarily instruments that fixture script so that,
when tests are run, the observations and analysis in the last gist
above can be confirmed. (These changes are also shown there.)
EliahKagan added a commit to EliahKagan/gitoxide that referenced this pull request Mar 16, 2025
The change in the previous commit of switching to the non-shim
`bash.exe` in `(git root)/usr/bin` causes problems, because the
environment may not be correct for shell commands and scripts.
In particular, the `PATH` might not enable standard POSIX tools to
be found, or the tools that are found may interoperate incorrectly
with the shell. The latter caused failures in GitoxideLabs#1862 in an analogous
choice of `sh.exe`, which were addressed by preferring the shim
when available. See:

- GitoxideLabs#1862 (comment)

Here, 90 tests started to fail when the test suite was run locally
from PowerShell (i.e. not a Git Bash environment) on a Windows 10
system that, in addition to a full Git for Windows installation,
contains a separate non-GfW MSYS2 installation whose `bin`
directories are in `PATH` even in non-MSYS2 environments. The
failures were described, and most of them investigated, as follows:

- GitoxideLabs#1864 (comment)
- https://gist.github.com/EliahKagan/3c5eebd091e66d8c912fddbce0a064cd
- https://gist.github.com/EliahKagan/17066ad1f7b0aa98e4fdf4642abe1d93

Most failures, including all those that were unintuitive, were
directly or indirectly due to the `make_remote_repos.sh` fixture
script encountering the error:

    fatal: bad config line 10 in file ./config

This happened due to the same incorrect behavior of `>>`, when used
by a shell that links to one `msys-2.0.dll` running a program that
links to a different `msys-2.0.dll` of another version or build, as
caused the failure encountered with the non-shim in GitoxideLabs#1862.

(It may be the handful of other failures are also caused by this
`>>` problem, but as of now that has not been examined.)

This commit temporarily instruments that fixture script so that,
when tests are run, the observations and analysis in the last gist
above can be confirmed. (These changes are also shown there.)
@EliahKagan EliahKagan force-pushed the run-ci/bash-program branch from 55f6be2 to e0b422a Compare March 16, 2025 13:45
@EliahKagan
Copy link
Member Author

EliahKagan commented Mar 16, 2025

As described and analyzed in this gist (see also dd585a3), most of the failures--specifically, those in the first two groups listed above in #1864 (comment), pertaining to make_remote_repos.sh--happen as a result of a malformed config file in a bare repository.

It becomes malformed when the fixture script attempts to append to it with >>, which on my system (and presumably others with a similar environment) instead overwrites without truncating. This happens due to the same >> problem described in #1862 (comment) and for the same reason.

I had not expected that this specific mechanism would be being the failures here. I am still not sure if it is behind all of them. I investigated those failures because they comprise most of the local failures observed here, and because they were not intuitive.

The other failures are intuitive, and most seem to be related to symlinks which one would expect could have problems when using the wrong version of POSIX tools on Windows. But a cursory look suggests they might also be due to this >> mechanism, which can also produce a well-formed but incorrect configuration file, for example if it writes something longer than the original file.

The failures that worried me and made me wonder if I was missing something that couldn't be addressed by preferring the shim have been investigated. It seems to me that it is not necessary to investigate the other failures before moving forward with #1862 or this PR.

The problem here is fixed, by using the shim first. Details can be seen in the diff. Before marking either of #1862 or this as ready, I will want to make sure that the local tests all pass with the changes here, both without GIX_TEST_IGNORE_ARCHIVES=1 and with it, and also that they pass in both those ways when the changes of these two PRs are combined. I'm running those local tests now.


Edit: As shown in this other gist, with the version that prefers to use the shim, this did not break anything in the local tests.

I ran the test suite four times, for the four relevant combinations of whether the changes from #1862 were included in the test and whether generated archives were allowed to be used. All runs were from PowerShell (to test the environment that failed when the shim was not preferred).

Both as this PR stands, and if it is replayed atop the changes from #1862:

  • Without GIX_TEST_IGNORE_ARCHIVES, all tests pass.

  • With GIX_TEST_IGNORE_ARCHIVES=1, the expected tests to fail on this local Windows 10 development system are the ones that fail, with no additional failures. Those failing tests are the 12 currently listed in #1358, plus the 3 listed in #1849 because I am using Git for Windows 2.48.1.

So the local results look good.

Regarding:

  • If #1862 comes in first, rebase for clearer history

Really this and #1862 could be merged in either order with no rebasing or anything else done in between. I think it might be slightly easier to understand the history if #1862 is merged first, since some of the changes here to bash_program() resemble some of the changes there to shell() but the changes here are less explained with comments.

Even more minor than that is that it might help slightly when looking at the commit history if this is rebased after #1862 is merged, but that is extremely minor since they are touching different parts of the code entirely. It is only for conceptual reasons that it could potentially be slightly confusing for their commits to appear interleaved when linearized.

If #1862 is merged first, I could rebase this and I think the new capabilities discussed in #1883 would allow me to merge it myself as well. (Actually, from the UI it looks like GitHub would allow me to merge #1862 or this already.)

@EliahKagan EliahKagan changed the title Make the bash_program() helper in gix-testtools more robust Make the bash_program() helper in gix-testtools a little more robust Mar 16, 2025
@EliahKagan EliahKagan marked this pull request as ready for review March 16, 2025 15:45
@EliahKagan EliahKagan requested a review from Byron March 16, 2025 15:48
@Byron
Copy link
Member

Byron commented Mar 17, 2025

Thanks a lot for sharing. Also, it's great to see these PRs become mergeable.

>> failing is a great surprise, I wouldn't have thought that this is possible. As I only read this comment, I hope to soon move over to #1862 as I'd also like to see these PRs merged in order, as suggested.

@EliahKagan
Copy link
Member Author

>> failing is a great surprise, I wouldn't have thought that this is possible. As I only read this comment, I hope to soon move over to #1862 as I'd also like to see these PRs merged in order, as suggested.

Yes, I would say it shouldn't be possible for >> to malfunction in this way. #1862 (comment) summarizes this, then details it with an examination of whether it should be considered a bug in MSYS2 and shows the experiments that establish it as the cause of the test that had been failing there (until it was changed to prefer the shim).

EliahKagan added a commit to EliahKagan/gitoxide that referenced this pull request Mar 18, 2025
Now that Git for Windows 2.49.0 has a stable release, this changes
the upgrade step that was added to `test-fixtures-windows` in
4237e5a (GitoxideLabs#1870), so that it downloads an installer from the release
marked as "latest", rather than the release that has the newest
tag. The release marked "latest" is usually a stable release in
projects that have any stable releases, and in particular it is a
stable release in Git for Windows.

This is *not* needed to switch from the release candidate to the
stable release for 2.49.0. The download logic already in place
currently gets the stable release automatically, because it is the
newest tag.

Nonetheless, there are three reasons to prefer the "latest" tag to
get the stable release, now that the stable release is available.
In descending order of significance, they are:

- We upgrade to work around GitoxideLabs#1849, for which 2.49.0 is preferable
  to 2.48.1 (which the Windows runner images currently have).
  Continuing to take the newest tag will eventually take a
  pre-release for the next version. That would probably work, but
  it is not currently a goal.

  There is sometimes a delay between when a stable release of Git
  for Windows comes out and when the stable runner images are
  released with it. (Pre-release runner images exist, but they are
  not run on GitHub-hosted runners.) So even assuming this upgrade
  step is to be removed once it is no longer needed, it could
  easily end up remaining long enough for a new Git for Windows
  pre-release to come out.

- An update may potentially be released for an earlier minor
  version (y in x.y.z), in which case the tag for it would be
  newer and we would downgrade instead. Now that the release
  marked "latest" is usable here, we can use it and avoid that.

- If we decide to eventually deliberately test pre-releases, the
  step added in GitoxideLabs#1849 would probably not be usable in that form,
  because it could take either the next pre-release or a patch to
  an ealier release per the above points, and also for the separate
  reason that this CI job is not necessarily where we would want to
  test that. (As one example, there is currently no CI testing of
  the Git for Windows SDK, even though supporting it is an explicit
  goal discussed in GitoxideLabs#1758, GitoxideLabs#1761, GitoxideLabs#1862, and GitoxideLabs#1864. If that is
  added, it may be a more opportune way to test prereleases.)
EliahKagan added a commit to EliahKagan/gitoxide that referenced this pull request Mar 18, 2025
Now that Git for Windows 2.49.0 has a stable release, this changes
the upgrade step that was added to `test-fixtures-windows` in
4237e5a (GitoxideLabs#1870), so that it downloads an installer from the release
marked as "latest", rather than the release that has the newest
tag. The release marked "latest" is usually a stable release in
projects that have any stable releases, and in particular it is a
stable release in Git for Windows.

This is *not* needed to switch from the release candidate to the
stable release for 2.49.0. The download logic already in place
currently gets the stable release automatically, because it is the
newest tag.

Nonetheless, there are three reasons to prefer the "latest" tag to
get the stable release, now that the stable release is available.
In descending order of significance, they are:

- We upgrade to work around GitoxideLabs#1849, for which 2.49.0 is preferable
  to 2.48.1 (which the Windows runner images currently have).
  Continuing to take the newest tag will eventually take a
  pre-release for the next version. That would probably work, but
  it is not currently a goal.

  There is sometimes a delay between when a stable release of Git
  for Windows comes out and when the stable runner images are
  released with it. (Pre-release runner images exist, but they are
  not run on GitHub-hosted runners.) So even assuming this upgrade
  step is to be removed once it is no longer needed, it could
  easily end up remaining long enough for a new Git for Windows
  pre-release to come out.

- An update may potentially be released for an earlier minor
  version (y in x.y.z), in which case the tag for it would be
  newer and we would downgrade instead. Now that the release
  marked "latest" is usable here, we can use it and avoid that.

- If we decide to eventually deliberately test pre-releases, the
  step added in GitoxideLabs#1849 would probably not be usable in that form,
  because it could take either the next pre-release or a patch to
  an ealier release per the above points, and also for the separate
  reason that this CI job is not necessarily where we would want to
  test that.

  (As one example, there is currently no CI testing of the Git for
  Windows SDK, even though supporting it, in general and for
  running the test suite, is an explicit goal discussed in GitoxideLabs#1758,
  GitoxideLabs#1761, GitoxideLabs#1862, and GitoxideLabs#1864. If that is added, it may be a more
  opportune way to test prereleases.)
EliahKagan added a commit to EliahKagan/gitoxide that referenced this pull request Mar 18, 2025
The change in the previous commit of switching to the non-shim
`bash.exe` in `(git root)/usr/bin` causes problems, because the
environment may not be correct for shell commands and scripts.
In particular, the `PATH` might not enable standard POSIX tools to
be found, or the tools that are found may interoperate incorrectly
with the shell. The latter caused failures in GitoxideLabs#1862 in an analogous
choice of `sh.exe`, which were addressed by preferring the shim
when available. See:

- GitoxideLabs#1862 (comment)

Here, 90 tests started to fail when the test suite was run locally
from PowerShell (i.e. not a Git Bash environment) on a Windows 10
system that, in addition to a full Git for Windows installation,
contains a separate non-GfW MSYS2 installation whose `bin`
directories are in `PATH` even in non-MSYS2 environments. The
failures were described, and most of them investigated, as follows:

- GitoxideLabs#1864 (comment)
- https://gist.github.com/EliahKagan/3c5eebd091e66d8c912fddbce0a064cd
- https://gist.github.com/EliahKagan/17066ad1f7b0aa98e4fdf4642abe1d93

Most failures, including all those that were unintuitive, were
directly or indirectly due to the `make_remote_repos.sh` fixture
script encountering the error:

    fatal: bad config line 10 in file ./config

This happened due to the same incorrect behavior of `>>`, when used
by a shell that links to one `msys-2.0.dll` running a program that
links to a different `msys-2.0.dll` of another version or build, as
caused the failure encountered with the non-shim in GitoxideLabs#1862.

(It may be the handful of other failures are also caused by this
`>>` problem, but as of now that has not been examined.)

This commit temporarily instruments that fixture script so that,
when tests are run, the observations and analysis in the last gist
above can be confirmed. (These changes are also shown there.)
@EliahKagan EliahKagan force-pushed the run-ci/bash-program branch from e0b422a to 720ae4a Compare March 18, 2025 15:25
@EliahKagan
Copy link
Member Author

EliahKagan commented Mar 18, 2025

Due to the effect of subsequent minor rebases both in #1862 and here (just to bring them forward, not to change them), which were done in that order, I think it no longer matters whether this is rebased (again) after merging #1862. Although the author timestamps are still interleaves, the committer timestamps on all commits in #1862 are now earlier than on all commits here. If that PR is merged first, then I think in practice they will be shown linearized in the expected way, with that PR's commits first, unless a tool is deliberately configured to do otherwise.

Edit: The failure is due to #1896, which is not specific to this PR. I'll rerun.

Starting in GitoxideLabs#1712, `gix-testtools` looks for `bash.exe` on Windows
in one of its common locations as provided by Git for Windows, by
taking the path given by `git --exec-path`, going up by three
components, and going down to `bin/bash.exe` under that. But the
`bin` and `bash.exe` components were appended in a way that used
`\` directory separators.

Ordinarily, that would be ideal, since `\` is the primary directory
separator on Windows. However, in this case, appending with `\`
produces a path that is harder to read (especially in diagostic
messages), and that may cause problems if it is processed by a
shell or in a way that is intended to operate similarly to shell
processing of `\`.

A path that does not explicitly prefer `/` but instead uses
`PathBuf::push` will have `\` in front of the new components, but
will still usually have `/` in front of the old components. This is
because, aside from the unusual case that the `GIT_EXEC_PATH`
environment vairable is set explicitly and its value uses all `\`
separators, the output of `git --exec-path`, which we use to find
where `git` installed on Windows, uses `/` separators.

The effect of this change seems to be fairly minor, with existing
test fixtures having worked before it was done. This is partly
because, on Windows, the value of `argv[0]` that the shell
actually sees -- and that populates `$0` when no script name is
available, as happens in `bash -c '...'` with no subsequent
arguments -- is translated by an MSYS DLL such as `msys-2.0.dll`
(or, for Cygwin, `cygwin1.dll`) into a Unix-style path meaningful
to the shell.

This also refactors for clarity, and adds new tests related to the
change.
This is to help support running them with a shell from the Git for
Windows SDK, which, relative to the directory where it's installed
in, provides a `usr/bin` directory with a `bash.exe` executable,
like the same-named directory in a non-SDK full installation of Git
for Windows via the installer or PortableGit or or via package
managers such as `scoop` that repackage PortableGit, but unlike
those other installations does not provide a `bin` directory.

Inside the MSYS2 "Git Bash" provided as part of the Git for
Windows SDK, there are both `/bin` and `/usr/bin` directories, but
this not related to the `bin` subdirectory of the root of the
installation. On both regular Git for Windows "Git Bash" and Git
for Windows SDK "Git Bash" environments, `/bin` in the environment
is mounted to refer to the same directory as `/usr/bin`. In both,
this is separate from `(git root)/bin` as accessed outside that
environment.

For example, in an SDK "Git Bash":

    $ mount
    C:/git-sdk-64 on / type ntfs (binary,noacl,auto)
    C:/git-sdk-64/usr/bin on /bin type ntfs (binary,noacl,auto)
    C:/Users/ek/AppData/Local/Temp on /tmp type ntfs (binary,noacl,posix=0,usertemp)
    C: on /c type ntfs (binary,noacl,posix=0,user,noumount,auto)
    $ cygpath -w /bin /usr/bin
    C:\git-sdk-64\usr\bin
    C:\git-sdk-64\usr\bin

And in a non-SDK "Git Bash":

    $ mount
    C:/Users/ek/AppData/Local/Temp on /tmp type ntfs (binary,noacl,posix=0,usertemp)
    C:/Users/ek/scoop/apps/git/2.48.1 on / type ntfs (binary,noacl,auto)
    C:/Users/ek/scoop/apps/git/2.48.1/usr/bin on /bin type ntfs (binary,noacl,auto)
    C: on /c type ntfs (binary,noacl,posix=0,user,noumount,auto)
    $ cygpath -w /bin /usr/bin
    C:\Users\ek\scoop\apps\git\2.48.1\usr\bin
    C:\Users\ek\scoop\apps\git\2.48.1\usr\bin

The former has another `bin` directory alongside the `usr` directory
on disk, containing shims for `git.exe`, `sh.exe`, and `bash.exe`,
while the latter does not, but in neither case does `/bin` inside
Git Bash refer to it. This other `bin` directory was formerly used
to find `bash.exe` to run test fixture scripts.

A possible reason to continue using `(git root)/bin` would be if
the shims modify the environment in a way that makes the fixtures
operate better.
The change in the previous commit of switching to the non-shim
`bash.exe` in `(git root)/usr/bin` causes problems, because the
environment may not be correct for shell commands and scripts.
In particular, the `PATH` might not enable standard POSIX tools to
be found, or the tools that are found may interoperate incorrectly
with the shell. The latter caused failures in GitoxideLabs#1862 in an analogous
choice of `sh.exe`, which were addressed by preferring the shim
when available. See:

- GitoxideLabs#1862 (comment)

Here, 90 tests started to fail when the test suite was run locally
from PowerShell (i.e. not a Git Bash environment) on a Windows 10
system that, in addition to a full Git for Windows installation,
contains a separate non-GfW MSYS2 installation whose `bin`
directories are in `PATH` even in non-MSYS2 environments. The
failures were described, and most of them investigated, as follows:

- GitoxideLabs#1864 (comment)
- https://gist.github.com/EliahKagan/3c5eebd091e66d8c912fddbce0a064cd
- https://gist.github.com/EliahKagan/17066ad1f7b0aa98e4fdf4642abe1d93

Most failures, including all those that were unintuitive, were
directly or indirectly due to the `make_remote_repos.sh` fixture
script encountering the error:

    fatal: bad config line 10 in file ./config

This happened due to the same incorrect behavior of `>>`, when used
by a shell that links to one `msys-2.0.dll` running a program that
links to a different `msys-2.0.dll` of another version or build, as
caused the failure encountered with the non-shim in GitoxideLabs#1862.

(It may be the handful of other failures are also caused by this
`>>` problem, but as of now that has not been examined.)

This commit temporarily instruments that fixture script so that,
when tests are run, the observations and analysis in the last gist
above can be confirmed. (These changes are also shown there.)
This changes `bash_program()` so that it will find the `bash.exe`
provided by Git for Windows that is most reliable for our use in
runinng test fixture scripts, of those that are available. First
it uses the shim, but falls back to the non-shim if the shim is
not available. If neither is found, then the fallback of using the
simple command `bash.exe` (which triggers a path search when run)
continues to be used.
To make it easier for users of `gix-testtools` to diagnose problems
or verify that the fallback for running fixutre scripts without
usable shebangs (which is effectively how any fixture shell script
is run on Windows), the formerly private `bash_program()` is now
public.

However, it is not recommend to rely on this specific value or on
observed behavior of how it is computed. The details may change at
any time.

The purpose of `bash_program()` and how it is used internally by
`gix-testtools` is also now documented explicitly. Broad details of
how it searches or guesses what path to use are likewise documented,
with a caveat that changes to them are not considered breaking.
This adds a `bash-program` subcommand, abbreviated `bp`, to the
`gix-testools` program (`jtt`) to check what the `bash_program()`
library function gives.

This is intended for diagnostic use and should probably not be used
in scripting. Currently it shows the quoted debug repreesentation
of the path.
@EliahKagan EliahKagan force-pushed the run-ci/bash-program branch from 720ae4a to 720a23f Compare March 19, 2025 06:20
Copy link
Member

@Byron Byron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wonderful, I am glad this works now.
I also like the idiomatic code.

@Byron Byron enabled auto-merge March 20, 2025 01:29
@Byron Byron merged commit 97d50a3 into GitoxideLabs:main Mar 20, 2025
37 of 39 checks passed
@EliahKagan
Copy link
Member Author

Thanks--I'm glad you like it!

The more substantial conceptually related PR, though technically independent of this one (I tested them both apart and together to be sure) is #1862, for gix-path and gix-command. If and when that one is in, further bug fixes and feature that use its more effective sh detection could be done, including those related to shebang interpretation on Windows.

@EliahKagan EliahKagan deleted the run-ci/bash-program branch March 20, 2025 02:16
EliahKagan added a commit to EliahKagan/gitoxide that referenced this pull request Mar 21, 2025
One of the `justfile` recipes ran `just --fmt --unstable`, and did
so as such. The problem with this is that the `just` executable in
the outer `just` call is not guaranteed to be the same `just` that
the inner call in the recipe finds. For example:

- In general, a user might use a `just` that is not in `$PATH` even
  when another `just` is in `$PATH`. This would happen when testing
  changes to `just`, and potentially in other use cases.

- The "inner" `just` is looked up by a POSIX-compatible shell that,
  on Windows, may have a changed environment. For example, the
  `sh.exe` shim provided by Git for Windows modifies environment
  variables including placing some directories in the front of
  `$PATH`. (See discussion in GitoxideLabs#1864 for details.)

Thus `just` provides a built-in function `just_executable()` that
can be used, and which we already use in the default recipe.

This uses that function instead. However, it is not as simple as
`{{ just_executable() }} --fmt --unstable`, because the path may
require quoting to be run in a shell.

In practice, it almost always needs to be quoted on Windows, where
otherwise a `\` is being given to the shell (which the shell is
required to interpret as a quoting character; this is distinct from
a scenario where a path might be passed as an argument to a shell,
in which case strange things may or may not occur). It might rarely
need to be quoted on other systems too, it it has spaces or other
even weirder contents.

So this uses `{{ quote(just_executable()) }}`. It does so through
the `j` variable that has already been assigned that value.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants