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
37 changes: 13 additions & 24 deletions .github/workflows/interactive-command.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ on:
command:
description: "Command to execute"
required: true
default: "sed --version"
default: "demo/all-demos.sh"
os:
description: "Operating system to run the command on"
required: true
default: "ubuntu-latest"
default: "macos-latest"
type: choice
options:
- ubuntu-latest
Expand All @@ -21,6 +21,9 @@ on:
default: false
type: boolean

run-name: |
ICE: ${{ inputs.command }} (${{ inputs.os }}, GNU? ${{ inputs.install_gnu_tools }})

permissions:
contents: read

Expand All @@ -29,30 +32,16 @@ jobs:
runs-on: ${{ inputs.os }}

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
submodules: recursive

- name: Install GNU tools on macOS
if: runner.os == 'macos-latest' && inputs.install_gnu_tools == 'true'
if: ${{ inputs.install_gnu_tools }}
run: |
brew install gnu-sed gawk grep findutils coreutils gnu-tar gnu-time gnu-indent gnu-getopt gnu-which
brew install gdate gxargs gcut ghead gtail gtr guniq gwc gdiff
echo 'export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/gawk/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/grep/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/findutils/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/gnu-tar/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/gnu-time/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/gnu-indent/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/gnu-getopt/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/gnu-which/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/gdate/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/gxargs/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/gcut/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/ghead/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/gtail/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/gtr/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/guniq/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/gwc/libexec/gnubin:$PATH"' >> $GITHUB_ENV
echo 'export PATH="/usr/local/opt/gdiff/libexec/gnubin:$PATH"' >> $GITHUB_ENV
bin/gnu-install.sh

- name: Execute command
run: ${{ inputs.command }}
58 changes: 58 additions & 0 deletions bin/gnu-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/usr/bin/env bash
###
### Script to install GNU tools (typically on macOS).
###
### Requires `brew` to be installed.
###

set -o errexit # abort on nonzero exit status
set -o nounset # abort on unbound variable
set -o pipefail # don't hide errors within pipes

### GNU Tools to install
###
### References:
### - https://gist.github.com/skyzyx/3438280b18e4f7c490db8a2a2ca0b9da
### - https://www.topbug.net/blog/2013/04/14/install-and-use-gnu-command-line-tools-in-mac-os-x/
### https://github.com/asantra1/macOS-gnu-tools/blob/master/gnu-cmd.sh

declare -a GNU_TOOLS=(
"binutils"
"coreutils"
"diffutils"
"ed"
"findutils"
"gawk"
"gnu-indent"
"gnu-sed"
"gnu-tar"
"gnu-which"
"gnutls"
"grep"
"gzip"
"screen"
"watch"
"wdiff"
"wget"
)

### Validate `brew` is installed
if ! command -v brew &>/dev/null; then
echo "Error: 'brew' is required. Please install it first."
exit 1
fi

### Install GNU Tools
for tool in "${GNU_TOOLS[@]}"; do
if brew list --formula | grep -q "^${tool}\$"; then
if brew outdated --formula | grep -q "^${tool}\$"; then
echo "Updating ${tool}..."
brew upgrade "${tool}"
else
echo "${tool} is already installed and up-to-date."
fi
else
echo "Installing ${tool}..."
brew install "${tool}"
fi
done
16 changes: 16 additions & 0 deletions demo/all-demos.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
###
### Run all demo scripts.
###

SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"
declare -r SCRIPT_DIR

# Find all -demo.sh files in the demo directory and run them.
for demo_script in "${SCRIPT_DIR}"/*-demo.sh; do
if [[ -f "${demo_script}" ]]; then
echo "Running demo: ${demo_script}"
"${demo_script}"
echo
fi
done
41 changes: 41 additions & 0 deletions demo/gnucompat-demo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
###
### Demo for GNU Tools Compatibility Layer
###

SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"
declare -r SCRIPT_DIR
# shellcheck source=/dev/null
source "${SCRIPT_DIR}/../lib_gnucompat.sh"

# Function to output the path and GNU status of a command
function output_command_info() {
local cmd_var_name="${1}"
local cmd="${!cmd_var_name}"
local cmd_path
cmd_path=$(command -v "${cmd}")
local gnu_status
if is_gnu "${cmd}"; then
gnu_status="Yes"
else
gnu_status="No"
fi
echo "${cmd_var_name}: ${cmd_path} (GNU? ${gnu_status})"
}

# Output information for each command
output_command_info "SED"
output_command_info "AWK"
output_command_info "GREP"
output_command_info "FIND"
output_command_info "SORT"
output_command_info "TAR"
output_command_info "DATE"
output_command_info "XARGS"
output_command_info "CUT"
output_command_info "HEAD"
output_command_info "TAIL"
output_command_info "TR"
output_command_info "UNIQ"
output_command_info "WC"
output_command_info "DIFF"
11 changes: 8 additions & 3 deletions lib_gnucompat.sh
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,16 @@ export DIFF
function is_gnu() {
local cmd="${1:?Error: No command provided to is_gnu function}"

# Check if the command is a GNU tool by expecting the version output
# to contain "GNU".
# Check if the command is available
if ! command -v "${cmd}" &>/dev/null; then
return 0
fi

("${cmd}" --version &>/dev/null) || return 1

local version_output
version_output="$("${cmd}" --version 2>&1)"
if "${GREP}" -q "GNU" <<<"${version_output}"; then
if [[ "${version_output}" == *"GNU"* ]]; then
return 0
else
return 1
Expand Down