cat-dev-null/has-rs
1
0
Fork
You've already forked has-rs
0
A port of the "has" shell tool, rewritten in Rust http://cat-dev-null.codeberg.page/has-rs
  • HTML 56.8%
  • Rust 23.4%
  • Shell 14.3%
  • Just 5.5%
cat-dev-null c0af1d4f9b
All checks were successful
Release / test (push) Successful in 1m53s
Release / build (push) Successful in 7m41s
Release / pages (push) Successful in 44s
Merge pull request 'release: v0.3.0' ( #7 ) from release/v0.3.0 into main
Reviewed-on: #7 
2026年04月04日 07:48:05 +02:00
.forgejo ci: attempting to validate CI files inside of CI 2026年04月03日 23:22:17 -06:00
.zed chore: zed editor settings 2026年03月01日 22:17:35 -07:00
pages feat(program): added support for new program pandoc 2026年04月03日 22:34:46 -06:00
pkg chore: slight change to way gitignore is done for pkg folder 2026年03月02日 05:01:19 -07:00
release_notes feat(program): added support for new program forgejo-runner 2026年04月03日 23:28:56 -06:00
src feat(program): added support for new program forgejo-runner 2026年04月03日 23:28:56 -06:00
test feat(program): added support for new program forgejo-runner 2026年04月03日 23:28:56 -06:00
.gitignore Merge branch 'pages' into release/v0.2.1 2026年03月02日 05:02:53 -07:00
.hasrc feat(program): added support for new program forgejo-runner 2026年04月03日 23:28:56 -06:00
.rusty-hook.toml feat(program): added support for new program forgejo-runner 2026年04月03日 23:28:56 -06:00
Cargo.lock chore: bumped to 0.3.0 2026年04月03日 22:20:14 -06:00
Cargo.toml chore: bumped to 0.3.0 2026年04月03日 22:20:14 -06:00
justfile ci: release assets have version in filename 2026年04月03日 22:20:14 -06:00
LICENSE chore: bumped copyright year 2026年03月02日 01:56:47 -07:00
README.md chore: bumping version to 0.2.3 2026年03月02日 22:26:51 -07:00

has-rs

This is a Rust port of the has shell script (hereby referred to as has-bash) that checks if common tools are installed.

Specifically, it is a port made to be as close to the original bash source as possible (and as is reasonable) to make keeping up to date with new functionality as easy as possible.

Installation:

cargo install --git https://codeberg.org/cat-dev-null/has-rs

Or if you would like to specify one of the features:

# Disables the new `--allow-unsafe` flag, making has-rs act more in line with has-bash
cargo install --git https://codeberg.org/cat-dev-null/has-rs --no-default-features
# OR
# To never have to set the HAS_ALLOW_UNSAFE environment variable
cargo install --git https://codeberg.org/cat-dev-null/has-rs --no-default-features --features always-allow-unsafe

Ideally this is a drop in replacement, but here is what I can confirm are the same as of has-bash 1.5.2.

  • -q flag to silence output
  • -h/--help flag to output help
  • Color flags behave the same (--color-auto, --color-always, --color-never)
  • Returns the number of missing programs as the exit code
    • Maxes out at 126 just like has-bash
  • Prints same output format
  • Auto-detects and checks .hasrc in the working directory
    • Comments are supported in the same way as has-bash (lines starting with #)
  • Setting the HAS_ALLOW_UNSAFE environment variable to y attempts to use --version for programs unknown by has-rs
  • Two pattern special cases act the same (*coreutils and linux*utils)

Differences from the bash version

  • The help output will look different
  • -q flag also has the long form --quiet
  • -v/--version flag outputs the version, but in the Rust clap standard format
    • has-rs: has 0.2.3
    • has-bash: v1.5.2
  • .hasrc supports comments not just as whole line but end of line (e.g. jq # needed for tooling)
  • Alternates can be specified by separating with the "|" character
    • For example, has "curl|wget" will check for curl and, if it is not found, will then check for wget
    • It is only counted as a failure if none of the programs are present
  • Optional programs can be specified by appending a ? to the program name
    • For example, has "curl?" will check for curl and, if it is not found, will not fail the check
  • The new --hide-optional flag will suppress output for missing alternates or optional programs
    • For example, has "curl|wget" will print a line for curl if it is not found; has "curl|wget" --hide-optional will not
  • The new --no-rc flag will skip loading the .hasrc file
  • The new --allow-unsafe flag acts like (and supersedes) the HAS_ALLOW_UNSAFE environment variable

has-rs can also be compiled so that "allow safe" is always allowed, which is achieved via the always-allow-unsafe feature. If this feature is enabled, allow-unsafe-flag cannot also be enabled, because there is no point to either the flag or the environment variable in that case.

Building

Whilst of course you can just use cargo build, this project uses just as a task runner.

Take a look at .hasrc (or if you have has-bash install, just run has) to see what is expected to be on your system.

Here's some helpful commands to get you started:

  • just --list or just -l shows all available recipes
  • just build or just will build for your host system
  • just build-all builds for all platforms, architectures, and standard C libraries
  • just build-all-linux, just build-all-windows, and just build-all-mac all do what they say
  • just test will run the non-Rust tests that ensure the program is working as expected
  • just dist will package up any binaries that have been compiled inside the dist directory

Why?

Some might ask, why port a perfectly good shell script to Rust?

  • I hate bash
  • I'm exploring Rust
  • For fun