Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 30 additions & 27 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,40 +13,43 @@ jobs:
- name: Run Shellcheck
uses: ludeeus/action-shellcheck@2.0.0

test:
name: test
test-ubuntu:
name: test (ubuntu)
runs-on: ubuntu-latest
strategy:
matrix:
container:
- debian # uses debian:buster-20200327-slim which is debian 10.3
- ubuntu16 # uses ubuntu:xenial-20200212 which is ubuntu 16.04

container: kdabir/has-test-containers:${{ matrix.container }}

steps:
- name: Clone Repo
uses: actions/checkout@v4

- name: test
run: make test
- name: Setup Bats and bats libs
id: setup-bats
uses: bats-core/bats-action@3.0.0
- name: Run Unit Tests
run: make unit-test
shell: bash
- name: Run Integration Tests
run: make intg-test
shell: bash

test_all:
name: test_all
runs-on: ubuntu-latest
strategy:
matrix:
container:
- ubuntu # uses ubuntu:bionic-20200311 which is ubuntu 18.04
- alpine # uses bash:5.0.16 which is alpine 3.11

container: kdabir/has-test-containers:${{ matrix.container }}

test-macos:
name: test (macos)
runs-on: macos-latest
steps:
- name: Clone Repo
uses: actions/checkout@v4

- name: test_all
run: bats -t ./tests/test_all_packages.bats
- name: Install bats-core
run: brew install bats-core
- name: Run Unit Tests
run: make unit-test
shell: bash
- name: Run Integration Tests
run: make intg-test
shell: bash

# intg-test:
# name: intg-test
# runs-on: ubuntu-latest
# steps:
# - name: Clone Repo
# uses: actions/checkout@v4
# - name: Run Integration Tests in Docker
# run: make docker-test
# shell: bash
10 changes: 8 additions & 2 deletions .hasrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# make to install/test the project
# required to install/test the project
make
curl
git
# bats for testing
# bats for testing shell script
bats
# for running integration tests
# their outputs will be tested
sed
awk
jq
node
78 changes: 78 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Contributing to has

Thank you for your interest in contributing! Please follow these guidelines to get started.

## How to run locally

1. **Clone the repository:**
```bash
git clone https://github.com/kdabir/has.git
cd has
chmod +x ./has
```
2. **Run the main script:**
```bash
./has <command-names>
```
Example:
```bash
./has git curl node
```
3. Install Prequisites for development

```bash
./has
```

running `has` from root of the project tells you about the pre-requisites required (because of `.hasrc` file)

## How to run tests locally

1. **Install dependencies:**
- On Ubuntu:
```bash
sudo apt-get update && sudo apt-get install -y bats make curl git
```
- On Mac (using Homebrew):
```bash
brew install bats-core make curl git
```
2. **Run the unit test suite:**
```bash
make test
# or
bats tests/unit/unit-tests.bats
```

## Adding more tools

The current list of supported packages can be viewed with `make list`

If the command you wish to include supports any of `-v`, `--version`, `-version`, `version`, `-V` then you can find
corresponding function which can be called to check presence and extract version.

- commands that use `--version` flag -> `__dynamic_detect--version()`
- commands that use `-version` flag -> `__dynamic_detect-version()`
- commands that use `-v` flag -> `__dynamic_detect-v()`
- commands that use `-V` flag -> `__dynamic_detect-V()`


However, for many tools version extraction may not work and you will need to add custom parsing of command's output. The `has` script is commented to guide developers about what needs to be done to add more tools.

## Adding features

