From 5f24719c00415d74bf998f7011b2dc52d7ba2b10 Mon Sep 17 00:00:00 2001 From: Mark Michaelis Date: Sat, 8 Mar 2025 00:24:32 +0100 Subject: [PATCH 01/15] ci(github): Checkout Workspace To be able to also execute scripts, checkout the workspace. --- .github/workflows/interactive-command.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/interactive-command.yml b/.github/workflows/interactive-command.yml index 3e20b1a..025f95c 100644 --- a/.github/workflows/interactive-command.yml +++ b/.github/workflows/interactive-command.yml @@ -29,6 +29,11 @@ jobs: runs-on: ${{ inputs.os }} steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + - name: Install GNU tools on macOS if: runner.os == 'macos-latest' && inputs.install_gnu_tools == 'true' run: | From bd8f1be126a9e9c99bc1c523ad5ea4224e83c9b4 Mon Sep 17 00:00:00 2001 From: Mark Michaelis Date: Sat, 8 Mar 2025 00:26:20 +0100 Subject: [PATCH 02/15] fix(lib): is_gnu --- lib_gnucompat.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib_gnucompat.sh b/lib_gnucompat.sh index e000435..5c36813 100644 --- a/lib_gnucompat.sh +++ b/lib_gnucompat.sh @@ -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 From 1ccce95d2fd0841dc97e3b253c41426ea295cf29 Mon Sep 17 00:00:00 2001 From: Mark Michaelis Date: Sat, 8 Mar 2025 00:26:50 +0100 Subject: [PATCH 03/15] fix(lib): Update Demo Script --- demo/gnucompat-demo.sh | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100755 demo/gnucompat-demo.sh diff --git a/demo/gnucompat-demo.sh b/demo/gnucompat-demo.sh new file mode 100755 index 0000000..90f13f6 --- /dev/null +++ b/demo/gnucompat-demo.sh @@ -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" From 622209ba3f8847aeb0d59ad41fcfcfc3f5ba63d0 Mon Sep 17 00:00:00 2001 From: Mark Michaelis Date: Sat, 8 Mar 2025 00:32:58 +0100 Subject: [PATCH 04/15] ci(github): Fix Actual OS Check --- .github/workflows/interactive-command.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/interactive-command.yml b/.github/workflows/interactive-command.yml index 025f95c..779d138 100644 --- a/.github/workflows/interactive-command.yml +++ b/.github/workflows/interactive-command.yml @@ -35,7 +35,7 @@ jobs: fetch-depth: 1 - name: Install GNU tools on macOS - if: runner.os == 'macos-latest' && inputs.install_gnu_tools == 'true' + if: inputs.os == 'macos-latest' && inputs.install_gnu_tools == 'true' 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 From f4ae248e7016a1355f9e655b5b0f2012747f9c2b Mon Sep 17 00:00:00 2001 From: Mark Michaelis Date: Sat, 8 Mar 2025 00:36:53 +0100 Subject: [PATCH 05/15] ci(github): Remove Extra OS Check Remove sanity check for macos. --- .github/workflows/interactive-command.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/interactive-command.yml b/.github/workflows/interactive-command.yml index 779d138..8885ca0 100644 --- a/.github/workflows/interactive-command.yml +++ b/.github/workflows/interactive-command.yml @@ -10,7 +10,7 @@ on: os: description: "Operating system to run the command on" required: true - default: "ubuntu-latest" + default: "macos-latest" type: choice options: - ubuntu-latest @@ -35,7 +35,7 @@ jobs: fetch-depth: 1 - name: Install GNU tools on macOS - if: inputs.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 From 79dbf77e43529eb44d5cb3f81a29a4df8ec93ca1 Mon Sep 17 00:00:00 2001 From: Mark Michaelis Date: Sat, 8 Mar 2025 00:41:20 +0100 Subject: [PATCH 06/15] ci(github): Remove gdate It is not available. --- .github/workflows/interactive-command.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/interactive-command.yml b/.github/workflows/interactive-command.yml index 8885ca0..2a6b28b 100644 --- a/.github/workflows/interactive-command.yml +++ b/.github/workflows/interactive-command.yml @@ -38,7 +38,7 @@ jobs: 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 + brew install 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 From dfa1cb6a04ac36804165d36d9eda18be18b1a09d Mon Sep 17 00:00:00 2001 From: Mark Michaelis Date: Sat, 8 Mar 2025 00:47:44 +0100 Subject: [PATCH 07/15] ci(github): Debugging Output Add some output of the available commands after GNU tools have been installed. --- .github/workflows/interactive-command.yml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/interactive-command.yml b/.github/workflows/interactive-command.yml index 2a6b28b..d83d04b 100644 --- a/.github/workflows/interactive-command.yml +++ b/.github/workflows/interactive-command.yml @@ -37,8 +37,20 @@ jobs: - name: Install GNU tools on macOS 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 gxargs gcut ghead gtail gtr guniq gwc gdiff + brew install \ + gnu-sed \ + gawk \ + grep \ + findutils \ + coreutils \ + diffutils \ + gnu-tar \ + gnu-time \ + gnu-indent \ + gnu-getopt \ + gnu-which + # Show tree of /usr/local/opt + ls -R /usr/local/opt 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 From 1776b29f8e72e50ffd6c539e776b97cc982f9514 Mon Sep 17 00:00:00 2001 From: Mark Michaelis Date: Sat, 8 Mar 2025 09:51:11 +0100 Subject: [PATCH 08/15] feat(bin): Script to Install GNU-Tools --- bin/gnu-install.sh | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100755 bin/gnu-install.sh diff --git a/bin/gnu-install.sh b/bin/gnu-install.sh new file mode 100755 index 0000000..7e993b0 --- /dev/null +++ b/bin/gnu-install.sh @@ -0,0 +1,70 @@ +#!/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" +) + +### GNU Tools to update +### +### Some GNU tools are already installed on macOS, but may be outdated. +### This list contains the tools that should be updated. +### +### References: +### - https://github.com/asantra1/macOS-gnu-tools/blob/master/gnu-cmd.sh + +declare -a GNU_TOOLS_TO_UPDATE=( + "bash" + "emacs" + "gpatch" + "m4" + "make" + "nano" +) + +### 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 + brew install "${tool}" +done + +### Update GNU Tools +for tool in "${GNU_TOOLS_TO_UPDATE[@]}"; do + brew upgrade "${tool}" +done From 3190ced728f2fec6ebc7f7cea783d1c55bb13577 Mon Sep 17 00:00:00 2001 From: Mark Michaelis Date: Sat, 8 Mar 2025 09:58:50 +0100 Subject: [PATCH 09/15] feat(bin): Use `install` Also to Update --- bin/gnu-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/gnu-install.sh b/bin/gnu-install.sh index 7e993b0..857a215 100755 --- a/bin/gnu-install.sh +++ b/bin/gnu-install.sh @@ -66,5 +66,5 @@ done ### Update GNU Tools for tool in "${GNU_TOOLS_TO_UPDATE[@]}"; do - brew upgrade "${tool}" + brew install "${tool}" done From 1cd02f66a33f855c68900c481ae0d172d0770b1f Mon Sep 17 00:00:00 2001 From: Mark Michaelis Date: Sat, 8 Mar 2025 10:05:52 +0100 Subject: [PATCH 10/15] feat(bin): Prevent "Up-To-Date" Warning --- bin/gnu-install.sh | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/bin/gnu-install.sh b/bin/gnu-install.sh index 857a215..b0b139e 100755 --- a/bin/gnu-install.sh +++ b/bin/gnu-install.sh @@ -36,23 +36,6 @@ declare -a GNU_TOOLS=( "wget" ) -### GNU Tools to update -### -### Some GNU tools are already installed on macOS, but may be outdated. -### This list contains the tools that should be updated. -### -### References: -### - https://github.com/asantra1/macOS-gnu-tools/blob/master/gnu-cmd.sh - -declare -a GNU_TOOLS_TO_UPDATE=( - "bash" - "emacs" - "gpatch" - "m4" - "make" - "nano" -) - ### Validate `brew` is installed if ! command -v brew &>/dev/null; then echo "Error: 'brew' is required. Please install it first." @@ -61,10 +44,15 @@ fi ### Install GNU Tools for tool in "${GNU_TOOLS[@]}"; do - brew install "${tool}" -done - -### Update GNU Tools -for tool in "${GNU_TOOLS_TO_UPDATE[@]}"; do - brew install "${tool}" + 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 From 72a0362b042911f5a5372f450f46e355608c7f27 Mon Sep 17 00:00:00 2001 From: Mark Michaelis Date: Sat, 8 Mar 2025 10:12:29 +0100 Subject: [PATCH 11/15] ci(github): Use gnu-install.sh --- .github/workflows/interactive-command.yml | 34 +---------------------- 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/.github/workflows/interactive-command.yml b/.github/workflows/interactive-command.yml index d83d04b..42fca42 100644 --- a/.github/workflows/interactive-command.yml +++ b/.github/workflows/interactive-command.yml @@ -37,39 +37,7 @@ jobs: - name: Install GNU tools on macOS if: ${{ inputs.install_gnu_tools }} run: | - brew install \ - gnu-sed \ - gawk \ - grep \ - findutils \ - coreutils \ - diffutils \ - gnu-tar \ - gnu-time \ - gnu-indent \ - gnu-getopt \ - gnu-which - # Show tree of /usr/local/opt - ls -R /usr/local/opt - 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 }} From a3a839f957833d8b321e2f2f0c1b729ca6307631 Mon Sep 17 00:00:00 2001 From: Mark Michaelis Date: Sat, 8 Mar 2025 13:08:23 +0100 Subject: [PATCH 12/15] ci(github): Also Init Submodules --- .github/workflows/interactive-command.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/interactive-command.yml b/.github/workflows/interactive-command.yml index 42fca42..743e8db 100644 --- a/.github/workflows/interactive-command.yml +++ b/.github/workflows/interactive-command.yml @@ -33,6 +33,7 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 1 + submodules: recursive - name: Install GNU tools on macOS if: ${{ inputs.install_gnu_tools }} From 4f02ecf10523e0306064827d20a5e9237406f803 Mon Sep 17 00:00:00 2001 From: Mark Michaelis Date: Sat, 8 Mar 2025 13:11:55 +0100 Subject: [PATCH 13/15] feat(demo): Add Script Running All Demos --- demo/all-demos.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100755 demo/all-demos.sh diff --git a/demo/all-demos.sh b/demo/all-demos.sh new file mode 100755 index 0000000..bea70b6 --- /dev/null +++ b/demo/all-demos.sh @@ -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 From 931edc90688fd7b6f0597cee7b71218e49eaa5a1 Mon Sep 17 00:00:00 2001 From: Mark Michaelis Date: Sat, 8 Mar 2025 13:13:18 +0100 Subject: [PATCH 14/15] ci(github): Default to Running All Demos --- .github/workflows/interactive-command.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/interactive-command.yml b/.github/workflows/interactive-command.yml index 743e8db..3da98dc 100644 --- a/.github/workflows/interactive-command.yml +++ b/.github/workflows/interactive-command.yml @@ -6,7 +6,7 @@ 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 From 82c39302d3e00c2f6f2b7dcb461608da9fe336dc Mon Sep 17 00:00:00 2001 From: Mark Michaelis Date: Sat, 8 Mar 2025 13:24:11 +0100 Subject: [PATCH 15/15] ci(github): Set a Dynamic Run Name --- .github/workflows/interactive-command.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/interactive-command.yml b/.github/workflows/interactive-command.yml index 3da98dc..cd07246 100644 --- a/.github/workflows/interactive-command.yml +++ b/.github/workflows/interactive-command.yml @@ -21,6 +21,9 @@ on: default: false type: boolean +run-name: | + ICE: ${{ inputs.command }} (${{ inputs.os }}, GNU? ${{ inputs.install_gnu_tools }}) + permissions: contents: read