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

Update an archive and add some missing executable bits #1589

Merged
merged 2 commits into from
Sep 11, 2024

Conversation

EliahKagan
Copy link
Member

@EliahKagan EliahKagan commented Sep 10, 2024

One of the fixture scripts was modified in b12c7c9 (#1587) to fix typos, which changed its hash, but a regenerated archive was not committed at that time.

Other fixture scripts were recently introduced, and they have current archives committed, but they were not given executable bits, even though they are executable scripts that start with #! and the other fixture scripts have +x.

This small "maintenance" PR addresses those two things (one per commit).

I have verified that tests pass locally on Ubuntu 24.04 LTS, macOS 14.6, and Windows 10, both before and after this change, and that the make_dangling_symlink_to_windows_reserved archive, which previously had an uncommitted change on Ubuntu and macOS after running the tests, is no longer changed when the test suite is run. (It did not show as dirty on Windows because gix-testtools suppresses archive generation on Windows, but committing the regenerated script should help Windows tests to run slightly faster, too.)

In b12c7c9 (GitoxideLabs#1587), the `make_dangling_symlink_to_windows_reserved`
script was changed to fix typos. Though this did not alter its
effect, its hash changed, so the committed archive generated from
it could no longer be used. This commits a regenerated archive.
Some of the more recently introduced fixture scripts were not
marked executable, even though the others are.

Because `gix-testtools` has a fallback that runs scripts with
`bash` explictly when executing them directly fails, this did not
break any scripts, but the executable bit is also useful to
document which files are meant to be runnable scripts.

This marks them executable. Now all the shell scripts that begin
with a `#!` have the executable bit set. (The handful of `.sh`
files that are not meant to be run as scripts, but instead are
sourced by other scripts, do not start with `#!` and continue not
to have `+x` applied to them.)
@Byron
Copy link
Member

Byron commented Sep 11, 2024

Thanks a lot, much appreciated.

I wondered if there should be a CI job that tests invariants, maybe based on just check-invariants, which simply runs a script to verify a few things. We might already have that in the form of the script that validates that gix-packetline-blocking still matches gix-packetline.

@Byron Byron merged commit 7c2af44 into GitoxideLabs:main Sep 11, 2024
15 checks passed
@EliahKagan EliahKagan deleted the maintenance branch September 11, 2024 07:08
@EliahKagan
Copy link
Member Author

I don't know a good near-instantaneous way to test whether archives need to be regenerated without having just run the tests. This is one of the reasons I implemented #1590 the way I did.

For scripts, though, we can certainly check all non-ignored files to make sure that files that seem to be scripts (or, I think better, that seem to be plain text) start with #! if and only if they are marked executable. Conceptually, I want to say this is sort of like checking the relationship between gix-packetline and gix-packetline-blocking, except that all of the design considerations point in the other direction:

  • This should be only a check (instead of only a fix) because examination is required to determine if a file should gain an executable bit or lose its #!.
  • Everything, automated including building and using just, works even if it finds a problem, so there is no reason for it to be a shell script. So it should be a subcommand in tests/tools/main.rs.

@Byron
Copy link
Member

Byron commented Sep 11, 2024

I like the idea of implementing such functionality in Rust instead.

However, I'd hope to bring more of such 'internal' functionality into the internal-tools crate, which probably isn't cheap to build but when done, it can do a lot of work quickly. Maybe that could be a separate job to not prolong the runtime of anything else.

Maybe another argument could be made to say that tests/tools/main.rs should only contain tools that are useful to everyone, which means that the mess-in-the-middle sub-command is probably too specific and should rather go to internal-tools as well. However, having 'what-seems-like-shell-scripts' carry executable bits, seems like something useful to everyone.

Despite all of this, my disposition is to turn gix-testtools into a pure library, and move all new functionality to run within this repository into internal-tools, a crate the won't be published. After all, maybe the build times aren't that bad, I didn't check.

@EliahKagan
Copy link
Member Author

Checking that fixtures have correct executable bits seems like something relevant to most users of gix-testtools, assuming most users of gix-testtools use it to run fixture scripts. So maybe it should go in gix-testtools. But that doesn't require that it go in main.rs: it could be implemented in a newly introduced public function in lib.rs and the utility that calls it could be elsewhere: either as a command-line tool in internal-tools, or just as a test case for gitoxide itself, alongside the top-level integration tests.

@Byron
Copy link
Member

Byron commented Sep 11, 2024

That's fair - let's put it into gix-testtools main.rs then - for now I wouldn't feel comfortable adding an actual 'test' or 'check' to the library though. If there is a demand, that could change, of course.

@EliahKagan
Copy link
Member Author

As alluded to in #1692 (comment), I no longer favor putting this in the main.rs for gix-testtools. I don't hold the view that this shoudn't be done or have anything against it. But I no longer specifically prefer it.

The reason is that it will either be portable to Windows or not:

  • If it's not portable to Windows, then even if useful and adequate to our needs, it will not be robust enough that is necessarily worth publishing in a crate.

  • If it is portable to Windows, then it will access the repository metadata itself to check executable bits, since Windows does not have Unix-style executable bits. (Tools in an MSYS-like environment generally treat text files as being marked executable when they start with a #!. That approach cannot be used here because the point of the check is that this can be wrong and that we want to find out when it is.)

    But then it should be written to use gitoixde to check that. To do so, it would need more gix-* crate dependencies than those gix-testtools currently declares. That might not be wanted. On the other hand, maybe my thinking here is the opposite of what it should be. Is it okay to have gix-testtools depend on more of gitoxide? Is it okay for internal-tools to depend on gix-* crates? (Can internal-tools depend on gix-testtools?)

@Byron
Copy link
Member

Byron commented Nov 25, 2024

  • But then it should be written to use gitoixde to check that. To do so, it would need more gix-* crate dependencies than those gix-testtools currently declares. That might not be wanted. On the other hand, maybe my thinking here is the opposite of what it should be. Is it okay to have gix-testtools depend on more of gitoxide? Is it okay for internal-tools to depend on gix-* crates? (Can internal-tools depend on gix-testtools?)

In theory, it should be OK for internal-tools to do anything, particularly because it's not being published. As it stands, gix-testtools shouldn't depend on more crates as even the current 'setup' is a hack and workaround that should really be fixed in cargo smart-release - after all, releases fail if gix-testtools dares to refer to current versions of workspace dependencies due to a cyclic dependency.

If a tool were to use Git to learn about executable bits, I'd think it could even use git.exe if it doesn't have access (or doesn't want to use) gix-index.

@EliahKagan
Copy link
Member Author

EliahKagan commented Nov 27, 2024

If a tool were to use Git to learn about executable bits, I'd think it could even use git.exe if it doesn't have access (or doesn't want to use) gix-index.

If that is acceptable, then another option could be for this to be a shell script.

An approach I do not favor, kept in for completeness (click to expand)

Such a script could even also automatically set and unset executable permissions based on the presence of #!, both in the index and in the working tree (as scripts have done in fixture repositories since #1652).

This could then be used on CI like check-packetline uses etc/copy-packetline.sh, except that for this the diff command would be git diff --staged --exit-code instead of git diff --exit-code.

Another difference is that, because changing executable permissions is much less likely to cause data loss, the script would not need to check for various conditions such as staged or unstaged changes and a currently in-progress merge. It could therefore be considerably simpler than etc/copy-packetline.sh.

Or, if the script does not modify anything but just reports files that start with #! but no +x in the index, and those that do not start with #! but have +x in the index, then the script could be simpler.

I favor this approach, because while there is much less risk of data loss here than in copy-packetline.sh, there is also more ambiguity about what the right thing is to do here:

  • Usually executable permissions should be brought in line with what the presence of absence of a #! would predict for them.
  • But sometimes the executable permissions could be correct and the #! should be added or removed.

I view the main benefits of doing this in Rust to be that it would demonstrate how to use gitoxide to check the repository and staged files (for both metadata and blob content), and that I might find it enjoyable to practice doing so. If external git is to be used, I think the benefits go away. (Regarding my own enjoyment, there is fortunately no lack of other opportunities to write small tools that use gitoxide for other things that I am already hoping to do. I may inquire as to whether some of them would be suitable for inclusion here as examples.)

I'll look into this further and, unless I find reasons to prefer otherwise (or you point out any), I'll do this as a shell script that reports incongruities in the index of #! vs. +x/-x.

@Byron
Copy link
Member

Byron commented Nov 28, 2024

I view the main benefits of doing this in Rust to be that it would demonstrate how to use gitoxide to check the repository and staged files (for both metadata and blob content), and that I might find it enjoyable to practice doing so. If external git is to be used, I think the benefits go away. (Regarding my own enjoyment, there is fortunately no lack of other opportunities to write small tools that use gitoxide for other things that I am already hoping to do. I may inquire as to whether some of them would be suitable for inclusion here as examples.)

Even though doing it as shell-script will be fine, if you'd prefer to write it in Rust then I think there should be no issue adding it to internal-tools - it has full access to all of gix, and clap on top of that. It is what gix-testtools cannot be.

EliahKagan added a commit to EliahKagan/gitoxide that referenced this pull request Nov 28, 2024
It is rare that text files should be stored in a repository with a
leading `#!` (shebang, a.k.a. hashbang) but `-x` permissions, or
with no leading `#!` but `+x` permissions. But it is easy for this
to happen by accident.

This introduces a script to check for that situation -- currently
only in files whose names end in `.sh`, which are the files in
which this minor problem has tended to arise in this repository.

This adds a `justfile` recipe for it, as well as a CI job that runs
the script. (The CI job does not run it via `just`, since not doing
so allows it to save time by not installing anything.)

Currently, this:

- Looks only at what is committed and staged, ignoring unstaged
  files and unstaged mode changes. (This is intended to allow it to
  be cross platform, because on Windows, Git repositories support
  the same modes as anywhere else, but the filesystem doesn't
  support Unix-style executable permissions.)

- Is implemented as a shell script. Unlike `copy-packetline.sh`,
  there would be no major disadvantage to having this be Rust code
  instead, since it is never used to correct a problem that keeps
  Rust code from building.

- Is called from a separate CI job than any others. But it could
  probably be called from one of the existing jobs instead.

There are some files already in the repository that fail the new
check, which should be given `+x` permissions. In this commit, they
are kept as-is, and new files that should be detected as *wrongly*
having `+x` permissions are added. This is to verify that the
script is fully working as expected, including when run on CI. Once
that is confirmed, the new test files can be removed, the scripts
missing `+x` fixed, and the CI job made to run only on Ubuntu.

(See the commented discussion in GitoxideLabs#1589 for further information.)
@EliahKagan
Copy link
Member Author

Thanks! I've opened #1708 for this. I had already written it as a shell script, so for now I've kept that way (this is discussed a bit in the PR description).

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