- If you are contributing a feature, please open an issue first to dicuss the idea.
- When implmenting, ensure to check current tests. Add test cases for your feature.
- Tests are executed using the excellent [bats](https://github.com/bats-core/bats-core) testing framework.
- Add tests and run `make test`

Raise the PR and **make sure the tests pass** on [GitHub Actions](https://github.com/kdabir/has/actions).


## Looking for support to maintain docker based tests
I'm not expert at docker (or shell scripts for that matter). I need someone to look at `tests/to-fix` dir to help me
with integration tests for all tools installed in docker containers.

- `test_all_packages.bats` will test every package has supports. This includes newly added commands so please add new packages to
- `alpine.Dockerfile` and `ubuntu.Dockerfile` to install the tool OR
- `packages_alpine_skip.txt` and `packages_ubuntu_skip.txt` to exclude the package from the tests
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2014-2018 Kunal Dabir, Saager Mhatre and various contributors
Copyright (c) 2014-2025 Kunal Dabir, Saager Mhatre and various contributors

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
Expand Down
32 changes: 30 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@ ifeq ($(PREFIX),)
PREFIX := /usr/local
endif

test : has
bats .hastest.bats

test: unit-test intg-test

unit-test:
bats tests/unit/unit-tests.bats
bats tests/unit/with-mocks.bats

intg-test:
bats -t tests/intg/intg-tests.bats

has :
# ensure 'has' in repo
Expand Down Expand Up @@ -38,3 +45,24 @@ uninstall :

.PHONY: test install uninstall update

CONTAINERS = ubuntu alpine

.PHONY: docker-test

docker-test:
@for c in $(CONTAINERS); do \
$(MAKE) docker-test-$$c; \
done

.PHONY: docker-test-%
docker-test-%:
docker build -t test-image:$* -f tests/to-fix/containers/$*.Dockerfile .
docker run --rm \
-v $(PWD):/workspace \
-w /workspace \
test-image:$* \
bash -c "make test || bats -t ./tests/to-fix/test_all_packages.bats || true"


list:
@grep -o "^ \\+[a-zA-Z0-9_|-]\\+)" has | grep -o "[a-zA-Z0-9_|-]\\+" | tr "|" "\\n" | sort -f | sed '1,3d'
69 changes: 25 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
`has` checks presence of various command line tools on the PATH and reports their installed version.

[![Build Status](https://github.com/kdabir/has/actions/workflows/main.yml/badge.svg)](https://github.com/kdabir/has/actions/workflows/main.yml)
[![Open Source Helpers](https://www.codetriage.com/kdabir/has/badges/users.svg)](https://www.codetriage.com/kdabir/has)

[![demo](demo.svg)](demo.svg)

Expand All @@ -13,19 +12,19 @@ Just [install](#installing) the `has` script, (there is no dependency apart from

```console
$ has node npm java git gradle
node 8.2.1
npm 5.3.0
java 1.8.0
git 2.14.1
gradle 4.0.1
node 22.17.0
npm 11.5.1
java 21.0.7
git 2.50.1
gradle 8.14.2
```

If everything is good `has` exits with status code `0`. The exit status code reflects number of commands **not found** on your path.

```console
$ has node go javac
node 8.2.1
go 1.8.3
node 22.17.0
go 1.24.5
✘ javac
```

Expand Down Expand Up @@ -104,9 +103,9 @@ If you are lazy, you can run `has` directly off the Internet as well:

```console
curl -sL https://git.io/_has | bash -s git node npm
git 2.17.1
node 11.11.0
npm 6.7.0
git 2.50.1
node 22.17.0
npm 11.5.1
```

**ProTip**: if that's too much typing every time, setup an alias in your `.bashrc`/`.zshrc` file:
Expand All @@ -119,7 +118,7 @@ And use it

```console
$ has git
git 2.17.1
git 2.50.1
$ type has
has is aliased to `curl -sL https://git.io/_has | bash -s'
```
Expand Down Expand Up @@ -153,22 +152,22 @@ When `has` is run in directory containing this file, it produces:

```console
$ has
git 2.19.1
curl 7.54.0
ruby 2.3.1
node 10.7.0
git 2.50.1
curl 8.5.0
ruby 3.4.1
node 22.17.0
```

Also, CLI arguments passed to `has` are additive to `.hasrc` file. For example, in the same dir, if the following command is fired,
`has` checks for both commands passed from cli args and provided in `.hasrc` file.

```bash
$ has java
java 11.0.1
git 2.19.1
curl 7.54.0
ruby 2.3.1
node 10.7.0
java 21.0.7
git 2.50.1
curl 8.5.0
ruby 3.4.1
node 22.17.0
```

**Pro Tip**: commit `.hasrc` file in root of your project. This can work as a quick check for confirming presence all command
Expand All @@ -180,31 +179,13 @@ On machines that don't even have `has` installed, your project's `.hasrc` is hon

> take a look at [.hasrc](https://github.com/kdabir/has/blob/master/.hasrc) file for this repo.

## Contributing
## Supporting

1. Star the repo, tweet about it, spread the word
2. Update the documentation (i.e. the README file)
3. Adding support for more commands
4. Adding more features to `has`
here are some ways you can help:

## Adding more tools
1. Star the repo, write about it, spread the word
2. Update the documentation (including this README)
3. Adding support for more commands and features - see [CONTRIBUTING.md](CONTRIBUTING.md)

The current list of supported packages can be viewed with `bash tests/packages_all.sh`

If the command you wish to include supports any of `-v`, `--version`, `-version`, `version`, `-V` then you can find
corresponding function which can be called to check presence and extract version. However, for many tools version
extraction may not work and you will need to add custom parsing of command's output. The `has` script is commented
to guide developers about what needs to be done to add more tools.

`/tests/test_all_packages.bats` will test every package has supports. This includes newly added commands so please add new packages to
- `alpine.Dockerfile` and `ubuntu.Dockerfile` to install the tool OR
- `packages_alpine_skip.txt` and `packages_ubuntu_skip.txt` to exclude the package from the tests

## Adding Features

If you are contributing a feature, please ensure to check current tests. Add test cases for your feature. Tests are
executed using the excellent [bats](https://github.com/bats-core/bats-core) testing framework. Add tests and run `make test`

Raise the PR and **make sure the tests pass** on [GitHub Actions](https://github.com/kdabir/has/actions).

### ♥
2 changes: 1 addition & 1 deletion has
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Has checks the presence of various command line tools on the PATH and reports th
Options:
-q Silent mode
-h, --help Display this help text and quit
-V, --version Show version number and quit
-v, --version Show version number and quit

Examples: ${BINARY_NAME} git curl node
EOF
Expand Down
Loading
Loading